Enum question

Discussion in 'C Programming' started by Brian Dude, May 9, 2010.

  1. Brian Dude

    Brian Dude Guest

    Hello, I have an enum that I'm using in my main source file and want to
    extern it to another:

    file1.c

    enum START_PT
    {
    CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT
    } pos;

    int main(void)
    {...}

    /*--------------*/

    file2.c

    extern enum START_PT pos;

    f()
    {
    switch(pos){
    case CENTER:
    break;
    case UPPER_LEFT:
    break;
    /*etc...*/
    }
    }


    I'm getting compilation errors for "undefined symbol CENTER" in file2.c.
    Do the names in an enumeration not get carried over through extern?

    TIA,
    Brian Dude
     
    Brian Dude, May 9, 2010
    #1
    1. Advertising

  2. Brian Dude

    Seebs Guest

    On 2010-05-09, Brian Dude <> wrote:
    > I'm getting compilation errors for "undefined symbol CENTER" in file2.c.
    > Do the names in an enumeration not get carried over through extern?


    They do not. "extern" allows you to access *objects* -- but an enumerated
    type is not an object. When file2 is compiled, nothing you've provided ever
    tells the compiler what "CENTER" is. (The fact that, later, it might be
    linked with something which knew doesn't matter; enumerations are dealt with
    during compilation.)

    The usual way to resolve this is to put the 'enum foo { a, b, c };' in
    a header file, which is included from both modules.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, May 9, 2010
    #2
    1. Advertising

  3. Brian Dude

    Eric Sosman Guest

    On 5/9/2010 2:11 PM, Brian Dude wrote:
    > Hello, I have an enum that I'm using in my main source file and want to
    > extern it to another:
    >
    > file1.c
    >
    > enum START_PT
    > {
    > CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT
    > } pos;
    >
    > int main(void)
    > {...}
    >
    > /*--------------*/
    >
    > file2.c
    >
    > extern enum START_PT pos;
    >
    > f()
    > {
    > switch(pos){
    > case CENTER:
    > break;
    > case UPPER_LEFT:
    > break;
    > /*etc...*/
    > }
    > }
    >
    > I'm getting compilation errors for "undefined symbol CENTER" in file2.c.
    > Do the names in an enumeration not get carried over through extern?


    They do not. Make yourself a header file, "startpt.h", say,
    and put in it

    enum START_PT
    {
    CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT
    };

    extern enum START_PT pos; /* or combine with the above */

    This much says "There is a type called `enum START_PT', with constants
    CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, and LOWER_RIGHT having the
    values 0 through 4. Also, there is a variable of this type named `pos';
    it's not defined here, but some other file will define it eventually."

    Now modify "file1.c" to read

    #include "startpt.h"
    enum START_PT pos; /* the "eventually" mentioned above */
    int main(void) { ... }

    and modify "file2.c" to read

    #include "startpt.h"

    .... without the `extern', because it's already in "startpt.h".

    Why do things in this particular way? First, by putting the
    declaration(s) in "startpt.h" you write them only once, and thus
    remove any chance of accidentally writing them differently in
    different files (imagine what would happen if two .c files disagreed
    on the order of LOWER_LEFT and LOWER_RIGHT, one of them mistakenly
    thinking it was a clockwise progression). Second, by including
    the declarations in the same compilation as the definition (in this
    case, "file1.h"), you give the compiler a chance to warn you if the
    declarations and the definition disagree, perhaps having gotten out
    of step while you were adding new features to the code.

    By the way: You've only sketched your code and there's surely
    more going on than is visible here, but on the surface this looks
    like a poor use of a global variable. Globals are the right response
    to some situations, but to fewer than many people at first think, and
    they have a nasty way of causing trouble as a program evolves. At a
    guess, you might be better off removing the `extern' and changing
    the files to look like

    /* file1.c */
    #include "startpt.h"
    static enum START_PT pos; /* `static' means "private" */
    int main(void) {
    /* or maybe put `pos' here, without `static' */
    ...
    f(pos);
    ...
    }

    /* file2.c */
    #include "startpt.h"
    int f(enum START_PT pos) {
    ...
    }

    I'm not saying this *is* best for your circumstances, of which I know
    too little, but that this is probably the pattern you should turn to
    first, until some compelling reason makes you abandon it.

    --
    Eric Sosman
    lid
     
    Eric Sosman, May 9, 2010
    #3
  4. Brian Dude

    Brian Dude Guest

    Eric Sosman wrote:

    <snip>

    >> Do the names in an enumeration not get carried over through extern?

    >
    > They do not. Make yourself a header file, "startpt.h", say,
    > and put in it
    >
    > enum START_PT
    > {
    > CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT
    > };
    >
    > extern enum START_PT pos; /* or combine with the above */
    >
    > This much says "There is a type called `enum START_PT', with constants
    > CENTER, UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, and LOWER_RIGHT having the
    > values 0 through 4. Also, there is a variable of this type named `pos';
    > it's not defined here, but some other file will define it eventually."
    >
    > Now modify "file1.c" to read
    >
    > #include "startpt.h"
    > enum START_PT pos; /* the "eventually" mentioned above */
    > int main(void) { ... }
    >
    > and modify "file2.c" to read
    >
    > #include "startpt.h"
    >
    > ... without the `extern', because it's already in "startpt.h".
    >
    > Why do things in this particular way? First, by putting the
    > declaration(s) in "startpt.h" you write them only once, and thus
    > remove any chance of accidentally writing them differently in
    > different files (imagine what would happen if two .c files disagreed
    > on the order of LOWER_LEFT and LOWER_RIGHT, one of them mistakenly
    > thinking it was a clockwise progression). Second, by including
    > the declarations in the same compilation as the definition (in this
    > case, "file1.h"), you give the compiler a chance to warn you if the
    > declarations and the definition disagree, perhaps having gotten out
    > of step while you were adding new features to the code.
    >
    > By the way: You've only sketched your code and there's surely
    > more going on than is visible here, but on the surface this looks
    > like a poor use of a global variable. Globals are the right response
    > to some situations, but to fewer than many people at first think, and
    > they have a nasty way of causing trouble as a program evolves. At a
    > guess, you might be better off removing the `extern' and changing
    > the files to look like
    >
    > /* file1.c */
    > #include "startpt.h"
    > static enum START_PT pos; /* `static' means "private" */
    > int main(void) {
    > /* or maybe put `pos' here, without `static' */
    > ...
    > f(pos);
    > ...
    > }
    >
    > /* file2.c */
    > #include "startpt.h"
    > int f(enum START_PT pos) {
    > ...
    > }
    >
    > I'm not saying this *is* best for your circumstances, of which I know
    > too little, but that this is probably the pattern you should turn to
    > first, until some compelling reason makes you abandon it.
    >


    Good points. The only reason I'm doing things as such is because I just
    recently decided to put a bunch of things into a separate file and
    needed to quickly get that variable over. The idea of a header didn't
    occur to me because that seemed a bit "grand" for just one variable, but
    I will likely incorporate the idea as my project grows. Thanks!
     
    Brian Dude, May 9, 2010
    #4
  5. Brian Dude

    Sjouke Burry Guest

    Brian Dude wrote:
    > Hello, I have an enum that I'm using in my main source file and want to
    > extern it to another:


    #include "my_enum.h"
     
    Sjouke Burry, May 9, 2010
    #5
  6. On 09 May 2010 18:22:37 GMT, Seebs <> wrote:

    > On 2010-05-09, Brian Dude <> wrote:
    > > I'm getting compilation errors for "undefined symbol CENTER" in file2.c.
    > > Do the names in an enumeration not get carried over through extern?

    >
    > They do not. "extern" allows you to access *objects* -- but an enumerated
    > type is not an object. <snip rest>


    extern enables inter-t.u. access to objects and functions, but not ANY
    type information, which as you noted is compile-time*: not enum types
    or constants, not struct/union types, not typedefs. (* except C99 VLA,
    and that has to be effectively 'auto' and so couldn't be sharable)

    Also not macros, in case anyone is even more imaginatively wrong.
     
    David Thompson, May 17, 2010
    #6
    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. -

    enum within an enum

    -, Jun 12, 2005, in forum: Java
    Replies:
    6
    Views:
    579
  2. Eric Sosman
    Replies:
    3
    Views:
    800
    Mayeul
    Feb 26, 2010
  3. Wojtek
    Replies:
    1
    Views:
    517
  4. Lew
    Replies:
    0
    Views:
    551
  5. Roedy Green
    Replies:
    0
    Views:
    752
    Roedy Green
    Feb 27, 2010
Loading...

Share This Page