[英]gcc compiler switch printf call with puts
我已經在我的ubuntu下編譯了一個簡單的C程序:
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
然后我使用gdb檢查了可執行文件的反匯編,然后看到了以下代碼:
0x000000000000063a <+0>: push %rbp
0x000000000000063b <+1>: mov %rsp,%rbp
0x000000000000063e <+4>: lea 0x9f(%rip),%rdi # 0x6e4
0x0000000000000645 <+11>: callq 0x510 <puts@plt>
0x000000000000064a <+16>: mov $0x0,%eax
0x000000000000064f <+21>: pop %rbp
0x0000000000000650 <+22>: retq
在這里,編譯器只是將printf調用與puts調用交換了。 當我使用printf嘗試此操作時,使用沒有附加新行的字符串對其進行調用,該調用在反匯編中仍然是對printf的調用。
我的問題是啟用這種功能的編譯器的機制是什么? 他是否讀取要發送給printf的字符串,並且由於printf是libc函數,因此編譯器可以確定此優化,因為他知道libc?
是。 GCC讀取並驗證格式字符串,以發出有關格式字符串說明符錯誤的編譯警告(例如,如果您使用%d
但參數是unsigned int
,則會打印警告。)由於它在編譯時會分析字符串,它還可以知道是否可以用puts()
調用替換printf()
,這是一種優化( puts()
更快,因為它不必解析字符串。)
某些功能被編譯器“更好地了解”,因為它們是最常用的功能。 printf
是此類功能之一。 編譯器甚至會分析格式字符串,並在參數類型錯誤時發出警告。 當編寫類似的函數時,也可以通過讓編譯器(使用適當的屬性)讓函數使用printf樣式格式字符串來使用此功能。 並且由於知道此函數的工作原理,因此可以優化對其的調用。 像這樣還有許多其他功能。 例如memcpy
家庭,許多數學等
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.