2011-06-30 68 views
9

這個例子的目的:如何比較POD類型

#include <iostream> 
#include <cstring> 

struct A 
{ 
    int a; 
    bool b; 
}; 

bool foo(const A a1, const A a2) 
{ 
    return (0 == std::memcmp(&a1, &a2, sizeof(A))); 
} 

int main() 
{ 
    A a1 = A(); 
    a1.a = 5;a1.b = true; 
    A a2 = A(); 
    a2.a = 5;a2.b = true; 

    std::cout<<std::boolalpha << foo(a1, a2) << std::endl; 
} 

會因爲襯墊的生產false

我無法訪問foo函數,我無法改變比較的方式。

假設bool佔用1個字節(這是我的系統上如此),如果我改變了struct A這樣:

struct A 
{ 
    int a; 
    bool b; 
    char dummy[3]; 
}; 

然後正常工作在我的系統(輸出true)。

有什麼我可以做的,以解決上述問題(獲得true輸出)?

+0

爲什麼你傳遞'const'值而不是'const'? ==>'foo(const A a1,const A a2);' – iammilind

+0

@iammilind'foo'函數來自第三方庫,我無權更改它的簽名 –

+0

您是否嘗試過打包結構似乎可以控制它?這樣你可能不需要使用memset「trick」。 VS:'#pragma pack(1)'就在結構之前。 G ++相同。 http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html – RedX

回答

11

由於結構中的填充,第一個不工作。對於兩個對象,填充都具有不同的位模式。

如果使用memset使用它之前設置的對象中的所有位,那麼它會工作:

A a1; 
std::memset(&a1, 0, sizeof(A)); 
a1.a = 5;a1.b = true; 

A a2; 
std::memset(&a2, 0, sizeof(A)); 
a2.a = 5;a2.b = true; 

在線演示:


順便說一句,你也可以寫POD的operator<,operator==等。

+0

'A a1 = A();'與A a1相同; std :: memset(&a1,0,sizeof(A));'。我可以爲POD編寫運算符,但我無法訪問執行比較的函數,因此我被std :: memcmp –

+1

@VJo卡住了:NO。它不是相同的'A a1 = A()'只初始化成員,而不是填充。也就是說,'A a1 = A()'相當於'A a1; memset(&a1.a,0,sizeof(a1.a)); memset(&a1.b,0,sizeof(a1.b));'。其餘的'(sizeof(A) - sizeof(a1.a) - sizeof(a1.b))'字節保持原樣,包含垃圾。 – Nawaz

+0

嗯,嚴格地說,'A a1 = A()'***不能保證***初始化填充,但它仍然可以這樣做。 – sharptooth