views:

283

answers:

6

The problem that I have is that I have two enums in two different files which should have the same sets of constants (two different processes are generated by the two files along with other files). I want the enums to be in sync i.e. when some one adds a new value to enum x and forgets to update the other enum, I want to throw a compilation error. Is that possible?

+11  A: 

Why aren't you putting this declaration in a single header file and then including it in the two locations it is needed?

Rob Wells
I want to know if such a thing can be done at compile time.
As far as I know it's not possible on compile time. You could of corse write a pre-preprocessor and run it before calling gcc (or whatever you use). This pre-preprocessor would generate both files or one of them from the other one.
Gregor
@Gregor, hmmm. Good call, you could generate the multiple copies of the relevant declaration as a separate phase before starting the compile itself.
Rob Wells
+5  A: 

Have each of the enums end with a known enum, such as LAST_ENUM_1 and LAST_ENUM_2. Use a #if in a file that has access to both header files to compare.

#if LAST_ENUM_1 != LAST_ENUM_2
   #error Enums have different sizes
#endif
Robert
+1 Nice idea. Didn't know there is something like `#error`.
Gregor
I think #error is part of the standard. Usually there's a #warning also (or similar) but it is not part of the C standard.
Robert
Are the values of enum constants even available to the preprocessor?I think they aren't, so the final check would have to be done in runtime...
Tobi
@Tobi - I tried it with the compiler I use for embedded work, and it gave me correct results. Although, it might be compiler dependent. Try it and see.
Robert
A: 

The names used in enums need to be unambiguous, so you'll have a problem: either the compiler has access to both definitions, then the enums can't be identical because of the name problem or the compiler has access to only one definition a time, then it has nothing to check against.

Even the number of elements (as proposed by Robert) can't be checked at compile time (the preprocesser doesn't know anything about the enums). If you really can't have one common header file, the easiest thing to do would be a runtime check at the start of your application.

groovingandi
A: 

use like

enum EMyEnum
{
    JOE   = 0,
    BLACK = 1,
    WHITE = 2,

    END_OF_ENUM = 3
}

if you use like that format, maybe you can handle everything easier

ufukgun
I wouldn't put '=3' at the end because that's another thing you have to remember to change when you add an enum.
Robert
+1  A: 

I really like the other answers better than the one I will sugest now...

If all other solutions don't work for you, write a simple perl script that checks if they are the same and make sure that the perl script is called from your makefile. It will solve your problem, but try to avoid if you can.

Johan
A: 

Since the compiler looks at one source file (translation unit, TU) at a time, there is no way for it to complain about a mismatch between the current TU and some other TU that it is not looking at.

You need to fix things so that you have one copy of the definition of the enum that is used by both programs - so it belongs in a header that is included by both. Pretty much anything else is too error prone for comfort.

Jonathan Leffler