不同的编译器显示 sizeof() 运算符的不同结果

Different compilers showing different results for sizeof() operator

#include<stdio.h>
int main(void)
{
    unsigned const* const a, b;
    printf("size of a: %ld, size of b: %ld ", sizeof(a), sizeof(b));
    return 0;
}

这段代码在不同的编译器上给出了不同的输出。 在 gcc 编译器中,输出为:

"size of a: 8, size of b: 4

在MSVS 2019编译器和MinGW编译器中,输出为

"size of a: 4, size of b: 4

我正在寻找此行为背后的解释。

编辑:

这里的ab有不同的变量类型吗?

32 位程序指针是 32 位长 == 4 字节。 64 位构建将有 64 位长指针 - 因此 8 个字节。

int 的 sizeof 最少为 2 个字节 - 通常为 4 个。

但即使是同一个编译器也会给你不同的数字(如果编译 32 位或 64 位程序):

https://godbolt.org/z/a45MPa

尽管 4 字节整数大小是典型值,但不能保证。特别是,大小取决于硬件和编译器。不同编译器中的 int 大小可以是 2 字节或 4 字节。

宣言

unsigned const* const a, b;

被解析为

unsigned const (* const a), b;

因此,ab 有不同的类型——a 是指向 const unsigned intconst 指针,而 b 只是const unsigned int.

这是 C 声明语法的一个方面,它没有被很好地教授并且经常使人绊倒。声明分为两个主要部分 - 一系列 声明说明符 和一系列 声明符 。指针性、数组性和函数性被指定为声明符的一部分。对于数组和函数声明符,这是显而易见的,因为 []() 运算符是后缀,但对于指针来说,这是令人困惑的,因为 a) * 运算符是一元的,而不是后缀,b) 空格是没有意义 - T *pT* p 的解释方式相同,如 T (*p).

对于上面的声明,声明说明符是unsigned const,声明符是* const ab

C 没有为大多数类型指定确切的大小 - 相反,它指定了这些类型必须能够表示的最小值范围。 unsigned int 必须能够表示 至少 范围内的值 [0..65535],这意味着它必须 至少 16位宽,但它可能更宽。指针类型与体系结构需要的一样大,在 64 位系统上通常为 8 个字节。