【发布时间】:2015-01-07 12:25:47
【问题描述】:
下面的代码是我看到的问题的简化版本;基本上外部函数testprint() 最终调用了test_xprintf.cpp 中定义的printf(),而不是标准的printf()。
(是的,代码看起来很奇怪,但它是为了代表问题,所以它本身不一定有意义。)
为什么链接器链接到test_xprintf 中定义的printf()?这是预期的行为还是依赖于工具?
//
// test_xprintf.cpp
//
#include <iostream>
#include <stdio.h>
#include <stdarg.h>
#include "test_dbgprintf.h"
/**
*
* There are 3 files in total:
* - test_xprintf.cpp
* - test_dbgprintf.h
* - test_dbgprintf.cpp
*
* Create a static C lib from test_dbgprintf.c and link with test_xprintf.cpp
*
* gcc -Wall -g -c -o test_dbgprintf.o test_dbgprintf.c &&
* ar -rcs libtest_dbgprintf.a test_dbgprintf.o &&
* g++ -Wall test_xprintf.cpp -L. -ltest_dbgprintf -I.
*/
extern "C" int printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
return -1;
}
int main()
{
// testprint() is a shell function which simply calls printf.
// If the printf function above is called, the return value will be -1.
int ret = testprint(4);
std::cout << "Ret value is " << ret << std::endl;
return ret;
}
//
// test_dbgprintf.h
//
#ifndef TEST_DBGPRINTF_H
#define TEST_DBGPRINTF_H
#if defined (__cplusplus)
extern "C" {
#endif
int testprint(int num);
#if defined (__cplusplus)
}
#endif
#endif
//
// test_dbgprintf.c
//
#include <stdio.h>
int testprint(int num)
{
// By right this should be calling the std printf but it is linked to the printf in test_printf.cpp instead.
return printf("This is called from testprint %d\n", num);
}
【问题讨论】:
-
你为什么要在 C++ 中尝试这种方法?只需使用命名空间或类来阐明您的意思是哪个
printf。 -
这不是自愿的,只是代码的组合方式。现在我更想知道为什么会发生而不是修复。
-
test_xprintf.cpp中printf()的签名与 std 库中printf()的签名匹配,并且它们都在您的全局命名空间中,因为您使用的是 C 而不是 C++。因此,链接器很可能只是在找到 std 库的 OBJ 之前找到 test_xprintf.cpp 的 OBJ。这是一个先到先得的问题。这正是 C++ 命名空间帮助解决的那种冲突。 -
在标准 C 或标准 C++ 中,这是未定义的行为(即标准不涵盖此处发生的情况)。您使用的是哪个链接器?
-
我正在使用 gnu 工具链。是的,我也这么认为;很高兴得到确认。