是否有可能通过extern链接来重载函数? [英] Is it possible to overload functions with extern linkage?

查看:159
本文介绍了是否有可能通过extern链接来重载函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 std声明中看到了一个奇怪的代码:: atexit

  externCint atexit(void(* func )()); 
externC ++int atexit(void(* func)()); // ...为什么有两个功能?

我猜这是某种函数重载,但看起来显然是错误的。



这是什么?为什么它是必要的?

解决方案

您的源代码问题



这是cppreference有点误导。



用不同的存储类指定符声明两次相同的函数是非法的,导致构建失败。如果您查看 libstdc ++ (GCC的标准库实现)的源代码,您会看到实际上只提供了 externC版本






虽然 [C ++ 11:18.5] 列出了两个声明,就像cppreference一样,这不是 ,这意味着两个声明都可以在单个实现中使用;这意味着一个实现可以选择声明它们:即它占 [C ++ 11:17.6.4.3.3 / 4]


来自标准C库的每个函数签名都通过外部链接声明,并保留给实现以用作函数签名同时具有externC和externC ++关联 [..]


/ b>


[C ++ 11:17.6.2.3/2]:从外部链接声明的C标准库中有 externC或 externC ++链接是实现定义的。建议为此目的使用 externC ++链接

这条规则在这里明确指出:


[C ++ 11:7.5 / 5]:

code>如果两个声明声明具有相同名称的函数和参数类型列表(8.3.5)成为同一名称空间的成员,或者声明具有相同名称的对象成为同一名称空间的成员,并且声明给出名称不同的语言联系,该方案是不健全的;如果声明出现在不同的翻译单元中,则不需要诊断。






为什么这可能会令人困惑



在我看来,这确实会在标准的其他地方引起一些问题;例如:


[C ++ 11:25.5 / 2]:内容与标准C库标题< stdlib.h> 相同,但以下情况除外:

[C ++ 11:25.5 / 3]:函数签名:

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

被两个声明取代:

<$ (void * key,const void * base,
size_t nmemb,size_t size,
int(* compar)(const void * *,const void *));
$ b $ externC ++void * bsearch(const void * key,const void * base,
size_t nmemb,size_t size,
int(* compar)(const void * const void *));

两者与原始声明具有相同的行为。


我认为这是一种语言缺陷。


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?

解决方案

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.

这篇关于是否有可能通过extern链接来重载函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆