2014-12-17 15 views
8

Sto cercando di usare alignas per i puntatori che sono membri della classe, e francamente non sono sicuro di dove dovrei metterlo.Lottando con sintassi alignas

Ad esempio:

class A 
{ 
private: 
    int n; 
    alignas(64) double* ptr;  

public: 
    A(const int num) : n(num), ptr(new double[num]) 
    {} 
}; 

che speravo assicurare i dati per PTR era allineato su un blocco di 64 byte. Utilizzando il compilatore Intel, non è così.

Qualcuno può indicarmi la direzione giusta per favore?

+5

Sembra essere [lavorare per me] (http://rextester.com/LCVUW98273) (notare la dimensione eccessivamente grande di 'A'). O speravi che i dati 'ptr' puntino ** a ** sarebbero stati troppo allineati? Ciò richiederebbe la violazione della causalità. –

+0

Forse il tuo compilatore non supporta un allineamento di 64? – Brian

+0

Grazie Igor, questo sta mostrando la fonte del mio fraintendimento. Il puntatore è allineato, non i dati a cui punta. Speravo che il blocco dati sarebbe uscito allineato. – user1683586

risposta

5

L'utilizzo della parola chiave alignas(N) su un membro di una classe fa sì che questo membro sia allineato in base all'allineamento specificato, non a nessuna entità potenzialmente indicata. Dopo tutto, quando si inizializza un puntatore con un valore non c'è controllo per allineare gli oggetti già esistenti.

si potrebbe desiderare di avere uno sguardo a std::align() che prende

  1. Una specifica per l'allineamento del puntatore restituito.
  2. La dimensione del blocco allineato.
  3. Un puntatore alla memoria allocata.
  4. La quantità della memoria allocata.

Restituisce un puntatore allineato in modo corrispondente a meno che non vi sia spazio sufficiente per soddisfare i requisiti di allineamento e dimensioni. Se non c'è abbastanza spazio la funzione restituisce un puntatore nullo.

+0

Sostituire 'ptr = x;' con 'ptr = decltype (ptr) (x & ~ uintptr_t (64-1));' garantirebbe che il ptr sia allineato su 64 limiti di byte. Non in senso buono, ammettiamolo. – Yakk

+0

@Yakk: Penso che usare 'std :: align()' sia preferibile. Ciò che l'implementazione fa per allineare appropriatamente il ponter è interamente fino all'implementazione. Poiché è probabile che il tuo approccio interferisca con la memoria _in front_ del puntatore, probabilmente vorrai prima spostare il puntatore su un valore adeguato. –

+0

Penso che il vero problema con la mia "soluzione" sia che sono andato fuori e ho modificato un puntatore, volenti o nolenti. Il puntatore è allineato, ma non punta a nulla di utile. – Yakk