Printing address function ... declaration?

Consider the following MCVE:

#include <iostream> int main() { void foo(int); std::cout << foo << std::endl; return 0; } 

Here, I intentionally try to print the function pointer incorrectly, so the <<overload operator, which accepts bool .

  basic_ostream& operator<<( bool value ); 

What puzzles me is that gcc 7.2 and clang 5.0 give a warning, but compiles and links the program.

At the same time, Visual Studio 15.5.6 does not bind this example.

Personally, I expected this code to not bind at all, even though the compiler used as foo seems to be using ODR.

Can someone explain why gcc and clang can link the program?

+5
source share
1 answer

This is a violation of ODR. But according to [basic.def.odr] / 10 , my attention:

Each program must contain exactly one definition of each non-line function or variable that is not used in this program outside the discarded expression; no diagnostics required . The definition can be explicitly displayed in the program, it can be found in the standard or user library or (if necessary), it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). A built-in function or variable must be defined in each translation unit in which it is odr - used outside the discarded operator.

And we must remember that compilers may assume that you are not writing code that exhibits undefined behavior or is otherwise poorly formed in a way that they do not need to diagnose. Since each function must have an address that is not null, the bool overload can only be called with true , since this is what the conversion should do in the actual program.

We can see GCC 7.3 doing just that. It passes 1 for what should be the result of the conversion, even at -O0 .

+7
source

Source: https://habr.com/ru/post/1275205/


All Articles