Menentukan 32 vs 64 bit di C ++


140

Saya mencari cara untuk menentukan dengan andal apakah kode C ++ sedang dikompilasi dalam 32 vs 64 bit. Kami telah menemukan apa yang kami anggap sebagai solusi yang masuk akal menggunakan makro, tetapi ingin tahu apakah orang-orang dapat memikirkan kasus-kasus di mana hal ini mungkin gagal atau apakah ada cara yang lebih baik untuk melakukan ini. Harap dicatat bahwa kami mencoba melakukan ini dalam lingkungan kompilator lintas platform dan multipel.

#if ((ULONG_MAX) == (UINT_MAX))
# define IS32BIT
#else
# define IS64BIT
#endif

#ifdef IS64BIT
DoMy64BitOperation()
#else
DoMy32BitOperation()
#endif

Terima kasih.


8
Jika Anda benar-benar peduli dengan ukuran kata dari arsitektur Anda, maka jangan mengabaikan kemungkinan bahwa itu bukan 32 atau 64-bit. Ada arsitektur 16 dan 128-bit di luar sana, lho.
alex tingle

Apa perbedaan antara operasi 64 bit dan 32 bit?
peterchen

2
Anda benar-benar tidak boleh mengondisikan ini pada lebar kata dari platform target. Sebaliknya, gunakan ukuran tipe data yang relevan secara langsung untuk menentukan apa yang harus dilakukan. stdint.hmungkin teman Anda, atau Anda mungkin perlu mengembangkan beberapa typedefs Anda sendiri.
Phil Miller

Tes ini tampaknya tidak bekerja pada Visual Studio 2008 SP1. Itu macet di "IS64BIT" untuk 32-bit dan 64-bit.
Contango

Jawaban:


102

Sayangnya tidak ada makro lintas platform yang mendefinisikan 32/64 bit di seluruh kompiler utama. Saya telah menemukan cara paling efektif untuk melakukan ini adalah sebagai berikut.

Pertama saya memilih representasi saya sendiri. Saya lebih suka ENVIRONMENT64 / ENVIRONMENT32. Kemudian saya mencari tahu apa yang digunakan semua kompiler utama untuk menentukan apakah itu lingkungan 64 bit atau tidak dan menggunakannya untuk mengatur variabel saya.

// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif

Rute lain yang lebih mudah adalah dengan mengatur variabel-variabel ini dari baris perintah kompilator.


3
nah, ada kompiler lain selain GCC dan VS. Misalnya QNX dan GHS muncul di pikiran (meskipun saya curiga QNX memiliki definisi waktu pembuatan yang mirip dengan GCC). Anda juga lupa arsitektur MIPS64 dan IA64 di pemeriksaan GCC Anda
Rom

14
@Rom, pasti lebih dari 2 kompiler dan arsitektur. Ini hanya dimaksudkan untuk menjadi contoh bagaimana mendekati masalah ini, bukan solusi lengkap.
JaredPar

2
Saya mengatakan "biasanya". "Idealnya" mungkin lebih realistis.
Steve Jessop

7
Saya pikir Anda harus menggunakan "#if ditentukan ( WIN32 ) || ditentukan (_WIN64)" dll
KindDragon

3
#if _WIN32 || _WIN64... #elif __GNUC__... #else # error "Missing feature-test macro for 32/64-bit on this compiler."?
Davislor

101
template<int> void DoMyOperationHelper();

template<> void DoMyOperationHelper<4>() 
{
  // do 32-bits operations
}

template<> void DoMyOperationHelper<8>() 
{
  // do 64-bits operations
}

// helper function just to hide clumsy syntax
inline void DoMyOperation() { DoMyOperationHelper<sizeof(size_t)>(); }

int main()
{
  // appropriate function will be selected at compile time 
  DoMyOperation(); 

  return 0;
}

2
Apa yang terjadi jika size_t bukan 4 atau 8?
Jesper

16
@Jesper, Anda akan mendapatkan kesalahan tautan dalam contoh di atas. Atau Anda dapat mengimplementasikan DoMyOperation untuk kasus itu
Kirill V. Lyadvinsky

1
Penggunaan template yang apik, dan pujian untuk menguji apa yang penting (ukuran beberapa jenis tertentu) daripada yang berkorelasi.
Phil Miller

2
Berhati-hatilah saat menggunakan size_t untuk ini. Anda dapat mengalami masalah jika tidak sesuai dengan ukuran penunjuk misalnya (misalnya pada platform dengan lebih dari satu ukuran penunjuk).
Logan Capaldo

8
Standar mengatakan bahwa ukuran size_tcukup besar untuk menampung ukuran objek yang dialokasikan dalam sistem. Biasanya itulah yang ingin Anda ketahui saat kompilasi bersyarat. Jika bukan itu yang Anda inginkan, Anda dapat menggunakan cuplikan ini dengan beberapa jenis lain, bukan size_t. Misalnya, bisa jadi void*.
Kirill V. Lyadvinsky

45

Sayangnya, dalam lingkungan lintas platform, lintas kompiler, tidak ada satu metode yang dapat diandalkan untuk melakukan ini murni pada waktu kompilasi.

  • Baik _WIN32 dan _WIN64 terkadang keduanya tidak ditentukan, jika pengaturan proyek cacat atau rusak (terutama pada Visual Studio 2008 SP1).
  • Proyek berlabel "Win32" dapat disetel ke 64-bit, karena kesalahan konfigurasi proyek.
  • Pada Visual Studio 2008 SP1, terkadang intellisense tidak mengubah bagian kode yang benar, menurut #define saat ini. Ini menyulitkan untuk melihat dengan tepat #define mana yang digunakan pada waktu kompilasi.

Oleh karena itu, satu - satunya metode yang dapat diandalkan adalah menggabungkan 3 pemeriksaan sederhana :

  • 1) Menyusun pengaturan waktu , dan;
  • 2) Pemeriksaan runtime , dan;
  • 3) Pemeriksaan waktu kompilasi yang kuat .

Pemeriksaan sederhana 1/3: Kompilasi pengaturan waktu

Pilih metode apa pun untuk menyetel variabel #define yang diperlukan. Saya menyarankan metode dari @JaredPar:

// Check windows
#if _WIN32 || _WIN64
   #if _WIN64
     #define ENV64BIT
  #else
    #define ENV32BIT
  #endif
#endif

// Check GCC
#if __GNUC__
  #if __x86_64__ || __ppc64__
    #define ENV64BIT
  #else
    #define ENV32BIT
  #endif
#endif

Pemeriksaan sederhana 2/3: Pemeriksaan waktu proses

Di main (), periksa kembali untuk melihat apakah sizeof () masuk akal:

#if defined(ENV64BIT)
    if (sizeof(void*) != 8)
    {
        wprintf(L"ENV64BIT: Error: pointer should be 8 bytes. Exiting.");
        exit(0);
    }
    wprintf(L"Diagnostics: we are running in 64-bit mode.\n");
#elif defined (ENV32BIT)
    if (sizeof(void*) != 4)
    {
        wprintf(L"ENV32BIT: Error: pointer should be 4 bytes. Exiting.");
        exit(0);
    }
    wprintf(L"Diagnostics: we are running in 32-bit mode.\n");
#else
    #error "Must define either ENV32BIT or ENV64BIT".
#endif

Pemeriksaan sederhana 3/3: Pemeriksaan waktu kompilasi yang kuat

Aturan umumnya adalah "setiap #define harus diakhiri dengan #else yang menghasilkan kesalahan".

#if defined(ENV64BIT)
    // 64-bit code here.
#elif defined (ENV32BIT)
    // 32-bit code here.
#else
    // INCREASE ROBUSTNESS. ALWAYS THROW AN ERROR ON THE ELSE.
    // - What if I made a typo and checked for ENV6BIT instead of ENV64BIT?
    // - What if both ENV64BIT and ENV32BIT are not defined?
    // - What if project is corrupted, and _WIN64 and _WIN32 are not defined?
    // - What if I didn't include the required header file?
    // - What if I checked for _WIN32 first instead of second?
    //   (in Windows, both are defined in 64-bit, so this will break codebase)
    // - What if the code has just been ported to a different OS?
    // - What if there is an unknown unknown, not mentioned in this list so far?
    // I'm only human, and the mistakes above would break the *entire* codebase.
    #error "Must define either ENV32BIT or ENV64BIT"
#endif

Perbarui 2017-01-17

Komentar dari @AI.G:

4 tahun kemudian (tidak tahu apakah itu mungkin sebelumnya) Anda dapat mengubah pemeriksaan run-time menjadi waktu kompilasi menggunakan statik assert: static_assert (sizeof (void *) == 4) ;. Sekarang semuanya selesai pada waktu kompilasi :)

Lampiran A

Secara tidak langsung, aturan di atas dapat disesuaikan untuk membuat seluruh basis kode Anda lebih andal:

  • Setiap pernyataan if () diakhiri dengan "else" yang menghasilkan peringatan atau kesalahan.
  • Setiap pernyataan switch () diakhiri dengan "default:" yang menghasilkan peringatan atau kesalahan.

Alasan mengapa ini bekerja dengan baik adalah karena ini memaksa Anda untuk memikirkan setiap kasus terlebih dahulu, dan tidak mengandalkan logika (terkadang cacat) di bagian "lain" untuk menjalankan kode yang benar.

Saya menggunakan teknik ini (di antara banyak lainnya) untuk menulis 30.000 proyek garis yang bekerja dengan sempurna sejak pertama kali digunakan dalam produksi (itu 12 bulan yang lalu).


sizeof(void*)apakah itu diselesaikan pada waktu kompilasi atau run-time? jika pada waktu kompilasi maka pada saat run-time pemeriksaan akan selalu dilakukan if(8!=8){...}.
Ameen

@ameen Ini diselesaikan pada saat run-time. Tujuan dari pemeriksaan ini adalah untuk memastikan bahwa program keluar dengan kesalahan yang sesuai jika bitnya tidak sesuai dengan yang diharapkan. Artinya, pengembang dapat segera memperbaiki kesalahan ini, daripada mencoba mendiagnosis bug halus yang muncul nanti.
Contango

3
4 tahun kemudian (tidak tahu apakah itu mungkin sebelum) Anda dapat mengkonversi cek run-time untuk mengkompilasi waktu satu menggunakan menegaskan statis: static_assert(sizeof(void*) == 4);. Sekarang semuanya selesai pada waktu kompilasi :)
Al.G.

1
static_assert(sizeof(void*) * CHAR_BIT == 32)lebih ekspresif dan benar secara teknis (walaupun saya tidak tahu arsitektur apa pun di mana byte memiliki jumlah bit yang berbeda dari 8)
Xeverous

1
Lihat juga jawaban saya di bawah ini yang menggabungkan jawaban luar biasa ini dengan " Makro Lebih Baik, Bendera Lebih Baik " dari Fluent C ++.
logam

31

Anda harus dapat menggunakan makro yang ditentukan di stdint.h. Secara khusus INTPTR_MAXadalah nilai yang Anda butuhkan.

#include <cstdint>
#if INTPTR_MAX == INT32_MAX
    #define THIS_IS_32_BIT_ENVIRONMENT
#elif INTPTR_MAX == INT64_MAX
    #define THIS_IS_64_BIT_ENVIRONMENT
#else
    #error "Environment not 32 or 64-bit."
#endif

Beberapa (semua?) Versi kompiler Microsoft tidak disertakan stdint.h. Tidak yakin mengapa, karena ini adalah file standar. Berikut versi yang dapat Anda gunakan:http://msinttypes.googlecode.com/svn/trunk/stdint.h


4
Mengapa tidak ada stdint.h untuk Microsoft? Karena diperkenalkan dengan standar C99, dan Microsoft tampaknya memiliki keengganan aktif untuk mengimplementasikan bahkan hal-hal termudah dari C99. Bahkan hal-hal perpustakaan mudah yang tidak memerlukan perubahan kompiler. Bahkan hal-hal yang sudah dilakukan saat mengompilasi untuk C ++ (seperti deklarasi setelah pernyataan). Saya tahu itu perlu pengujian, dll., Tetapi saya juga tahu bahwa MS mendapatkan (atau pernah mendapat) sebagian besar perpustakaannya dari Dinkumware / Plauger, dan Dinkumware memiliki perpustakaan C99 selama bertahun-tahun.
Michael Burr

2
VC ++ 2010 (beta 1, bagaimanapun) memiliki <stdint.h>dan <cstdint>. Adapun keadaan saat ini - perpustakaan VC ++ berasal dari Dinkumware (masih - TR1 diambil dari sana juga), tetapi dari apa yang saya ingat pernah membaca di VCBlog, ia mengalami refactoring yang cukup signifikan untuk dikompilasi dengan bersih /clr, bekerja dengan semua MSVC tipe non-standar seperti __int64, dan sebagainya - itulah sebabnya tidak sesederhana hanya dengan mengambilnya dan memasukkannya ke versi kompiler berikutnya.
Pavel Minaev

2
Ini membawa saya ke jawaban yang benar, tetapi saya pikir Anda harus membandingkan dengan UINT64_MAX bukan INT64_MAX. Saya menggunakan SIZE_MAX == UINT64_MAX - prob yang sama
Arno Duvenhage

15

Itu tidak akan berfungsi pada Windows untuk awalnya. Panjang dan int keduanya 32 bit apakah Anda sedang mengompilasi untuk jendela 32 bit atau 64 bit. Saya akan berpikir memeriksa apakah ukuran pointer 8 byte mungkin merupakan rute yang lebih dapat diandalkan.


2
Sayangnya sizeof dilarang dalam #if direktif (jika Anda memikirkannya preprocessor tidak memiliki cara untuk mengatakannya)
EFraim

Ya, itulah mengapa saya berhenti menyarankan memeriksa ukuran penunjuk daripada menggunakan sizeof - Saya tidak dapat memikirkan cara portabel untuk melakukannya dari atas kepala saya ...
mattnewport

3
Pertanyaan tidak (belum) mengatakan itu memiliki harus dilakukan pada saat pra-prosesor. Banyak / sebagian besar kompiler dengan pengoptimalan aktif akan melakukan pekerjaan yang layak untuk menghilangkan kode mati, bahkan jika Anda "membiarkannya sampai waktu proses" dengan tes seperti sizeof(void*) == 8 ? Do64Bit() : Do32Bit();. Itu masih bisa meninggalkan fungsi yang tidak terpakai dalam biner, tetapi ekspresi kemungkinan dikompilasi hanya untuk panggilan ke fungsi "benar".
Steve Jessop

1
@onebyone yang memecahkan masalah pemanggilan fungsi, tetapi bagaimana jika saya ingin mendeklarasikan variabel tipe yang berbeda berdasarkan platform, itu perlu dilakukan di preprocessor kecuali Anda ingin mendeklarasikan beberapa variabel dan menggunakannya berdasarkan pernyataan if ( yang juga akan dioptimalkan jika tidak digunakan, tetapi tidak akan terlalu menyenangkan dalam kode)
Falaina

1
Maka Anda benar, ekspresi konstan dalam kondisional tidak baik. Pendekatan Kirill dapat melakukan apa yang Anda inginkan, meskipun:template<int> struct Thing; template<> struct Thing<4> { typedef uint32_t type; }; template<> struct Thing<8> { typedef uint64_t type; }; typedef Thing<sizeof(void*)>::type thingtype;
Steve Jessop

9

Anda bisa melakukan ini:

#if __WORDSIZE == 64
char *size = "64bits";
#else
char *size = "32bits";
#endif

1
Dalam banyak lingkungan pemrograman untuk bahasa turunan C dan C pada mesin 64-bit, variabel "int" masih memiliki lebar 32 bit, tetapi bilangan bulat dan pointer panjang memiliki lebar 64 bit. Ini dijelaskan sebagai memiliki model data LP64. unix.org/version2/whatsnew/lp64_wp.html
Hermes

6
Try this:
#ifdef _WIN64
// 64 bit code
#elif _WIN32
// 32 bit code
#else
   if(sizeof(void*)==4)

       // 32 bit code
   else 

       // 64 bit code   
#endif

7
Kode ini salah. Pada 64-bit, _WIN32 dan _WIN64 ditentukan. Jika Anda memutarnya (periksa dulu _WIN64) tentu saja berfungsi.
BertR

4

"Dikompilasi dalam 64 bit" tidak didefinisikan dengan baik di C ++.

C ++ hanya menetapkan batas bawah untuk ukuran seperti int, long dan void *. Tidak ada jaminan bahwa int adalah 64 bit meskipun dikompilasi untuk platform 64 bit. Model ini memungkinkan misalnya 23 bit intdansizeof(int *) != sizeof(char *)

Ada berbagai model pemrograman untuk platform 64 bit.

Taruhan terbaik Anda adalah tes khusus platform. Terbaik kedua, keputusan portabel Anda harus lebih spesifik dalam apa adalah 64 bit.


3

Pendekatan Anda tidak terlalu jauh, tetapi Anda hanya memeriksa apakah longdan intberukuran sama. Secara teoritis, keduanya bisa 64 bit, dalam hal ini pemeriksaan Anda akan gagal, dengan asumsi keduanya menjadi 32 bit. Berikut adalah pemeriksaan yang benar-benar memeriksa ukuran jenis itu sendiri, bukan ukuran relatifnya:

#if ((UINT_MAX) == 0xffffffffu)
    #define INT_IS32BIT
#else
    #define INT_IS64BIT
#endif
#if ((ULONG_MAX) == 0xfffffffful)
    #define LONG_IS32BIT
#else
    #define LONG_IS64BIT
#endif

Pada prinsipnya, Anda dapat melakukan ini untuk semua jenis yang Anda miliki makro yang ditentukan sistem dengan nilai maksimal.

Perhatikan, bahwa standar long longharus minimal 64 bit bahkan pada sistem 32 bit.


Satu hal yang perlu diperhatikan, untuk UINT_MAX dan ULONG_MAX yang akan didefinisikan, Anda mungkin ingin memiliki #include <limits.h>suatu tempat sebelum #ifpengujian Anda .
Alexis Wilke

3

Orang sudah menyarankan metode yang akan mencoba menentukan apakah program sedang dikompilasi di 32-bitatau 64-bit.

Dan saya ingin menambahkan bahwa Anda dapat menggunakan fitur c ++ 11 static_assertuntuk memastikan bahwa arsitekturnya seperti yang Anda pikirkan ("untuk bersantai").

Jadi di tempat Anda menentukan makro:

#if ...
# define IS32BIT
  static_assert(sizeof(void *) == 4, "Error: The Arch is not what I think it is")
#elif ...
# define IS64BIT
  static_assert(sizeof(void *) == 8, "Error: The Arch is not what I think it is")
#else
# error "Cannot determine the Arch"
#endif

static_assert(sizeof(void*) * CHAR_BIT == 32)lebih ekspresif dan benar secara teknis (walaupun saya tidak tahu arsitektur apa pun di mana byte memiliki jumlah bit yang berbeda dari 8)
Xeverous

2

Kode di bawah ini berfungsi dengan baik untuk sebagian besar lingkungan saat ini:

  #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) &&     !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    #define IS64BIT 1
 #else
    #define IS32BIT 1
#endif

3
Perhatikan bahwa _WIN64mengharuskan Anda telah disertakan <windows.h>. Dengan Visual C ++, lebih baik menggunakan built-in mendefinisikan compiler: _M_IX86, _M_X64, _M_ARM, _M_ARM64, dll
Chuck Walbourn

Untuk PowerPC, saya percaya Anda perlu memeriksa __ppc64__, __powerpc64__dan _ARCH_PPC64. Itu menangkap AIX dan platform lainnya juga.
jww

1

Jika Anda dapat menggunakan konfigurasi proyek di semua lingkungan Anda, itu akan membuat definisi simbol 64- dan 32-bit menjadi mudah. Jadi Anda akan memiliki konfigurasi proyek seperti ini:

Debug
32-bit Rilis
32-bit Debug
64-bit Rilis 64-bit

EDIT: Ini adalah konfigurasi umum, bukan konfigurasi target. Panggil mereka apapun yang kamu mau.

Jika Anda tidak bisa melakukan itu, saya suka ide Jared.


Atau gabungkan keduanya: deteksi otomatis konfigurasi pada kompiler yang Anda ketahui, tetapi kembali untuk melihat #define yang ditentukan dalam proyek / command-line / apa pun pada kompiler yang tidak dikenal.
Steve Jessop

4
Bagaimana solusi khusus VisualStudio Anda akan membantu dengan pertanyaan lintas platform OP ??
alex tingle

3
@ Jon: Hmm. Mereka TIDAK didukung dalam segala jenis lingkungan lintas platform menurut definisi . Kecuali jika itu adalah definisi lintas platform MS - berfungsi pada versi Windows yang lebih baru.
EFraim

1
@EFraim: Ya, Anda dapat TARGET 32- atau 64-bit menggunakan VS, tapi bukan itu yang saya bicarakan. Konfigurasi proyek generik, dan nama yang saya tetapkan, sama sekali tidak ada hubungannya dengan platform. Jika konfigurasi proyek spesifik terhadap VS, maka itu memalukan karena sangat berguna.
Jon Seigel

1
Saya rasa ini adalah jawaban yang benar. Ini lebih dapat diandalkan daripada mencoba mendeteksi sesuatu secara otomatis. Semua IDE yang pernah saya lihat mendukung fitur ini dalam beberapa bentuk, dan saya yakin yang belum pernah saya lihat mendukungnya juga. Jika Anda menggunakan make, atau jam, Anda dapat menyetel variabel dari baris perintah saat dipanggil, seperti biasa.

1

Saya akan menempatkan sumber 32-bit dan 64-bit di file yang berbeda dan kemudian memilih file sumber yang sesuai menggunakan sistem build.


2
Ini akan serupa dengan memiliki sistem build yang memberi Anda tanda seperti -DBUILD_64BIT. Seringkali, hal-hal tertentu sangat mirip dengan 32 dan 64 bit sehingga menyimpannya dalam file yang sama bisa sangat praktis.
Alexis Wilke

Mempertahankan file sumber kembar rawan kesalahan. IMO bahkan #jika bit64 yang sangat besar .. semua kode, untuk 64bit #lain .. semua kode, untuk 32bit #endif lebih baik dari itu. (# if's line-by-line is ideal in my view)
brewmanz

1

Meminjam dari jawaban bagus Contango di atas dan menggabungkannya dengan " Makro Lebih Baik, Bendera Lebih Baik " dari Fluent C ++, Anda dapat melakukan:

// Macro for checking bitness (safer macros borrowed from 
// https://www.fluentcpp.com/2019/05/28/better-macros-better-flags/)
#define MYPROJ_IS_BITNESS( X ) MYPROJ_IS_BITNESS_PRIVATE_DEFINITION_##X()

// Bitness checks borrowed from https://stackoverflow.com/a/12338526/201787
#if _WIN64 || ( __GNUC__ && __x86_64__ )
#    define MYPROJ_IS_BITNESS_PRIVATE_DEFINITION_64() 1
#    define MYPROJ_IS_BITNESS_PRIVATE_DEFINITION_32() 0
#    define MYPROJ_IF_64_BIT_ELSE( x64, x86 ) (x64)
    static_assert( sizeof( void* ) == 8, "Pointer size is unexpected for this bitness" );
#elif _WIN32 || __GNUC__
#    define MYPROJ_IS_BITNESS_PRIVATE_DEFINITION_64() 0
#    define MYPROJ_IS_BITNESS_PRIVATE_DEFINITION_32() 1
#    define MYPROJ_IF_64_BIT_ELSE( x64, x86 ) (x86)
    static_assert( sizeof( void* ) == 4, "Pointer size is unexpected for this bitness" );
#else
#    error "Unknown bitness!"
#endif

Kemudian Anda bisa menggunakannya seperti:

#if MYPROJ_IS_BITNESS( 64 )
    DoMy64BitOperation()
#else
    DoMy32BitOperation()
#endif

Atau menggunakan makro ekstra yang saya tambahkan:

MYPROJ_IF_64_BIT_ELSE( DoMy64BitOperation(), DoMy32BitOperation() );

0

Saya menambahkan jawaban ini sebagai kasus penggunaan dan contoh lengkap untuk pemeriksaan runtime yang dijelaskan dalam jawaban lain .

Ini adalah pendekatan yang saya ambil untuk menyampaikan kepada pengguna akhir apakah program dikompilasi sebagai 64-bit atau 32-bit (atau lainnya, dalam hal ini):

version.h

#ifndef MY_VERSION
#define MY_VERSION

#include <string>

const std::string version = "0.09";
const std::string arch = (std::to_string(sizeof(void*) * 8) + "-bit");

#endif

test.cc

#include <iostream>
#include "version.h"

int main()
{
    std::cerr << "My App v" << version << " [" << arch << "]" << std::endl;
}

Kompilasi dan Uji

g++ -g test.cc
./a.out
My App v0.09 [64-bit]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.