2012-04-04 21 views
16

Leggendo la documentazione della libreria Eigen, ho notato che some objects cannot be passed by value. Ci sono sviluppi in C++ 11 o sviluppi pianificati che renderanno sicuro passare tali oggetti per valore?Il futuro dell'allineamento C++: passando per valore?

Inoltre, perché non c'è alcun problema nel restituire tali oggetti in base al valore?

+6

Hai guardato ['std :: aligned_storage <>'] (http://en.cppreference.com/w/cpp/types/aligned_storage)? – ildjarn

+2

Non ho mai sentito parlare di un oggetto che non può essere passato per valore e considererebbe mal progettato tale oggetto. Mi chiedo perché Eigen l'abbia fatto? –

+0

@ildjarn: Ora ho :) Potresti spiegare come influenza il passaggio di un tipo in base al valore? –

risposta

9

che potevano fare questo in C++ 11:

class alignas(16) Matrix4f 
{ 
    // ... 
}; 

Ora la classe sarà sempre allineato su un limite di 16 byte.

Inoltre, forse sono stupido ma non dovrebbe comunque essere un problema. Data una classe come questa:

class Matrix4f 
{ 
public: 
    // ... 
private: 
    // their data type (aligned however they decided in that library): 
    aligned_data_type data; 

    // or in C++11 
    alignas(16) float data[16]; 
}; 

compilatori sono ora obbligati a destinare una Matrix4f su un limite di 16 byte in ogni caso, perché sarebbe romperlo; il livello di classe alignas dovrebbe essere ridondante. Ma sono stato conosciuto per avere torto nel passato, in qualche modo.

+0

Ovviamente, sono necessari anche stack allineati a 16 byte ... Penso che alcuni compilatori popolari non rispettino i requisiti di allineamento per variabili locali e argomenti a meno che non si configuri anche l'allineamento dello stack. –

+3

@BenVoigt: Ah. :/Beh, almeno con 'alignas' è richiesto al compilatore di sputare un errore che dice" mi dispiace, non posso farlo ". (Ergo, imporre il passaggio per riferimento quando richiesto realmente.) – GManNickG

+0

@BenVoigt: Se questo è il caso, non è possibile inserire le proprietà intrinseche del compilatore (senza configurazioni del compilatore speciali) per SSE o altre cose simili nello stack, poiché hanno bisogno di 16 byte allineamento. –

16

È del tutto possibile che Eigen sia solo una libreria terribilmente scritta (o solo mal concepita); solo perché qualcosa è online non lo rende vero. Ad esempio:

Passare gli oggetti in base al valore è quasi sempre una pessima idea in C++, poiché ciò significa copie inutili e si dovrebbe passarle invece per riferimento.

Questo non è un buon consiglio in generale, a seconda dell'oggetto. A volte è necessario pre-C++ 11 (perché si potrebbe desiderare che un oggetto sia non copiabile), ma in C++ 11, è mai mai necessario. Potresti ancora farlo, ma non è mai necessario per passare sempre un valore per riferimento. Puoi semplicemente spostarlo per valore se contiene memoria allocata o qualcosa del genere. Ovviamente, se si tratta di una sorta di "look-but-don -t-touch", const& va bene.

Oggetti struct semplici, presumibilmente come quelli di Eigen Vector2d sono probabilmente abbastanza economici da copiare (specialmente in x86-64, dove i puntatori sono a 64 bit) che la copia non significherà molto in termini di prestazioni. Allo stesso tempo, lo è l'overhead (in teoria), quindi se si è in un codice critico delle prestazioni, può essere d'aiuto.

Quindi, di nuovo, non può.

Il particolare problema di arresto anomalo di cui Eigen sembra parlare riguarda l'allineamento degli oggetti. Tuttavia, la maggior parte del supporto di allineamento specifico del compilatore C++ 03 garantisce l'allineamento in tutti i casi. Quindi non c'è motivo che dovrebbe "rendere il tuo programma in crash!". Non ho mai visto una libreria SSE/AltaVec/etc che utilizza dichiarazioni di allineamento specifiche del compilatore che hanno causato arresti anomali con i parametri di valore. E ne ho usati parecchi.

Quindi se stanno avendo qualche tipo di problema di crash con questo, allora considererei Eigen di ... un merito dubbio. Non senza ulteriori indagini.

Inoltre, se un oggetto non è sicuro da passare in base al valore, come suggerito dai documenti Eigen, il modo corretto per gestirlo sarebbe rendere l'oggetto non costruibile dalla copia. L'assegnazione delle copie andrebbe bene, poiché richiede un oggetto già esistente. Tuttavia, Eigen non lo fa, il che suggerisce ancora una volta che gli sviluppatori hanno perso alcuni dei punti migliori del design dell'API.

Tuttavia, per la cronologia, C++ 11 ha la parola chiave alignas, che è un modo standard per dichiarare che un oggetto deve essere di un certo allineamento.

Inoltre, perché non c'è alcun problema nel restituire tali oggetti in base al valore?

Chi dice che non c'è (notando il problema di copia, non il problema di allineamento)? La differenza è che non è possibile restituire un valore temporaneo per riferimento. Quindi non lo fanno perché non è possibile.

+0

Grazie per la tua risposta (+1) - In risposta alla tua domanda "chi dice che non c'è?" Stavo semplicemente citando il fondo della documentazione collegata. Dicono che non c'è. –

+2

@NeilG: Immagino che non ci siano problemi nel restituire oggetti in base al valore, dal momento che il temporaneo (che può essere non allineato o non esiste nemmeno) non può essere comunque utilizzato.I valori sono allineati correttamente sia prima che dopo il ritorno, indipendentemente da dove (o se) sia temporaneo. –

+0

@MooingDuck: Grazie, questo risponde alla parte del valore di ritorno della mia domanda. –

Problemi correlati