Include files with function prototypes and variable declaration/definition

  • Thread starter Kristian Virkus
  • Start date
K

Kristian Virkus

Hello!

I would like to write a C programm with multiple include files, where
one may use another one (to print the value of a variable).
When I try to compile the program below, the linker says, there's a
multiple definition of 'value'.
I'm using Windows XP, MinGW (included with Code::Blocks 1.0RC2) with
GCC 3.4.4.

Can anyone help me to solve the problem?

Thanks a lot!
Kristian Virkus


Make output
=================================================
gcc -c -o func_a.o func_a.c
gcc -c -o func_b.o func_b.c
gcc -c -o main.o main.c
gcc -o main.exe func_b.o func_a.o main.o
func_a.o:func_a.c:(.bss+0x0): multiple definition of `value'
func_b.o:func_b.c:(.bss+0x0): first defined here
main.o:main.c:(.bss+0x0): multiple definition of `value'
func_b.o:func_b.c:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [main] Error 1


Makefile
=================================================
CC=gcc
main: main.o func_a.o func_b.o
$(CC) -o main.exe func_b.o func_a.o main.o
main.o: main.c func_a.o func_b.o
$(CC) -c -o main.o main.c
func_a.o: func_a.c
$(CC) -c -o func_a.o func_a.c
func_b.o: func_b.c
$(CC) -c -o func_b.o func_b.c


main.c
=================================================
#include "func_a.h"
#include "func_b.h"

int main()
{
fncA();
fncB();
}


func_a.h
=================================================
#ifndef FUNC_A_H_
#define FUNC_A_H_

int value = 0;
extern void fncA();

#endif


func_a.c
=================================================
#include "func_a.h"

void fncA()
{
}


func_b.h
=================================================
#ifndef FUNC_B_H_
#define FUNC_B_H_

extern void fncB();

#endif


func_b.c
=================================================
#include <stdio.h>
#include "func_a.h"
#include "func_b.h"

void fncB()
{
printf("%d", value);
}
 
R

Richard Heathfield

Kristian Virkus said:
Hello!

I would like to write a C programm with multiple include files, where
one may use another one (to print the value of a variable).
When I try to compile the program below, the linker says, there's a
multiple definition of 'value'.

If you must use file scope objects with external linkage (which is
sometimes, but rarely, a good idea), do not define them in a header.
Instead, *declare* them in a header, and define them in exactly one
source file. So:

func_a.h
=================================================
#ifndef FUNC_A_H_
#define FUNC_A_H_

int value = 0;

Change this to:

extern int value;

That's a declaration, but not a definition, so it reserves no storage.
It just provides necessary information to the compiler about the
object.
extern void fncA();

#endif


func_a.c
=================================================
#include "func_a.h"

Here, add:

int value = 0;

or just:

int value;

since static objects are initialised to 0 anyway. This is a definition,
not merely a declaration, so it reserves storage.

<snip>
 
K

Kristian Virkus

Hello again!
If you must use file scope objects with external linkage (which is
sometimes, but rarely, a good idea), do not define them in a header.
Instead, *declare* them in a header, and define them in exactly one
source file.

Yes, that works. I'm sure I tried that before but it did not work
because of some reason.
How would you normally realize the value-variable? With #define value
0 or how?

Thanks,
Kristian
 
M

Mark McIntyre

Hello again!


Yes, that works. I'm sure I tried that before but it did not work
because of some reason.
How would you normally realize the value-variable? With #define value
0 or how?

Just like Richard said. Declare it in a header, define it / set its
value in exactly one source file.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
T

Tydr Schnubbis

Kristian said:
If it shall be a constant.
#define VALUE 0


That's the common way to do it in C. It's common to use upper case
names for these symbolic constants, just to differentiate them from
variables.
 
G

Guest

Tydr said:
#define VALUE 0

That's the common way to do it in C. It's common to use upper case
names for these symbolic constants, just to differentiate them from
variables.

Usually better would be enum { value = 0 }, possibly using the
uppercase spelling. This makes sure value obeys normal scope rules and
doesn't cause value to be replaced with 0 when you're not using it in
an expression. It does mean you can't use it in #if expressions,
though, so sometimes it's not the right way to go.
 
T

Thad Smith

Kristian said:
>
> How would you normally realize the value-variable? With #define value
> 0 or how?


If it shall be a constant.

Trimming quotations is good, but please provide sufficient context.

As far as specifying a constant for your program, there are several ways
to do this. The technique I use often depends on my overall program
structure.

With an initial value of 0, if 0 is the natural value for the
application, such as initial value for a summation, a constant 0 where
the variable is defined is fine, assuming it doesn't need to be
initialized in multiple places.

If the number has special significance, such as the maximum number of
iterations allowed for an algorithm, I add a comment explaining the
significance.

In many cases there are several system parameters, such as minimum
frequency, number of frequency channels, and channel spacing, that I
want to define in one place. I will usually group them together and
probably define them with a macro name. The definition will have a
comment explaining the significance of the value and the units, such as
kHz for frequency. Those special values will be defined in _only one
place_, which prevents problems with inconsistent data whenever changes
are made. Derived values, such as maximum frequency, is computed from
the fundamental parameters. Since the parameters are constants, the
arithmetic expression is a constant expression and is as efficient at
run time as a single constant. These derived values are usually
assigned to additional macros:

#define FREQ_MAX_KHZ (FREQ_MIN_KHZ + NCHANNELS * CHANNEL_SEP_KHZ)
/* maximum transmission frequency, kHz */

My own experience is that describing constants and variable use
accurately, where defined, makes the program much easier to understand,
and thus, less likely to have errors.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top