[英]Why do I get a warning for an unaligned pointer but not a reference
I have project I'm porting from from 32 bit Windows to 64 bit, which includes code that can be simplified as follows:我有一个项目要从 32 位 Windows 移植到 64 位,其中包括可以简化如下的代码:
void FuncA(double &x)
{
x = 0;
}
void FuncB(double *x)
{
*x = 0;
}
#pack(1)
struct
{
char c;
double x;
} MyStruct;
#pack();
void MyFunc()
{
MyStruct M;
FuncA(M.x); // This is OK
FuncB(&M.x); // This generates a warning C4366
}
When compiling under VS2010 SP1 targeting 64 bit, calling FuncB
with a member of a packed struct generates the following warning:在针对 64 位的 VS2010 SP1 下编译时,使用打包结构的成员调用
FuncB
生成以下警告:
warning C4366: The result of the unary '&' operator may be unaligned警告 C4366:一元“&”运算符的结果可能未对齐
Whereas calling FuncA
does not.而调用
FuncA
则不然。 I would have thought that both cases would have compiled down to pretty much the same code.我原以为这两种情况都会编译成几乎相同的代码。 Are references somehow safer from alignment problems than the equivalent pointer?
引用是否比等效指针更安全? Or is it that MSVC is simply not issuing a warning where it should?
还是 MSVC 根本没有在应该发出警告的地方发出警告? The project requires the struct packing is maintained, so my choices are to either change
FuncB
to该项目需要维护结构包装,所以我的选择是将
FuncB
更改为
void FuncB(__unaligned double *x)
{
*x = 0;
}
or to simply use FuncA
in all such cases.或者在所有这些情况下简单地使用
FuncA
。 The latter would be preferable as it is more portable, but I'm wondering is it going to work or is the lack of a warning in the reference case simply a shortcoming in the compiler?后者更可取,因为它更便携,但我想知道它是否会起作用,或者参考案例中缺少警告只是编译器的一个缺点?
Edit: The Microsoft help entry for this error is here .编辑:此错误的 Microsoft 帮助条目在此处。 The __unaligned help suggests that failing to heed this warning will cause exceptions to be thrown on Itanium processors.
__unaligned帮助表明不注意此警告将导致在 Itanium 处理器上引发异常。 Further trawling around MSDN suggests there may be issues surrounding unaligned references .
对 MSDN 的进一步搜索表明可能存在围绕未对齐引用的问题。 While this may not cause problems for my current users, if the Itanium architecture becomes more widely used in future, I could be setting up a support nightmare.
虽然这可能不会给我当前的用户带来问题,但如果 Itanium 架构在未来得到更广泛的使用,我可能会遇到支持噩梦。 Plan is now to add specific wrappers for all the functions that use the packed structures, to avoid the pointers and the __unaligned keyword.
现在计划为所有使用压缩结构的函数添加特定的包装器,以避免指针和 __unaligned 关键字。
A reference and a pointer is pretty much the same thing (under the hood, so to speak), so from a safety perspective, it's no different.引用和指针几乎是一样的东西(可以这么说),所以从安全的角度来看,它没有什么不同。 It's probably more of an oversight and/or that the compiler is less concerned by references, as they can't be passed outside of a C++ environment (although I'm inclined to think that it's simply an oversight).
这可能更多是一种疏忽和/或编译器不太关心引用,因为它们不能在 C++ 环境之外传递(尽管我倾向于认为这只是一种疏忽)。
It may also be that the compiler is more concerned by pointers because it is more likely that pointers are used for performance, where you want to iterate over a range of double
values (eg by allocating more space than the struct itself uses, and storing further double
values after it) - you can't do that with a reference.也可能是编译器更关心指针,因为指针更有可能用于性能,您希望在一系列
double
值上进行迭代(例如,通过分配比结构本身使用的更多的空间,并进一步存储它后面的double
值) - 你不能用引用来做到这一点。 Since unaligned access is at least slower than an aligned access, this can have consequences for performance, and in some systems, it will cause a OS trap, which will either "fix up" the unaligned access (at a pace of a couple of orders of magnitued slower than an ordinary aligned access), or the OS simply says "Your program caused an unaligned access, I'm killing it".由于未对齐访问至少比对齐访问慢,这会对性能产生影响,并且在某些系统中,它会导致操作系统陷阱,这将“修复”未对齐访问(以几个命令的速度)比普通的对齐访问慢),或者操作系统只是说“您的程序导致了未对齐的访问,我正在杀死它”。
There are also issues with multithreading, as unaligned access may not be atomically updating the data.多线程也存在问题,因为未对齐的访问可能不会自动更新数据。 Of course, you should use
std::atomic
or similar for data shared between threads.当然,对于线程之间共享的数据,您应该使用
std::atomic
或类似方法。
The x86 is perfectly able to read a double
from an unaligned address. x86 完全能够从未对齐的地址读取
double
精度值。 I think Itanium isn't but I'm suspecting you don't use that processor anyway, statistically speaking.我认为 Itanium 不是,但我怀疑您无论如何都不会使用该处理器,从统计上讲。 Other, older architectures, such as Alpha may have problems reading unaligned memory.
其他较旧的体系结构(例如 Alpha)可能会在读取未对齐的内存时出现问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.