chasep255
chasep255

Reputation: 12185

What is wrong with this C code? Strange Error

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++?

File 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;

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

Build

"/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

Answers (1)

Gene
Gene

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

Related Questions