我已经遵循有线代码。使用 clang++ 运行失败,使用 g++ 运行。 在aarch64中,
long long int
是8 bytes
,struct S94
是16 bytes
(为什么?在x86-64中似乎是1 byte
)。
我看到了https://en.cppreference.com/w/cpp/language/bit_field,但没有这种情况。
我猜这是一个未定义的行为或实现定义的,因为它是如此连线,但没有证据。
谁能解释一下这段代码?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
extern void *memset (void *__s, int __c, size_t __n);
typedef long long int Talllong __attribute__((aligned));
struct S94 {
Talllong: 0;
};
struct S94 s94;
void check94va(int z, ...) {
va_list ap;
va_start(ap, z);
struct S94 arg1 = va_arg(ap, struct S94);
long long int tmp = va_arg(ap, long long);
//printf("result = %lld\n", tmp);
if (tmp != 2LL) {
printf("Fails!!!!\n");
}
va_end(ap);
}
int main(void) {
memset(&s94, '\0', sizeof(s94));
//printf("sizeof(s94) = %ld\n", sizeof(s94));
check94va(1, s94, 2LL);
return 0;
}
拥有大小为 0 的字段意味着该字段和下一个字段将具有下一个分配单元边界的内存位置。在 C++ 中,对于具有严格对齐要求的平台,该单位的大小为
sizeof(Talllong)
(在 C 中,据我所知,它是未定义的,可能是 sizeof(int)
,因为不支持大于 unsigned int
的字段)。
因此,结构体的开头、零 0 的字段和结构体的结尾必须有 3 个不同的地址,按 8 字节对齐,因为
S94
结构体的下一个相邻实例应从唯一对齐的地址开始。这使得结构体的大小为 16。
x86-64 没有分配单元对齐要求。这使得两个第一个地址相同,并且结构将具有最小可能大小
char
。