2012-01-29 8 views
8

I puntatori intelligenti sono puntatori sottostanti, quindi esiste un modo per definire un parametro shared_ptr su una funzione come non aliasing di un altro shared_ptr o un altro puntatore di qualsiasi tipo?È possibile applicare __restrict__ a shared_ptr <T>?

Oppure, per qualche motivo, non necessario?

Sono interessato ai compilatori gcc> = 4.2 e llvm-clang> = 2.0 (anche le risposte per altri compilatori potrebbero essere interessanti).

+0

C++ non ha alcuna parola chiave 'restrict' o' __restrict__'. Se stai chiedendo informazioni sulle estensioni della lingua in un particolare compilatore, devi dire quale. –

+0

@ BenVoigt scusa - chiarito in modifica. – James

+3

Sembra improbabile che una soluzione che vuole lavorare su puntatori ristretti voglia rivendicare la proprietà condivisa del puntatore. Per non parlare del fatto che in un sistema con proprietà condivisa si finisce per sapere che i puntatori sono effettivamente distinti. In ogni caso, immagino che la tua funzione actualky voglia prendere dei puntatori [ristretti] piuttosto che 'std :: shared_ptr ' s. –

risposta

7

Basta estrarre i puntatori con .get() e contrassegnarli come __restrict__. Ricorda, inserire __restrict__ nei parametri della funzione equivale a mettere __restrict__ su variabili locali. In particolare, il compilatore non tenta di impedirti di chiamare la funzione con due puntatori che puntano ovviamente allo stesso oggetto; per esempio. foo(i,i).

Se si vuole fare una promessa al compilatore che alcuni puntatori non fanno riferimento a vicenda, consentendo al compilatore di fare di più ottimizzazioni, quindi utilizzare il codice qui sotto e fare le operazioni attraverso xp e yp invece di x e y .

#include<iostream> 
#include<memory> 
using namespace std; 

void foo(shared_ptr<int> x, shared_ptr<int> y) { 
     int * __restrict__ xp = x.get(); 
     int * __restrict__ yp = y.get(); 
} 

int main() { 
     shared_ptr<int> i = make_shared<int>(3); 
     shared_ptr<int> j = make_sharet<int>(4); 
     foo(i,j); 
} 
+2

Perché dici che i parametri della funzione di marcatura come 'restrict' sono diversi dalla dichiarazione delle variabili locali del puntatore' restrict'? È qualcosa che ha a che fare con l'ottimizzazione di 'gcc' o è un comportamento sottostante di' restrict' (che attualmente non capisco;)) –

+0

Dico che è * non * diverso. Proverò a riformularlo per essere più chiaro. –

+0

Stavo per scrivere questo, ma non sono riuscito a trovare QUALSIASI grammatica per '__restrict__' che dicesse se è stato permesso sulle variabili locali. C'è documentazione da qualche parte? –

5

Se si desidera eseguire operazioni non-alias sull'oggetto sottostante associato con un puntatore condiviso si potrebbe esplicitamente delegare ad una routine di lavoro che prende un non-alias parametro pointer:

void worker (mytype *__restrict x, mytype *__restrict y) 
{ 
    // do something with x, y with a no-alias guarantee 
} 

int main() 
{ 
    std::shared_ptr<mytype> p(new mytype); 
    std::shared_ptr<mytype> q(new mytype); 

// explicitly delegate the shared object 
    worker(p.get(), q.get()); 

    return 0; 
} 

io non sono sicuramente quello che hai in mente, ma questo permetterebbe alla gestione della memoria di alto livello di essere gestita in sicurezza dal puntatore intelligente, mentre il lavoro a basso livello forse in modo più efficiente con puntatori no-alias.

Come @BenVoigt ha sottolineato, restrict è solo ufficialmente parte di c99 - c++ non si suppone che ne sappia nulla. MSVC lo supporta comunque tramite __restrict e come hai detto GCC ha __restrict__.

Spero che questo aiuti.