这个C代码有什么问题?奇怪的错误

时间:2013-12-10 01:27:17

标签: 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

另外我只是注意到,如果我从main.c中删除我的include并且只将它保留在bigint.cpp中,它仍会编译。我看起来因为某些原因我只能包括一次。

1 个答案:

答案 0 :(得分:2)

关键是

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

您肯定在多个bigint.h文件中包含.c。由于预处理器通过文本替换来工作,这与在每个包含文件中声明相同的函数相同。因此,链接器会看到相同函数名的多个定义并死掉。

正如@Wumpus指出的那样,你可以通过声明函数static inline来解决这个问题。 static声明符使函数显示在.c所在的位置(无论是include还是直接)。它的符号不会暴露给链接器。

请注意,同一函数的inline和多个static声明都会导致代码膨胀。应该使用它们 - 就像你似乎已经完成的那样 - 仅限于小功能。