1

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
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.

chasep255
  • 11,745
  • 8
  • 58
  • 115
  • 1
    You probably want `static inline`. Related question: http://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever-useful-in-c99 –  Dec 10 '13 at 01:34

1 Answers1

2

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 @Wumpus 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.

Gene
  • 46,253
  • 4
  • 58
  • 96