what is concerned best practice regarding the following "pattern"?
#ifndef BLAFOO_H
#define BLAFOO_H
/* ...
* ...
*/
#endif /* BLAFOO_H */
how should i name the header in the #define directive? i've seen all from said BLAFOO_H to __BLAFOO_H to _BLAFOO_H_ etc..
Name them BLAFOO_H (personnally I use BLAFOO_H_ where BLAFOO is the header file name ).
Make sure your BLAFOO doesn't clash with other files/libraries/etc. you're using, e.g. have your project and/or module name be parth of that name.
Identifiers starting with a _ is reserved for the implementation/compiler, so don't use that.
I use an UUID that is my guarantee that #define not clashed with others. I've seen it somewhere and decided to use it as well.
My pattern is like this: __<filename>_H_<uuid>__,
eg. #define __TYPES_H_79057761_16D6_478A_BFBC_BBF17BD3E9B9__ for a file named types.h
As with other C-style questions, just be consistent. There is no way that you are going to know the namespace every library that someone might link with your program in the future. Why? Many of them have not been written yet :)
As such, its not a question of include guards, its a question of what to name the header in the first place.
I might come up with some cool new string utilities, and name the header strutil. That's a bad idea, because (surely) someone else has come up with cool new string utilities and named the header the same.
So, I name mine post_strutils.h and:
#ifndef POST_STRUTILS_H
#define POST_STRUTILS_H
/* code */
#endif
I may even call it post_str_utils.h and define the include guards appropriately because I know that I have a very common last name. Finding a namespace is sometimes difficult. Simply using one offers no guarantee that someone else did a search prior to releasing something to the wild. Be as unique as possible.
Depending on where someone tells their compiler to search for headers, its not just namespace conflicts that come into play, its also file names. Do your best to name the header uniquely, then write the include guard to match it. Someone might want to #error if the header has been included multiple times, if only to cut #include directives that aren't needed, using a UUID kind of makes doing so confusing, since it doesn't match (or even resemble) the file name of the header in question. It also makes grep/awk(or similar) powered lint scripts harder to write.
I'm not saying you should name every library / module after yourself, but do take care to make the public header file names unique. A quick conference with a search engine will tell you if you hit on an unused namespace. Please, let the include guards match (or at least closely resemble) the header. Again, consistency is highly praised. From your example, I'd expect:
int blahfoo_init(void);
double blahfoo_getval(blahfoo_t *blah);
If you go through the bother of finding a unique namespace, be sure to use it :)
The only real requirement is that it won't conflict with another project that uses the same name for its file. For all of the projects I've seen, it usually completely quantifies the namespace (or whatever folder the file is in for C) along with the project name. Sometimes it includes the date the file was created too.
So if you're working on project ABC in folder DEF today, then you could do:
#ifndef ABC_DEF_BLAFOO_H_05_30_2010
And this is very unlikely to conflict with anything.
It doesn't really matter as long as it's not likely to be used anywhere else. I usually go with something like BLAFOO_H_INCLUDED.
Related
I am writing linear list ADT as my practice in DS class. I use one header file, one function source code and a driver as a whole project. I defined macro "ELEMENT_TYPE" and "MAXSIZE" in the header file. My design is that I can #undef and immediately #define those two macros in the driver program to change "ELEMENT_TYPE" to any type the driver need.
If I put these code:
#undef ELEMENT_TYPE
#define ELEMENT_TYPE char
#undef MAXSIZE
#define MAXSIZE 50
into the header file after the #define, then in the driver program, the functions can be recognized properly(For example, insertion() 's second augment was "ELEMENT_TYPE", use those code above, IDE shows that insertion() receive a char augment in driver program.) However, if I put those codes into the driver below #include "foo.h", then IDE cannot recognize what augments the fuction should receive and use the initial definition of "ELEMENT_TYPE", in this case, int. Who know what was wrong in my program so that preprocessing directives don't work properly?
Here are the original codes:
driver.c
https://paste.ubuntu.com/p/6B76vmk6nN/
linear_list.c
https://paste.ubuntu.com/p/SHq4W5zkGM/
linear_list.h
https://paste.ubuntu.com/p/VY8vcgFD89/
PS:I am not native English speaker, so maybe there are some places I didn't express clearly. Point them out and I'll add more details if needed.
What it sounds like is happening is you're trying to #define these values in the driver in the hopes that they will stay defined in linear_list.c.
The problem is that these files are compiled separately and then linked. The #defines placed in driver.c cannot change those found in linear_list.c.
In order to have the effect I think you would like, you will need to change these values in linear_list.h. This is the best way to do this because that header is included in both the source files, and will presumably be #included in any file that works with the functions defined in linear_list.c. Please bear in mind that in order to see a change in the behavior of your program you will need to recompile not only driver.c but linear_list.c after changes to linear_list.h have been made.
As a side note, you should generally #include local headers like linear_list.h after you #include global headers like stdio.h and stdlib.h. In linear_list.c either of those headers could overwrite the values you've used in linear_list.h, if those identifiers are used. They look like they could be common enough, that it's not implausible that some header may use them, so it may be worthwhile to use a more unique identifier in the future. Which leads me to my final point: using #undef on these identifiers without checking if they're used somewhere else could lead to some problems, so you should generally check with #ifndef.
Hope that helps. If I've misunderstood please correct me.
EDIT: Clarification, additional information, credit to the other answer for reminding me of some important practices.
Macros in source code are replaced with the macro definition in effect at that point where the macro is used in the source code. So function declarations using ELEMENT_TYPE use the macro definition that most recently precedes the declaration. Changing the macro later will not change the function definition.
An alternative is to define ELEMENT_TYPE in the header only if it is not already defined:
#if ! defined ELEMENT_TYPE
#define ELEMENT_TYPE char
#endif
Then a source file can do either of:
Do not define ELEMENT_TYPE itself. When the header is included, the default type of char will be used.
Define ELEMENT_TYPE, then include the header. If desired, #undef ELEMENT_TYPE afterward. The type the source file provides in ELEMENT_TYPE will be used.
The driver and the program that uses it must use the same type. You cannot compile the driver using one type and the program using another. Compiling the program with a different type will not change the driver.
Testing some code including term.h, I've seen some strange errors using usual identifiers such as tab or columns. It comes from the fact that this header defines a lot of macros. Here are some examples:
/* from term.h */
#define columns CUR Numbers[0]
#define lines CUR Numbers[2]
#define bell CUR Strings[1]
#define insert_line CUR Strings[53]
#define tab CUR Strings[134]
However, I didn't find any documentation about these macroconstants. It seems to be shortcuts to access to some members of a TERMINAL data structure. Of course, a solution is to #undef every identifier used in the source code. But it is very restrictive.
So my question is: why do not prefix the identifiers of term.h?
They are often used as local variables in real source code, so it leads to incomprehensible errors.
There are two ways to deal with the identifier clash:
Change the identifiers in term.h
Change the identifiers in your code
The first is a no-no for reasons I hopefully need not explain. term.h was there long before your code ever formed as a thought in your brain. Thus it is entirely your fault^Wproblem^Wresponsibility to have created clashing identifiers. :-)
Maybe there's another option:
Don't use/include term.h in the first place.
One option, assuming you MUST use term.h is to isolate the inclusion of that file to a particular module, so that your overall code doesn't clash. But as Jens says, it's your task to "not have name clashes". Public header files that belong to the system shouldn't be changed just because you use the same names as those.
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.
I'm learning C and hope someone can explain what's the logic of using #ifndef?
I also find many C programs I looked, people seems following a convention using the filename following the #ifndef, #define and #endif. Is there any rule or tip on how to choose this name?
#ifndef BITSTREAM_H
#define BITSTREAM_H
#include <stdio.h>
#include <stdint.h>
/*Some functions*/
#endif
Header files will often use logic like this to avoid being included
more than once. The first time a source file includes them, the name
isn't defined, so it gets defined and other things are done.
Subsequent times, the name is defined, so all that is skipped.
The one you posted, in particular, is called an Include Guard.
The term for what you're looking for is Preprocessor Directives.
#ifndef doesn't need to be followed by a filename, for example it's common to see #ifdef WINDOWS or #ifndef WINDOWS, etc.
#ifndef means "if not defined". It is commonly used to avoid multiple include's of a file.
Tom Zych: "Header files will often use logic like this to avoid being included more than once."
This is true but it really is only necessary for "public" headers, like headers for library functions, where you don't have any control over how the headers are included.
This trick is unnecessary for headers used in projects where you have control over how things are included. (If there's a use for them outside of public headers, it's not a common one).
If you avoid using them in "private" headers, you'll more likely include headers in a less haphazard way.
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.