精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【gcc編譯優(yōu)化系列】static與inline的區(qū)別與聯(lián)系

嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 來(lái)源:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 2022-07-11 09:08 ? 次閱讀

1 問(wèn)題來(lái)源

今天偶然留意到RT-Thread論壇的一個(gè)問(wèn)題帖子,它的題目是RTT-VSCODE插件編譯RTT工程與RTT Studio結(jié)果不符,這種編譯問(wèn)題是我最喜歡深扒的,于是我點(diǎn)進(jìn)去看了看。

得知,它的核心問(wèn)題就是有一個(gè)類(lèi)似這樣定義的函數(shù)(為了簡(jiǎn)要說(shuō)明問(wèn)題,我精簡(jiǎn)了代碼):

/* main.c */

inline void test_func(int a, int b)
{
    printf("%d, %d\n", a, b);
}

int main(int argc, const char *argv[])
{
    /* do something */

    /* call func */
    test_func(1, 2);

    return 0;
}

然后,問(wèn)題就是 同一套工程代碼在RT-Thread Studio上能夠編譯通過(guò),但在VSCODE上卻產(chǎn)生錯(cuò)誤,這個(gè)錯(cuò)誤居然是undefined reference to ‘test_func’

2 問(wèn)題分析

看到undefined reference to ‘testfunc’這個(gè)錯(cuò)誤,熟悉C代碼編譯流程的都知道,這是一個(gè)典型的鏈接錯(cuò)誤,也就是說(shuō)錯(cuò)誤發(fā)在鏈接階段,鏈接錯(cuò)誤的原因是找不到testfunc函數(shù)的實(shí)現(xiàn)體

相信你一定也有許多問(wèn)號(hào)??????

test_func不是定義在main.c里面嗎?????

不就在main函數(shù)的上面嗎??????

怎么可能會(huì)發(fā)生鏈接錯(cuò)誤呢??????

我們平時(shí)寫(xiě)函數(shù)不就是這樣寫(xiě)的嗎??????

難道這個(gè)inline作妖??????

3 知識(shí)點(diǎn)分析

3.1 inline關(guān)鍵字是干嘛的?

準(zhǔn)確來(lái)說(shuō),它這個(gè)inline是一個(gè)C++關(guān)鍵字,在函數(shù)聲明或定義中,函數(shù)返回類(lèi)型前加上關(guān)鍵字inline,即可以把函數(shù)指定為內(nèi)聯(lián)函數(shù)。但是由于市面上的大部分C編譯器都可以兼容部分C++的關(guān)鍵字和語(yǔ)法,所以我們也經(jīng)常見(jiàn)到inline出現(xiàn)在C代碼中。

3.2 inline與宏定義有什么區(qū)別?

  1. 宏定義發(fā)生在預(yù)編譯處理階段,它僅僅是做字符串的替換,沒(méi)有任何的語(yǔ)法規(guī)則檢查,比如類(lèi)型不匹配,宏展開(kāi)后的各種語(yǔ)法問(wèn)題,的確讓人比較頭疼;
  2. inline函數(shù)則是發(fā)生在編譯階段,有完整的語(yǔ)法檢查,在Debug版本中也可以跟普通函數(shù)一樣,正常打斷點(diǎn)進(jìn)行調(diào)試;
  3. 由于處理的階段不一樣,這就導(dǎo)致如果宏函數(shù)展開(kāi)后仍然是一個(gè)函數(shù)調(diào)用的話,它是具有調(diào)用函數(shù)的開(kāi)銷(xiāo),包括函數(shù)進(jìn)棧出棧等等;而inline函數(shù)卻僅僅是函數(shù)代碼的拷貝替換,并不會(huì)發(fā)生函數(shù)調(diào)用的開(kāi)銷(xiāo),在這一點(diǎn)上inline具有很高的執(zhí)行效率。

3.3 inline函數(shù)與普通函數(shù)有什么區(qū)別?

正如上面提及的,普通函數(shù)的調(diào)用在匯編上有標(biāo)準(zhǔn)的 push 壓實(shí)參指令,然后 call 指令調(diào)用函數(shù),給函數(shù)開(kāi)辟棧幀,函數(shù)運(yùn)行完成,有函數(shù)退出棧幀的過(guò)程;而 inline 內(nèi)聯(lián)函數(shù)是在編譯階段,在函數(shù)的調(diào)用點(diǎn)將函數(shù)的代碼展開(kāi),省略了函數(shù)棧幀開(kāi)辟回退的調(diào)用開(kāi)銷(xiāo),效率高。

3.4 static函數(shù)與普通函數(shù)有什么區(qū)別?

兩者唯一的區(qū)別在于可見(jiàn)范圍不一樣:

  1. 不被static關(guān)鍵字修飾的函數(shù),它在整個(gè)工程范圍內(nèi),全局都可以調(diào)用,即其屬性是global的;只要函數(shù)參與了編譯,且最后鏈接的時(shí)候把函數(shù)的.o文件鏈接進(jìn)去了,是不會(huì)報(bào)undefined reference to ‘xxx’的;
  2. 被static關(guān)鍵字修飾的函數(shù),只能在其定義的C文件內(nèi)可見(jiàn),即其屬性由global變成了local,這個(gè)時(shí)候如果有另一個(gè)C文件的函數(shù)想調(diào)用這個(gè)static的函數(shù),那么對(duì)不起,最終鏈接階段會(huì)報(bào)undefined reference to ‘xxx’錯(cuò)誤的。

4 解決方案

回到前文的問(wèn)題,該如何解決這個(gè)問(wèn)題呢?我的想法,有兩種解決思路:

4.1 放棄inline函數(shù)的優(yōu)勢(shì),將inline函數(shù)修改為普通函數(shù)

這個(gè)方法很簡(jiǎn)單,無(wú)非就是去掉inline,做個(gè)降維處理,把inline函數(shù)變成普通函數(shù),自然編譯鏈接就不會(huì)報(bào)錯(cuò)。但我想,既然寫(xiě)代碼的原作者加了inline,肯定是希望用上inline的高效率的特性,所以去掉inline顯然不是一個(gè)明智的選擇。

4.2 對(duì)inline函數(shù)加上static修飾

這一個(gè)做法,就可以很聰明地把它的問(wèn)題給解決了。一個(gè)函數(shù)被static和inline修飾,證明這個(gè)函數(shù)是一個(gè)靜態(tài)的內(nèi)聯(lián)函數(shù),它的可見(jiàn)范圍依然是當(dāng)前C文件,且同時(shí)具備inline函數(shù)的特性。

5 知其然且知其所以然

5.1 實(shí)踐出真理

為了驗(yàn)證4.2的改法是否有效, 我在rt-thread/bsp/qemu-vexpress-a9中快速做個(gè)驗(yàn)證,只需要在applications/main.c里面添加下面的測(cè)試代碼:

/* applications/main.c */
static inline void test_func(int a, int b)
{
  printf("%d, %d\n", a, b);
}

int main(void)
{
    printf("hello rt-thread\n");

    test_func(1, 2);

    return 0;
}

特此說(shuō)明下,我使用的交叉編譯鏈?zhǔn)牵?strong>gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gcc

然后使用scons編譯,果然編譯成功了,運(yùn)行rtthread.elf,功能一切正常。

而當(dāng)我去掉static的時(shí)候,期望中的鏈接錯(cuò)誤果然出現(xiàn)了。

LINK rtthread.elf
build/applications/main.o: In function `main':
/home/recan/win_share_workspace/rt-thread-share/rt-thread/bsp/qemu-vexpress-a9/applications/main.c:253: undefined reference to `test_func'
collect2: error: ld returned 1 exit status
scons: *** [rtthread.elf] Error 1
scons: building terminated because of errors.

為了做進(jìn)一步驗(yàn)證,我在rtconfig.py里面的CFLAGS加了一個(gè)編譯選項(xiàng):-save-temps=obj;這個(gè)選項(xiàng)的作用就是在編譯的過(guò)程中,把中間過(guò)程文件也同步輸出,這里的中間文件有以下幾個(gè):

xxx.o 文件:這是最終對(duì)應(yīng)單個(gè)C文件生成的二進(jìn)制目標(biāo)文件,這個(gè)文件是最終參與鏈接成可執(zhí)行文件的。

xxx.s 文件:這是由預(yù)編譯處理后的xxx.i文件編譯得到的匯編文件,里面描述的是匯編指令;

xxx.i 文件:這是預(yù)編譯處理之后的文件,比如想宏定義被展開(kāi)之后是怎么樣的,就可以看這個(gè)文件;

關(guān)于使用GCC編譯C程序的完整過(guò)程這個(gè)話題,我已經(jīng)整理出來(lái)了,分享分享給大家,畢竟這個(gè)知識(shí)點(diǎn),對(duì)于解決編譯問(wèn)題可是幫助非常大的。

5.2 實(shí)踐結(jié)果分析

為了做對(duì)比,我把整個(gè)編譯執(zhí)行了兩次,一次是加上static的,一次是不加static的;

5.2.1 .i文件對(duì)比

對(duì)比結(jié)果如下,使用的是linux下的diff命令

diff ./build/applications/main.i.nostatic ./build/applications/main.i.static
4516c4516
<             inline void test_func(int a, int b)
---
> static inline void test_func(int a, int b) 

結(jié)果我們發(fā)現(xiàn)如我們期望一樣,nostatic的僅比static的少了一個(gè)static修飾符,其他都是一樣的。

5.2.2 .s文件對(duì)比

.s文件使用文本對(duì)比工具,發(fā)現(xiàn)加了static的.s文件,里面有test_func的匯編實(shí)現(xiàn)代碼,而不加的這個(gè)函數(shù)直接就被優(yōu)化掉了,壓根就找不到它的實(shí)現(xiàn)。

5.2.3 .o文件對(duì)比

由于.o文件已經(jīng)不是可讀的文本文件了,我們只能通過(guò)一些命令行工具來(lái)查看,這里推薦linux命令行下的nm工具,具體用途和方法可以使用man nm查看下。這里直接給出對(duì)比的命令行結(jié)果:

nm -a ./build/applications/main.o.nostatic | grep test_func
         U test_func

nm -a ./build/applications/main.o.static | grep test_func  
000002d8 t test_func 

OK,從中已經(jīng)可以看到重要區(qū)別了:在不帶static的版本中,main.c里定義的testfunc函數(shù)被認(rèn)為是一個(gè)外部函數(shù)(標(biāo)識(shí)為U),而被static修飾的卻是本地實(shí)現(xiàn)函數(shù)(標(biāo)識(shí)為T(mén))。 而標(biāo)識(shí)為U的函數(shù)是需要外部去實(shí)現(xiàn)的,這也就解釋了為何nostatic的版本會(huì)報(bào)undefined reference to 'testfunc' 錯(cuò)誤,因?yàn)閴焊蜎](méi)有外部的誰(shuí)去實(shí)現(xiàn)這個(gè)函數(shù)。

5.4 終極實(shí)驗(yàn)

5.4.1 補(bǔ)充測(cè)試代碼

為了驗(yàn)證好這幾個(gè)關(guān)鍵字的區(qū)別,以及為何加了inline還不內(nèi)聯(lián),如何才能真正的內(nèi)聯(lián),我補(bǔ)充了一下測(cè)試代碼:

#include 

#if 0
/* only inline function : link error ! */
inline void test_func(int a, int b)
{
    printf("%d, %d\n", a, b);
}
#endif

/* normal function: OK */
void test_func1(int a, int b)
{
    printf("%d, %d\n", a, b);
}

/* static function: OK */
static void test_func2(int a, int b)
{
    printf("%d, %d\n", a, b);
}

/* static inline function: OK, but no real inline */
static inline void test_func3(int a, int b)
{
    printf("%d, %d\n", a, b);
}

/* always_inline is very important*/
#define FORCE_FUNCTION  __attribute__((always_inline))

/* static inline function: OK, it real inline. */
FORCE_FUNCTION static inline void test_func4(int a, int b)
{
    printf("%d, %d\n", a, b);
}

int main(int argc, const char *argv[])
{
    printf("Hello world !\n");

    /* call these functions with the same input praram */
    //test_func(1, 2);
    test_func1(1, 2); // normal
    test_func2(1, 2); // static
    test_func3(1, 2); // static inline (real inline ?)
    test_func4(1, 2); // static inline (real inline ?)

    return 0;
}

5.4.2 編譯驗(yàn)證

執(zhí)行編譯

gcc main.c -save-temps=obj -Wall -o test_static -Wl,-Map=test_static.map

成功編譯,運(yùn)行也完全沒(méi)有問(wèn)題。

./test_static 
Hello world !
1, 2
1, 2
1, 2
1, 2

5.4.3 進(jìn)階分析

通過(guò)上面的章節(jié),我們可以知道,我們應(yīng)該重點(diǎn)分析.s文件和.o文件,因?yàn)?o文件不可讀,我們用nm-a查看下:

 nm -a test_static.o | grep test_func
0000000000000000 T test_func1
000000000000002e t test_func2
000000000000005c t test_func3

結(jié)果發(fā)現(xiàn)test_func4不在里面了,看樣子是被真正inline了? 我們打開(kāi).s文件確認(rèn)下:

    .file   "main.c"
    .text
    .section    .rodata
.LC0:
    .string "%d, %d\n"
    .text
    .globl  test_func1
    .type   test_func1, @function
test_func1:
.LFB0:
    .cfi_startproc
    endbr64
    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    %esi, -8(%rbp)
    movl    -8(%rbp), %edx
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   test_func1, .-test_func1
    .type   test_func2, @function
test_func2:
.LFB1:
    .cfi_startproc
    endbr64
    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    %esi, -8(%rbp)
    movl    -8(%rbp), %edx
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size   test_func2, .-test_func2
    .type   test_func3, @function
test_func3:
.LFB2:
    .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    %esi, -8(%rbp)
    movl    -8(%rbp), %edx
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE2:
    .size   test_func3, .-test_func3
    .section    .rodata
.LC1:
    .string "Hello world !"
    .text
    .globl  main
    .type   main, @function
main:
.LFB4:
    .cfi_startproc
    endbr64
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    movq    %rsi, -32(%rbp)
    leaq    .LC1(%rip), %rdi
    call    puts@PLT
    movl    $2, %esi
    movl    $1, %edi
    call    test_func1
    movl    $2, %esi
    movl    $1, %edi
    call    test_func2
    movl    $2, %esi
    movl    $1, %edi
    call    test_func3
    movl    $1, -8(%rbp)
    movl    $2, -4(%rbp)
    movl    -4(%rbp), %edx
    movl    -8(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE4:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
    .section    .note.GNU-stack,"",@progbits
    .section    .note.gnu.property,"a"
    .align 8
    .long    1f - 0f
    .long    4f - 1f
    .long    5
0:
    .string  "GNU"
1:
    .align 8
    .long    0xc0000002
    .long    3f - 2f
2:
    .long    0x3
3:
    .align 8
4:

從中,我們可以看到testfunc1與testfunc2的區(qū)別是testfunc1是GLOBAL的,而testfunc2是LOCAL的;而testfunc2與testfunc3卻是完全一模一樣;也就是說(shuō)testfunc3使用static inline壓根就沒(méi)有被內(nèi)聯(lián)。 我們?cè)僬艺襱estfunc4,發(fā)現(xiàn)已經(jīng)找不到了,到底是不是內(nèi)聯(lián)了?我們?cè)倏纯磎ain函數(shù)里面調(diào)用的部分:

main:
.LFB4:
    .cfi_startproc
    endbr64
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    movq    %rsi, -32(%rbp)
    leaq    .LC1(%rip), %rdi
    call    puts@PLT

    movl    $2, %esi
    movl    $1, %edi
    call    test_func1  //調(diào)用test_func1函數(shù)

    movl    $2, %esi
    movl    $1, %edi
    call    test_func2  //調(diào)用test_func2函數(shù)

    movl    $2, %esi
    movl    $1, %edi
    call    test_func3  //調(diào)用test_func3函數(shù)

    movl    $1, -8(%rbp)
    movl    $2, -4(%rbp)
    movl    -4(%rbp), %edx
    movl    -8(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    nop
    movl    $0, %eax
    leave               //“調(diào)用”test_func4函數(shù),使用了內(nèi)聯(lián),直接拷貝了代碼,并不是真的函數(shù)調(diào)用。


    .cfi_def_cfa 7, 8

嘩,果然,這才是真正的內(nèi)聯(lián)啊,我們終于揭開(kāi)了這個(gè)神秘的面紗。

5.4 實(shí)踐經(jīng)驗(yàn)總結(jié)

  • inline有利有弊,切記使用的時(shí)候,最好讓它跟static一起使用,否則可能導(dǎo)致的問(wèn)題超出你的想象。
  • 加了inline,不是你想內(nèi)聯(lián),編譯器就一定會(huì)幫你內(nèi)聯(lián)的,還得看代碼的實(shí)現(xiàn)。
  • 如果要強(qiáng)制內(nèi)聯(lián),還得加參數(shù)修飾,每個(gè)C編譯器的方法還不一樣,比如gcc的是使用_attribute((alwaysinline))修飾定義的函數(shù)即可。

6 更多分享

本項(xiàng)目的所有測(cè)試代碼和編譯腳本,均可以在我的github倉(cāng)庫(kù)01workstation中找到,歡迎指正問(wèn)題。

歡迎關(guān)注我的github倉(cāng)庫(kù)01workstation,日常分享一些開(kāi)發(fā)筆記和項(xiàng)目實(shí)戰(zhàn),歡迎指正問(wèn)題。

同時(shí)也非常歡迎關(guān)注我的CSDN主頁(yè)和專(zhuān)欄:

【CSDN主頁(yè):架構(gòu)師李肯】

【RT-Thread主頁(yè):架構(gòu)師李肯】

【C/C++語(yǔ)言編程專(zhuān)欄】

【GCC專(zhuān)欄】

信息安全專(zhuān)欄】

【RT-Thread開(kāi)發(fā)筆記】

有問(wèn)題的話,可以跟我討論,知無(wú)不答,謝謝大家。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • GCC
    GCC
    +關(guān)注

    關(guān)注

    0

    文章

    105

    瀏覽量

    24822
  • static
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    10356
  • inline
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    1628
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    GCC編譯優(yōu)化系列】前后編譯的兩版本固件bin大小不一樣?

    GCC編譯優(yōu)化系列】前后編譯的兩個(gè)版本固件bin大小不一樣,怎么辦?
    的頭像 發(fā)表于 09-09 09:01 ?4546次閱讀
    【<b class='flag-5'>GCC</b><b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b><b class='flag-5'>系列</b>】前后<b class='flag-5'>編譯</b>的兩版本固件bin大小不一樣?

    Linux 下GCC編譯

    一、Linux 下多文件編譯 在上一篇 Linux 下的 C 編程我們知道了 Linux 下的編譯器為 GCC ,以及如何使用 GCC 進(jìn)行編譯
    的頭像 發(fā)表于 09-11 15:18 ?2535次閱讀
    Linux 下<b class='flag-5'>GCC</b>的<b class='flag-5'>編譯</b>

    使用gcc編譯優(yōu)化與不優(yōu)化問(wèn)題

    同樣的程序,使用gcc編譯優(yōu)化與不優(yōu)化的結(jié)果不一代碼如下:1. #include 2.3. int main()4. {5.int i = 1;6.7.i
    發(fā)表于 09-27 10:33

    請(qǐng)問(wèn)static inline有什么作用?

    其實(shí)統(tǒng)一接口,大家都需要實(shí)現(xiàn)這個(gè)接口,如果不用static,那就很有可能重名。編譯就會(huì)出錯(cuò)了。這里的接口 指什么呢?? 可以截圖看么??static inline 是內(nèi)聯(lián)的:小函數(shù),而
    發(fā)表于 04-28 06:56

    編譯cmsis_gcc.h文件時(shí)有上百個(gè)警告信息是怎么回事?

    編譯時(shí) cmsis_gcc.h 這個(gè)文件有上百個(gè)警告信息,提示的警告信息都一樣,不知道是怎么回事,請(qǐng)問(wèn)這個(gè)警告信息是為什么?能不能修改一下給消除掉#define __STATIC_FORCEINLINE __attribute
    發(fā)表于 05-09 09:54

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    默認(rèn)的鏈接腳本【GCC編譯優(yōu)化系列staticinline
    發(fā)表于 07-26 14:56

    AVR系列單片機(jī)GCC免費(fèi)編譯工具

    AVR系列單片機(jī)GCC免費(fèi)編譯工具
    發(fā)表于 04-13 15:23 ?54次下載

    淺談gcc編譯

    3.3 gcc編譯器 GNU CC(簡(jiǎn)稱(chēng)為gcc)是GNU項(xiàng)目中符合ANSI C標(biāo)準(zhǔn)的編譯系統(tǒng),能夠編譯用C、C++和Object C等語(yǔ)言
    發(fā)表于 10-18 13:48 ?0次下載

    常見(jiàn)gcc編譯警告整理以及解決方法

     GCC有很多的編譯選項(xiàng),警告選項(xiàng);指定頭文件、庫(kù)路徑;優(yōu)化選項(xiàng)。本文針整理一下GCC的警告選項(xiàng)以及gcc
    發(fā)表于 11-14 11:19 ?2.1w次閱讀

    GCC編譯優(yōu)化指南

    (cpp) → 編譯(gcc或g++) → 匯編(as) → 連接(ld) ;括號(hào)中表示每個(gè)階段所使用的程序,它們分別屬于 GCC 和 Binutils 軟件包。顯然的,優(yōu)化應(yīng)當(dāng)從
    發(fā)表于 04-02 14:36 ?527次閱讀

    gcc編譯優(yōu)化系列】如何獲取gcc默認(rèn)的鏈接腳本

    我們都知道在一般的嵌入式開(kāi)發(fā)中,使用gcc編譯固件的一般流程是,先把所有的.c文件和.s文件編譯成.o文件,然后把所有的.o文件鏈接成一個(gè)elf文件,最后由elf文件導(dǎo)出bin文件。 那么在鏈接成
    的頭像 發(fā)表于 07-11 09:15 ?3381次閱讀

    GCC編譯優(yōu)化系列】實(shí)戰(zhàn)分析C代碼遇到的編譯問(wèn)題及解決思路

    GCC編譯優(yōu)化系列】實(shí)戰(zhàn)分析C工程代碼可能遇到的編譯問(wèn)題及其解決思路
    的頭像 發(fā)表于 07-10 23:15 ?1369次閱讀
    【<b class='flag-5'>GCC</b><b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b><b class='flag-5'>系列</b>】實(shí)戰(zhàn)分析C代碼遇到的<b class='flag-5'>編譯</b>問(wèn)題及解決思路

    GCC編譯優(yōu)化系列】multiple-definition

    GCC編譯優(yōu)化系列】這種讓人看不懂的multiple-definition真的有點(diǎn)讓人頭疼
    的頭像 發(fā)表于 07-11 09:26 ?6946次閱讀
    【<b class='flag-5'>GCC</b><b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b><b class='flag-5'>系列</b>】multiple-definition

    GCC編譯優(yōu)化系列】-specs=kernel.specs

    GCC編譯優(yōu)化系列GCC編譯鏈接時(shí)候--specs=kernel.specs鏈接屬性究竟是個(gè)
    的頭像 發(fā)表于 07-11 09:25 ?3321次閱讀
    【<b class='flag-5'>GCC</b><b class='flag-5'>編譯</b><b class='flag-5'>優(yōu)化</b><b class='flag-5'>系列</b>】-specs=kernel.specs

    LL庫(kù)中常見(jiàn)關(guān)鍵字__STATIC_INLINE

    LL庫(kù)中常見(jiàn)關(guān)鍵字__STATIC_INLINE,其定義見(jiàn)cmsis_gcc.h
    的頭像 發(fā)表于 07-24 11:30 ?1383次閱讀
    LL庫(kù)中常見(jiàn)關(guān)鍵字__<b class='flag-5'>STATIC_INLINE</b>