标准C ++库链接 [英] Standard c++ library linking
问题描述
我试图了解标准库何时链接到我自己的二进制文件.我写了以下内容:
I'm trying to understand when does standard library linking to my own binary. I've written the following:
#include <stdio.h>
double atof(const char*);
int main(){
const char * v="22";
printf("Cast result is %f", atof(v));
}
使用g++ -c main.cpp
编译成功,但是当我链接刚创建的目标文件时出现错误.错误描述是:
It's compiling successful with g++ -c main.cpp
, but when I'm linking just created object file I've an error. Error descriptio is:
/tmp/ccWOPOS0.o: In function `main':
main.cpp:(.text+0x19): undefined reference to `atof(char const*)'
collect2: error: ld returned 1 exit status
但是我不明白为什么会导致此错误?我认为标准的c ++库通过ld
链接程序自动链接到我的二进制文件.包含头文件和只声明一个我需要显式使用的函数之间有什么区别.
But I don't understand why this error is caused? I think that the standard c++ library automatically linked to my binary by the ld
linker. What is the difference between the including header files and just declaring a functions which I need to use explicitly .
推荐答案
作为C ++中的一般规则,手动声明诸如atof()
之类的库函数是一个坏主意.
As a general rule in C++, it is a bad idea to manually declare library functions such as atof()
.
它在旧的C程序中曾经很常见,但是C没有函数重载,因此对于几乎"正确的声明更为宽容. (有些旧的编译器是,我不能真正代表最新的编译器).这就是为什么我们将C描述为弱类型"语言,而将C ++描述为更强类型"语言.
It used to be common in old C programs, but C doesn't have function overloading so it is more forgiving about "almost" correct declarations. (Well some of the old compilers were, I can't really speak for the newest ones). That is why we describe C as a "weakly typed" language, while C++ is a more "strongly typed" language.
另一个麻烦是,编译器执行名称修改":它们传递给链接器的名称是源名称的修改版本. C编译器可能执行与C ++编译器完全不同的名称处理. atof()
的标准lib版本是C函数.要在C ++源文件中声明它,您需要将其声明为
An additional complication is that the compilers perform "name mangling": the name they pass to the linker is a modified version of the source name. The C compiler may perform quite different name mangling from the C++ compiler. The standard lib version of atof()
is a C function. To declare it in a C++ source file you need to declare it as
extern "C"
{
double atof(const char *);
}
或可能
extern "C" double atof(const char *);
还有许多其他复杂性,但这足以继续进行下去.
There are many additional complexities, but that is enough to go on with.
最安全的想法是只包含适当的标题.
Safest idea is to just include the appropriate headers.
#include <iostream>
#include <cstdlib>
int main()
{
const char v[]= "22";
std::cout << "Cast result is " << atof(v) << std::endl;
return 0;
}
额外的背景,以回复@DmitryFucintv的评论
- 通话约定
在调用函数时, 调用约定 有关如何在调用函数和被调用函数之间传递参数和返回值的信息.在x86架构上,最常见的两个是 __cdecl 和 __ stdcall ,但还有许多其他的东西.
When calling a function, a calling convention is an agreement on how parameters and return values are passed between the calling function and the called function. On x86 architecture, the two most common are __cdecl and __stdcall, but a number of others exist.
请考虑以下内容:
/* -- f.c --*/
int __stdcall f(int a, double b, char *c)
{
// do stuff
return something;
}
/* main.c */
#include <iostream>
extern int __cdecl f(int a, double b, char *c);
int main()
{
std::cout << f(1, 2.3, "45678") << std::endl;
return 0;
}
在C程序中,这可能会编译并链接OK.函数f()
期望其__stdcall格式的args,但我们以__cdecl格式传递它们.结果是不确定的,但很容易导致堆栈损坏.
In a C program, this will probably compile and link OK. The function f()
is expecting its args in __stdcall format, but we pass them in __cdecl format. The result is indeterminate, but could easily lead to stack corruption.
由于C ++链接器有点麻烦,它可能会生成与您看到的错误类似的错误.大多数人都认为这是更好的结果.
Because the C++ linker is a bit fussier, it will probably generate an error like the one you saw. Most would agree that is a better outcome.
2名称处理
名称修饰(或名称修饰)是一种方案,编译器在其中添加了一些额外的字符 object 名称为链接器提供一些提示. object 可以是函数或变量.允许函数重载的语言(例如C ++和Java)必须执行类似的操作,以便链接程序可以区分具有相同名称的不同函数之间的区别. 例如
Name Mangling (or name decoration) is a scheme where the compiler adds some extra characters to the object name to give some hints to the linker. An object might be a function or a variable. Languages that permit function overloading (like C++ and Java) must do something like this so that the linker can tell the difference between different functions with the same name. e.g.
int f(int a);
int f(double a);
int f(const char *a, ...);
这篇关于标准C ++库链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!