Question

When I read the header stddef.h provided by gcc, I have found a possible mistake. At first, I'm sure it's a mistake. But after I have read the header stddef.h of three different versions of gcc(3.4.5, 4,4,3 and 4,6,3), I found they are same at the point, so I'm not sure. Perhaps I'm wrong.

#if (!defined(_STDDEF_H) && !defined(_STDDEF_H_) && !defined(_ANSI_STDDEF_H) \
     && !defined(__STDDEF_H__)) \
    || defined(__need_wchar_t) || defined(__need_size_t) \
    || defined(__need_ptrdiff_t) || defined(__need_NULL) \
    || defined(__need_wint_t)

The above code is the beginning of stddef.h. The following is the ending of stddef.h. There are a pair.

#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
      || __need_XXX was not defined before */

I think that there is a mistake in the line:

      || __need_XXX was not defined before */

Should the word "not" be deleted?

It is easy, but if it's mistake, why hasn't the mistake been found and changed?

Was it helpful?

Solution

Not really a bug, I think, and barely even a cosmetic wart.

  1. It is in a comment and has no effect on what the compiler sees (the pre-processor eliminates the comments).

  2. The comment is saying 'none of these various defines were defined before'.

    That is: (_STDDEF_H was not defined and _STDDEF_H_ was not defined and _ANSI_STDDEF_H was not defined and __STDDEF_H__ was not defined) OR if we still need one of the various __need_XXX features, then the body of the header was processed. Before the || terms were added, it was clearer; they were probably added later than the main set of defined symbols identifying the header file.

Granted, the language in the comment could be made more precise, but the abbreviation is fairly typical of the way it is done. It is clear which #if the #endif is referring to. You can submit a suggested patch, but don't be surprised if nothing much happens with it. If it was my header and I needed that much complexity, I'd probably use something like:

#endif /* (!_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__) || __need_XXX */

and I might be tempted to use:

#endif /* (!_STDDEF_H && !_STDDEF_H_ && ...) || __need_XXX || ... */

There's a lot of history in those comments and defines, no doubt. System headers are not a good place to learn from. They tend to be inscrutable because they're driven in multiple directions simultaneously by a diverse set of standards, and they accrete complications over time as the standards evolve.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top