外部"C"静态空隙*功能

extern "C" static void* function

本文关键字:功能 静态 外部      更新时间:2023-10-16

在阅读了extern和static之后,我很困惑地发现代码中有以下行:

extern "C" static void* foo(int* a){
    return foo1(a);
}

为什么这不会产生任何错误?

下面也编译并执行与您的行相同的操作:

extern "C" {
  static void* foo(int* a){
    return foo1(a);
  }
}

static意味着foo()将仅在文件范围内可用,并且在链接时会覆盖extern "C"。通常情况下,extern "C"会在导出链接器时影响链接器使用的函数的名称,以便在链接整个程序时可以从其他对象文件调用该函数。通常,当您想要链接到从定义foo()的C源构建的对象文件时,或者当您想要定义foo()以便C代码可以调用它时,就会使用此选项。然而,static导致foo根本无法导出,因此它基本上甚至没有名称(它有内部,而不是外部链接)。

CCD_ 9也具有次要作用。它也成为foo类型的一部分。也就是说,C++代码将把foo看作具有类型extern "C" void(int*)。基本上,这控制了调用约定。例如,C++编译器在寄存器/堆栈上的参数排列方式可能与C编译器不同。使foo成为C函数意味着它将使用C约定而不是C++约定。这使得例如将指向foo的函数指针传递给期望指向C函数的指针的C函数是安全的。例如,标准库具有

extern "C" typedef int C_CMP(void const*, void const*);
extern "C++" typedef int CXX_CMP(void const*, void const*);
void std::qsort(void *, std::size_t, std::size_t, C_CMP);
void std::qsort(void *, std::size_t, std::size_t, CXX_CMP);

对于extern "C"&foo被传递给第一个过载,但没有它/对于extern "C++",它被传递给第二个过载。在没有extern "C"的情况下声明foo,然后尝试将其传递到一个C函数中,该函数需要指向C函数的指针,这是不安全的。它可能会工作,但也可能会严重损坏。加上extern "C",它就变得正确了——你是安全的。