Definition in Header files

Discussion in 'C Programming' started by Madhur, Oct 23, 2007.

  1. Madhur

    Madhur Guest

    I have problems faced in adding definitions in the command header
    file. I have defined a header file which includes huge set of global
    constants and I am using them in all the C files.

    For example my sample.h file looks like this

    /*************

    File : sample.h

    ****************/


    const int a1 = 0;
    const int a2 = 0;


    /****End of sample.h*********/


    My source code looks like this

    /*****************
    File:sample1.c

    ***********/
    #include "sample.h"

    int main()
    {
    }

    /*****End of sample1.c************/

    /***************
    File : sample2.c
    **************/

    #include "sample.h

    int main()
    {
    }

    /*******End of sample2.c**********/

    Now the problem is during linking it says multiple definition of
    symbols a1 and a2. I can avoid this problem by having a C file which
    contains the definitions and H file for declarations. But is there any
    way I can avoid doing this. Please let me know.
     
    Madhur, Oct 23, 2007
    #1
    1. Advertisements

  2. Madhur

    user923005 Guest

    Global things that don't have to be global is a bad idea.
    Nevertheless, you can use them {warning -- untested} as follows:

    -- const.c --
    #include "const.h"
    int gVal = 100;
    double gPi = 3.1415926535897932384626433832795;
    -- end const.c --

    -- const.h --
    extern int gVal;
    extern double gPi;
    -- end const.h --

    -- main.c --
    #include <stdio.h>
    #include "const.h"
    int main(void)
    {
    printf("gVal = %d and gPi = %f\n", gVal, gPi);
    return 0;
    }
    -- end main.c --
     
    user923005, Oct 23, 2007
    #2
    1. Advertisements

  3. Madhur

    Ian Collins Guest

    Why avoid doing the obvious?
     
    Ian Collins, Oct 23, 2007
    #3
  4. Madhur

    Madhur Guest

    Here are a1 and a2 are global variables and I will be using in both
    sample1.c and sample2.c files.
    This what I wanted to avoid.. as indicated by me
     
    Madhur, Oct 23, 2007
    #4
  5. Madhur

    Madhur Guest

    I want those variable to be const. Defining them in a C file , I can
    not declare them as const.
    Why doesn't C compilation doesn't support Internal linkage as it is
    supported by C++??
     
    Madhur, Oct 23, 2007
    #5

  6. Well, no really good ways.

    You can do like you suggested and put the definitions in a separate
    file. This is probably the best approach, but has the obvious problem
    of considerable duplication.

    A second possibility is to make all of these constants static as
    well. That solves the multiple definition problem, but duplicates the
    constants in each module that includes the header. Depending on the
    exact definition of "huge" and the number of times the header is
    included, this may result in an unacceptable expansion of the
    executable.

    Third you could keep the definitions in the header, but play
    preprocessor games so that when most users of the constants include
    the header, the initializations are omitted. For example:

    const int a1
    #ifdef IN_DEFINING_MODULE
    = 0
    #endif
    ;

    The you'd have a const.c which included const.h along with the
    #define:

    /* const.c */
    #define IN_DEFINING_MODULE
    #include "const.h"

    This is obviously ugly, but it does work.

    As others have pointed out, it's probably a sign of a design problem
    if you have "huge" numbers of global constants, so you may want to
    start by rethinking your design.
     
    robertwessel2, Oct 23, 2007
    #6
  7. Madhur

    user923005 Guest

    Of course you can.
    We might ask, why doesn't C support block data statements like
    Fortran?

    At any rate, you can have external const in C. The code you posted
    should not work in C++ either. Every time you include that header
    file, it defines a new instance of the variables.

    C:\tmp>cl /W4 /Ox const.c main.c
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
    for 80x86
    Copyright (C) Microsoft Corporation. All rights reserved.

    const.c
    main.c
    Generating Code...
    Microsoft (R) Incremental Linker Version 8.00.50727.762
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:const.exe
    const.obj
    main.obj

    C:\tmp>lin const.c main.c

    C:\tmp>"C:\Lint\Lint-nt" +v -i"C:\Lint" std.lnt -os(_LINT.TMP)
    const.c main.c
    PC-lint for C/C++ (NT) Vers. 8.00u, Copyright Gimpel Software
    1985-2006

    --- Module: const.c (C)

    --- Module: main.c (C)

    C:\tmp>type _LINT.TMP | more

    --- Module: const.c (C)

    --- Module: main.c (C)

    ---
    output placed in _LINT.TMP

    C:\tmp>type const.c
    #include "const.h"
    const int gVal = 100;
    const double gPi = 3.1415926535897932384626433832795;

    C:\tmp>type const.h
    #ifndef CONST_H_INCLUDED
    #define CONST_H_INCLUDED

    extern const int gVal;
    extern const double gPi;

    #endif /* CONST_H_INCLUDED */


    C:\tmp>type main.c

    #include <stdio.h>
    #include "const.h"
    int main(void)
    {
    printf("gVal = %d and gPi = %f\n", gVal, gPi);
    return 0;
    }


    C:\tmp>const
    gVal = 100 and gPi = 3.141593
     
    user923005, Oct 23, 2007
    #7
  8. Madhur

    Ian Collins Guest

    *Please* don't quote signatures.
    Nonsense, how else would one declare an extern constant?
    C isn't C++.
     
    Ian Collins, Oct 23, 2007
    #8
  9. Madhur

    Ian Collins Guest

    Where?
     
    Ian Collins, Oct 23, 2007
    #9

  10. The definitions in the proposed const.c largely duplicates the
    declarations in const.h, and introduces the usual double maintenance
    problems. How severe those are is dependent on the situation.
     
    robertwessel2, Oct 23, 2007
    #10
  11. Madhur

    user923005 Guest

    OK. You want to access public objects from 100 files.
    How would you do it?
     
    user923005, Oct 23, 2007
    #11

  12. As I said, there's not really a great way in C, all the approaches
    have issues, the best one for the OP will depend on his exact
    situation. Some other languages have better ways to define interfaces
    than C, or have a better notion of what a "constant" is, where
    "better" defined is in terms of solving the OP's problem, but those
    are rather OT.
     
    robertwessel2, Oct 23, 2007
    #12
  13. Madhur

    user923005 Guest

    I am not wondering how you would do it in another language. I am
    wondering about your less redundant method to do it in C.
     
    user923005, Oct 23, 2007
    #13

  14. What part of "there's not really a great way in C" is not clear? Or
    my earlier post where I outlined three approaches, and their
    limitations, to the problem at hand?
     
    robertwessel2, Oct 23, 2007
    #14
  15. Madhur

    Road Tang Guest

    Madhur wrote:

    Yes, In C++ , it's not a problem. but In C, it's a compile error.
    I suggest you to use macro to define const-like value.

    #define A1 0
    #define A2 0

    If you think there are const variable, and won't change them, then
    the macro is better choice for you in C.

    C is C, and C++ is C++. Each one has its own solution and convention.

    -Road
     
    Road Tang, Oct 23, 2007
    #15
  16. Madhur

    Ian Collins Guest

    and macros aren't the best option in either. If a value doe not have to
    be a compile time constant in C, use extern const <type>. If it does,
    use an enum.
     
    Ian Collins, Oct 23, 2007
    #16
  17. Madhur

    Road Tang Guest

    ....snip ....
    It's really a problem to use multiple const variable like this.

    but yes, the code works well in C++, though not in C.

    -Road
     
    Road Tang, Oct 23, 2007
    #17
  18. Madhur

    Road Tang Guest

    Well, i said the macro is just "better".
    and enum and extern const maybe a more better solution,
    if your two "if"s are true.

    but what would you do if you just want a const double value,
    and use it everwhere, but doesn't bother where definition it is?

    So macro have its position.

    I doesn't claim something is the best absolutely.
    You know, it depends what you require.

    -Road.
     
    Road Tang, Oct 23, 2007
    #18
  19. Madhur

    pete Guest

    How many different programs is that supposed to be?
    There's only one function named "main" in a program.
    It looks like you're trying to link two different programs together.
    You're talking about avoiding the right way to write C code.
     
    pete, Oct 23, 2007
    #19
  20. you can only use enum for a constant of type int, and even that can be an
    issue because sizeof(enum toto) is not necessarily the same as sizeof(int).
    for a double you have to use a macro or a global const variable.
    You can make that static, but it may lead to space wastage and the compiler
    might complain about static variables being defined but not used.
    It would be useful to have a way to tell the compiler that a global variable
    is meant to be used as a constant value. I propose to extend the meaning of
    inline for this purpose:

    static inline double const PI = 3.14159265358979323846;
     
    Charlie Gordon, Oct 23, 2007
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.