簡體   English   中英

為什么我收到未對齊指針的警告而不是引用的警告

[英]Why do I get a warning for an unaligned pointer but not a reference

我有一個項目要從 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 幫助條目在此處 __unaligned幫助表明不注意此警告將導致在 Itanium 處理器上引發異常。 對 MSDN 的進一步搜索表明可能存在圍繞未對齊引用的問題 雖然這可能不會給我當前的用戶帶來問題,但如果 Itanium 架構在未來得到更廣泛的使用,我可能會遇到支持噩夢。 現在計划為所有使用壓縮結構的函數添加特定的包裝器,以避免指針和 __unaligned 關鍵字。

引用和指針幾乎是一樣的東西(可以這么說),所以從安全的角度來看,它沒有什么不同。 這可能更多是一種疏忽和/或編譯器不太關心引用,因為它們不能在 C++ 環境之外傳遞(盡管我傾向於認為這只是一種疏忽)。

也可能是編譯器更關心指針,因為指針更有可能用於性能,您希望在一系列double值上進行迭代(例如,通過分配比結構本身使用的更多的空間,並進一步存儲它后面的double值) - 你不能用引用來做到這一點。 由於未對齊訪問至少比對齊訪問慢,這會對性能產生影響,並且在某些系統中,它會導致操作系統陷阱,這將“修復”未對齊訪問(以幾個命令的速度)比普通的對齊訪問慢),或者操作系統只是說“您的程序導致了未對齊的訪問,我正在殺死它”。

多線程也存在問題,因為未對齊的訪問可能不會自動更新數據。 當然,對於線程之間共享的數據,您應該使用std::atomic或類似方法。

x86 完全能夠從未對齊的地址讀取double精度值。 我認為 Itanium 不是,但我懷疑您無論如何都不會使用該處理器,從統計上講。 其他較舊的體系結構(例如 Alpha)可能會在讀取未對齊的內存時出現問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM