|
|
Log in / Subscribe / Register

Best practice?

Best practice?

Posted Apr 3, 2014 5:54 UTC (Thu) by wahern (subscriber, #37304)
In reply to: Best practice? by bernat
Parent article: Glibc feature test macros

I compile and test all my projects on Linux, NetBSD, FreeBSD, OpenBSD, OS X, and Solaris. And I can say without a doubt that the last thing you should do, if you're writing portable programs, is to fiddle with POSIX or XOPEN feature macros!

Why?

Because most portable code actually uses one or more non-standard interfaces, and good luck making those routines visible again if you did something like -D_POSIX_C_SOURCE=200809L. FTM systems are wildly different on various platforms.

Also, many systems don't support the latest POSIX standard. For example, Solaris only supports POSIX up to 2001, even though it actually implements many of the new interfaces. So if you define _POSIX_C_SOURCE (to any value), you paradoxically _lose_ a ton of "POSIX" interfaces.

Or look at calls like mkstemp. It's in POSIX 2008, but previously it was only an X/Open extension. On Solaris there's no easy way to get it; if you define _POSIX_C_SOURCE, it disappears. If you define _XOPEN_SOURCE, you get it, but you lose the POSIX API. If you try to define both _POSIX_C_SOURCE and _XOPEN_SOURCE, the system headers barf.

Nope. In my experience, you define _GNU_SOURCE on Linux, and on every other system, leave well enough alone. Linux is the only widely used system that has a strict environment by default, AFAIK. Every other system exposes all their interfaces (excepting conflicting ones) by default, which means the last thing you want to do is define _POSIX_C_SOURCE or _XOPEN_SOURCE, unless you're a glutton for punishment, or are on some strict-POSIX crusade. Sometimes you want to define macros like _REENTRANT, _THREAD_SAFE, or the 64-bit FS macros, but those are orthogonal to the larger standards macros, and do not destroy visibility to other interfaces.

There's no substitute for testing your code on various systems. Virtual machines makes this easy-peasy. You're life is easier if you avoid FTMs. Then you can use convenient, de-facto standard APIs. It's 2014. Most of the interfaces you want are supported everywhere, but far fewer systems support the standard they were most recently specified in.

C standards are a slightly different issue, but fortunately you can have a compiler on a single platform warn you about certain constructs. Also, there's always the option of just using GCC everywhere. I try to support GCC, clang, and Solaris Studio (which require no special effort to get ahold of other than installing the OS), but you have to draw the line somewhere, because while being "portable" doesn't necessarily mean being less productive, it can make you less productive if you do it the wrong way.

Portability is a process, not a product. Most projects can be made way more portable than they are with little effort, especially if early in the development process you test-test-test, and don't code yourself into a corner.


to post comments


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds