gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 16:07:30 26 4
gpt4 key购买 nike

我有一个项目要从 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
}

在针对 64 位的 VS2010 SP1 下编译时,使用打包结构的成员调用 FuncB 会生成以下警告:

警告 C4366:一元“&”运算符的结果可能未对齐

而调用 FuncA 则不会。我原以为这两种情况都会编译成几乎相同的代码。引用是否比等效指针更安全地避免对齐问题?还是 MSVC 根本没有在应该发出警告的地方发出警告?该项目需要维护结构包装,所以我的选择是将 FuncB 更改为

void FuncB(__unaligned double *x)
{
*x = 0;
}

或者在所有这些情况下简单地使用 FuncA。后者更可取,因为它更便携,但我想知道它是否会起作用,或者引用案例中缺少警告只是编译器中的一个缺点?

编辑:此错误的 Microsoft 帮助条目是 here . __unaligned help 建议不注意此警告将导致在 Itanium 处理器上抛出异常。进一步搜索 MSDN 建议 there may be issues surrounding unaligned references .虽然这可能不会给我当前的用户带来问题,但如果 Itanium 架构在未来得到更广泛的使用,我可能会遇到支持方面的噩梦。现在计划为所有使用打包结构的函数添加特定的包装器,以避免指针和 __unaligned 关键字。

最佳答案

引用和指针几乎是一回事(可以这么说),所以从安全的角度来看,它们没有什么不同。这可能更多是一种疏忽和/或编译器不太关心引用,因为它们不能传递到 C++ 环境之外(尽管我倾向于认为这只是一种疏忽)。

也可能是编译器更关心指针,因为指针更有可能用于性能,您希望在 double 值范围内迭代(例如,通过分配更多空间比结构本身使用的空间,并在它之后存储更多的 double 值) - 你不能用引用来做到这一点。由于未对齐访问至少比对齐访问慢,这会对性能产生影响,并且在某些系统中,它会导致操作系统陷阱,这将“修复”未对齐访问(以几个命令的速度比普通对齐访问慢得多),或者操作系统只是说“你的程序导致了未对齐访问,我正在杀死它”。

多线程也有问题,因为未对齐的访问可能不会自动更新数据。当然,对于线程之间共享的数据,您应该使用 std::atomic 或类似的。

x86 完全能够从未对齐的地址读取 double。我认为 Itanium 不是,但从统计学上讲,我怀疑您无论如何都不会使用该处理器。其他较旧的架构,例如 Alpha,可能会在读取未对齐的内存时遇到问题。

关于c++ - 为什么我收到未对齐指针的警告而不是引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17146792/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com