在这种情况下,GCC 和 clang 是否显示与 Visual Studio 相同的结果,关于语言链接?
Do GCC and clang show the same result as Visual Studio on this case, about language linkage?
[dcl.link]/4:
联动规格嵌套。当联动规格嵌套时, 最内在的是语言联系。联动规格 不建立范围。仅应出现联动规范 在命名空间范围内。在联动规范中,指定的 语言链接适用于所有函数的功能类型 声明符、带外部链接的函数名称和变量 在链接规范中声明的具有外部链接的名称。 [ 示例:
extern "C" // the name f1 and its function type have C language linkage; void f1(void(*pf)(int)); // pf is a pointer to a C function
。
— 结束示例 ]
请注意,传递给下面c_f()
函数&foo
指针不是指向 C 函数的指针。此代码在VS2017中正常编译和链接。但根据[dcl.link]/4的说法,它不应该。
文件main.cpp
:
#include <stdio.h>
extern "C" // the name c_f and its function type have C language linkage;
void c_f(void(*pf)(int)); // pf is a pointer to a C function
void foo(int i) {
printf("%dn", i);
}
extern "C" void c_foo(int);
int main() {
c_foo(1); // Calls c_foo(int) defined in other.c
c_f(&foo); // Calls c_f(void(*)(int)) defined in other.c, but &foo is not a pointer to a C function !!
}
文件other.c
:
#include <stdio.h>
void c_f(void(*pf)(int)){
pf(2);
}
void c_foo(int i) {
printf("%dn", i);
}
我很想知道 clang 和 GCC 是否符合标准,但我无法在 Web 编译器中验证这一点。
编辑
我突然意识到,在上述问题上,我真的不需要两个文件来验证 clang 和 GCC 是否符合标准。如果标准要求 C 函数的地址,作为函数c_f()
的参数,并且main.cpp
中的代码提供C++函数的地址,则C++编译器在编译此文件时必须抱怨1。但这在叮当和海湾合作委员会中都不会发生。那么,我不妨说,叮当和海湾合作委员会在这方面也是有缺陷的。
1(如果我们假设需要诊断
你的代码根据 [dcl.link]/1 和 [expr.call]/1 显示未定义的行为(重点是我的(:
[dcl.link]/1:
所有函数类型、具有外部链接的函数名称和具有外部链接的变量名称都具有语言链接。[ 注意:与具有语言链接的实体关联的某些属性特定于每个实现,此处不进行介绍。例如,特定的语言链接可能与表示具有外部链接的对象和函数名称的特定形式相关联,或者与特定的调用约定相关联,等等。 — 尾注 ] 所有函数类型、函数名称和变量名称的默认语言链接是C++语言链接。具有不同语言链接的两个函数类型是不同的类型,即使它们在其他方面相同。
[expr.call]/1:
函数调用是一个后缀表达式,后跟括号,其中包含可能为空的、以逗号分隔的初始值设定项子句列表,这些初始值设定项子句构成函数的参数。后缀表达式应具有函数类型或函数指针类型。对于对非成员函数或静态成员函数的调用,后缀表达式应为引用函数的左值(在这种情况下,后缀表达式上禁止函数到指针的标准转换(,或者应具有函数指针类型。通过函数类型与被调用函数定义的函数类型的表达式调用函数会导致未定义的行为([dcl.link](。对于对非静态成员函数的调用,后缀表达式应是隐式([class.mfct.non-static]、[class.static](或显式类成员访问,其 id-expression 是函数成员名称,或指向选择函数成员的成员的指针表达式;调用作为对象表达式引用的类对象的成员。在隐式类成员访问的情况下,隐含的对象是 this 指向的对象。[注意:形式为f((的成员函数调用被解释为(*this(.f(((参见[class.mfct.non-static](。如果使用函数或成员函数名称,则可以重载该名称,在这种情况下,应根据 [over.match] 中的规则选择适当的函数。如果所选函数是非虚拟函数,或者类成员访问表达式中的 id 表达式是限定 id,则调用该函数。否则,将调用对象表达式动态类型中的最终覆盖器;此类调用称为虚函数调用。[ 注意:动态类型是对象表达式的当前值所引用的对象类型。[class.cdtor] 描述了当对象表达式引用正在构造或销毁的对象时虚拟函数调用的行为。— 尾注 ]
- 算术运算的结果类似于:C浮点变量中的1/3
- 在这种情况下,GCC 和 clang 是否显示与 Visual Studio 相同的结果,关于语言链接?
- 你能在任何独立于架构的低级语言中获得更小的整数吗?
- 如何在未评估的上下文中将成员函数的结果类型应用于类成员
- 特定于域的语言工具 Visual Studio 2012 输出C++
- 适用于交互式移动地图的语言/框架
- 如何创建一个同时适用于多种语言的包装器
- 将多态函数应用于每个元组元素的结果类型
- 错误 C4146:一元减号运算符应用于无符号类型,结果仍然无符号
- 如何将函数静态应用于非类型模板包的各个元素并对结果求和
- 依赖于基类以获取派生类结果的C++函数
- 基于套接字的通信独立于用于实现它的编程语言.怎么可能
- 将函数应用于参数包的每个元素的语言功能
- 嵌套用于未产生所需结果的循环
- 什么样的语言特性适合于只有几行不同的类似函数
- 在Java或C++等编程语言中有效地模拟SQL的group by子句,而不是求助于RDBMS
- 使用C语言和图形库编写独立于操作系统的程序
- CryptEncrypt为不同的语言提供不同的结果
- 为什么编译器不帮助我们解决类型特征,而是求助于语言怪癖?
- 如何将排序函数应用于字符串.find( ) 以按字母顺序打印结果