Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
771 views
in Technique[技术] by (71.8m points)

c++ - Is Visual Studio buggy in printing the function address?

Take the following testcase:

#include <iostream>

void foo()
{}

int main()
{
   std::cout << &foo << std::endl;
}

GCC 4.1.2, GCC 4.8 and GCC 4.9 (C++03 and C++11) all give the following output when building and then compiling:

$ g++ main.cpp -o test && ./test
main.cpp: In function 'int main()':
main.cpp:8:23: warning: the address of 'void foo()' will always evaluate as 'true' [-Waddress]
   std::cout << &foo << std::endl;
                 ^
1

This is supposedly because the only viable stream insertion for the function pointer is conversion-to-bool (and a cast to void* would be required to actually get an address into the stream).

However, Microsoft Visual Studio 2012 and 2013 output a pointer address instead.

Which set of toolchains is conformant? And is the non-conformance documented anywhere?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

MSVC can be made to function correctly and perform the conversion from function pointer to bool if you disable language extensions (/Za switch). If you do that, your code produces the following warnings (at /W4 on VS2013)

1>main.cpp(8): warning C4305: 'argument' : truncation from 'void (*)(void)' to 'std::_Bool'
1>main.cpp(8): warning C4800: 'void (*)(void)' : forcing value to bool 'true' or 'false' (performance warning)

and the output is 1


This behavior is documented under the Casts section

Both the C++ compiler and C compiler support these kinds of non-ANSI casts:
...
Non-ANSI casts of a function pointer to a data pointer

Sure enough, the following line compiles only with /Za disabled

void *p = &foo;

Disabling language extensions produces the error message

1>main.cpp(8): error C2440: 'initializing' : cannot convert from 'void (*)(void)' to 'void *'
1>          There is no context in which this conversion is possible

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...