www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Does the default opEquals include padding in the comparison? If so,

reply Simon van Bernem <simon.vanbernem yahoo.de> writes:
I ask this question because I chased a very very nasty bug all 
the way down, and I think I found the offender:

I have a extern(C++) struct that contains an 8-byte integer 
followed by a 4-byte enum value. I came across two variables of 
that type, that are not equal by comparison (no opEquals 
defined), but when comparing their individual members, all of 
them are equal. If I inspect the values in the debugger, all 
members are also equal.

Only the raw memory shows that there is a difference in the 
4-byte padding after the enum value. The value that originated 
from C++ has some bits set, while the one initialized in D code 
is all zeros. Garbage data in padding is allowed in C++, since 
the contents of padding is undefined behavior.

The only explanation I can think of is that D memcmps the entire 
struct including the padding. Is this correct?

If so, what can I do about this? Why doesn't the opEquals get 
modified appropriately even though the struct is extern(C++)? Can 
I tell D to only compare the non-padding parts? Or is there a 
msvc/clang compiler switch to tell them to initialize padding to 
0?

I though about using memset 0 all over my C++ code, but that is 
very error prone, so I am now trying to get rid of all padding in 
interfacing structs (since there is a warning for that), but that 
also feels like a workaround, not like solution.
Oct 21 2020
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 21 October 2020 at 19:23:43 UTC, Simon van Bernem 
wrote:
 The only explanation I can think of is that D memcmps the 
 entire struct including the padding. Is this correct?

 If so, what can I do about this? Why doesn't the opEquals get 
 modified appropriately even though the struct is extern(C++)? 
 Can I tell D to only compare the non-padding parts? Or is there 
 a msvc/clang compiler switch to tell them to initialize padding 
 to 0?
https://dlang.org/changelog/2.085.0.html#no-cmpsb
Oct 21 2020
parent Simon van Bernem <simon.vanbernem yahoo.de> writes:
On Wednesday, 21 October 2020 at 20:10:03 UTC, Paul Backus wrote:
 On Wednesday, 21 October 2020 at 19:23:43 UTC, Simon van Bernem 
 wrote:
 The only explanation I can think of is that D memcmps the 
 entire struct including the padding. Is this correct?

 If so, what can I do about this? Why doesn't the opEquals get 
 modified appropriately even though the struct is extern(C++)? 
 Can I tell D to only compare the non-padding parts? Or is 
 there a msvc/clang compiler switch to tell them to initialize 
 padding to 0?
https://dlang.org/changelog/2.085.0.html#no-cmpsb
Thanks! Great to see this was already adressed.
Oct 21 2020