2010-09-21 36 views
6

我有一個函數,需要一個無符號長整數*,並且需要將它傳遞給一個外部函數庫,該函數需要一個無符號整數*,並且在這個平臺上,unsigned int/long的大小相同。正在打破嚴格的鋸齒規則

void UpdateVar(unsigned long* var) { 
    // this function will change the value at the address of var 
    ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable 
} 

這產生了一個警告,說它打破了嚴格的鋸齒規則。有沒有解決辦法?

謝謝

編輯:我很抱歉不清楚。代碼是一個原子更新,因此繞着庫來存儲它不是一個選項。我可以下降到組裝,但我想用C++來做到這一點。

+0

僅適用於單個對象或long/int數組? – sellibitze

+0

這是一個原子存儲到單個32位內存。 – coderdave

回答

8
void UpdateVar(unsigned long* var) { 
    unsigned int x = static_cast<unsigned int>(*var); 
    ExternalLibUpdateVar(&x); 
    *var = static_cast<unsigned long>(x); 
} 
+0

製作這個'static_cast's,我會投票。 – sbi

+0

對不起,沒有注意到C++標籤 – dave

+0

在這種情況下'static_cast'和'reinterpret_cast'之間的真正區別是什麼? – identity

2

這應該工作:

void UpdateVar(unsigned long* var) { 
    // this function will change the value at the address of var 
    ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var)); 
} 
+0

如果sizeof(long)危險!= sizeof(int) – nos

+0

他在原文中表示他們的平臺尺寸保證相同。但是,是的,你是對的。 – identity

+1

+1。在某些情況下,我認爲這實際上是恰當的。但是這實際上取決於這種情況,我覺得在程序中使用某種'sizeof(int)== sizeof(long)'檢查會更舒服,如果不滿足條件,編譯失敗 - C++ 0x的'static_cast'任何人? :-) – sellibitze

0

intlong必須具有相同尺寸的C標準的任務沒有;此外,即使它們具有相同的大小,標準中的任何內容都沒有規定它們具有相同的表示形式(除此之外,它們可能具有不兼容的填充位和陷印表示組合,因此兩種類型之間的別名不能提供任何服務有用的目的)。

該標準的作者不希望強制執行者針對平臺,其中intlong之間的別名不會識別這種別名。他們也不想編寫適用於某些平臺(那些會出現別名會影響目的的平臺)的規則,而不是其他規則(不適用的平臺)。相反,他們認爲編寫優質編譯器的人會嘗試在其有用的情況下識別別名。

能夠使用指向一個32位類型的指針讀取和寫入具有相同表示的另一個32位類型的值顯然是有用的,特別是在API拆分期望的類型時尤其如此。如果某平臺上的某些常見API使用int*表示32位值,而其他API則使用long*,則該平臺的通用實現必須允許使用另一種類型的指針訪問任一類型的數據。但是,不幸的是,一些編譯器的作者更快速地處理程序的某個子集,而不是更有用地處理更大的程序子集,並且如果需要交換數據,則不能依賴於生成有用的代碼在使用相同數據表示但不同命名類型的API之間,除非完全禁用別名分析。當然,如果一個人的目標是C語言適用於微控制器的通用目的,這些問題並不重要。