2014-11-21 17 views
8

Durante l'apprendimento dei problemi di allineamento, mi sono reso conto che la mia implementazione di g ++ 4.9 (macports OS X) non supportava lo std::align. Se provo a compilare (con -std=c++11) questo codice di esempio da http://www.cplusplus.com/reference/memory/align/std :: align non supportato da g ++ 4.9

// align example 
#include <iostream> 
#include <memory> 

int main() { 
    char buffer[] = "------------------------"; 
    void * pt = buffer; 
    std::size_t space = sizeof(buffer) - 1; 
    while (std::align(alignof(int), sizeof(char), pt, space)) { 
    char* temp = static_cast<char*>(pt); 
    *temp = '*'; ++temp; space -= sizeof(char); 
    pt = temp; 
    } 
    std::cout << buffer << '\n'; 
    return 0; 
} 

il compilatore sputa fuori l'errore

error: 'align' is not a member of 'std' 

Questo sembra strano come g ++ sembra aver implementato il supporto di allineamento dal g ++ 4.8 , https://gcc.gnu.org/projects/cxx0x.html (N2341)

Il codice viene compilato in clang ++ senza problemi.

Si tratta di un problema ben noto di g ++ di cui non sono a conoscenza? I compilatori online che ho testato (ideone e coliru) rifiutano anche il codice.

risposta

12

Sì, questa è una caratteristica nota mancante per gcc:

+0

Grazie per il link, appena visto che non ce l'ha fatta in g ++ 4.9 tronco, anche se il bug è stato segnalato più di un anno fa. – vsoftco

+1

@vsoftco, "trunk g ++ 4.9" non ha senso. Non esiste "g ++ 4.9 trunk". C'è il ramo 4.9, e c'è il tronco, che è un ramo diverso. La correzione è stata apportata al bagagliaio. Il campo Target Milestone nella segnalazione bug dice che sarà in GCC 5.0 –

+0

@JonathanWakely finalmente ottenuto :) – vsoftco

2

In alternativa si potrebbe scrivere il proprio codice di allineamento che corrisponde al comportamento di std::align. Il prossimo pezzo di codice è scritto da David Krauss in un post trovate qui: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350

inline void *align(std::size_t alignment, std::size_t size, 
       void *&ptr, std::size_t &space) { 
    std::uintptr_t pn = reinterpret_cast<std::uintptr_t>(ptr); 
    std::uintptr_t aligned = (pn + alignment - 1) & - alignment; 
    std::size_t padding = aligned - pn; 
    if (space < size + padding) return nullptr; 
    space -= padding; 
    return ptr = reinterpret_cast< void * >(aligned); 
} 
+1

Attenzione che la riga 'auto new_space = space - (aligned - pn);' è un potenziale underflow non firmato. Il link menzionato fornisce anche la versione corretta. – Kemal

Problemi correlati