0

main.c:

#include <stdio.h>
#include "proto.h"

int main(void)
{

    return(0);
} // end main

support.c:

#include "proto.h"

\\ only function defintions

proto.h:

#ifndef proto
#define proto
double PI = 3.14159;
int LOOP_LIMIT = 90;

#endif

makefile:

main: main.o  support.o 
    gcc -lm -o main main.o support.o
main.o: main.c proto.h
    gcc -c main.c
support.o: support.c proto.h
    gcc -c support.c

Whenever I run the makefile with the files defined as above, I always get a multiple definition error, despite having a conditional compilation.

I am not sure what is happening here and how to resolve the issue.

Error message is:

multiple definition of `PI'
multiple definition of `LOOP_LIMIT'
Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176

1 Answers1

2

You cannot define variables in a header that gets included from more than one compilation unit. PI and LOOP_LIMIT end up both in main.o and in support.o, so you get a linker error. The proper way to do it is declaring them extern in the header:

proto.h

#ifndef proto
#define proto
extern double PI;
extern int LOOP_LIMIT;

#endif

And then defining them in one and only one .c file:

support.c

#include "proto.h"

double PI = 3.14159;
int LOOP_LIMIT = 90;

\\ only function defintions

By the way, it looks like these guys might be constants rather than variables, so either declare and define them as const, or write them as preprocessor definitions:

#define PI 3.14159
#define LOOP_LIMIT 90

With those, you also avoid the linking problem.

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Bingo, that seems to do the stuff :) Just one note, why would #define work? Won't there be an attempt to redefine the same thing, as with multiple definition of variables. – Shamim Hafiz - MSFT Mar 01 '13 at 23:47
  • 1
    No. `#define` works almost like a copy/paste operation and is handled by the preprocessor, before the compiler even sees the code. So if you write `double circumference = PI * diameter;`, the compiler would see `double circumference = 3.14159 * diameter;`. The actual symbol `PI` does not end up in the compiled object files at all. – Thomas Mar 01 '13 at 23:54