title: Define Feature Macro: Compiler Argument vs Source Code?
body: <p>I recently came across the feature macro <code>_POSIX_C_SOURCE</code> which allows to specify the minimum required POSIX version when including headers that contain POSIX functions like <a href="https://pubs.opengroup.org/onlinepubs/009604599/functions/strdup.html" rel="nofollow noreferrer"><code>strdup</code></a> (<code>&lt;string.h&gt;</code>, Also upcoming to C23) or <a href="https://linux.die.net/man/3/clock_gettime%60" rel="nofollow noreferrer"><code>clock_gettime</code></a> (<code>&lt;time.h&gt;</code>) for example. The correctly way to enable <code>strdup</code> would be to define <code>_POSIX_C_SOURCE</code> at least <code>200401L</code> (Year 2004, version 1), for <code>clock_gettime</code> it would be at least <code>200101L</code>. Some library vendors might not write checks/<code>#ifs</code> to enable or disable the function declarations, which would make some programs not compile with other library implementations, when the programmer did not define the feature macro.</p>
  <hr />
  <p>There are two ways you could possibly enable the POSIX features.</p>
  <h3>1. Define before inclusion</h3>
  <pre><code>#define _POSIX_C_SOURCE 200401L
  #include &lt;time.h&gt;
  #include &lt;string.h&gt;
  </code></pre>
  <h3>2. Define in the compiler arguments and ensure it in the source:</h3>
  <pre><code>gcc ... -D_POSIX_C_SOURCE=200401L
  </code></pre>
  <p>in a source file</p>
  <pre><code>#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE &lt; 200401L
  #  error the minimum required POSIX version is 2004.1
  #endif
  #include &lt;time.h&gt;
  #include &lt;string.h&gt;
  </code></pre>
  <p>I thought about inserting the check, because a source file might be compiled in a different way (Other compiler, other buildchain, other makefile etc...), this prevents from missing the compiler argument.</p>
  <hr />
  <p>I think the first is the quickest, but the second is more clean.</p>
  <h3>Questions</h3>
  <ol>
  <li>Does the first have a problem if a header was included before the feature macro was defined? (See code below)</li>
  <li>Are previously disabled functions enabled because the file is now included with a version number (greater than the default)?</li>
  <li>Is there a better way to define and ensure these macros?</li>
  </ol>
  <pre><code>#include &lt;time.h&gt;
  #include &lt;string.h&gt;
  ...
  #define _POSIX_C_SOURCE 200401L
  #include &lt;time.h&gt;
  #include &lt;string.h&gt;
  </code></pre>