GNU 如何在未定义 _GNU_SOURCE 时扩展函数 运行

How's GNU extended function running when didn't defined _GNU_SOURCE

我在不同平台测试了"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 中运行正常,它都 returns LLONG_MAX(0x7FFFFFFFFFFFFFFF).

我的问题是:

1 为什么我没有定义_GNU_SOURCE,但是gcc还是能找到正确的函数?

2 为什么gcc找对了函数还是失败了,有的时候函数还能用,有的时候就出错了?

3 为什么function失败的结果在不同的平台上是不同的,架构平台或其他因素如何影响不同的结果?

4 GNU扩展函数的正确使用方法?

谢谢!

隐式函数声明,默认启用的 GCC 扩展,使用 return 类型的 int,但是函数定义为 returning long long .有了这样的类型不匹配,任何事情都可能发生。实际上,结果取决于调用约定,这就是它们因架构而异的原因。

你真的应该用 -Werror=implicit-function-declaration 编译(或使用 C++)。将近二十年前(在 ISO/IEC 9899:1999 中),隐式函数声明已从 C 中删除,但我们仍然无法更改 GCC 默认值,因为太多的 autoconf 检查会中断,导致软件意外丢失功能。

(我想你的意思是在你的问题中写 retval 而不是 errno。)