Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to overload functions with extern linkage?

I saw a strange code, in declaration of std::atexit:

extern "C"   int atexit( void (*func)() );
extern "C++" int atexit( void (*func)() ); // ... why are there two functions?

I guess it's some kind of function overloading, but it seems obviously wrong.

What's it? and why is it necessary?

like image 857
ikh Avatar asked Sep 29 '22 18:09

ikh


1 Answers

The problem with your source

This is cppreference being a little misleading.

Declaring the same function twice with different storage-class-specifiers is illegal and causes a build failure. If you look at the source for libstdc++ (GCC's standard library implementation), you'll see that only the extern "C" version is actually provided.


The standard's take on this

Although [C++11: 18.5] lists both declarations, just as does cppreference, this does not mean that both may be used in a single implementation; it means that an implementation may choose to declare either of them: that is, it accounts for [C++11: 17.6.4.3.3/4] which says:

Each function signature from the Standard C library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage [..]

Also:

[C++11: 17.6.2.3/2]: Whether a name from the C standard library declared with external linkage has extern "C" or extern "C++" linkage is implementation-defined. It is recommended that an implementation use extern "C++" linkage for this purpose

The rule is made explicitly clear here:

[C++11: 7.5/5]: If two declarations declare functions with the same name and parameter-type-list (8.3.5) to be members of the same namespace or declare objects with the same name to be members of the same namespace and the declarations give the names different language linkages, the program is ill-formed; no diagnostic is required if the declarations appear in different translation units. [..]


Why this can be confusing

To my mind, this does cause some problems in other places within the standard; for example:

[C++11: 25.5/2]: The contents are the same as the Standard C library header <stdlib.h> with the following exceptions:

[C++11: 25.5/3]: The function signature:

bsearch(const void *, const void *, size_t, size_t,
        int (*)(const void *, const void *));

is replaced by the two declarations:

extern "C" void *bsearch(const void *key, const void *base,
                         size_t nmemb, size_t size,
                         int (*compar)(const void *, const void *));

extern "C++" void *bsearch(const void *key, const void *base,
                           size_t nmemb, size_t size,
                           int (*compar)(const void *, const void *));

both of which have the same behavior as the original declaration.

I consider that to be a language defect.

like image 79
Lightness Races in Orbit Avatar answered Oct 13 '22 06:10

Lightness Races in Orbit