与外部的“C”二义性,重载和函数指针(Possible ambiguity with extern

2019-07-22 05:34发布

随着正常功能,一个可以写

extern "C" int Frotz(int);  // in a header

int Frotz(int x) { return x; }

函数指针,不过,这似乎已经编译器之间的不一致实现。

extern "C" int Klutz(int (*)(int), int);

int Klutz(int (*fptr)(int), int x) { return (*fptr)(x); }

在声明中,该说法也extern "C" 。 在定义中,大多数编译器似乎满足这些功能,使Klutzextern "C"的功能。 太阳和Cray编译器,然而,解释这些功能作为不同,产生一个重载int Klutz(int (*fptr)(int), int x)后来生成链路时间误差。

虽然C ++ 98和第7.5.5 C ++ 11所担保的诠释Frotz ,我不能告诉我们,如果标准不明确是否extern "C"之前或检查超载后应该发生的匹配。

应该Klutz以上产生错位(C ++)符号或extern "C"符号?

编辑1

我可以用一个typedef来澄清对函数指针有C或C ++ ABI,但我感兴趣的(a)是否这里的代码定义Klutz有C ++联动,(B),其定义为具有C键,或(c )根据标准是模糊的,因此编译器可以自由选择如何解释它。

编辑2

这似乎是一个已知的问题,至少通过搜索bug跟踪这些编译器。 在我的测试中,GCC,铛,英特尔,MSVC,IBM XL,PathScale公司,PGI和Open64都分不清函数类型是除了语言联动,由标准明确要求相同(参见7.5.1节,引接受的答案)。 修复此将打破很多现有的代码,需要一个ABI改变。 我不知道实际使用对C与C ++语言联动不同的调用约定的任何编译器。

  • GCC错误 :“找到理由,要求从下一个标准删除此功能是怎么样的相关;-)” ......“我们甚至可以在官方WONTFIX决定。”

  • 铛的错误 :“我害怕的实际执行这一规则,因为这样做正确意味着使所述规范类型,它是要打破一吨的代码的语言联动的一部分。”

Answer 1:

与c ABI和C ++ ABI不能保证是相同的。 这样,一个extern "C"函数指针是从C ++函数指针不同的类型。 你需要的东西是这样的:

extern "C" {
    typedef int (*KlutzFuncType)(int);
    int Klutz (KlutzFuncType, int);
}

int Klutz (KlutzFuncType fptr, int x) { return (*fptr)(x); }

有这个问题的一些讨论在这里 。


我只有复印件草案 。 从7.5p1:

两个函数类型用不同的语言联系,即使它们在其他方面相同的不同类型。

我对此的解读是,你的第一个的第一个参数Klutz有不同的类型比你的第二个的第一个参数Klutz ,所以你的第二个Klutz应该有C ++联动。


有没有参加语言联动考虑了功能的类型,尽管标准说什么C ++实现。 在下面的代码段, KlutzCxxFuncType指与C ++键的功能,而KlutzCFuncType是指具有C链接的功能。

typedef int (*KlutzCxxFuncType)(int);

extern "C" {
    typedef int (*KlutzCFuncType)(int);
    int Klutz (KlutzCFuncType, int);
}

int Klutz (KlutzCxxFuncType fptr, int x) { return (*fptr)(x); }
int Klutz (KlutzCFuncType fptr, int x) { return (*fptr)(x); }

不区分基于语言联动功能类型的编译器会生成对这个代码重新定义错误。 例如, g++ 4.7.2将发出:

prog.cpp: In function ‘int Klutz(KlutzCFuncType, int)’:
prog.cpp:9:5: error: redefinition of ‘int Klutz(KlutzCFuncType, int)’
prog.cpp:8:5: error: ‘int Klutz(KlutzCxxFuncType, int)’ previously defined here


文章来源: Possible ambiguity with extern “C”, overloading, and function pointers
标签: c++ standards