2014-09-13 10 views
6

Inspired by my observation in a previous question, postanowiłem zrobić mały test:Dlaczego clang pozwala mi wziąć tymczasowe przez odwołanie non const w trybie C++ 03?

#include <iostream> 
#include <sstream> 

int main() 
{ 
    char c = 'A'; 
    std::stringstream ss("B"); 

    // I know this is bad mojo; that's why I'm testing it 
    ss >> char(c); 

    std::cout << c << std::endl; 
} 

Moja wersja kompilatora:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

Kompilacja dzyń w trybie C++ 03 , kompiluje i działa poprawnie:

$ clang++ -Wall -pedantic -std=c++03 test.cpp 
test.cpp:9:6: warning: expression result unused [-Wunused-value] 
    ss >> char(c); 
    ~~^~~~~~~~ 
1 warning generated. 
$ ./a.out 
A 

Wydrukuje się A, co jest w porządku, biorąc pod uwagę, że ten kod nie powinien się nawet kompilować. Przejście do trybu C++ 11, poprawnie błędy podczas kompilacji (error: invalid operands to binary expression ('std::stringstream' (aka 'basic_stringstream<char>') and 'int')).

Tak, w trybie C++ 03 daje ostrzeżenie, ale nie jest to ostrzeżenie, którego oczekiwałbym (spodziewałem się pewnego rodzaju ostrzeżenia/błędu "przyjmowanie tymczasowych odwołań" lub ostrzeżenia lub błędu mówiącego no operator>> akceptuje parametr char).

Moje pytanie brzmi: dlaczego kod został pomyślnie skompilowany w trybie C++ 03? Czy używasz alternatywnego przeciążenia z operator>>, które pozwala uniknąć użycia tymczasowego przez odniesienie? Czy jest zbyt luźna i pozwala mi wziąć tymczasowe przez odniesienie? Zastanawiam się, dlaczego klang w ogóle akceptuje ten kod; GCC 4.9 prawidłowo błędy w C++ 03/11 tryby z znacznie bardziej istotny błąd (error: no match for 'operator>>' (operand types are 'std::stringstream {aka std::basic_stringstream<char>}' and 'char')). Zachowanie Clanga w trybie C++ 03 jest dla mnie zagadkowe.

+2

Moja wersja ('clang wersja 3.5.0 (tagi/RELEASE_350/wersja ostateczna), Target: x86_64-unknown-linux-gnu, Model wątku: posix') poprawnie wyświetla błędy, więc możliwe, że jest to błąd, który zostało naprawione. –

+0

Spodziewałbym się, że 5.1 będzie późniejszy niż 3.5.0. Więc jeśli cokolwiek, to zostało wprowadzone, a nie naprawione. – celtschk

+1

@celtschk 5.1 to numer wersji Apple. Jest oparty na wersji 3.4svn, więc 3.5 jest nowsza. – sepp2k

Odpowiedz

2

myślę, że powołuje się na operator bool() z std::stringstream, to znaczy, że kod jest interpretowany jako

bool(ss) >> char(c); 

co oczywiście jest ważne stwierdzenie bez skutku. Niejawna konwersja do bool zwraca !fail() i jest co pozwala kod jak

while (ss >> foo) 
    ... 

Standard pozwala na konwersję do innego rodzaju, który konwertuje do bool zamiast zwykłego bool (na przykład void*) dokładnie, aby uniknąć tego typu problemów. Najwyraźniej twoja implementacja nie wykorzystuje tej wolności.

+0

Ach, to miałoby sens, zwłaszcza, że ​​'operator bool()' został zmieniony w C++ 11 na 'explicit'. – Cornstalks

Powiązane problemy