Skip to main content

Preprocessor Symbols

Table of content

First of all, the following definitions of preprocessor symbols (with the exception of xtd targets and xtd paths) are not defined by xtd, but are standard definitions. Normally, you won't need to use these definitions in your programs to use xtd. However, you may need to use them for specific purposes outside xtd.

Operating Systems

The following table represents the different preprocessor symbols for the operating systems supported by xtd:

SymbolsOS
__ANDROID__Android
__APPLE__macOS
__FreeBSD__FreeBSD
__linux__Linux
__unix__Unix
_POSIX_VERSIONPosix
_WIN32Windows

To detect the different Apple platforms, it is necessary to include the TargetConditionals.h file which contains the different target definitions.

For a more complete list of platforms see Pre-defined Compiler Macros Wiki - Operating systems.

Examples

The following code shows how to detect the operating system with the preprocessor symbols:

#ifdef HAVE_UNISTD_H // needed for _POSIX_VERSION (see https://www.gnu.org/software/autoconf/manual/autoconf-2.64/html_node/Particular-Headers.html#index-g_t_005fPOSIX_005fVERSION-585)
# include <unistd.h>
#endif

#if defined(_WIN32)
# define __platform_name__ "Microsoft Windows"
#elif defined(__APPLE__)
# include <TargetConditionals.h>
# if TARGET_OS_WIN32 != 0
# define __platform_name__ "WIN32 API"
# elif TARGET_OS_WINDOWS != 0
# define __platform_name__ "Windows"
# elif TARGET_OS_UNIX != 0
# define __platform_name__ "Unix"
# elif TARGET_OS_LINUX != 0
# define __platform_name__ "Linux"
# elif TARGET_OS_MAC != 0
# if TARGET_OS_OSX != 0
# define __platform_name__ "macOS"
# elif TARGET_OS_IPHONE != 0
# if TARGET_OS_IOS
# define __platform_name__ "iOS"
# elif TARGET_OS_TV != 0
# define __platform_name__ "tvOS"
# elif TARGET_OS_WATCH != 0
# define __platform_name__ "watchOS"
# elif TARGET_OS_BRIDGE != 0
# define __platform_name__ "Bridge device"
# elif TARGET_OS_MACCATALYST != 0
# define __platform_name__ "Catalyst macOS"
# else
# error "Unknown iPhone platform"
# endif
# elif TARGET_OS_DRIVERKIT != 0
# define __platform_name__ "macOS, iOS, tvOS, or watchOS"
# elif TARGET_IPHONE_SIMULATOR != 0
# define __platform_name__ "iPhone Simulator"
# else
# error "Unknown Apple platform"
# endif
# else
# error "Unknown target"
# endif
#elif defined(__ANDROID__)
# define __platform_name__ "Android"
#elif defined(__FreeBSD__)
# define __platform_name__ "FreeBSD"
#elif defined(__linux__)
# define __platform_name__ "Linux"
#elif defined(__unix__)
# define __platform_name__ "Unix"
#elif defined(_POSIX_VERSION)
# define __platform_name__ "Posix"
#else
# error "Unknown platform"
#endif

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("platform_name=\"{}\"", __platform_name__);
console::write_line("platform_name=\"{}\"", environment::os_version().name());
}

// This code produces the following output if under macOS :
//
// platform_name="macOS"
// platform_name="macOS"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::os_version.

But it can be useful for your own developments.

Architectures

The following table represents the different preprocessor symbols for the architectures supported by xtd:

SymbolsArchitectures
__amd64__AMD64
__arm__ARM
__aarch64__ARM64
__i386__Intel x86
__ia64__Intel Itanium (IA-64)

For a more complete list of compiler see Pre-defined Compiler Macros Wiki - Architectures.

Examples

The following code shows how to detect the architecture with the preprocessor symbols:

#if defined(__amd64__)
# define __architecture_name__ "amd64"
#elif defined(__arm__)
# define __architecture_name__ "arm"
#elif defined(__aarch64__)
# define __architecture_name__ "arm64"
#elif defined(__i386__)
# define __architecture_name__ "intel x86"
#elif defined(__ia64__)
# define __architecture_name__ "intel itanium (IA-64)"
#else
# error "Unknown compiler"
#endif

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("architecture_name=\"{}\"", __architecture_name__);
console::write_line("architecture_name=\"{}\"", environment::processor_information().architecture_string());
}

// This code produces the following output if architecture is ARM64:
//
// architecture_name="arm64"
// architecture_name="arm64"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::processor_information.

But it can be useful for your own developments.

Compilers

The following table represents the different preprocessor symbols for the compilers supported by xtd:

SymbolsCompiler
__clang__Clang
__GNUC__GCC C/C++
_MSC_VERMicrosoft Visual C++

For a more complete list of compiler see Pre-defined Compiler Macros Wiki - Compilers.

Examples

The following code shows how to detect the compiler with the preprocessor symbols:

#if defined(_MSC_VER)
# define __comiler_name__ "MSVC"
#elif defined (__APPLE__) && defined(__clang__)
# define __comiler_name__ "Apple Clang"
#elif defined(__clang__)
# define __comiler_name__ "Clang"
#elif defined(__GNUC__)
# define __comiler_name__ "GCC"
#else
# error "Unknown compiler"
#endif

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("compiler_name=\"{}\"", __comiler_name__);
console::write_line("compiler_name=\"{}\"", environment::compiler_version().name());
}

// This code produces the following output if compiler is Clang:
//
// compiler_name="Clang"
// compiler_name="Clang"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::compiler_version.

But it can be useful for your own developments.

Standards

The following table represents the different preprocessor symbols for the C++ standard supported by xtd:

SymbolsStandard
__cplusplus = 199711LC++98 (not supported)
__cplusplus = 201103LC++11 (not supported)
__cplusplus = 201402LC++14 (not supported)
__cplusplus = 201703LC++17
__cplusplus = 202002LC++20
__cplusplus = 202302LC++23
__cplusplus = 202600LC++26

For a more complete list of compiler see Pre-defined Compiler Macros Wiki - Standards.

Examples

The following code shows how to detect the C++ standard with the preprocessor symbols:

#if defined(__cplusplus)
# if __cplusplus == 202600L
# define __standard_name__ "C++ 26"
# elif __cplusplus == 202302L
# define __standard_name__ "C++ 23"
# elif __cplusplus == 202002L
# define __standard_name__ "C++ 20"
# elif __cplusplus == 201703L
# define __standard_name__ "C++ 17"
# elif __cplusplus == 201402L
# define __standard_name__ "C++ 14 (not supported)"
# elif __cplusplus == 201103L
# define __standard_name__ "C++ 11 (not supported)"
# elif __cplusplus == 199711L
# define __standard_name__ "C++ 98 (not supported)"
# else
# define __standard_name__ "Unknown C++ standard"
# endif
#else
# error "Not C++ standard"
#endif

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("standard_name=\"{}\"", __standard_name__);
console::write_line("standard_name=\"{}\"", environment::cpp_version().name());
}

// This code produces the following output if C++20:
//
// platform_name="C++ 20"
// platform_name="C++ 20"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::cpp_version.

But it can be useful for your own developments.

Build types

The following table represents the different preprocessor symbols for the build type by xtd:

SymbolsBuild type
NDBUGThe build type is release

NDEBUG is the only definition in the C++ standard for whether the build type is debug or release.

Examples

The following code shows how to detect the buil type with the preprocessor symbols:

#if defined(NDEBUG)
# define __build_type__ "release"
#else
# define __build_type__ "debug"
#endif

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("build_type=\"{}\"", __build_type__);
console::write_line("build_type=\"{}\"", environment::compiler_version().build_type());
}

// This code produces the following output if build type debug:
//
// build_type="debug"
// build_type="debug"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::compiler_version().build_type.

But it can be useful for your own developments.

xtd targets

The following table represents the different preprocessor symbols for the xtd targets:

SymbolsTargetValue
__XTD_CURRENT_TARGET_ID__The current target id[0...8]
__XTD_TARGET_ID_UNKNOWN__The target is unknown0
__XTD_TARGET_ID_CONSOLE_APPLICATION__The target is console application1
__XTD_TARGET_ID_GUI_APPLICATION__The target is gui application2
__XTD_TARGET_ID_TEST_APPLICATION__The target is test application3
__XTD_TARGET_ID_INTERFACE_LIBRARY__The target is interface library4
__XTD_TARGET_ID_MODULE_LIBRARY__The target is interface library5
__XTD_TARGET_ID_SHARED_LIBRARY__The target is shared library6
__XTD_TARGET_ID_STATIC_LIBRARY__The target is static library7
__XTD_TARGET_ID_CUSTOM_TARGET__The target is custom target8

If you are not using CMake to generate your project, you must define them. See the xtd.cmake overview section for more information.

Examples

The following code shows how to detect the xtd folder with the folder symbols:

#include <xtd/xtd.core>

#if defined(__XTD_CURRENT_TARGET_ID__)
# if __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_UNKNOWN__
# define __TARGET_ID_NAME__ "unknown"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_CONSOLE_APPLICATION__
# define __TARGET_ID_NAME__ "console application"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_GUI_APPLICATION__
# define __TARGET_ID_NAME__ "gui application"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_TEST_APPLICATION__
# define __TARGET_ID_NAME__ "test application"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_INTERFACE_LIBRARY__
# define __TARGET_ID_NAME__ "interface library"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_MODULE_LIBRARY__
# define __TARGET_ID_NAME__ "module library"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_SHARED_LIBRARY__
# define __TARGET_ID_NAME__ "shared library"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_STATIC_LIBRARY__
# define __TARGET_ID_NAME__ "static library"
# elif __XTD_CURRENT_TARGET_ID__ == __XTD_TARGET_ID_CUSTOM_TARGET__
# define __TARGET_ID_NAME__ "custom target"
# else
# error "Current target id invalid"
# endif
#else
# error "Current target id not defined"
#endif

using namespace xtd;

auto main() -> int {
console::write_line("target_type=\"{}\"", __TARGET_ID_NAME__);
console::write_line("target_type=\"{}\"", environment::target_type().name());
}

// This code produces the following output for a consome application:
//
// target_type="console application"
// target_type="console application"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::target_type.

xtd paths

The following table represents the different preprocessor symbols for the xtd paths:

SymbolsPathValue
__XTD_INSTALL_PATH__The installation folder of xtd${XTD_INSTALL_PATH}/include"
__XTD_LOCALE_PATH__The xtd locale folder${XTD_INSTALL_PATH}/include"
__XTD_REFERENCE_GUIDE_PATH__The xtd reference guide folder${XTD_INSTALL_PATH}/include"
__XTD_THEMES_PATH__The xtd themes folder${XTD_INSTALL_PATH}/include"
__XTD_INCLUDE_PATH__The xtd inlude folder${XTD_INSTALL_PATH}/include"
__XTD_LIB_PATH__The xtd libraries folder${XTD_INSTALL_PATH}/lib"
__XTD_REOURCES_PATH__The xtd resources folder${XTD_INSTALL_PATH}/lib"
__XTD_CONSOLE_INCLUDE_PATH__The xtd::console inlude folder${XTD_CONSOLE_INSTALL_PATH}/include"
__XTD_CONSOLE_LIB_PATH__The xtd::console libraries folder${XTD_CONSOLE_INSTALL_PATH}/lib"
__XTD_DRAWING_INCLUDE_PATH__The xtd::drawing inlude folder${XTD_DRAWING_INSTALL_PATH}/include"
__XTD_DRAWING_LIB_PATH__The xtd::drawing libraries folder${XTD_DRAWING_INSTALL_PATH}/lib"
__XTD_DRAWING_RESOURCES_PATH__The xtd::drawing resources folder${XTD_DRAWING_INSTALL_PATH}/share/xtd/resources"
__XTD_FORMS_INCLUDE_PATH__The xtd::forms inlude folder${XTD_FORMS_INSTALL_PATH}/include"
__XTD_FORMS_LIB_PATH__The xtd::forms libraries folder${XTD_FORMS_INSTALL_PATH}/lib"
__XTD_FORMS_RESOURCES_PATH__The xtd::forms resources folder${XTD_FORMS_INSTALL_PATH}/share/xtd/resources"
__XTD_TUNIT_INCLUDE_PATH__The xtd::tunit inlude folder${XTD_TUNIT_INSTALL_PATH}/include"
__XTD_TUNIT_LIB_PATH__The xtd::tunit libraries folder${XTD_TUNIT_INSTALL_PATH}/lib"

If you are not using CMake to generate your project, you must define them. See the xtd.cmake overview section for more information.

Examples

The following code shows how to detect the xtd folder with the folder symbols:

#include <xtd/xtd.core>

using namespace xtd;

auto main() -> int {
console::write_line("xtd_themes=\"{}\"", __XTD_THEMES_PATH__);
console::write_line("xtd_themes=\"{}\"", environment::get_folder_path(environment::special_folder::xtd_themes));
}

// This code produces the following output if under unix like system:
//
// xtd_themes="/usr/local/share/xtd/themes"
// xtd_themes="/usr/local/share/xtd/themes"

Remarks

When using xtd, you do not need to use these preprocessor symbols.

It is better to use xtd::environment::get_folder_path.

See also