Di seluruh basis kode C kami, saya melihat setiap makro didefinisikan dengan cara berikut:
#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#endif
#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#endif
#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#endif
#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
#endif
Apa alasan melakukan pemeriksaan definisikan ini daripada hanya menentukan makro?
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
Saya tidak dapat menemukan praktik ini dijelaskan di mana pun di web.
c
macros
c-preprocessor
ifndef
Trevor Hickey
sumber
sumber
Jawaban:
Ini memungkinkan Anda untuk mengganti makro saat Anda sedang menyusun:
Definisi di file header digunakan sebagai default.
sumber
Seperti yang saya katakan di komentar, bayangkan situasi ini:
foo.h
defs.h
bar.c
Akan mencetak
44
.Namun, jika kondisional
ifndef
tidak ada, hasilnya adalah peringatan kompilasi redefinisi MACRO dan akan dicetak64
.sumber
ifdef
untuk menghindari definisi ulang).#infdef
s digunakan sebagai nilai "fallback" atau "default". Pada dasarnya, "jika pengguna mengkonfigurasinya, baiklah. Jika tidak, mari gunakan nilai default."#defines
di header perpustakaan yang merupakan bagian dari ABI perpustakaan, Anda tidak boleh menggabungkannya#ifndef
. (Atau lebih baik, gunakanenum
). Saya hanya ingin memperjelas bahwa#ifndef
hanya pantas jika memiliki definisi khusus untuk sesuatu dalam satu unit kompilasi tetapi tidak yang lain tidak apa-apa. Jikaa.c
menyertakan header dalam urutan yang berbeda darib.c
, mereka mungkin mendapatkan definisi yang berbeda darimax(a,b)
, dan salah satu dari definisi tersebut mungkin putus denganmax(i++, x)
, tetapi yang lain mungkin menggunakan temporaries dalam ekspresi-pernyataan GNU. Setidaknya masih membingungkan!#ifdef FOO
#error FOO already defined!
#endif
#define FOO x
Saya tidak tahu konteksnya tetapi ini dapat digunakan untuk memberikan ketersediaan kepada pengguna untuk menimpa nilai yang ditetapkan oleh definisi makro tersebut. Jika pengguna secara eksplisit menentukan nilai yang berbeda untuk salah satu makro tersebut, itu akan digunakan sebagai ganti nilai yang digunakan di sini.
Misalnya di g ++ Anda dapat menggunakan
-D
tanda tersebut selama kompilasi untuk meneruskan nilai ke makro.sumber
Ini dilakukan agar pengguna file header dapat mengganti definisi dari kodenya atau dari flag -D compiler.
sumber
Setiap proyek C berada di beberapa file sumber. Saat mengerjakan satu file sumber, pemeriksaan tampaknya (dan sebenarnya) tidak ada gunanya, tetapi saat mengerjakan proyek C besar, sebaiknya periksa definisi yang ada sebelum menentukan konstanta. Idenya sederhana: Anda memerlukan konstanta dalam file sumber spesifik tersebut, tetapi mungkin sudah ditentukan di file lain.
sumber
Anda bisa memikirkan tentang kerangka kerja / pustaka yang memberi pengguna preset default yang memungkinkan pengguna untuk mengkompilasi dan mengerjakannya. Definisi tersebut tersebar di file yang berbeda dan pengguna akhir disarankan untuk menyertakan file config.h itu di mana dia dapat mengkonfigurasi nilainya. Jika pengguna lupa beberapa mendefinisikan sistem dapat terus bekerja karena preset.
sumber
Menggunakan
memungkinkan pengguna untuk menentukan nilai makro menggunakan argumen baris perintah (dalam gcc / clang / VS)
-DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
.Ada alasan penting lainnya. Merupakan kesalahan untuk mendefinisikan ulang makro preprocessor secara berbeda. Lihat jawaban ini untuk pertanyaan SO lainnya . Tanpa
#ifndef
pemeriksaan, kompilator akan menghasilkan kesalahan jika-DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
digunakan sebagai argumen baris perintah dalam pemanggilan kompilator.sumber