Consider the following MCVE:
#include <iostream>
int main()
{
void foo(int);
std::cout << foo << std::endl;
return 0;
}
Here I intentionally try to print a pointer to a function in a wrong way so that the operator<< overload which accepts bool
is chosen.
basic_ostream& operator<<( bool value );
The thing that puzzles me is that both gcc 7.2 and clang 5.0 produce a warning, but compile and link the program.
In the same time, Visual Studio 15.5.6 doesn't link this example.
Personally, I expected, that this code won't link at all despite the compiler used as foo
seems to be ODR-used.
Could anybody explain why gcc and clang are able to link the program?
We can get the address of a function by just writing the function's name without parentheses. Please refer function pointer in C for details. In C/C++, name of a function can be used to find address of function.
To print the memory address, we use '%p' format specifier in C. To print the address of a variable, we use "%p" specifier in C programming language. There are two ways to get the address of the variable: By using "address of" (&) operator.
How do I print the address stored in the pointer in C++? int *ptr = &var; printf("%p", ptr); That will print the address stored in ptr will be printed.
In C, we can get the memory address of any variable or member field (of struct). To do so, we use the address of (&) operator, the %p specifier to print it and a casting of (void*) on the address.
It is an ODR violation. But according to [basic.def.odr]/10, emphasis mine:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
And we must recall that compilers are free to assume you don't write code that exhibits undefined behavior or is otherwise ill-formed in ways they don't need to diagnose. Because each function must have an address that isn't null, the bool
overload can just be called with true
, since that's what the conversion must yield in a valid program.
We can see GCC 7.3 doing just that. It passes 1 for what is meant to be the result of the conversion, even at -O0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With