假設我想確保始終使用不同的引數值(編譯時)呼叫該函式。
理想的情況是這樣編譯:
enum en {
en_A,
en_B
};
...
foo(en_A);
但這失敗了:
enum en {
en_A,
en_B
};
...
foo(en_A);
...
foo(en_A);
因此,我們應該只能呼叫某個函式 foo(en_A) 一次(foo(en_B) 也是如此)。
不太可取但也可以接受的是定義 foo_en_A、foo_en_B 并確保它們中的每一個只被呼叫一次。
是否可以在 C 中執行類似編譯時的操作?
uj5u.com熱心網友回復:
是否可以在 C 中執行類似編譯時的操作?
不,這是不可能的。不僅C語言缺乏反射——不能自我檢查,而且C語言一次編譯一個“翻譯單元”。雖然編譯器擴展部分可能在一個 TU 中實作該檢查,但您必須提供一個特殊的聯結器或聯結器插件來跨多個 TU 實作它。
要在編譯時做您想做的事,您必須使用 C 源代碼本身之外的外部工具。這些工具可以處理生成的程式、檢查程式集,或者可以處理 C 源代碼本身。
(你在問 XY 問題)。
確保日志庫的用戶永遠不會使呼叫模棱兩可(例如,從兩個不同的地方設定相同的錯誤),以便可以清楚地跟蹤代碼中產生錯誤的地方
要做到這一點,只需記錄__FILE__和__LINE__雇用理智的程式員,他們永遠不會將非唯一的日志訊息放在同一行上,或者使用相同的路徑編譯不同的檔案。
無論如何,還有另一種解決問題的方法。不需要程式員在整個代碼庫中鍵入唯一的數字,只需生成它們的數字即可。我曾經在一個裸機小型嵌入式系統中作業,該系統的通信能力非常低,每小時只有位元組數。用 shell 撰寫的工具awk將掃描整個代碼庫以獲取準確的字串UNIQUE(),并且每個此類呼叫都將被整個源代碼庫中的唯一編號替換,然后進行編譯。因此,不是“要求程式員擁有唯一的編號”,而是自己生成編號,這比檢查您的所有同事是否已經使用了某個編號更容易編程。
uj5u.com熱心網友回復:
我懷疑由于與停機問題困難相同的原因,通常很難進行預處理。實際上,如果您要在沒有 的情況下運行此系統NDEBUG,assert則不會使用相同的輸入兩次呼叫該函式。
#include <stdio.h>
#include <limits.h>
#include <assert.h>
/* http://c-faq.com/misc/bitsets.html */
#define BITMASK(b) (1 << ((b) % CHAR_BIT))
#define BITSLOT(b) ((b) / CHAR_BIT)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))
#define BITNSLOTS(nb) ((nb CHAR_BIT - 1) / CHAR_BIT)
enum en {
en_A,
en_B,
en_NUM
};
static unsigned char debug_en[BITNSLOTS(en_NUM)];
static void foo(const enum en en) {
assert(!BITTEST(debug_en, en)
&& (BITSET(debug_en, en), 1));
}
int main(void) {
foo(en_A);
foo(en_B);
foo(en_A);
return 0;
}
這給出了第二個斷言失敗中止foo(en_A)。但是,它不是編譯時測驗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/338862.html
