6

Is it better to #define _BSD_SOURCE or to set CPPFLAGS=-D_BSD_SOURCE?

It seems to me that if a piece of source code relies on a particular standard, it is best to spell it out explicitly in the code itself with a #define. However, a lot of commentary suggests that specifying the standard on the compile line is more appropriate. What are the advantages of omitting the standard from the source code and only specifying it at compile time?

William Pursell
  • 204,365
  • 48
  • 270
  • 300

1 Answers1

6

If you specify defines in your source there is a risk that the same header file can be included in several source files (translation units) but with different preprocessor definitions, which can lead to One Definition Rule violation which is often a pain to debug.

By specifying defines for the whole project rather than in the individual source files the chance of such One Definition Rule violation is minimized.

Also, if a need arises to add a new define, you change only one makefile, rather than all the source files.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • But you may use different standards for each translation unit. If the entire project is C89 conforming except that one TU uses a gnu extension, isn't it better for that one file to #define _GNU_SOURCE than to taint the whole project? This way, if I use a function that depends on a more modern standard than C89 in some other TU, but I'm not aware of that reliance, I'll know about it at compile time. If the entire project is dependent on the modern standard, it makes it more difficult to remove the dependency. – William Pursell Jan 13 '11 at 14:34
  • I must confess, I've never mixed and matched sources requiring different standards (or preprocessor defines) in one binary. If I did, I would still specify the flags for that particular source in the makefile (as target specific variables) simply because all my compiler flags are in one place in the makefile. Moreover, I often compile my sources with different compilers (g++, SunCC) on different platforms, so it is the platform-specific makefile which is the right place to accommodate platform specific defines. – Maxim Egorushkin Jan 13 '11 at 15:27
  • 1
    @William: the problem is that if you try to mix different standards in different translation units, there's no guarantee that you can safely link the resulting objects into a single executable. It might work, or might fail, or might appear to work, but give you subtle, tough to diagnose problems at runtime. – Chris Dodd Jan 13 '11 at 17:52
  • You can also use specific targets for those translation units that require different defines in your makefile. – Ioan Jan 13 '11 at 20:50