[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