C(GCC)中sizeof()的行为
在回答关于sizeof()的问题时,为了看看GCC如何处理,我写了下面的代码:
#include<stdio.h>
#include<stddef.h>
#include<limits.h>
int main(int ac, char *argv[])
{
printf("%zun", sizeof(9999999999999999999999999999999999999999999999999999) );
printf("%zu %zu n", sizeof(int), sizeof(long long));
return 0;
}
编译后,GCC(4.1.2)发出警告(如预期):
t.c:8:24: warning: integer constant is too large for its type
t.c: In function main:
t.c:8: warning: integer constant is too large for long type
输出是:
16
4 8
GCC如何说sizeof(9999999999999999999999999999999999999999999999999999)
是16 sizeof(9999999999999999999999999999999999999999999999999999)
无论numnber
有多大,对于大于LLONG_MAX
整数字面量,总是16。 在我的64位平台上, sizeof(long)
等于sizeof(long long)
。
为什么GCC这样表现? 这是一种未定义的行为?!
gcc有一个叫做__int128
的特殊非标准类型,它是一个128位(16字节)的整数。 所以sizeof(__int128)
将返回16.它的接缝就像你的超大常量被视为这种__int128
类型。 考虑下面的代码:
typeof(9999999999999999999999999999999999999999999999999999) (*funcptr_a)();
unsigned __int128 (*funcptr_b)();
void dummy() {
funcptr_a = funcptr_b;
}
如果我更改funcptr_a和funcptr_b的声明中的任何类型,则分配funcptr_a = funcptr_b;
触发警告。 我没有得到警告(64位Linux上的gcc 4.6.3),因此我知道大整数常量的类型是unsigned __int128
。
顺便说一句,与铿锵3.0(也是64位Linux)你的代码输出
8
4 8
我会说这不是未定义的,而是一个实现定义的行为。 引用C99标准(章节6.4.4.1,第56页):
[...]如果一个整数常量不能用列表中的任何类型表示,那么它可能有一个扩展整数类型,如果扩展整数类型可以表示它的值。 [..]
我们可以问gcc本身:
__typeof__ (9999999999999999999999999999999999999999999999999999) var = 1;
printf("%lldn", var);
sizes.c:10:5: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘__int128’ [-Wformat]
所以gcc选择 - 如果支持 - 类型__int128
为太大的十进制常量。
什么神秘? 这是最大型的尺寸。 你被警告过。
标准所保证的是各种类型的相对大小。
1 == sizeof(char)<= sizeof(short)<= sizeof(int)<= sizeof(long)<= sizeof(long long)
链接地址: http://www.djcxy.com/p/21137.html