У меня есть программа goo.cПонимание неожиданного результата благодаря непревзойденному прототипу (C89)
void foo(double);
#include <stdio.h>
void foo(int x){
printf ("in foo.c:: x= %d\n",x);
}
, который вызывается foo.c
int main(){
double x=3.0;
foo(x);
}
я скомпилировать и запустить
gcc foo.c goo.c
./a.out
Угадайте, что? Я получаю результат «x = 1». Тогда я считаю, что подпись «foo» должна была быть void foo(int)
. По-видимому, мое двойное значение ввода 3.0 должно быть опущено до int. Но, если я пытаюсь увидеть значение (межд) 3.0 с тестовой программой:
int main(){
double x=3.0;
printf ("%d", ((int) x));
}
я получаю 3 в качестве выходного сигнала, что делает ранее `х = 1' еще более трудно понять. Есть идеи? Для получения информации, мой gcc запускается с использованием стандарта ANSI C. Благодарю.
[EDIT] Если я использую GCC -S как предложено СП1,
я goo.s
.file "goo.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movabsq $4613937818241073152, %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, -24(%rbp)
movsd -24(%rbp), %xmm0
call foo
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
и foo.s
.file "foo.c"
.section .rodata
.LC0:
.string "in foo.c:: x= %d\n"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
Тот, кто знает, как read Assembly может помочь выяснить исходную проблему?
На какой машине вы работаете? Скорее всего, произошло то, что двойники передаются функциям с использованием регистров с плавающей запятой (в отличие от регистров общего назначения, которые используются для целых чисел). Функция пытается прочитать из целочисленного регистра, который не инициализирован и просто имеет место 1. Вы можете точно видеть, что происходит, если вы используете '-S' и смотрите на код сборки для ваших функций. – JS1