【发布时间】:2019-04-16 01:54:38
【问题描述】:
我在不同平台上测试了诸如“wcstoq”之类的GNU扩展功能。 一开始我没有用 D_GNU_SOURCE 编译测试用例,所以得到如下编译警告:
wcstoq.c:31:12: warning: implicit declaration of function 'wcstoq'; did you mean 'wcstol'? [-Wimplicit-function-declaration]
retval=wcstoq(nptr,endptr,base);
^~~~~~
wcstol
当我使用 gdb 调试这个测试用例时,它进入了与我定义 _GNU_SOURCE 的情况相同的正确函数。 但是当我没有定义 _GNU_SOURCE 时,函数就出错了。
例如:
当我在 x86_64 中测试超出范围的情况时,它应该设置retval= LLONG_MAX(0x7FFFFFFFFFFFFFFF),但它实际上设置了retval= -1(0xFFFFFFFFFFFFFFFF)。
当我在其他平台 ppc 中测试时,结果也让我感到困惑,它实际上设置了retval=0x000000007FFFFFFF。
当我定义_GNU_SOURCE时,函数在x86_64和ppc中运行正常,它都返回LLONG_MAX(0x7FFFFFFFFFFFFFFF)。
我的问题是:
1 为什么我没有定义_GNU_SOURCE,但是gcc还是能找到正确的函数?
2 为什么gcc找对了,函数还是失败了,有些情况下函数还能用,有些时候就出错了?
3 为什么不同平台的功能失败结果不同,架构平台或其他因素如何影响不同的结果?
4 GNU 扩展函数的正确使用方法?
谢谢!
【问题讨论】:
-
在您显示的情况下没有 prototype 定义,因此编译不知道参数的大小(或数量)。 external 符号存在,因为它不是宏或内联符号。
-
我认为 4) 的最佳答案是您应该定义
_GNU_SOURCE以使库标头包含 GNU 扩展的原型。完全没有声明,编译器假定返回类型是int。 -
谢谢,@PeterCordes,你知道更多关于隐式声明函数的行为的信息吗,不仅是返回类型,还有一些输入或输出参数,是不是意味着这个函数的行为是不可预测或未定义?尤其是对于 GNU 扩展函数?
-
谢谢@ThomasDickey,但我很困惑和好奇为什么即使没有定义_GNU_SOURCE也可以调用该函数,以及为什么该函数的行为或输出在不同平台上不一样
标签: gcc compilation gnu cpu-architecture glibc