hi all, I repost here a problem that I met using GCC 3.4.4 and ABI for AMD64 (-march=athlon64). the following C code typedef struct { int32_t a; void *b; } S; void fs() { char t[255]; int i; for(i=0;i<255;i++) t[i]=(char)(i+1); } int cmp1(S a1, S a2) { return !memcmp(&a1,&a2,sizeof(S)); } int cmp2(S a1, S a2) { return a1.a==a2.a && a1.b==a2.b; } void put(S y) { int a,b; S x; x=y; a=cmp1(x,y); b=cmp2(x,y); printf("a=%d b=%d\n",a,b); } int main() { S a; a.a=1; a.b=&a; fs(); put(a); return 0; } compiled for my linux x86_64 using the amd64 ABI (-march=athlon64) with gcc 3.4.4 prints "a=0 b=1"! i have seen why and it is clear to me how a such result is produced. I add below a commented assembly listing of the incriminated part. i think that it is not a bug and that the structure can not be compared using 'memcmp'. do you agree or it a bug ? is it a bug or is it normal? if it is a bug, must i open a bug track? please comment. regards josé First, the "put" function. After the obligatory initialisation code... > .globl put > .type put, @function > put: > .LFB8: > pushq %rbp > .LCFI8: > movq %rsp, %rbp > .LCFI9: > subq $48, %rsp > .LCFI10: The parameter (y) was passed in edi:rsi. Here it is saved on the stack. Presumably this is done to make debugging easier. 96 bits are copied. > movl %edi, -16(%rbp) > movq %rsi, -8(%rbp) This makes a copy of the parameter on the stack. This is the translation of the 'x=y' instruction. This time 128 bits are copied (why?) which means that, if we called memcmp(&x,&y,sizeof(S)) right now, it would return 0 (i.e. they are the same). But... > movq -16(%rbp), %rax > movq %rax, -48(%rbp) > movq -8(%rbp), %rax > movq %rax, -40(%rbp) Here, cmp1 is called. As we already saw, only the meaningful part of the structure is passed, in register (edx:rcx for one parameter, edi:rsi for the other one). The result is saved on the stack (local var a) > movl -16(%rbp), %edx > movq -8(%rbp), %rcx > movl -48(%rbp), %edi > movq -40(%rbp), %rsi > call cmp1 > movl %eax, -20(%rbp) This time, cmp2 is called and the result is saved in b > movl -16(%rbp), %edx > movq -8(%rbp), %rcx > movl -48(%rbp), %edi > movq -40(%rbp), %rsi > call cmp2 > movl %eax, -24(%rbp) > movl -24(%rbp), %edx > movl -20(%rbp), %esi > movl $.LC0, %edi > movl $0, %eax > call printf > leave > ret > .LFE8: > .size put, .-put Now it should be clear why cmp1 isn't working. Let's have a look Entry code > .globl cmp1 > .type cmp1, @function > cmp1: > .LFB6: > pushq %rbp > .LCFI3: > movq %rsp, %rbp > .LCFI4: > subq $48, %rsp save the parameters on the stack (one structure = 96 bits of data + 32 bits of junk) > .LCFI5: > movl %edi, -16(%rbp) > movq %rsi, -8(%rbp) > movl %edx, -32(%rbp) > movq %rcx, -24(%rbp) compare 128 bits of "data" on the stack. Obviously this won't work. (I'll presume a call to memcmp was generated rather than rep cmpsq because optimisations were turned off) > leaq -32(%rbp), %rsi > leaq -16(%rbp), %rdi > movl $16, %edx > call memcmp > movl %eax, -36(%rbp) > cmpl $0, -36(%rbp) > sete %al > movzbl %al, %eax > movl %eax, -36(%rbp) > movl -36(%rbp), %eax > leave > ret > .LFE6: > .size cmp1, .-cmp1 > .globl cmp2 > .type cmp2, @function Obviously, cmp2 works because it only compares 96 bits of data > cmp2: > .LFB7: > pushq %rbp > .LCFI6: > movq %rsp, %rbp > .LCFI7: > movl %edi, -16(%rbp) > movq %rsi, -8(%rbp) > movl %edx, -32(%rbp) > movq %rcx, -24(%rbp) > movl $0, -36(%rbp) > movl -16(%rbp), %eax > cmpl -32(%rbp), %eax > jne .L7 > movq -8(%rbp), %rax > cmpq -24(%rbp), %rax > jne .L7 > movl $1, -36(%rbp) > .L7: > movl -36(%rbp), %eax > leave > ret > .LFE7: > .size cmp2, .-cmp2