Is it possible to overload functions with extern l

2019-04-08 18:00发布

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?

2条回答
手持菜刀,她持情操
2楼-- · 2019-04-08 18:08

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++ Standard

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. 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.

查看更多
叼着烟拽天下
3楼-- · 2019-04-08 18:27

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.

查看更多
登录 后发表回答