Вторая попытка
Хорошо, возможно, моя первая попытка задать вопрос была слишком запутанной.Итак, здесь мы снова идем ...
В функции, которая принимает переменное число аргументов, например, printf
, когда вы передаете структуру, какой тип сгенерированного кода вы ожидаете?
Я спрашиваю это, основываясь на этом коде:
#include <stdio.h>
struct edge{
int v1, v2;
};
int main(void){
struct edge edges;
edges.v1=5;
edges.v2=20;
printf("'%d'\n", edges);
return 0;
}
При компиляции этого в моем окне Windows, он передает 2 целочисленных аргумента:
.file "simple_test_case2.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "'%d'\12\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
call ___main
movl $5, 24(%esp)
movl $20, 28(%esp)
movl 24(%esp), %eax
movl 28(%esp), %edx
movl %eax, 4(%esp)
movl %edx, 8(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
ret
.def _printf; .scl 2; .type 32; .endef
Но сгенерированный кодпо моему linux, просто передайте ему один адрес памяти:
.file "simple_test_case2.c"
.section .rodata
.LC0:
.string "'%d'\n"
.text
.align 2
.globl main
.type main, @function
main:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $16, %rsp
.LCFI2:
movl $5, -16(%rbp)
movl $20, -12(%rbp)
movq -16(%rbp), %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
ret
.LFE2:
.size main, .-main
.globl __gxx_personality_v0
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zPR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x6
.byte 0x3
.long __gxx_personality_v0
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB2
.long .LFE2-.LFB2
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB2
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE1:
.ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-48)"
.section .note.GNU-stack,"",@progbits
Так что это мой вопрос, когда вы передаете только одну структуру функции, подобной printf
, сгенерированный код должен передать только один аргументили отправить все члены структуры к нему?
Первая попытка
У моего друга возникли проблемы с программой, которая не работала должным образом в Windows.Итак, я взглянул на исходный код и урезал контрольный пример до следующего:
#include <stdio.h>
struct edge{
int v1, v2;
};
int main(void){
struct edge edges;
edges.v1=5;
edges.v2=20;
//This is the expected behavior for me:
printf("'%d' '%d' '%d' '%d'\n", edges.v1, edges.v1, edges.v1, edges.v1);
//This is supposed to work like this? It should pass the whole struct to printf?
printf("'%d' '%d' '%d' '%d'\n", edges, edges, edges, edges);
printf("'%d' '%d' '%d' '%d'\n", edges, edges);
return 0;
}
Итак, протестировано на коробке с Windows 7 с
gcc (tdm-1) 4.5.0
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
И вывод такой:
'5' '5' '5' '5'
'5' '20' '5' '20'
'5' '20' '5' '20'
На linux box с
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
я получил такой вывод:
'5' '5' '5' '5'
'5' '5' '5' '5'
'5' '5' '229971840' '-641776368'
Вывод из linux box one, это тот, который я ожидал...
Затем я взглянул на ассемблерный код, сгенерированный каждым компилятором, и увидел, что в моем окне Windows код передает всю структуру в printf, как члены v1, так и члены v2 (и это оправдываетрезультаты, достижения).Но на коробке Linux сгенерированный код прошел, как я и ожидал, только первый член структуры.
Так что же должно быть в этом случае?
Для меня ожидаемыйэто Linux, но, возможно, я ошибаюсь, и это случай неопределенного поведения.