Diversas vezes estamos desenvolvendo programas portáveis com C++ que precisamos criar um único código que funcione em diversas plataformas .
E para isso precisamos usar DIRETIVAS DE PRÉ PROCESSAMENTO: #ifdef
, #if defined()
, …
Nesse caso existem MACROS
específicas para cada sistema operacional, por exemplo:
__linux__
;_WIN32
.Abaixo um exemplo de um código C++ que roda em ambos sistemas operacionais e emite um “Hello, World!” conforme o sistema operacional:
#include <iostream>
int main(){
#if defined(__linux__) // Ou #if __linux__
std::cout << "Olá, GNU/Linux!" << '\n';
#elif _WIN32
std::cout << "Olá, Windows!" << '\n';
#else
std::cout << "Olá, Other!" << '\n';
#endif
}
No caso do Windows, você ainda pode criar outro #if
dentro para detectar se:
_WIN64
, esse Windows é só 64-bit;_WIN32
, ambos tanto 64-bit quanto 32-bit__CYGWIN__
outra alternativa mais moderna.Exemplo:
#include <iostream>
int main(){
#if __linux__
std::cout << "Olá, GNU/Linux!" << '\n';
#elif _WIN32
#if defined(_WIN64)
std::cout << "Olá, Windows 64-bit!" << '\n';
#else
std::cout << "Olá, Windows!" << '\n';
#endif
#else
std::cout << "Olá, Other!" << '\n';
#endif
}
Você ainda pode detectar todos os sistema operacionais. Abaixo um outro exemplo que detecta, além de Linux e Windows, verifica também se é: macOS, FreeBSD, Android:
#include <iostream>
int main(){
#if defined(__ANDROID__)
std::cout << "Olá, Android!" << '\n';
#elif __FreeBSD__
std::cout << "Olá, FreeBSD!" << '\n';
#elif __linux__
std::cout << "Olá, GNU/Linux!" << '\n';
#elif __APPLE__
std::cout << "Olá, macOS!" << '\n';
#elif _WIN32
std::cout << "Olá, Windows!" << '\n';
#else
std::cout << "Olá, Other!" << '\n';
#endif
}
Você ainda pode verificar se é do tipo UNIX (Linux ou BSD, macOS NÃO): unix
, __unix
ou __unix__
.
Para uma lista completa de todas as macros para sistemas operacionais que você pode ver aqui .
Para ter uma lista de macros que você pode detectar, use o gcc
ou g++
:
Pode ser que o
clang
eclang++
também tenha essas opções, mas eu ainda não os reinstalei para testar.
g++ -dM -E - </dev/null
# Ou
gcc -dM -E - </dev/null
g++ -dM -E - <NUL:
# Ou
gcc -dM -E - <NUL:
A saída será extensa:
Pequeno trecho abaixo.
#define __SSP_STRONG__ 3
#define __DBL_MIN_EXP__ (-1021)
#define __UINT_LEAST16_MAX__ 0xffff
#define __FLT16_HAS_QUIET_NAN__ 1
#define __ATOMIC_ACQUIRE 2
#define __FLT128_MAX_10_EXP__ 4932
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
#define __GCC_IEC_559_COMPLEX 2
#define __UINT_LEAST8_TYPE__ unsigned char
#define __SIZEOF_FLOAT80__ 16
#define __INTMAX_C(c) c ## L
#define __CHAR_BIT__ 8
#define __UINT8_MAX__ 0xff
#define __SCHAR_WIDTH__ 8
#define __WINT_MAX__ 0xffffffffU
#define __FLT32_MIN_EXP__ (-125)
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __SIZE_MAX__ 0xffffffffffffffffUL
#define __WCHAR_MAX__ 0x7fffffff
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
....
cpp sistemasoperacionais windows gcc