2015-11-06 161 views
1

在生活中第一次看到它。當輸入參數改變時,編譯器給出錯誤,說明函數未定義。這怎麼發生enter image description here當只有輸入參數改變時,顯示對sin的未定義引用

在圖像中,函數的第一次調用沒有錯誤。如果我用變量去除sin函數調用,這個錯誤不存在。真的很好奇.....

+1

優化可能嗎? – Downvoter

+1

'theta'的類型是什麼? – JimmyB

+5

請發佈您的代碼和錯誤的*文本*不是圖像 –

回答

3

這是爲什麼。考慮以下代碼:

#include <stdio.h> 
#include <math.h> 

int main() 
{ 
    printf("%.3f\n", sin(0.5)); 
    return 0; 
} 

GCC通知,你會立即採取恆定的正弦和罪(0.5)的實際值來替換它,你可以從下面主要拆卸看到:

(gdb) disass main 
Dump of assembler code for function main: 
    0x000000000040052d <+0>: push %rbp 
    0x000000000040052e <+1>: mov %rsp,%rbp 
    0x0000000000400531 <+4>: sub $0x10,%rsp 
    0x0000000000400535 <+8>: movabs $0x3fdeaee8744b05f0,%rax 
    0x000000000040053f <+18>: mov %rax,-0x8(%rbp) 
    0x0000000000400543 <+22>: movsd -0x8(%rbp),%xmm0 
    0x0000000000400548 <+27>: mov $0x4005e4,%edi 
    0x000000000040054d <+32>: mov $0x1,%eax 
    0x0000000000400552 <+37>: callq 0x400410 <[email protected]> 
    0x0000000000400557 <+42>: mov $0x0,%eax 
    0x000000000040055c <+47>: leaveq 
    0x000000000040055d <+48>: retq 
End of assembler dump. 

現在,讓我們改變它,以便優化是不可能的:

#include <stdio.h> 
#include <math.h> 

int main(int argc, char** argv) 
{ 
    printf("%.3f\n", sin((double)argc)); 
    return 0; 
} 

現在你真正需要調用它在數學庫中定義的罪()函數。如果您不在gcc的正確位置提供-lm標誌(最好的地方在最後),鏈接將失敗。這裏是反彙編:

Dump of assembler code for function main: 
    0x000000000040063d <+0>: push %rbp 
    0x000000000040063e <+1>: mov %rsp,%rbp 
    0x0000000000400641 <+4>: sub $0x20,%rsp 
    0x0000000000400645 <+8>: mov %edi,-0x4(%rbp) 
    0x0000000000400648 <+11>: mov %rsi,-0x10(%rbp) 
    0x000000000040064c <+15>: cvtsi2sdl -0x4(%rbp),%xmm0 
    0x0000000000400651 <+20>: callq 0x400540 <[email protected]> 
    0x0000000000400656 <+25>: movsd %xmm0,-0x18(%rbp) 
    0x000000000040065b <+30>: mov -0x18(%rbp),%rax 
    0x000000000040065f <+34>: mov %rax,-0x18(%rbp) 
    0x0000000000400663 <+38>: movsd -0x18(%rbp),%xmm0 
    0x0000000000400668 <+43>: mov $0x400704,%edi 
    0x000000000040066d <+48>: mov $0x1,%eax 
    0x0000000000400672 <+53>: callq 0x400510 <[email protected]> 
    0x0000000000400677 <+58>: mov $0x0,%eax 
    0x000000000040067c <+63>: leaveq 
    0x000000000040067d <+64>: retq 
End of assembler dump. 

請注意對sin @ plt的調用。

從你的屏幕截圖看來,你正在使用某種圍繞gcc的視覺工具。檢查文檔如何更改鏈接程序庫。如果它可以讓你直接修改鏈接器命令,只需在它的末尾加上-lm,你的代碼就可以工作。

0

這只是猜想。如果您使用數學庫,並且只在頂部添加標題,則錯誤是因爲您沒有鏈接庫。 maths.h應該爲你工作。

相關問題