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
。)
我在不同平台测试了"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
。)