注册 登录
编程论坛 C++教室

为什么这段程序错了呢?

后卿 发布于 2023-03-09 13:12, 203 次点击
e.h文件
extern "C" int ave();
e.c文件
int ave()
{
    return 1;
}
extern.cpp文件
#include<iostream>
#include "e.h"
int main()
{
    std::cout << ave();
}
报错原因:无法解析的外部命令ave???
请问有人知道吗
5 回复
#2
rjsp2023-03-09 16:50
按理应该可以编译通过,你可以先去掉 extern "C" 试试能不能编译通过?

另外
extern "C" 与 extern 功能完全不同
extern "C" 是指示使用C语言的命名规则
extern 是指示使用外部连接
#3
后卿2023-03-09 17:00
回复 2楼 rjsp
我在CSDN上和群里都问了,几个编程十年经验的人都说可以编译的,折腾了一下午后,终于知道什么原因了,在源文件前面也要加extern C
#4
rjsp2023-03-10 09:22
回复 3楼 后卿
因为你说了“e.h文件…巴拉巴拉…”,别人以为“e.c文件”中必然 #include "e.h" 了,提问时懒得写全

即,别人以为你说的是
程序代码:
extern "C" int ave();
int ave()
{
    return 1;
}
程序代码:
#include<iostream>
extern "C" int ave();
int main()
{
    std::cout << ave();
}


实际你说的却是
int ave()
{
    return 1;
}
程序代码:
#include<iostream>
extern "C" int ave();
int main()
{
    std::cout << ave();
}
#5
rjsp2023-03-10 09:40
说说编译成功或失败的原因

extern "C" int ave();
int ave()
{
    return 1;
}
因为指定是使用C语言的命名规则,生成的目标文件中就有一个类似 ave_我是C连接符 的名字

int ave()
{
    return 1;
}
因为没指定使用C语言的命名规则,生成的目标文件中就有一个类似 ave_我是C++连接符 的名字

#include<iostream>
extern "C" int ave();
int main()
{
    std::cout << ave();
}
因为指定是使用C语言的命名规则,它会在目标文件中寻找类似 ave_我是C连接符 的名字


#include<iostream>
int main()
{
    std::cout << ave();
}
因为没指定使用C语言的命名规则,它会在目标文件中寻找类似 ave_我是C++连接符 的名字

--------------------------------

而C和C++的链接名不一样的原因是 C++支持重载,即 不同的函数在源代码中可以使用同一个名称,那么自然就需要在目标文件中区分开,实际使用不同的名称
比如
    int foo( int );
    int foo( double, double );
在C++中可以同时存在,因此它需要在编译时取个不同的名字,比如
    foo_这是参数为int的链接名
    foo_这是参数为double和double的链接名
而C语言不允许重载,那只需要简单的
    _foo

定义 和 调用 必须保证同名才会在 link 阶段找到
#6
后卿2023-03-10 10:08
回复 5楼 rjsp
ok,明白
1