编辑:跳到我最新版本的问题的水平规则下方。
仅假设 sizeof(double) * CHAR_BITS <= 64,C++03 保证以下程序中的断言始终得到满足?
union u {
std::int64_t m_int;
double m_double;
};
int main()
{
double d = get_a_random_double();
u u1;
u1.m_double = d;
u u2;
u2.m_int = u1.m_int;
assert(u2.m_double == d);
}
我担心标准可能无法保证 int64_t 值的副本保留我们用来保存双精度的所有位。
另一方面,我很确定标准保证以下使用 chars 而不是 unt64_t 的替代方案始终满足断言:
struct chars {
char m_x[sizeof(double)];
};
union u {
chars m_chars;
double m_double;
};
int main()
{
double d = get_a_random_double();
u u1;
u1.m_double = d;
u u2;
u2.m_chars = u1.m_chars;
assert(u2.m_double == d);
}
你同意?
编辑:
好的,我必须承认标准不支持通过联合进行的转换。
那么这个我尝试在不使用联合的情况下通过一系列字符传输双精度数的情况呢:
int main()
{
double d, e;
char c[sizeof(double)];
char* p_d = static_cast<char*>(static_cast<void*>(&d));
char* p_e = static_cast<char*>(static_cast<void*>(&e));
d = get_a_random_double();
// double -> chars
std::copy(p_d, p_d+sizeof(double), c);
// chars -> double
std::copy(c, c+sizeof(double), p_e);
assert(e == d);
}
这个标准是否保证始终满足断言?
编辑:是的!参见 C++11 3.9/2“类型”
下一个我尝试在不使用联合的情况下通过 int64_t 传输双槽的情况如何。
我知道 int64_t 不是 c++03 的一部分,所以让我们来谈谈 c++11。
再次注意,我假设 sizeof(double) * CHAR_BITS <= 64。
int main()
{
double d, e;
std::int64_t i, j;
char c[sizeof(std::int64_t)];
char* p_d = static_cast<char*>(static_cast<void*>(&d));
char* p_e = static_cast<char*>(static_cast<void*>(&e));
char* p_i = static_cast<char*>(static_cast<void*>(&i));
char* p_j = static_cast<char*>(static_cast<void*>(&j));
d = get_a_random_double();
// double -> chars -> std::int64_t
std::copy(p_d, p_d+sizeof(double), c);
std::copy(c, c+sizeof(std::int64_t), p_i);
// std::int64_t -> std::int64_t
j = i; // <------------ Are all bits preserved here?
// std::int64_t -> chars -> double
std::copy(p_j, p_j+sizeof(std::int64_t), c);
std::copy(c, c+sizeof(double), p_e);
assert(e == d);
}
和以前一样,我担心的一个问题是复制标准整数类型之一 (std::int64_t) 是否会“损坏”某些位(例如,一些不参与整数值表示的位)。或者,整数分配是否保证总是忠实地复制整数占用的字节的所有位?