Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing the address of function... declaration?

Tags:

c++

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?

like image 372
Edgar Rokjān Avatar asked Feb 06 '18 21:02

Edgar Rokjān


People also ask

How do you print the address of a function?

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.

How do I print an address value?

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 you print the address of a variable in C++?

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.

How do you print the address of a struct in C?

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.


1 Answers

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.

like image 118
StoryTeller - Unslander Monica Avatar answered Oct 04 '22 10:10

StoryTeller - Unslander Monica