Global variable declaration in headers

Discussion in 'C Programming' started by Method Man, Oct 10, 2004.

  1. Method Man

    Method Man Guest

    Can someone explain the scope/linkage differences between the following 4
    global declarations and when one should be used (theoretically) over the
    rest?

    sample.h
    ---------
    #ifndef SAMPLE_H
    #define SAMPLE_H

    int a;
    const int b;
    static int c;
    extern int d;

    #endif
    ---------

    And if I gave 'd' an initial value, what the consequences would be (if any)?
     
    Method Man, Oct 10, 2004
    #1
    1. Advertising

  2. Method Man

    jacob navia Guest

    Method Man wrote:
    > Can someone explain the scope/linkage differences between the following 4
    > global declarations and when one should be used (theoretically) over the
    > rest?
    >
    > sample.h
    > ---------
    > #ifndef SAMPLE_H
    > #define SAMPLE_H
    >
    > int a;


    Reserve sizeof(int) bytes for a in the uninitialized variables section,
    that at program startup will be set to zero. This definition will be
    used *unless* some other definition appears like:
    int a = 78;
    If the second definition appears anywhere in the program, it will be
    used instead of this one.

    > const int b;

    Same as previously but now b can't be assigned to.
    > static int c;

    Same as the first definition but the name "c" will not be visible
    in other modules of the program.
    > extern int d;

    This integer variable is defined somewhere else as an external, and
    is used in this module.
    > And if I gave 'd' an initial value, what the consequences would be (if any)?


    int a = 78;
    Reserve sizeof(int) byte in the data section and fill it with the bit
    pattern 78. This is definitive, no other definition can follow.
    const int b = 78;
    Same as above but the value of b can't be changed.
    Some compilers will optimize:
    static const int b = 78;
    so that all references of this "variabl" will be replaced with 78.

    static int c=78;
    Same as the first one except that the name is not visible elsewhere.

    extern int d = 78;
    This is equivalent to the first definition, int d = 78;
     
    jacob navia, Oct 10, 2004
    #2
    1. Advertising

  3. Method Man

    pete Guest

    Method Man wrote:
    >
    > Can someone explain the scope/linkage
    > differences between the following 4
    > global declarations and when one should be used
    > (theoretically) over the rest?
    >
    > sample.h
    > ---------
    > #ifndef SAMPLE_H
    > #define SAMPLE_H
    >
    > int a;
    > const int b;
    > static int c;
    > extern int d;
    >
    > #endif
    > ---------


    d is the only one of those declarations that belongs in a header file.
    d should also be declared in one of the C files in the C program,
    like sample.c.
    Having static c in the header file,
    defeats the whole point of the static keyword.
    Every C file which #includes sample.h,
    will have it's own a, b and c, that the other C files don't know about.

    > And if I gave 'd' an initial value,
    > what the consequences would be (if any)?


    If you did that, then you wouldn't be able to declare d
    in a C file which #included sample.h.

    --
    pete
     
    pete, Oct 10, 2004
    #3
  4. Groovy hepcat Method Man was jivin' on Sun, 10 Oct 2004 02:02:09 -0400
    in comp.lang.c.
    Global variable declaration in headers's a cool scene! Dig it!

    >Can someone explain the scope/linkage differences between the following 4
    >global declarations and when one should be used (theoretically) over the
    >rest?
    >
    >sample.h
    >---------
    >#ifndef SAMPLE_H
    >#define SAMPLE_H
    >
    >int a;


    File scope and external linkage.

    >const int b;


    File scope and external linkage.

    >static int c;


    File scope and internal linkage.

    >extern int d;


    File scope and external linkage.

    >#endif
    >---------
    >
    >And if I gave 'd' an initial value, what the consequences would be (if any)?


    It would become a definition. Definitions are bad in a header.
    Headers should contain declarations, not definitions.

    --

    Dig the even newer still, yet more improved, sig!

    http://alphalink.com.au/~phaywood/
    "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
    I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
     
    Peter Shaggy Haywood, Oct 11, 2004
    #4
  5. Method Man

    Michael Mair Guest

    Hiho,


    pete wrote:
    > Method Man wrote:
    >

    [snip header-file]
    >>static int c;

    >

    [snip]
    > Having static c in the header file,
    > defeats the whole point of the static keyword.


    Not necessarily. You can for example use a header for
    testing/extended error state returns and so on and count
    the number of errors encountered/store error states and
    so on. In order to make sure that the translation units
    or modules do not get confused, you use static variables.
    I have seen similar mechanisms in large code.
    However, if possible I'd rather make do without as it
    certainly does not enhance clarity...


    Cheers
    Michael
     
    Michael Mair, Oct 11, 2004
    #5
  6. Method Man

    pete Guest

    Michael Mair wrote:
    >
    > Hiho,
    >
    > pete wrote:
    > > Method Man wrote:
    > >

    > [snip header-file]
    > >>static int c;

    > >

    > [snip]
    > > Having static c in the header file,
    > > defeats the whole point of the static keyword.

    >
    > Not necessarily. You can for example use a header for
    > testing/extended error state returns and so on and count
    > the number of errors encountered/store error states and
    > so on. In order to make sure that the translation units
    > or modules do not get confused, you use static variables.
    > I have seen similar mechanisms in large code.


    I don't understand how that header file is used, and how there
    would be a benefit from having a static object declaration in it.
    What would a program that used it, be like?
    Which C files would include it, in a program?
    How many C files would there be in a program which used it.

    --
    pete
     
    pete, Oct 13, 2004
    #6
  7. Method Man

    Michael Mair Guest

    Hi pete,

    sorry for getting back to you only now (busy today, so answers
    which require much thought take longer)


    pete wrote:
    > Michael Mair wrote:
    >
    >>Hiho,
    >>
    >>pete wrote:
    >>[snip]
    >>
    >>>Having static c in the header file,
    >>>defeats the whole point of the static keyword.

    >>
    >>Not necessarily. You can for example use a header for
    >>testing/extended error state returns and so on and count
    >>the number of errors encountered/store error states and
    >>so on. In order to make sure that the translation units
    >>or modules do not get confused, you use static variables.
    >>I have seen similar mechanisms in large code.

    >
    > I don't understand how that header file is used, and how there
    > would be a benefit from having a static object declaration in it.


    As I said in the snipped part, I do not think it is a good
    technique. I do no longer have access to the code but an
    untested sample header file could look like that:

    #ifndef CATCH_ERROR
    #define CATCH_ERROR

    #include <stddef.h> /* for size_t */

    /* error states */
    enum ce_errortypes {
    CE_OK=0,
    CE_INVALID_INPUT,
    /* Easy checks ^ */
    CE_START_BAD_ERRORS,
    /* Bad Errors v */
    CE_INVALID_OP,
    CE_INVALID_RANGE,
    CE_END
    };

    static unsigned long int ce_statecounters[(size_t)CE_END+1];

    #ifdef COUNT_ERRORS
    # define RETURN(ret_int) \
    { ce_statecounters[( (ret_int) >= 0 && (ret_int)< CE_END \
    && (int)(ret_int)==(ret_int) ) \
    ? (int)(ret_int) : CE_END] += 1; \
    return (ret_int);}
    #else
    # define RETURN(ret_int) return (ret_int);
    #endif

    #define HOW_MANY_CHECK_ERRORS(num) {enum ce_errortypes counter;\
    (num) = 0; for(counter=1;counter<CE_START_BAD_ERRORS;\
    counter++) {(num) += ce_statecounters[counter];}}
    #define HOW_MANY_BAD_ERRORS(num) {enum ce_errortypes counter;\
    (num) = CE_START_BAD_ERRORS+1; for(counter=1;\
    counter<CE_END;counter++)\
    {(num) += ce_statecounters[counter];}}
    #define HOW_MANY_STRANGE_ERRORS(num) (num) = ce_statecounters[CE_END]

    #endif

    It is right now only for (non-negative) int returns but I did
    not bother wo write more tests and mapping and so on.
    The functions return 0/CE_OK on success and you do
    if (ret=fun1(....))
    RETURN(..appropriate error value..);

    You just include the header for the files you want to test and use
    RETURN instead of return.
    In your test routine or somewhere else you just find out
    about the types of encountered errors by using HOW_MANY_..._ERRORS

    It can come in handy for simulation software where you do not
    necessarily have convergence in every step; so you just count the
    "not converged" errors and decide based on that number whether
    the result is acceptable or whether you suspect that the result
    and the repercussions if wrong might get your customers to want
    you to pay for the damage...

    You make ce_statecounters static because you only want to count
    it per file.


    > What would a program that used it, be like?


    Ugly. I think this is answered above.

    > Which C files would include it, in a program?


    Those which need this kind of treatment?
    I am not trying to be evasive but I am not sure what you want to
    know. In the example with the simulation software, typically
    the high level solver routines and the matrix assembly would use
    that kind of stuff.

    > How many C files would there be in a program which used it.


    42.
    Honestly, are you kidding?


    --Michael
     
    Michael Mair, Oct 13, 2004
    #7
  8. Method Man

    pete Guest

    Michael Mair wrote:
    >
    > Hi pete,
    >
    > sorry for getting back to you only now (busy today, so answers
    > which require much thought take longer)
    >
    > pete wrote:
    > > Michael Mair wrote:
    > >
    > >>Hiho,
    > >>
    > >>pete wrote:
    > >>[snip]
    > >>
    > >>>Having static c in the header file,
    > >>>defeats the whole point of the static keyword.
    > >>
    > >>Not necessarily. You can for example use a header for
    > >>testing/extended error state returns and so on and count
    > >>the number of errors encountered/store error states and
    > >>so on. In order to make sure that the translation units
    > >>or modules do not get confused, you use static variables.
    > >>I have seen similar mechanisms in large code.


    > You make ce_statecounters static because you only want to count
    > it per file.


    Thank you.

    --
    pete
     
    pete, Oct 15, 2004
    #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. Thomas Matthews
    Replies:
    2
    Views:
    921
    Thomas Matthews
    Jan 26, 2005
  2. dont bother
    Replies:
    0
    Views:
    847
    dont bother
    Mar 3, 2004
  3. Bolin
    Replies:
    4
    Views:
    419
  4. Phil
    Replies:
    4
    Views:
    716
    Gabriel Genellina
    Jan 17, 2010
  5. Ian
    Replies:
    2
    Views:
    2,073
Loading...

Share This Page