2013-12-10 54 views
1

我想第一次寫C,我不斷收到以下錯誤。當我註釋掉這個函數和我的常量時,它會編譯。我可以不像C++那樣在頭文件中聲明常量和內聯函數嗎?這個C代碼有什麼問題?奇怪的錯誤

#include <stdlib.h> 

typedef unsigned long base_int; 
typedef unsigned long long overflow_int; 
typedef base_int * big_int; 
const unsigned int INIT_LENGTH = 3; 

inline int bi_sign(big_int x) 
{ 
    return 2; 
} 
void bi_create(int); 
void bi_dealloc(big_int *); 
//End of bigint.h 

"/C/CPP Dev/msys/bin/make.exe" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf 
make.exe[1]: Entering directory `/c/Users/Chase/Documents/NetBeansProjects/CBigNum' 
"/C/CPP Dev/msys/bin/make.exe" -f nbproject/Makefile-Debug.mk dist/Debug/MinGW-Windows/cbignum.exe 
make.exe[2]: Entering directory `/c/Users/Chase/Documents/NetBeansProjects/CBigNum' 
mkdir -p build/Debug/MinGW-Windows 
rm -f "build/Debug/MinGW-Windows/big_int.o.d" 
gcc -c -g -MMD -MP -MF "build/Debug/MinGW-Windows/big_int.o.d" -o build/Debug/MinGW-Windows/big_int.o big_int.c 
mkdir -p build/Debug/MinGW-Windows 
rm -f "build/Debug/MinGW-Windows/main.o.d" 
gcc -c -g -MMD -MP -MF "build/Debug/MinGW-Windows/main.o.d" -o build/Debug/MinGW-Windows/main.o main.c 
mkdir -p dist/Debug/MinGW-Windows 
gcc  -o dist/Debug/MinGW-Windows/cbignum build/Debug/MinGW-Windows/big_int.o build/Debug/MinGW-Windows/main.o 
build/Debug/MinGW-Windows/main.o: In function `bi_sign': 
C:\Users\Chase\Documents\NetBeansProjects\CBigNum/bigint.h:9: multiple definition of `bi_sign' 
build/Debug/MinGW-Windows/big_int.o:C:\Users\Chase\Documents\NetBeansProjects\CBigNum/bigint.h:9: first defined here 
collect2.exe: error: ld returned 1 exit status 
make.exe[2]: *** [dist/Debug/MinGW-Windows/cbignum.exe] Error 1 
make.exe[2]: Leaving directory `/c/Users/Chase/Documents/NetBeansProjects/CBigNum' 
make.exe[1]: *** [.build-conf] Error 2 
make.exe[1]: Leaving directory `/c/Users/Chase/Documents/NetBeansProjects/CBigNum' 
make.exe": *** [.build-impl] Error 2 

所以這裏是我更新的頭文件。 (我添加了幾個函數。) 我也有其他文件,main.c和bigint.c都包含了bitint.h。 僅在我註釋掉bigint.cpp文件中的#include「bigint.h」時纔會編譯代碼。該文件中沒有任何其他內容。與以前一樣的錯誤。

#ifndef BIGINT_H 
#define BIGINT_H 
#include <stdlib.h> 

typedef unsigned long base_int; 
typedef unsigned long long overflow_int; 
typedef base_int * big_int; 
const unsigned int INIT_LENGTH = 3; 

//Memory 
int bi_sign(const big_int x); 
unsigned int bi_length(const big_int x); 
unsigned int bi_mem_size(const big_int x); 
void bi_init(big_int * x, int n); 
big_int bi_create(int x); 
void bi_dealloc(big_int* x); 
void bi_copy(const big_int, big_int*); 

//Arithmetic 
big_int bi_add(const big_int, const big_int); 
big_int bi_add_int(const big_int, int); 
big_int bi_mult(const big_int, const big_int); 
big_int bi_mult_int(const big_int, int); 
big_int bi_sub(const big_int, const big_int); 
big_int bi_sub_int(const big_int, int); 
void bi_incby(big_int*, unsigned int); 
void bi_decby(big_int*, unsigned int); 
void bi_multby(big_int*, unsigned int); 
#endif 

另外我只是注意到,如果我刪除我的include從main.c,只留下它在bigint.cpp它仍然編譯。我看起來像我只能因爲某種原因包括一次。

+1

你可能想要'靜態內聯'。相關問題:http://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever-useful-in-c99 –

回答

2

重點線是

C:\Users\Chase\Documents\NetBeansProjects\CBigNum/bigint.h:9: multiple definition of `bi_sign' 

你肯定包括多個.c文件bigint.h。由於預處理器通過文本替換工作,這與在每個包含文件中聲明相同的函數相同。因此,鏈接器會看到同一個函數名稱的多個定義並死亡。

正如@Wumpus指出的,你可以通過聲明函數static inline來解決這個問題。 static聲明器使函數在本地出現在.c的位置(無論是通過include還是直接)。它的符號不會暴露給鏈接器。

請注意,同一個函數的inline和多個static聲明都可能導致代碼膨脹。它們應該像你似乎已經完成的那樣使用 - 只用於小功能。