Include files with function prototypes and variable declaration/definition

Discussion in 'C Programming' started by Kristian Virkus, Feb 7, 2007.

  1. 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);
    }
     
    Kristian Virkus, Feb 7, 2007
    #1
    1. Advertising

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

    <snip>

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

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Feb 7, 2007
    #2
    1. Advertising

  3. 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
     
    Kristian Virkus, Feb 7, 2007
    #3
  4. > With #define value 0 or how?

    If it shall be a constant.
     
    Kristian Virkus, Feb 7, 2007
    #4
  5. On 7 Feb 2007 07:01:23 -0800, in comp.lang.c , "Kristian Virkus"
    <> wrote:

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


    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
     
    Mark McIntyre, Feb 7, 2007
    #5
  6. Kristian Virkus wrote:
    >> With #define value 0 or how?

    >
    > 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.
     
    Tydr Schnubbis, Feb 7, 2007
    #6
  7. Tydr Schnubbis wrote:
    > Kristian Virkus wrote:
    > >> With #define value 0 or how?

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


    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.
     
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 7, 2007
    #7
  8. Kristian Virkus

    Thad Smith Guest

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


    Kristian Virkus wrote:
    >>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.

    --
    Thad
     
    Thad Smith, Feb 8, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bo Jacobsen
    Replies:
    6
    Views:
    513
    David M. Cook
    Mar 7, 2004
  2. Bolin
    Replies:
    4
    Views:
    412
  3. vaib

    variable declaration and definition!

    vaib, Oct 5, 2007, in forum: C Programming
    Replies:
    17
    Views:
    532
  4. Pierre Yves
    Replies:
    2
    Views:
    495
    Pierre Yves
    Jan 10, 2008
  5. Syren Baran

    function prototypes and function addresses

    Syren Baran, Jan 9, 2008, in forum: C Programming
    Replies:
    6
    Views:
    310
Loading...

Share This Page