Bagikan melalui


#if, #elif, #else, dan arahan #endif (C/C++)

Arahan #if , dengan arahan #elif, #else, dan #endif , mengontrol kompilasi bagian file sumber. Jika ekspresi yang Anda tulis (setelah #if) memiliki nilai bukan nol, grup baris segera mengikuti arahan #if disimpan di unit terjemahan.

Tatabahasa

kondisi:
if-part elif-partsopt else-partopt endif-line

if-part :
teks if-line

if-line :
#if ekspresi konstanta
pengidentifikasi #ifdef
pengidentifikasi #ifndef

elif-parts :
teks garis elif
teks elif-parts elif-line

elif-line :
#elif ekspresi konstanta

bagian lain :
teks baris lain

else-line :
#else

garis endif :
#endif

Keterangan

Setiap arahan #if dalam file sumber harus dicocokkan dengan arahan #endif penutup. Sejumlah arahan #elif dapat muncul antara arahan #if dan #endif , tetapi paling banyak satu arahan #else diizinkan. Arahan #else , jika ada, harus menjadi arahan terakhir sebelum #endif.

Arahan #if, #elif, #else, dan #endif dapat bersarang di bagian teks arahan #if lainnya. Setiap arahan #else, #elif, atau #endif berlapis milik arahan #if terdekat sebelumnya.

Semua arahan kompilasi kondisional, seperti #if dan #ifdef, harus cocok dengan direktif #endif penutupan sebelum akhir file. Jika tidak, pesan kesalahan dihasilkan. Ketika direktif kompilasi bersikala terkandung dalam file include, mereka harus memenuhi kondisi yang sama: Tidak boleh ada direktif kompilasi bersyarkat yang tidak cocok di akhir file include.

Penggantian makro dilakukan dalam bagian baris yang mengikuti perintah #elif, sehingga panggilan makro dapat digunakan dalam ekspresi konstanta.

Prapemroses memilih salah satu kemunculan teks yang diberikan untuk pemrosesan lebih lanjut. Blok yang ditentukan dalam teks dapat berupa urutan teks apa pun. Ini dapat menempati lebih dari satu baris. Biasanya teks adalah teks program yang memiliki arti untuk pengkompilasi atau prapemrosan.

Prapemroses memproses teks yang dipilih dan meneruskannya ke pengkompilasi. Jika teks berisi direktif praproscessor, praproscessor menjalankan arahan tersebut. Hanya blok teks yang dipilih oleh pra-prosesor yang dikompilasi.

Prapemroses memilih item teks tunggal dengan mengevaluasi ekspresi konstanta mengikuti setiap direktif #if atau #elif hingga menemukan ekspresi konstanta benar (bukan nol). Ini memilih semua teks (termasuk direktif pra-prosesor lainnya yang dimulai dengan #) hingga #elif, #else, atau #endif terkait.

Jika semua kemunculan ekspresi konstanta salah, atau jika tidak ada direktif #elif muncul, prapemrosemilihan blok teks setelah klausul #else . Ketika tidak ada klausa #else, dan semua instans ekspresi konstanta di blok #if salah, tidak ada blok teks yang dipilih.

Ekspresi konstanta adalah ekspresi konstanta bilangan bulat dengan batasan tambahan ini:

  • Ekspresi harus memiliki jenis integral dan hanya dapat menyertakan konstanta bilangan bulat, konstanta karakter, dan operator yang ditentukan .

  • Ekspresi tidak dapat menggunakan sizeof atau operator type-cast.

  • Lingkungan target mungkin tidak dapat mewakili semua rentang bilangan bulat.

  • Terjemahan mewakili jenis int dengan cara yang sama seperti jenis long, dan unsigned int cara yang sama seperti unsigned long.

  • Penerjemah dapat menerjemahkan konstanta karakter ke sekumpulan nilai kode yang berbeda dari yang ditetapkan untuk lingkungan target. Untuk menentukan properti lingkungan target, gunakan aplikasi yang dibangun untuk lingkungan tersebut untuk memeriksa nilai LIMITS. Makro H .

  • Ekspresi tidak boleh mengkueri lingkungan, dan harus tetap terisolasi dari detail implementasi pada komputer target.

Operator pra-prosesor

ditentukan

Operator praprosesor yang ditentukan dapat digunakan dalam ekspresi konstanta khusus, seperti yang ditunjukkan oleh sintaks berikut:

didefinisikan( pengidentifikasi )
pengidentifikasi yang ditentukan

Ekspresi konstanta ini dianggap benar (bukan nol) jika pengidentifikasi saat ini ditentukan. Jika tidak, kondisinya salah (0). Pengidentifikasi yang didefinisikan sebagai teks kosong dianggap ditentukan. Operator yang ditentukan dapat digunakan dalam #if dan arahan #elif, tetapi tidak di tempat lain.

Dalam contoh berikut, kompilasi kontrol direktif #if dan #endif dari salah satu dari tiga panggilan fungsi:

#if defined(CREDIT)
    credit();
#elif defined(DEBIT)
    debit();
#else
    printerror();
#endif

Panggilan fungsi ke credit dikompilasi jika pengidentifikasi CREDIT ditentukan. Jika pengidentifikasi DEBIT ditentukan, panggilan fungsi ke debit dikompilasi. Jika tidak ada pengidentifikasi yang ditentukan, panggilan ke printerror dikompilasi. Keduanya CREDIT dan credit merupakan pengidentifikasi yang berbeda di C dan C++ karena kasusnya berbeda.

Pernyataan kompilasi bersyarah dalam contoh berikut mengasumsikan konstanta simbolis yang ditentukan sebelumnya bernama DLEVEL.

#if DLEVEL > 5
    #define SIGNAL  1
    #if STACKUSE == 1
        #define STACK   200
    #else
        #define STACK   100
    #endif
#else
    #define SIGNAL  0
    #if STACKUSE == 1
        #define STACK   100
    #else
        #define STACK   50
    #endif
#endif
#if DLEVEL == 0
    #define STACK 0
#elif DLEVEL == 1
    #define STACK 100
#elif DLEVEL > 5
    display( debugptr );
#else
    #define STACK 200
#endif

Blok #if pertama menunjukkan dua set arahan #if berlapis, #else, dan #endif. Serangkaian arahan pertama diproses hanya jika DLEVEL > 5 benar. Jika tidak, pernyataan setelah #else diproses.

Arahan #elif dan #else dalam contoh kedua digunakan untuk membuat salah satu dari empat pilihan, berdasarkan nilai DLEVEL. Konstanta STACK diatur ke 0, 100, atau 200, tergantung pada definisi DLEVEL. Jika DLEVEL lebih besar dari 5, maka pernyataan

#elif DLEVEL > 5
display(debugptr);

dikompilasi, dan STACK tidak ditentukan.

Penggunaan umum untuk kompilasi bersyarkat adalah untuk mencegah beberapa penyertaan file header yang sama. Di C++, di mana kelas sering didefinisikan dalam file header, konstruksi seperti ini dapat digunakan untuk mencegah beberapa definisi:

/*  EXAMPLE.H - Example header file  */
#if !defined( EXAMPLE_H )
#define EXAMPLE_H

class Example
{
    //...
};

#endif // !defined( EXAMPLE_H )

Kode sebelumnya memeriksa untuk melihat apakah konstanta EXAMPLE_H simbolis ditentukan. Jika demikian, file telah disertakan dan tidak perlu diolah ulang. Jika tidak, konstanta EXAMPLE_H didefinisikan untuk menandai CONTOH. H seperti yang sudah diproses.

__has_include

Visual Studio 2017 versi 15.3 dan yang lebih baru: Menentukan apakah header pustaka tersedia untuk dimasukkan:

#ifdef __has_include
#  if __has_include(<filesystem>)
#    include <filesystem>
#    define have_filesystem 1
#  elif __has_include(<experimental/filesystem>)
#    include <experimental/filesystem>
#    define have_filesystem 1
#    define experimental_filesystem
#  else
#    define have_filesystem 0
#  endif
#endif

Lihat juga

Arahan pra-prosesor