Clang将不同的函数签名编译为相同的符号

时间:2019-06-09 18:40:27

标签: c++ clang++

当我碰到一些我认为会给我链接器错误但没有的错误时,我正在阅读c ++链接器教程并使用一些函数调用。

我正在使用LLVM版本10在MacOS上进行编译

❯ c++ --version
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

我有2个cpp文件,log.cpp

#include <iostream>

void Log(const char* message)
{
    std::cout << message << std::endl;
}

math.cpp

#include <iostream>

int Log(const char* message);

int Multiply(int a, int b)
{
    int res = Log("Multiply");
    std::cout << "Got res: " << res << std::endl;
    return a * b;
}

int main()
{
    std::cout << Multiply(5, 8) << std::endl;
}

math.cpp中,我故意声明Log函数的返回类型不匹配。我希望可以编译它,但随后无法链接,但实际上它可以正常运行。我什至保存了返回值并打印出来以用于娱乐,这是按预期进行的垃圾处理,因为Log函数不返回任何内容。

/tmp
❯ c++ math.cpp log.cpp -o math

/tmp
❯ ./math
Multiply
Got res: -2002196896
40

我通过转储程序集并查看正在生成的功能符号走了一步:

/tmp
❯ c++ -S math.cpp log.cpp

/tmp
❯ ls -l *.s
-rw-r--r-- 1 rsahae wheel 31924 Jun  9 11:38 log.s
-rw-r--r-- 1 rsahae wheel 32022 Jun  9 11:38 math.s

/tmp
❯ grep Log log.s math.s
log.s:  .globl  __Z3LogPKc              ## -- Begin function _Z3LogPKc
log.s:__Z3LogPKc:                             ## @_Z3LogPKc
math.s: callq   __Z3LogPKc

所以现在我明白了为什么链接器不给出错误,因为即使方法签名不同,符号也看起来是相同的。

我在互联网上四处张望,但找不到明确告诉我这种行为发生原因的帖子。

我尝试了返回类型(浮点型和字符串型)的其他变体,它们仍然生成相同的符号。我还尝试过更改显然会产生不同符号的参数,并因此产生了预期的错误。

对于编译器为何将具有不同签名(具有返回类型)的这两个声明编译到同一符号中的问题,有人可以帮我解释或指向文档吗?

0 个答案:

没有答案