GCC Built-in Functions

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

内容简介:最近上課的時候鬧了一個大笑話(而且那門課還是組合語言不是程式設計...)。我寫了下面這隻程式:很明顯,這程式沒有 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加上去囉。


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

查看所有标签

猜你喜欢:

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

大型网站系统与Java中间件开发实践

大型网站系统与Java中间件开发实践

曾宪杰 / 电子工业出版社 / 2014-4-24 / 65.00

本书围绕大型网站和支撑大型网站架构的 Java 中间件的实践展开介绍。从分布式系统的知识切入,让读者对分布式系统有基本的了解;然后介绍大型网站随着数据量、访问量增长而发生的架构变迁;接着讲述构建 Java 中间件的相关知识;之后的几章都是根据笔者的经验来介绍支撑大型网站架构的 Java 中间件系统的设计和实践。希望读者通过本书可以了解大型网站架构变迁过程中的较为通用的问题和解法,并了解构建支撑大型......一起来看看 《大型网站系统与Java中间件开发实践》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码