[This concerns the POSIX c99 utility, but gcc should probably behave in the same way, as on some platforms, c99 is gcc.]
In http://www.opengroup.org/onlinepubs/9699919799/utilities/c99.html POSIX specifies: -D name[=value] Define name as if by a C-language #define directive. If no = value is given, a value of 1 shall be used. The -D option has lower precedence than the -U option. That is, if name is used in both a -U and a -D option, name shall be undefined regardless of the order of the options. However, gcc doesn't take the precedence rule into account: $ cat tst.c int main(void) { #ifdef FOO return 1; #else return 0; #endif } $ c99 tst.c -UFOO -DFOO=1 $ ./a.out zsh: exit 1 ./a.out whereas FOO should be undefined and the return value should be 0, not 1. I could reproduce this with various GCC versions, including: gcc-snapshot (Debian 20090718-1) 4.5.0 20090718 (experimental) [trunk revision 149777] -- Summary: POSIX requires that option -D have a lower precedence than -U Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: vincent at vinc17 dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40960