简体   繁体   English

为什么我收到未对齐指针的警告而不是引用的警告

[英]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.

相关问题 为什么我在MSVC上收到此警告? - Why do I get this warning on MSVC? 为什么GCC 5.3.0在绑定对“this”指针的引用时发出警告 - Why GCC 5.3.0 gives warning when binding reference to “this” pointer 为什么在“形成对引用类型的引用”映射中出现错误? - Why do I get an error in “forming reference to reference type” map? 为什么我会在#pragma上收到警告C4081? - Why do I get warning C4081 on this #pragma? 为什么我会收到此代码的匿名类型警告? - Why do I get the anonymous type warning for this code? 为什么会收到Wsign转换警告? - Why do I get Wsign-conversion warning? 为什么我使用fprintf在这个C代码中收到警告? - why do I get warning in this C code using fprintf? 为什么我会收到“未引用的本地变量”警告? (C ++) - Why do I get an “Unreferenced Local Variable” warning? (C++) 对齐指针未对齐访问? - Unaligned access on aligned pointer? 对于级联成员函数调用,为什么需要返回引用? 为什么仅此指针还不够? - For cascading member function calls, why do i need to return the reference? Why isn't just the this pointer sufficient?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM