对于 C++ 来说,带有标记对齐属性的零宽度位字段的空结构是未定义的行为吗?

问题描述 投票:0回答:1

我已经遵循有线代码。使用 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;
}
c++ clang++
1个回答
0
投票

拥有大小为 0 的字段意味着该字段和下一个字段将具有下一个分配单元边界的内存位置。在 C++ 中,对于具有严格对齐要求的平台,该单位的大小为

sizeof(Talllong)
(在 C 中,据我所知,它是未定义的,可能是
sizeof(int)
,因为不支持大于
unsigned int
的字段)。

因此,结构体的开头、零 0 的字段和结构体的结尾必须有 3 个不同的地址,按 8 字节对齐,因为

S94
结构体的下一个相邻实例应从唯一对齐的地址开始。这使得结构体的大小为 16。

x86-64 没有分配单元对齐要求。这使得两个第一个地址相同,并且结构将具有最小可能大小

char

© www.soinside.com 2019 - 2024. All rights reserved.