Reputation: 12185
I am trying to write C for the first time and I keep getting the following error. When I comment out the function and my constant it will compile. Can I not declare constants and inline functions in the header file like I do in 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
Output:
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
So here is my updated header file. (I added a few more functions.) I have too other files, main.c and bigint.c both which include bitint.h.
The code compiles only when I comment out the #include "bigint.h" in the bigint.cpp file. There is nothing else yet in that file. Same error as before.
#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
Also I just noticed that if I remove my include from main.c and only leave it in bigint.cpp it still compiles. I looks like I can only include it once for some reason.
Upvotes: 1
Views: 1030
Reputation: 47020
The key line is
C:\Users\Chase\Documents\NetBeansProjects\CBigNum/bigint.h:9: multiple definition of `bi_sign'
You are certainly including bigint.h
in multiple .c
files. Since the preprocessor works by text substitution, this is the same as declaring the same function in each of the including files. Consequently, the linker sees multiple definitions of the same function name and dies.
As user2404501 points out, you can fix this by declaring the function static inline
. The static
declarator makes the function local to the .c
where it appears (whether by include
or directly). It's symbol is not exposed to the linker.
Note that both inline
and multiple static
declarations of the same function can result in code bloat. They should be used—as you seem to have done—only on small functions.
Upvotes: 3