2015-04-18 30 views
11

今天我在程序中犯了一个小错字,并且为什么我没有得到任何输出,尽管程序编译得很好。基本上,它减少了这一点:为什么在流输出中<而不是<<仍然编译?

#include <iostream> 

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

我完全不知道在这里进行了什么样的隐式转换,因此程序仍然编译(包括G ++ 4.9.2,甚至G ++ 5)。我刚刚意识到,铿锵++拒绝代码。是否有转换为void*正在执行(想不到别的)?我记得看到过这样的事情,但我认为它是用g ++ 5来解决的,但似乎并非如此。

编辑:我不与-std=c++11编译,所以代码是有效的在预C++ 11(由于转换到的ostreamvoid*)。在编写-std=c++11 g ++ 5拒绝代码时,g ++ 4.9仍然接受它。

+2

尽管使用'-Wall'时,我从g ++ 4.9.2得到一个关于未使用计算值的警告。 –

+0

@Raphael的确,当我编译时我没有看到所有的警告,现在我看到并意识到发生了什么事情,虽然要说它有点不寻常。我大部分时间使用'-Wall',但是这是一小段代码,我编译成了一些崇高的文本,并且意识到它神奇地工作。 – vsoftco

+0

为什么[this](http://coliru.stacked-crooked.com/a/) 667a9c3ad1ee9afe)给出0作为输出? – Destructor

回答

9

是,编译器转换coutvoid*。如果您使用-S开关获得代码的反汇编,你会看到这样的事情:

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 

这清楚地表明,operator void*是罪魁祸首。

与Bill Lynch所说的相反,我可以用—std=c++11Compiler Explorer进行复制。但是,它似乎是一个实现缺陷,因为C++ 11应该在basic_ios上替换operator void*operator bool

+0

在C++ 11中,'std :: ostream'上没有'operator void *()'。所以这将是一个实施缺陷。 –

+0

我认为这是g ++ 4.9中的缺陷(g ++ 5拒绝它) – vsoftco

+0

g ++ 4.9 **不完全符合C++ 11在某些方面不符合ABI。这是其中的一件事。 g ++ 5将完全符合C++ 11标准。 –

5

这只在C++ 11之前有效。

你基本上做的:((void *) std::cout) < ((char *) "test")

+0

对不起,我收回了,没有使用'-std = C++ 11' .... g ++ 5确实拒绝它,g ++ 4.9.2不会,即使使用'-std = c + + 11'。 – vsoftco

相关问题