【发布时间】:2021-04-11 13:05:02
【问题描述】:
我有一个问题:long double 的大小是16 bytes,当我检查sizeof() 没有问题时,它返回16 但我做了这个小程序来填充一个 16 字节的字符串使用long double 强制转换为零,但它只填充了 10 个字节而不是 16 个零,仅比 long 和 double 多两个,为什么会发生这种情况?
#include <stdio.h>
int main(void)
{
char s[17] = "aaaaaaaaaaaaaaaa";
*((long double *)s) = 0.L;
for (int i = 0; i < 16; i++)
printf("%d", (int)s[i]);
write(1, "\n", 1);
return (0);
}
输出:
0000000000979797979797
代替:
0000000000000000
对于double,它的输出效果很好:
000000009797979797979797
那么为什么它适用于double 而不是long double?
【问题讨论】:
-
16不等于17,需要存储一个16个字符的字符串。
-
@PaulOgilvie 我知道我的字符串长度为 17,但结束字节已经是
0所以这也应该填充前 16 个字节而不是 10 个字节 -
*((long double *)s)是 strict aliasing violation,因此是未定义的行为。它还可能违反6.3.2.3 Pointers, paragraph 7 的对齐限制:“指向对象类型的指针可能会转换为指向不同对象类型的指针。如果生成的指针未正确对齐所引用的类型,则行为未定义。”不管是谁教你写这样的代码都是不称职的。使用类似memcpy().