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?
I think you can not see such a code. At least there might be preprocessor directives similar to
#if
or#ifdef
that separate these two declarations because according to the C++ Standard5 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. Except for functions with C++ linkage, a function declaration without a linkage specification shall not precede the first linkage specification for that function. A function can be declared without a linkage specification after an explicit linkage specification has been seen; the linkage explicitly specified in the earlier declaration is not affected by such a function declaration.
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:Also:
The rule is made explicitly clear here:
Why this can be confusing
To my mind, this does cause some problems in other places within the standard; for example:
I consider that to be a language defect.