我想实现浮点数数组的初始化。使用预先计算的十六进制值。结果与此类似:
double arr[3];
memcpy(&arr[0], "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f",24);
我希望这样的初始化是在一行中完成的。就像在这个例子中一样(但对于我的情况下的浮点数):
const char s[] = "\x48\x69\x21";
语法是否可行?
答案 0 :(得分:1)
更接近的是工会。问题是字符串litteral的最后一个字符为null,但这应该有效:
union {
char chr[3 * sizeof(double) + 1];
double arr[3];
} val = { "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a"
"\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f" };
因为它使用了一个额外的字节会浪费一些内存(通常是32位机器上的4个字节)
参考标准:
在C a(非规范性)注释中说它应该适用于6.5.2.3结构和联盟成员
如果用于访问union对象内容的成员与上次使用的成员不同 在对象中存储一个值,该值的对象表示的相应部分被重新解释 作为6.2.6中描述的新类型中的对象表示(有时称为“类型”的过程) 双关“)
我找不到C ++的任何参考说明是否允许,但所有常见的编译器都接受它。我能找到的相关性更高
9.5联盟[class.union]
在联合中,最多一个非静态数据成员可以随时处于活动状态,即at的值 大多数非静态数据成员可以随时存储在一个联合中......联合对象的所有非静态数据成员都具有相同的地址。
解释了它可以运作的原因
和
3.10左值和右值[basic.lval]
§10如果一个程序试图通过一个以外的glvalue来访问一个对象的存储值 以下类型的行为未定义... [联合访问未引用]
明确表示会导致未定义的行为。问题是C 6.5表达式中存在同一段(称为严格别名规则)......
TL / DR:联合方式在C语言中明显有效,在C ++中可能是UB,所以我的建议是将它放在一个链接到C ++程序的C编译单元中。
答案 1 :(得分:0)
C++20 在 C++ 中带来了一种急需的非 UB 类型双关方法。您现在可以执行以下操作。欢喜。
double arr[] = {
std::bit_cast<double>(0xE33BEFF6C178C63F),
std::bit_cast<double>(0xF9375A8DFDAE753F),
std::bit_cast<double>(0x62E958484F49C63F)
};
答案 2 :(得分:0)
我建议使用 hex floating-point literals 而不是位模式
double arr[] =
{
-0x1.beff6c178c63fp564, // 0xE33BEFF6C178C63F
-0x1.75a8dfdae753fp916, // 0xF9375A8DFDAE753F
0x1.958484f49c63fp559, // 0x62E958484F49C63F
};