GCC Built-in Functions

栏目: 服务器 · 编程工具 · 发布时间: 6年前

内容简介:最近上課的時候鬧了一個大笑話(而且那門課還是組合語言不是程式設計...)。我寫了下面這隻程式:很明顯,這程式沒有 include 任何 header file,理論上應該是要包含 stdio.h。在編譯的過程中,compiler 吐出了下面的test.c: In function ‘main’:

最近上課的時候鬧了一個大笑話(而且那門課還是組合語言不是程式設計...)。我寫了下面這隻程式:

int main()
{
    printf( "Hello\n" );
    return 0;
}

很明顯,這程式沒有 include 任何 header file,理論上應該是要包含 stdio.h。在編譯的過程中,compiler 吐出了下面的 警告信息 ( 不是錯誤信息唷 ):

test.c: In function ‘main’:

test.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]

printf( "Hello\n" );

^

test.c:3:5: warning: incompatible implicit declaration of built-in function ‘printf’

test.c:3:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’

但是程式會動,還是可以印出 Hello 的字樣。為什麽?我這時候信誓旦旦的跟大家說,因為 printf 在 libc.so 裡面有,因此就算編譯的時候找不到,gcc 在連結 libc.so 的時候還是會看的到 printf ,所以這時候還是可以執行的。為了證明這件事情,我用 nm 去看一下編出來的 test.o

0000000000000000 T main

U puts

等一下, where is my printf ?? ...在學生面前要保持鎮定,大概 printf 在系統裡被改成 puts ... 然後再做實驗給同學看,這次換成利用 libm.so 的 pow 函式。

int main()
{
    printf( "2^3 = %f\n", pow( 2.0,3.0 ) );
    return 0;
}

然後說,這時候應該一定會有警告,而且程式還跑不起來,因為沒有 link 到 libm.so (我可沒有 -lm 的選項啊)。結果 ... 居然可以跑 ... ?? Why?? 趕快用 nm 看一下

0000000000000000 T main

U printf

恩,printf 出來了,萬歲,但我的 pow 呢?發生什麽事了,而且還可以執行,當場在課堂上楞在那邊發呆。掰不下去以後決定承認自己的無知 ... 還影響到後面上課個進行(因為都在想這個問題 ...)。

追下去,才發現真正的理由,那就是 ... gcc 它作弊 。相關資料可以參考這個網頁: Other Built-in Functions Provided by GCC 。資料節錄如下:

GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and are not documented here because they may change from time to time; we do not recommend general use of these functions .


The remaining functions are provided for optimization purposes .


With the exception of built-ins that have library equivalents such as the standard C library functions discussed below, or that expand to library calls, GCC built-in functions are always expanded inline and thus do not have corresponding entry points and their address cannot be obtained . Attempting to use them in an expression other than a function call results in a compile-time error.

簡單來說,gcc 內建了一堆函式而且不具有 symbol,在程式執行的時候他會直接以 inline 的方式去處理這些函式。所以根本就不會有 symbol 在那邊。要證明這件事情,我們可以使用 -fno-builtin 這個 option 來停用 gcc 的 built-in function。之後再來編編看剛剛的程式:

neokent@Banner /data/test/20181026 $ gcc -fno-builtin -c test2.c 

test2.c: In function ‘main’:

test2.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]

printf( "2^3 = %f\n", pow( 2.0, 3.0 ) );

^

test2.c:3:27: warning: implicit declaration of function ‘pow’ [-Wimplicit-function-declaration]

printf( "2^3 = %f\n", pow( 2.0, 3.0 ) );

^

neokent@Banner /data/test/20181026 $ gcc -fno-builtin test2.c -o test2

test2.c: In function ‘main’:

test2.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]

printf( "2^3 = %f\n", pow( 2.0, 3.0 ) );

^

test2.c:3:27: warning: implicit declaration of function ‘pow’ [-Wimplicit-function-declaration]

printf( "2^3 = %f\n", pow( 2.0, 3.0 ) );

^

/tmp/cczfqITn.o: 於函式 main:

test2.c:(.text+0x2d): 未定義參考到「pow」

collect2: error: ld returned 1 exit status

可以看到,pow 現在找不到定義了。解決方式?當然就是把 -lm 以及 header file加上去囉。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Open Scene Graph3.0三维视景仿真技术开发详解

Open Scene Graph3.0三维视景仿真技术开发详解

国防工业出版社 / 2012-7-1 / 46.00元

OpenSceneGraph 3.0三维视景仿真技术开发详解,ISBN:9787118081411,作者:杨化斌 著 杨化斌 编一起来看看 《Open Scene Graph3.0三维视景仿真技术开发详解》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具