首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >示例中` `char _Alignas(double)`的大小为什么不是8?

示例中` `char _Alignas(double)`的大小为什么不是8?
EN

Stack Overflow用户
提问于 2021-09-14 03:17:19
回答 2查看 53关注 0票数 0
代码语言:javascript
复制
#include <stdio.h>
int main(void)
{
    char c1 = '0';
    char _Alignas(double) c2 = '0';

    printf("char alignment:   %zd\n", _Alignof(char));
    printf("double alignment: %zd\n", _Alignof(double));
    printf("&c1: %p\n", &c1);
    printf("&c2: %p\n", &c2);

    return 0;
}

在我的环境中运行,结果是:

代码语言:javascript
复制
char alignment: 1
double alignment: 8
&c1: 000000000061FE1F
&c2: 000000000061FE18

由gcc 8.1.0版本编译(x86_64-posix seh-rev0,由MinGW-W64项目构建)。

我想知道为什么&c2&c1之间的字节数是7,而不是8(在我的环境中是sizeof(double))?

EN

回答 2

Stack Overflow用户

发布于 2021-09-14 04:11:30

为什么char _Alignas双倍大小不是8?

对齐意味着地址是某个值的倍数。它与变量的大小无关。_Alignas(8)表示地址将是8的倍数,即以十六进制的0或8结尾

我想知道为什么&c2和&c1之间的字节是7,而不是8(在我的环境中,大小为双精度)?

未指定堆栈上变量的位置。编译器可以自由地将c1放在c2之前或之后。这里唯一的要求是c2必须是8的倍数。如果c1是8的倍数,并且编译器选择将c2放在8的倍数之后,那么将使用7字节的填充。但是它们显然可以将c1放在c2之前,并且它们的地址仅相差1。您可以很容易地看到each compiler puts the variables in different positions with different distances

有关更多细节,请阅读

票数 2
EN

Stack Overflow用户

发布于 2021-09-14 04:00:29

对齐确定地址的位置,而不是它们将占用的空间大小。

一个char只占用1个字节,即使它在8个字节的边界上对齐。在c1和c2之间有6个未使用的字节。

通常,对齐和大小是相同的,或者将对齐四舍五入为2的幂。这是因为在许多架构上,可能需要多个获取指令才能从未对齐的内存地址中检索。

在您的示例中,c1在1字节边界上对齐,因此它被放置在堆栈上的第一个可用位置。

c2在8字节边界上对齐,因此它跳过所需的字节数,直到地址在8字节边界上对齐。这意味着(地址% 8) == 0。如果c2的类型是double,它将需要移动到下一个对齐的地址,提前8个字节,但由于它只是一个char,所以它正好适合第一个8字节的边界。(编辑:正如其他人所指出的,编译器可以重新排列变量,在这种情况下很可能会这样做)

对齐方式可以大于或小于元素的大小。

在某些架构上,您只需在2或4字节边界上对齐即可。计算机根本不能寻址“中间字节”。不需要地址线,所以如果对齐4个字节的地址(并且总是读取4个字节),那么只需使用14个地址线就可以寻址2^16字节的内存。这可以减少存储器总线所需的大小。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69171393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档