2015-04-18 13 views
11

Oggi ho fatto un piccolo errore di battitura nel mio programma e stavo vagando perché non stavo ottenendo alcun risultato, sebbene il programma fosse compilato correttamente. Fondamentalmente riduce a questo:Perché <invece di << nell'output dello stream è ancora compilato?

#include <iostream> 

int main() 
{ 
    std::cout < "test"; // no << but < 
} 

ho assolutamente idea di che tipo di conversione implicita viene eseguita qui così il programma viene compilato ancora (sia g ++ 4.9.2 e anche g ++ 5). Ho appena realizzato che clang ++ rifiuta il codice. Esiste una conversione in void* eseguita (non riesco a pensare ad altro)? Ricordo di aver visto qualcosa di simile, ma pensavo che fosse stato risolto in g ++ 5, ma non sembra essere il caso.

EDIT: non ero compilazione con -std=c++11, in modo che il codice era valida in pre-C++ 11 (a causa della conversione al void* di ostream). Quando si compila con -std=c++11 g ++ 5 rifiuta il codice, g ++ 4.9 lo accetta ancora.

+2

Viene visualizzato un avviso da g ++ 4.9.2 su un valore calcolato inutilizzato anche se si utilizza '-Wall'. –

+0

@Raphael in effetti, quando ho compilato non ho guardato tutti gli avvertimenti, ora vedo e ho realizzato cosa è successo, anche se devo dire che è un po 'insolito. Uso la maggior parte del tempo '-Wall', tuttavia questo era un piccolo pezzo di codice che ho compilato in un testo sublime e ho realizzato che funziona magicamente – vsoftco

+0

Perché [questo] (http://coliru.stacked-crooked.com/a/ 667a9c3ad1ee9afe) fornisce 0 come output? – Destructor

risposta

9

Sì, il compilatore è la conversione cout ad un void*. Se si utilizza l'opzione -S per ottenere lo smontaggio del codice, vedrete qualcosa di simile:

mov edi, OFFSET FLAT:std::cout+8 
    call std::basic_ios<char, std::char_traits<char> >::operator void*() const 
    cmp rax, OFFSET FLAT:.LC0 
    setb al 
    test al, al 

che rende chiaro che operator void* è il colpevole.

Contrariamente a quanto detto da Bill Lynch, sono in grado di riprodurlo con —std=c++11 su Compiler Explorer. Tuttavia, sembra essere un difetto di implementazione, dal momento che C++ 11 avrebbe dovuto sostituire operator void* con operator bool su basic_ios.

+0

In C++ 11, non c'è 'operator void *()' su 'std :: ostream'. Quindi questo sarebbe un difetto di implementazione. –

+0

Penso che sia un difetto in g ++ 4.9 (g ++ 5 lo rifiuta) – vsoftco

+0

g ++ 4.9 ** non è ** pienamente compatibile con C++ 11 in alcuni punti per non rompere il suo ABI. Questa è una delle cose. g ++ 5 sarà completamente compatibile con C++ 11. –

5

Questo è valido solo prima del C++ 11.

Stai fondamentalmente facendo: ((void *) std::cout) < ((char *) "test")

+0

scusate, lo riprendo, non stavo usando '-std = C++ 11' .... g ++ 5 lo rifiuta davvero, g ++ 4.9.2 no, anche con' -std = c + + 11'. – vsoftco

Problemi correlati