best-practice on C header files with #ifndef #define #endif
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
.
精彩评论