2013-04-10 36 views
6

Przenoszę istniejący kod do kompilacji pod gcc 4.7.2 i natknąłem się na dziwny problem z nullptr. Udało mi się gotować w dół do prostego testu:gcc nullptr issue

#include <stdio.h> 

const char* g_marker = "Original value"; 

void SetMarker(const char* s) 
{ 
    g_marker = s; 
} 

char* Test1() 
{ 
    return SetMarker("I was here 1"), nullptr; 
} 

char* Test2() 
{ 
    SetMarker("I was here 2"); 
    return nullptr; 
} 

char* Test3() 
{ 
    return SetMarker("I was here 3"), (char*)NULL; 
} 

int main() 
{ 
    char* returnValue = Test1(); 
    printf("%s\n", g_marker); 
} 

skompilować ten zg ++ test.cpp -o testu -std = C++ 0x.

Wyjście, którego oczekiwałbym, to "Byłem tutaj 1", ale otrzymałem "Wartość pierwotną", co oznacza, że ​​SetMarker nigdy nie jest wywoływany.

Wywołanie Test2 lub Test3 daje oczekiwany wynik.

Kod, nad którym pracuję, wykorzystuje wzorzec widoczny w Test3 - pierwotnie bez rzutowania przed NULL - który dawał błąd przy niepoprawnej konwersji z int na char *, więc zacząłem zmieniać wszystkie te wartości NULL na nullptr. Niestety, to po prostu nie zachowuje się poprawnie.

Jestem prawdopodobnie zmuszony do zmiany kodu, aby użyć wzorca w Test2 (który wolę mimo to), ale jestem ciekawy, czy jest to błąd w kompilatorze, czy też czegoś brakuje.

+1

Wygląda jak błąd w starszych wersjach g ++; 4.8.0 podaje prawidłowy wynik. – ecatmur

Odpowiedz

7

Jest to błąd w g ++: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52988

g ++ był odrzucając skutki uboczne w wyrażeniach typu nullptr_t, przy założeniu, że wszystkie wartości nullptr_t są równoważne (które są, ale to nie znaczy, że ci może ignorować efekty uboczne!)

Zostało to naprawione w wydaniu 4.8.0; nowe wydania w gałęziach 4.x (4.6.4 i 4.7.3) również powinny mieć poprawkę.