2014-11-21 13 views
8

Podczas nauki o problemach z wyrównaniem itp. Zdałem sobie sprawę, że moja implementacja g ++ 4.9 (macports OS X) nie ma wsparcia dla std::align. Gdy próbuję skompilować (z -std=c++11) ten przykładowy kod z http://www.cplusplus.com/reference/memory/align/std :: align nie obsługiwany przez 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; 
} 

kompilator wypluwa błąd

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

To wydaje się dziwne, jak g ++ wydaje się być realizowane wsparcie wyrównania ponieważ g ++ 4.8 , https://gcc.gnu.org/projects/cxx0x.html (N2341)

Kod kompiluje się pod klang ++ bez żadnych problemów.

Czy jest to znany problem z g ++, którego nie znam? Kompilatory online, które przetestowałem (ideone i coliru) również odrzucają kod.

Odpowiedz

12

Tak, jest to znany brakującym elementem dla gcc:

+0

Dzięki za link, tylko widział, że nie udało się w g ++ 4.9 bagażniku, choć błąd został zgłoszony więcej niż rok temu. – vsoftco

+1

@vsoftco, "bagażnik g ++ 4.9" nie ma sensu. Nie ma tu pnia "g ++ 4.9". Istnieje gałąź 4.9, a tam jest pień, który jest inną gałęzią. Poprawka została wprowadzona do bagażnika. Pole Cel milowy w raporcie o błędzie mówi, że będzie ono w GCC 5.0 –

+0

@ JonathanWakely w końcu to dostało :) – vsoftco

2

Jako alternatywę można napisać własny kod kalibracji, który pasuje do zachowania std::align. Kolejny fragment kodu został napisany przez Davida Krauss w poście znaleźć tutaj: 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

Pamiętaj, że linia 'auto new_space = space - (wyrównane - pn);' to potencjalny niepodpisany niedomiar. Wspomniany link zapewnia również poprawioną wersję. – Kemal

Powiązane problemy