代码之家  ›  专栏  ›  技术社区  ›  Alexander

在这种情况下,关于语言链接,GCC和clang是否显示了与Visual Studio相同的结果?

  •  1
  • Alexander  · 技术社区  · 8 年前

    [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
    

    结束示例]

    观察指针 &foo 传递给函数 c_f() 指向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("%d\n", 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("%d\n", i);
    }
    

    c_f() 和中的代码 main.cpp 1. clang 也不在 GCC

    1) 如果我们假设需要诊断

    1 回复  |  直到 8 年前
        1
  •  1
  •   underscore_d    8 年前

    您的代码显示未定义的行为,根据 [dcl.link]/1 [expr.call]/1

    [dcl.link]/1:

    具有不同语言链接的两种函数类型是不同的类型,即使它们在其他方面是相同的 .

    函数调用是一个后缀表达式,后跟括号,其中包含可能为空的逗号分隔的初始值设定项子句列表,这些子句构成函数的参数。后缀表达式应具有函数类型或函数指针类型。对于对非成员函数或静态成员函数的调用,后缀表达式应为引用函数的左值(在这种情况下,函数到指针的标准转换在后缀表达式上被抑制),或者应具有函数指针类型。 通过函数类型不同于被调用函数定义的函数类型的表达式调用函数会导致未定义的行为