• 你真的知道C语言里extern "C" 的作用吗?


    经常在C语言的头文件中看到下面的代码:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // all of your legacy C code here
    
    #ifdef __cplusplus
    }
    #endif
    

    这通常用于C++C混合编程的时候,为了防止C++的编译器在编译C文件的时候出现错误;
    众所周知,C++可以进行函数名重载,但是C则没有这种功能,那这和extern "C"又有什么关系呢?
    先看下面这个表格,如下所示;

    语言 描述
    C 函数名可以作为唯一ID和代码段的程序建立联系
    C++ 因为重载的关系,函数名符号会被破坏,从而会更加函数的参数不同而重新生成函数符号

    未添加 extern “C”

    test.h

    #ifndef TEST_H
    #define TEST_H
    
    void foo1(void);
    void foo2(void);
    void foo3(int i);
    
    #endif
    

    test.c

    
    void foo1(void){}
    void foo2(void) {}
    void foo3(int i){}
    
    int main(int argc,char** argv){
    	
    	foo1();
    	foo2();
    	foo3(1);	
    	return 0;
    }
    
    

    编译这两个文件,生成test.o文件,通过objdump查看函数符号;

    g++ -c test.c test.h
    objdump -t test.o
    

    可以看到函数符号已经被编译器修改了;
    在这里插入图片描述

    添加extern “C”

    test.h

    #ifndef TEST_H
    #define TEST_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    void foo1(void);
    void foo2(void);
    void foo3(int i);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    test.c

    #ifdef __cplusplus
    extern "C" {
    #endif
    void foo1(void){}
    void foo2(void) {}
    void foo3(int i){}
    #ifdef __cplusplus
    }
    #endif
    
    int main(int argc,char** argv){
    	
    	foo1();
    	foo2();
    	foo3(1);	
    	return 0;
    }
    
    

    编译这两个文件,生成test.o文件,通过objdump查看函数符号;

    g++ -c test.c test.h
    objdump -t test.o
    

    这时候函数符号是正确的;
    在这里插入图片描述

    extern “C” 是告诉C++的编译器不要打我这些C函数的主意;参考这篇文章会更加详细。

  • 相关阅读:
    HDU.2087 剪花布条
    一个acm过来人的心得
    一个acm过来人的心得
    HDU.2190 悼念512汶川大地震遇难同胞——重建希望小学
    HDOJ.2501 Tiling_easy version
    HDOJ.2501 Tiling_easy version
    HDU
    poj3216 Prime Path(BFS)
    poj1426 Find The Multiple (DFS)
    Rikka with Nickname (简单题)
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783360.html
Copyright © 2020-2023  润新知