2013-06-21 118 views
0

我一直在試圖理解我得到的有關_sbrk函數的鏈接錯誤,並偶然發現了庫中的這個函數定義。現在C函數定義和Extern關鍵字

extern caddr_t _sbrk(int incr); 

// ... some other definitions ... 

extern caddr_t _sbrk(int incr) 
{ 
static unsigned char *heap = NULL; 
unsigned char *prev_heap; 

if (heap == NULL) { 
    heap = (unsigned char *)&_end; 
} 
prev_heap = heap; 

heap += incr; 

return (caddr_t) prev_heap; 
} 

,我知道什麼extern做一個函數的聲明,但是在功能定義中使用的時候,我不知道它的意思...

有誰知道什麼意思extern像這樣使用時也?

相關文件位於asf/sam/utils/syscalls/gcc/syscalls.c目錄中的Atmel軟件框架(ASF)中。

它是在嵌入式環境中,我得到有關_sbrk_exit缺少定義,_kill,linkrt錯誤一堆...

這是有道理的生成存根,但我本來期望,在至少給定的_sbrk定義會起作用?

更新:

好了,似乎它可能有助於增加約我如何連接所有的這一起一點點信息。

我有一個可執行項目(將與GCC構建),我有一個靜態庫項目鏈接到生成的可執行文件(也用GCC構建)。

它們都沒有啓用優化(它可以更容易在嵌入式目標上進行調試,而不會像在藥物上那樣跳躍)。

靜態庫包含上面提到的ASF代碼。 ASF是由Atmel Studio 6.0中包含的一些嚮導自動生成的。

靜態庫中的一些代碼包括<stdio.h>這不是我需要的,但我並不想改變自動生成的代碼(它必然會取消我的更改)。從連接

錯誤如下:

Invoking: ARM/GNU Linker : (crosstool-NG 1.15.3 - Atmel build: 59) 4.7.0 
    "C:\Program Files (x86)\Atmel\Atmel Studio 
6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMGCCToolchain\bin\arm-none-eabi-gcc.exe" -o 
Bootloader_Stage1.elf cmsis/src/startup_sam3n.o cmsis/src/system_sam3n.o 
Bootloader_Stage1.o -Wl,-Map="Bootloader_Stage1.map" -Wl,--start-group -lm - 
lBootloaderShared -Wl,--end-group -L"../cmsis/linkerScripts" - 
L"../../BootloaderShared/Debug" -Wl,--gc-sections -Tsam3n4b_flash.ld -mcpu=cortex-m3 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-abort.o): In function 
`abort': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/stdlib/abort.c(63,1): undefined reference to `_exit' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-sbrkr.o): In function 
`_sbrk_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/sbrkr.c(60,1): undefined reference to `_sbrk' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function 
`_kill_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/signalr.c(61,1): undefined reference to `_kill' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function 
`_getpid_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/signalr.c(96,1): undefined reference to `_getpid' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-writer.o): In function 
`_write_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/writer.c(58,1): undefined reference to `_write' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-closer.o): In function 
`_close_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/closer.c(53,1): undefined reference to `_close' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-fstatr.o): In function 
`_fstat_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/fstatr.c(62,1): undefined reference to `_fstat' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-isattyr.o): In function 
`_isatty_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/isattyr.c(58,1): undefined reference to `_isatty' 
    Invoking: ARM/GNU Linker : (crosstool-NG 1.15.3 - Atmel build: 59) 4.7.0 
    "C:\Program Files (x86)\Atmel\Atmel Studio 
6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMGCCToolchain\bin\arm-none-eabi-gcc.exe" -o 
Bootloader_Stage1.elf cmsis/src/startup_sam3n.o cmsis/src/system_sam3n.o 
Bootloader_Stage1.o -Wl,-Map="Bootloader_Stage1.map" -Wl,--start-group -lm - 
lBootloaderShared -Wl,--end-group -L"../cmsis/linkerScripts" - 
L"../../BootloaderShared/Debug" -Wl,--gc-sections -Tsam3n4b_flash.ld -mcpu=cortex-m3 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-abort.o): In function 
`abort': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/stdlib/abort.c(63,1): undefined reference to `_exit' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-sbrkr.o): In function 
`_sbrk_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/sbrkr.c(60,1): undefined reference to `_sbrk' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function 
`_kill_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/signalr.c(61,1): undefined reference to `_kill' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-signalr.o): In function 
`_getpid_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/signalr.c(96,1): undefined reference to `_getpid' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-writer.o): In function 
`_write_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/writer.c(58,1): undefined reference to `_write' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-closer.o): In function 
`_close_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/closer.c(53,1): undefined reference to `_close' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-fstatr.o): In function 
`_fstat_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/fstatr.c(62,1): undefined reference to `_fstat' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-isattyr.o): In function 
`_isatty_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/isattyr.c(58,1): undefined reference to `_isatty' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-lseekr.o): In function 
`_lseek_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/lseekr.c(58,1): undefined reference to `_lseek' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-readr.o): In function 
`_read_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/readr.c(58,1): undefined reference to `_read' 
collect2.exe(0,0): ld returned 1 exit statusc:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-lseekr.o): In function 
`_lseek_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/lseekr.c(58,1): undefined reference to `_lseek' 
    c:/program files (x86)/atmel/atmel studio 
6.0/extensions/atmel/armgcc/3.3.1.128/armgcctoolchain/bin/../lib/gcc/arm-none- 
eabi/4.7.0/../../../../arm-none-eabi/lib/thumb\libc.a(lib_a-readr.o): In function 
`_read_r': 
/usr/local/avr32studio/hudson/workspace/arm-gnu-toolchain/.build/src/newlib- 
1.19.0/newlib/libc/reent/readr.c(58,1): undefined reference to `_read' 
collect2.exe(0,0): ld returned 1 exit status 

更新2:

我已經解決了我的問題聯繫起來。看來Atmel軟件框架包含#include <assert.h>這是調用所有其他功能的軟件框架。在該標頭中的assert()宏定義如下

#ifdef NDEBUG   /* required by ANSI standard */ 
# define assert(__e) ((void)0) 
#else 
# define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ 
          __ASSERT_FUNC, #__e)) 

定義NDEBUG鏈接問題消失後。據我所見NDEBUG沒有在其他地方使用(不刪除任何我依賴的其他代碼),所以我可以離開符號定義。

正如我前面提到的,我已經接受了回答extern問題的答案,並投票支持解決鏈接問題的答案。

+0

你在鏈接嗎?我不認爲這些'extern'關鍵字做*任何*。 –

+0

瞭解'extern'檢查這[L1](http://stackoverflow.com/questions/1433204/what-are-extern-variables-in-c)。 –

+0

@Carl Norum是的,我連接它,但它有點複雜,所以我會更新我的問題。 – nonsensickle

回答

3

在函數聲明中指定extern沒有問題。從C99 6.9.1/4 「函數定義」:

語法

function-definition: 
    declaration-specifiers declarator declaration-list[opt] compound-statement 

...

的存儲類說明,如果有的話,在聲明符應爲externstatic

但是,關於函數定義的extern並不特別有用。從C99 6.2.2/4「的標識符的聯繫」:

爲了與存儲類說明extern在一個範圍,其中該標識符的先前聲明是可見的,如果在現有的聲明指定內部聲明的標識符或外部鏈接,後面聲明中標識符的鏈接與先前聲明中指定的鏈接相同。如果前面的聲明不可見,或者前面的聲明沒有指定鏈接,則標識符具有外部鏈接。

如果某個函數的標識符聲明沒有存儲類說明符,那麼它的鏈接就像使用存儲類說明符extern聲明一樣。

所以,函數的第一個聲明之後,在隨後的函數聲明任何extern被忽略,即使是首次聲明static

+0

謝謝,這解釋了它。我還發現@Dayal rai提到'函數定義也是一個函數聲明',對理解有用。這也出現在你的答案中,但不是很明顯。無論它被接受。再次感謝。 – nonsensickle

1

extern在函數定義之前只是表示該函數有外部聯動(which it has anyway by default)

只要聲明具有它並且已經在定義的編譯中看到了,就不應該在函數定義上使用'extern'。 還記得definitions are declarations also

+0

...在原型/聲明中它不是必需的。沒有'static'聲明的函數總是有外部鏈接。 –

+0

你和邁克爾伯爾的答案一起解釋完美。謝謝! – nonsensickle

1

在對鏈接問題的部分回答中,鏈接器抱怨說它沒有鏈接在一起的任何東西,例如,目標文件(可能還包括預編譯的庫)包含_sbrk()函數,該函數由的代碼調用。其他幾個低級庫功能也是如此。

extern不會影響您的問題。

+0

你是對的,我發現我的問題在哪裏。我將用我找到的解決方案更新我的問題。謝謝 – nonsensickle