1. 在实际项目中转换后取消引用指针真的安全吗?
如果指针碰巧没有正确对齐,它确实会导致问题。我亲眼看到并修复了由于将 achar*
转换为更严格对齐的类型而导致的实际生产代码中的总线错误。即使您没有收到明显的错误,您也可能会遇到不太明显的问题,例如性能下降。即使您没有立即发现任何问题,严格遵循标准以避免 UB 也是一个好主意。(代码打破的一条规则是严格的别名规则,§ 3.10/10*)
更好的选择是使用std::memcpy()
或者std::memmove
如果缓冲区重叠(或更好bit_cast<>()
)
unsigned char data[16];
int i1, i2, i3, i4;
std::memcpy(&i1, data , sizeof(int));
std::memcpy(&i2, data + 4, sizeof(int));
std::memcpy(&i3, data + 8, sizeof(int));
std::memcpy(&i4, data + 12, sizeof(int));
一些编译器比其他编译器更努力地确保 char 数组的对齐比必要的更严格,因为程序员经常会犯这个错误。
#include <cstdint>
#include <typeinfo>
#include <iostream>
template<typename T> void check_aligned(void *p) {
std::cout << p << " is " <<
(0==(reinterpret_cast<std::intptr_t>(p) % alignof(T))?"":"NOT ") <<
"aligned for the type " << typeid(T).name() << '\n';
}
void foo1() {
char a;
char b[sizeof (int)];
check_aligned<int>(b); // unaligned in clang
}
struct S {
char a;
char b[sizeof(int)];
};
void foo2() {
S s;
check_aligned<int>(s.b); // unaligned in clang and msvc
}
S s;
void foo3() {
check_aligned<int>(s.b); // unaligned in clang, msvc, and gcc
}
int main() {
foo1();
foo2();
foo3();
}
http://ideone.com/FFWCjf
2. C-style cast 和 reinterpret_cast 有什么区别吗?
这取决于。C 风格的转换根据所涉及的类型做不同的事情。指针类型之间的 C 风格转换将产生与 reinterpret_cast 相同的结果;请参阅 § 5.4显式类型转换(强制转换表示法)和 § 5.2.9-11。
3. C和C++有什么区别吗?
只要您处理的是 C 中合法的类型,就不应该有。
* 另一个问题是 C++ 没有指定从一种指针类型转换为具有更严格对齐要求的类型的结果。这是为了支持甚至无法表示未对齐指针的平台。但是,当今的典型平台可以表示未对齐的指针,并且编译器将这种强制转换的结果指定为您所期望的。因此,此问题是混叠违规的次要问题。见[expr.reinterpret.cast]/7。