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

上一篇: Behaviour of sizeof() in C (GCC)

下一篇: Why does sizeof(x++) not increment x?