[dmd-internals] Struct equality

Shahid govellius at gmail.com
Tue Nov 6 08:42:58 PST 2012


I've been poking around in the backend when I noticed that structs are
being compared with cod2's cdmemcmp(), dmd makes sure that struct
padding is always initialised to 0 ( TDPL page268 7.1.11 )
so it is not a problem...

However Given:
-----
struct S 
{
    byte a;
    int  b;
}
static assert( S.sizeof == 8 );
static assert( S.a.offsetof == 0 );
static assert( S.b.offsetof == 4 );
-----


Question 1. What if the struct comes from C?
============================================
In C struct padding values are "unspecified"

To Quote from C99 (6.2.6.1)
> When a value is stored in an object of structure or union type,
> including in a member object, the bytes of the object representation
> that correspond to any padding bytes take unspecified values.

-----
extern(C) S c_func();
int main(){
	S s1;
	S s2 = c_func();
	if( s1 == s2 ) return 1;
	return 0;
}
-----
DMD codegen (linux)

void main():
{
push   rbp
mov    rbp,rsp
sub    rsp,0x10
// Init s1
mov    rax,QWORD PTR [_D4test.1S6__initZ]
mov    QWORD PTR [rbp-0x10],rax

call   c_func
mov    QWORD PTR [rbp-0x8],rax

// if ( s1 == s2 )
lea    rsi,[rbp-0x10]
lea    rdi,[rbp-0x8]
movabs rcx,0x8
xor    eax,eax
repz cmps BYTE PTR ds:[rsi],BYTE PTR es:[rdi]
jne    3b <_Dmain+0x3b>

mov    eax,0x1 // return 1
leave  
ret    
xor    eax,eax // return 0
leave  
ret    
}



Question 2. What about Void Initializations?
============================================
In func2() all fields are eventually initialised,
but the padding is undefined.

-----
S func1() {
	S x;
	x.a = 1; x.b = 2;
	return x;
}
S func2() {
	S x = void;
	x.a = 1; x.b = 2;
	return x;
}
-----
DMD codegen (linux)

S func1()
{
push   rbp
mov    rbp,rsp
sub    rsp,0x8

lea    rax,[rbp-0x8]
xor    rcx,rcx
mov    QWORD PTR [rax],rcx

mov    BYTE  PTR [rbp-0x8],0x1
mov    DWORD PTR [rbp-0x4],0x2
mov    rax,QWORD PTR [rbp-0x8]
leave
ret
}
S func2()
{
push   rbp
mov    rbp,rsp
sub    rsp,0x8
mov    BYTE  PTR [rbp-0x8],0x1
mov    DWORD PTR [rbp-0x4],0x2
mov    rax,QWORD PTR [rbp-0x8]
leave
ret
}


More information about the dmd-internals mailing list