C program - checking whether two enums are in sync at compile time - c

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?

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

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

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.

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.

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

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.

Related

How to Protect Against Symbol Redefinition

My project incorporates a stack, which has a number of user-defined types (typedef). The problem is that many of these type definitions conflict with our in-house type definitions. That is, the same symbol name is being used. Is there any way to protect against this?
The root of the problem is that to use the stack in our application, or wrapper code, as the case may be, a certain header file must be included. This stack header file in turn includes the stack provider's types definition file. That's the problem. They should have included their type definition file via a non-public include path, but they didn't. Now, there are all sorts of user-defined type conflicts for very common names, such as BYTE, WORD, DWORD, and so forth.
Since you probably can't easily change the program stack you are using, you will have to start with your own code.
The first thing to do is (obviously) to limit the number of names in the global namespace, as far as possible. Don't use global variables, just use static ones, as an example.
The next step is to adopt a naming convention for your code modules. Suppose you have an "input module" in the project. You could then for example prefix all functions in the input module "inp".
void inp_init (void);
void inp_get (int input);
#define INP_SOMECONSTANT 4
typedef enum
{
INP_THIS,
INP_THAT,
} inp_something_t;
And so on. Whenever these items are used elsewhere in the code, they will not only have a unique identifier, it will also be obvious to the reader which module they belong to, and therefore what purpose they have. So while fixing the namespace conflicts, you gain readability at the same time.
Something like the above could be the first steps to implementing a formal coding standard, something you need to do sooner or later anyway as a professional programmer.
I suggest you define a wrapping header that redefines all of the functions and structures exported by the stack in terms of your own types. This header is then included in your system files but not in the stack files (where it would conflict). You can then compile and link but there is a weak point at the interface. If you select your types correctly in your redefinitions, it should work correctly, leaving only an maintenance problem on each update from the stack supplier...
I think that I've come up with a reasonable workaround, for the time being, but as Lundin stated, a formal coding standard is needed for a long-term solution.
Basically what I did was to move the inclusion of the required stack header file to before the inclusion of our in-house type definitions file. Then, between those two includes I added a compiler macro to set a defined constant dependent on whether the stack's header file single-include protection definition has been defined. Then, I used that conditional defined constant as a conditional compile option in our in-house type definition file to prevent the conflicting data-types from being re-defined. It's a little sloppy, but progress can only be made in incremental steps.

Best constants c convention

Suppose I would like to declare a set of constants in C (representing error codes of an application). how would you divide them into files ? would you use enum in external file and include it ?
Thanks,
James
Yes, #defines or enums in a .h file is the way to go. Enums are useful if you're debugging with a debugger like gdb as you'll see a more descriptive value than a number.
If it's a set of related numeric values, then an enum is the correct approach. If the values are C strings or otherwise not representable by an enum (or if they don't sensibly form a set of related values), you can use one of two approaches.
Either use preprocessor #define statements, or use extern const-marked variables. The former is resolved at compile-time, so you can use it to specify array lengths or to actively call code when used. The latter, however, allows you to change the value of the constant (by specifying it in a .c file rather than a .h file) without having to recompile every file that uses it.
Because extern const-marked variables can be changed in that fashion, they are preferable in code that is reused across many projects, or code that is distributed as a library. Changes to the library are then possible without forcing programs to be recompiled.
If it's a set of values an enumeration declared in a header file would suffice (some people use #defines but since the value doesn't matter an enumeration works just fine in this case). If you simply want to compare to error codes this is a good method.

Duplicate struct definition (One definition in header and another in C source)

Declared one structure STRUCT_ABC in a header file abc.h
Included abc.h in abc.c file and used STRUCT_ABC in some function inside abc.c.
Another file def.c does not include abc.h. But in def.c, i again defined a structure with same name, i.e. STRUCT_ABC, but with different contents.
Both abc.c & def.c are under same library and control first comes in abc.c during runtime.
Control goes from abc.c to def.c and comes back, say multiple times.
Can this give a runtime error always, or sometimes this might work?
It certainly won't cause you a runtime error.
The compiler will pick up the definition of the structure it saw when compiling the file that uses the structure, so you shouldn't get any compilation or linker errors either.
Really, though, if you want to use the same structure in 2 places, you're better off defining it in a single header and #includeing it in multiple .c files. It will make maintenance easier (you only need to update the structure once) and you'll know for sure which definition you're using (since there's only one).
If my memory is correct, this is compiler dependent (depends on how much decoration is applied to the definitions of the struct), but it would usually work (though we'd need more specifics to be sure). As long as the two units of code don't know about the conflicting declaration in the other unit, the compiler isn't really using the same name for each struct, and eventually it compiles down to an unnamed memory block in any event. Don't go passing the struct from abc to def and expect it to work (it will probably error on compile if you try), but as long as they aren't stepping on each others' toes it should be fine.
Like the other posters stated, if you are strictly defining the structs in both places, you should be okay. However, you're asking for trouble, particular if def.c ever needs to include abc.h.
From your description, it isn't 100% clear to me whether STRUCT_ABC is the struct name or an instance name. If you are defining instances of the structs in both files (outside of a function), and the instances are named the same you would have a compile problem unless you declare one or both instances static.
The errors should be compile errors, unless you trick a function expecting one STRUCT_ABC into using the other other (ie through a pointer).

How to track down cause of missing struct from include files in C?

I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
When I run the preprocessor over this project, it does include that file, but the preprocessor output does not have the struct definition (but does include enum's from that file).
Is there a method to figure out why some of a header file gets to the preprocessor output, and some does not?
TIA
(Also, this is not the only compile error, the port is half done but it should be at least getting past this part)
I usually just track back from the structure to find all the enclosing "#ifdef" and "#if" lines that the preprocessor will encounter and see which one is controlling the removal of the structure from the input stream into the compiler.
That generally works pretty quickly for all but the hairiest of header files (i.e., those with a great many nested conditional compile statements). For those, I generally have a look at the preprocessor output to identify the last line in the header file that made it to the compiler input stream.
Almost certainly the next line will be a conditional compile statement where you haven't met the condition for inclusion.
For example, if this is the header file, you would need to track back to see that _KERNEL should be defined in order to get the declaration and definition.
I'm afraid not; you will have to look for #ifdefs that surround your area of interest and track down why those symbols are not defined. If it's porting to Linux/UNIX and you are missing things from the standard headers, you might have not defined the right _XOPEN_SOURCE or _BSD_SOURCE in your Makefile or config.h .
The most likely reason is there's a #define somewhere around the definition. Since the corresponding symbol is not defined or defined to some other value the definition is not included even when the header itself is included. You'll have to inspect this manually.
Raymond Chen has a blog post about this.
You may find yourself in a twisty maze of #ifdefs. Or you may be wondering why your macros aren't working.
I have these lines in my header file:
#define MM_BUSY 0x0001
#define MM_IDLE 0x0002
but when I try to use them, I get errors.
sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier
Any idea why this is happening?
Solution: Use #error to track down the problem the same way you'd scatter printf around to track down a regular bug.
Source: Use the #error directive to check whether the compiler even sees you
I do not think that there is a better way beside checking the preprocessor output to know why one file is included or not. Here is the gcc's preprocessor's output format that may help you understand the preprocessor's ouput.
Also, another way you may have a try to compare the outputs between that you are porting and the existing one.
You said:
I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (Prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
This error can occur if you try to embed a pmc_mdep into some other structure before you have defined a pmc_mdep fully. Note that you can embed pointers to incomplete types into structures, but not actual instances of the incomplete type.
You also discuss running the preprocessor over the file that should define the structure, and you see enums form the header, but not the structure definition. That suggests that maybe you have a stray comment that is removing the structure unintentionally, or perhaps you have the structure definition embedded between #ifdef XXX and #endif but XXX is not defined when you do the compilation. It could even be #if 0.
I'd run the C preprocessor on just the header that contains the structure definition to see what that produces; it will be shorter than trying to look at the output for the entire program (source file). If I couldn't spot the issue swiftly, I'd mark parts with something like stray enums to see which ones get through and which ones don't.

How to know line numbers of local declarations/loops in a C function

I wanted to know at which line number are the declarations in a given C function.
Also which lines have if/while/for loops or which lines span multiple lines (ie they
donot end on same line).
I think we need to know why you want the line number in order to help you.
Variously:
1) You can use __LINE__ in the code to get the current line number.
2) Most editors can show the line numbers next to the code.
If you want to script breakpoints, I'm not sure if that's possible - I'd suggest setting break-points on filename and function, and then splitting up the code till that's sufficient. Alternatively investigate other ways of getting the testing done - e.g. splitting up the code so unit tests can check it.
Maybe I did not understand your question, but you can use ctags (or one of its variants) to get a list of declarations and their line numbers.
For example exuberant ctags is capable of generating tags (line numbers) for all types of C/C++ language tags, including all of the following:
class names
macro definitions
enumeration names
enumerators
function definitions
function prototypes/declarations
class, interface, struct, and union data members
structure names
typedefs
union names
variables (definitions and external declarations)
If you can, use the diff tool. It provides line numbers as part of the output. Your tool could then parse that output, looking for declarations or primary code.

Resources