3

Is there such functionality in GCC/C++. For example

#ifdef __linux__ 
//linux code goes here
#elif _WIN32
    // windows code goes here
#else

#endif

For ex. force compile for linux

gcc/g++ my_prog.c -di __linux__ -o ./my_prog

This is just for one case, but you get the idea. Is there flexibility to fully control the macro compilation process to override default with command line parameters? Including with custom directives

8

2 Answers 2

7

You can set a macro in gcc with -D, as in

gcc my_prog.C -Duse_linux

but you should avoid identifiers with special meaning for macro names. Defining a macro whose name contains a double underscore, such as __linux__, has undefined behavior (if any part of the standard library is used, so pretty much all the time).

Reference: gcc documentation - 3.14 Options Controlling the Preprocessor

Sign up to request clarification or add additional context in comments.

2 Comments

Promoting a comment by Jerry Jeremiah to an answer.
Same for clang. MS's compiler uses /DFOO instead of -DFOO
1

The GCC commandline option -DFOO[=value] has the same effect as placing #define FOO [val] on an imaginary source line before the real first line of every source file compiled by the command. The option -UFOO has the same effect as placing #undef FOO on an imaginary line. If there are N such options on the commandline then it as if there are N imaginary lines.

However the C Standard - C17 here, but likewise any other edition - states:

7.1.3 Reserved identifiers ... All identifiers that begin with an underscore and either an uppercase letter or another under- score are always reserved for any use, except those identifiers which are lexically identical to keywords ... If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

So it is UB for you to define, e.g. __linux__ or _WIN32, and the likeliest (and kindest) UB that your compiler will exihibit if you try to is simply to ignore your definitions that conflict with its reserved ones.

Such reserved macro names are pre-defined by your compiler. E.g. this compiler:

$ gcc --version | head -n1
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0

$ echo | gcc -dM -E - | grep linux; echo Done
#define __linux 1
#define __gnu_linux__ 1
#define linux 1
#define __linux__ 1
Done
        
$ echo | gcc -dM -E - | grep x86; echo Done
#define __x86_64 1
#define __x86_64__ 1
Done

was built to target x86_64 GNU/Linux and not built to target Windows:

$ echo | gcc -dM -E - | grep _WIN32; echo Done
Done

Whereas this cross-compiler:

$ echo | x86_64-w64-mingw32-gcc-win32 -dM -E - | grep linux ; echo Done
Done

$ echo | x86_64-w64-mingw32-gcc-win32 -dM -E - | grep _WIN32; echo Done
#define __WIN32__ 1
#define _WIN32 1
#define __WIN32 1
Done

$ echo | x86_64-w64-mingw32-gcc-win32 -dM -E - | grep x86 ; echo Done
#define __x86_64 1
#define __x86_64__ 1
Done

was built to target x86_64 Windows. And this one:

$ echo | aarch64-linux-gnu-gcc -dM -E - | grep linux ; echo Done
#define __linux 1
#define __gnu_linux__ 1
#define linux 1
#define __linux__ 1
Done

$ echo | aarch64-linux-gnu-gcc -dM -E - | grep x86 ; echo Done
Done

echo | aarch64-linux-gnu-gcc -dM -E - | grep ARM_ARCH ; echo Done
#define __ARM_ARCH_PROFILE 65
#define __ARM_ARCH 8
#define __ARM_ARCH_8A 1
#define __ARM_ARCH_ISA_A64 1
Done

was built to target ARM 64 GNU/Linux.

These pre-defined macros are not defaults that you can override. They report immutable features of the compiler that programmers can query with the like of:

#ifdef __linux__
...
#endif

In other words it is not the case that any GCC compiler can be made act as any desired cross-compiler by feeding it the right macro definitions.

A few pre-defined macros are mandated by the Standard. See 6.10.8 Predefined macro names in the same document. The rest (including all 3.7.3 System-specific Predefined Macros like the ones mentioned) are chosen and defined by the compiler implementer, so there is no over-arching regulation of what they are, how they are defined, or what they mean.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.