enum {} ?

Discussion in 'Mac Programming' started by Blakeasd, Jul 12, 2011.

  1. Blakeasd macrumors 6502a

    Joined:
    Dec 29, 2009
    #1
    What is enum{}? I came across it in a sample project and I'm not sure what is is. I did a Google search, "What is a enum in Objective-C" and I didn't get any answers about what it is, so my question is:
    What is a "enum {}"?
    Thanks
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Objective-C is a superset of C. enums are C, not Objective-C.
     
  3. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #3
    Thanks,
    I found an about.com article about enums{}, but the example Xcode project I'm looking at has only one constant in it, so what is the point of using an enum{} here?
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Post the code. It's difficult to guess at a rationale for code, without seeing the actual code.
     
  5. Blakeasd thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
  6. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #6
    There are two modern uses of enum.

    The first, and its original, usage is what the about.com "article" probably talked about, which is creating enumeration types. For example:
    Code:
    enum RGBColor { RedColor, GreenColor, BlueColor };
    
    The second way is to create constants without using the evil of #define. The old-school way of doing the code you posted is:
    Code:
    #define kTagTileMap 1
     
  7. PatrickCocoa macrumors 6502a

    Joined:
    Dec 2, 2008
    #7
    Theology

    So what's evil about #define? I've never really thought about it, and am open to conversion on this issue.
     
  8. jiminaus, Jul 12, 2011
    Last edited: Jul 12, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #8
    Okay, so given #define kTagTileMap 1, does the following code compile?
    Code:
    -(void)kTagTileMap
    {
       return 1;
    }
    I know it's a convoluted example, but it demonstrates the point. The pre-processor doesn't consider syntactic context at all. It just blindly replaces tokens.

    If the same code above was compiled given the enum constant instead, it would compile with no surprises. Except that it would be dubious to have a method named the same as a constant.


    The real example I encountered was under windows. The windows API claims to have a MessageBox function. Except it doesn't actually have a MessageBox function. It has a pair of functions called MessageBoxB and MessageBoxW. MessageBoxB takes 8-bit strings, while MessageBoxW takes 16-bit Unicode strings. The windows.h file either #define MessageBox MessageBoxB or #define MessageBox MessageBoxW depending on if UNICODE is defined.

    Now I was trying to create a MessageBox member function in C++. But I was getting linker errors from some objects complaining that the MessageBox member function wasn't defined, other objects that used the MessageBox member function didn't complain. I was confused for weeks (this is in the days before the Internet and forums).

    I was bitten my Microsoft's use of the #define sledgehammer. All though the source code said I was defining a MessageBox memeber function, the preprocessor was sometimes replacing MessageBox with MessageBoxB and sometimes not depending on either windows.h was included before or after my class's header file. It turned out the class's .cpp file did include windows.h header before the class's header file, so the member function was actually being emitted as MessageBoxB.
     
  9. PatrickCocoa macrumors 6502a

    Joined:
    Dec 2, 2008
    #9
    When I was your age . . .

    Thanks, I'll keep that in mind. War stories, gotta love 'em.
     
  10. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #10
    I would think of that as a rather poorly named example. RGBColor SOUNDS like a struct of 3 distinct parts. Perhaps named as PrimaryColor or something it would make more sense.
    Something to think about.
     
  11. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #11
    You're right. I was thinking of it being used to them as indexes to an array.
     
  12. mfram macrumors 65816

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #12
    Another advantage to enums is that they will be in the debug symbol tables and debuggers have access to them.
     
  13. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #13
    #defined constants are normally all caps, the above example shows why that is a good pattern to follow. Also, for modern code I think it's better to use the const keyword than enum if what you really want is a constant, if you don't want to use the #define that is.
     
  14. jiminaus, Jul 13, 2011
    Last edited: Jul 13, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #14
    I disagree. const defines an object (in the traditional sense, not the OO sense) where as the "enum hack" defines a pure constant.

    Consider.

    main.c
    Code:
    #include "makesound.h"
    
    int main(int argc, const char* argv[])
    {
        makeSound(kBeep);
        makeSound(kBoop);
        makeSound(-1);
        return 0;
    }
    makesound.h
    Code:
    #ifndef makesound_h
    #define makesound_h
    
    const int kBeep = 1;
    const int kBoop = 2;
    
    void makeSound(int soundConstant);
    
    #endif
    makesound.c
    Code:
    #include "makesound.h"
    #include <stdio.h>
    
    void makeSound(int soundConstant)
    {
        switch (soundConstant) {
            case kBeep:
                printf("Beep\n");
                break;
            case kBoop:
                printf("Boop\n");
                break;
            default:
                fprintf(stderr, "%s: invalid sound constant: %d\n", __PRETTY_FUNCTION__, soundConstant);
                break;
        }
    }
    This code won't build. The following linker error will ensue.
    Code:
    ld: duplicate symbol _kBeep in makesound.o and main.o
    You either have to:

    1) make the constants extern in makesound.h and then define the constants in makesound.c, making it very difficult for the compiler to "inline" the constants, in fact you couldn't do a switch in main like was done in makeSound in this senario; or

    2) make the constants static and suffer the code bloat of having multiple copies of the constant objects in the resulting binary
     
  15. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #15
    It's pretty common in C++ from where const is taken and adapted to C. Your above example works if you use extern in the .h file and define the constants in the .c file using clang here. Otherwise use a #define, using an enum for it's "constness" only, strikes me as a hack.
     

Share This Page