我正在寫DEBUG_MSG
列印除錯訊息
#define DEBUG_MSG(msg_str) _DEBUG_MSG_GENERIC(msg_str)
這_DEBUG_MSG_GENERIC
是因為我想:
int
輸入引數為時顯示訊息int
char*
輸入引數為時顯示訊息char*
及其實作:
#define _DEBUG_MSG_GENERIC(strs) \
_Generic( (strs), \
int: _DEBUG_MSG_INT, \
default: _DEBUG_MSG_STR \
)(strs)
現在我想用宏函式和來實作_DEBUG_MSG_INT
和:_DEBUG_MSG_STR
printf
#define _DEBUG_MSG_INT(val) printf("%d\n", val);
#define _DEBUG_MSG_STR(str) printf("%s\n", str);
但我得到的錯誤資訊是:
main.c:14:30: error: ‘_DEBUG_MSG_INT’ undeclared (first use in this function); did you mean ‘DEBUG_MSG’?
14 | int: _DEBUG_MSG_INT, \
| ^~~~~~~~~~~~~~
我該如何解決?
_generic
只支持函式(函式指標)不支持宏函式嗎?
完整代碼
#include <stdio.h>
#define DEBUG_MSG(msg_str) _DEBUG_MSG_GENERIC(msg_str)
#define _DEBUG_MSG_GENERIC(strs) \
_Generic( (strs), \
int: _DEBUG_MSG_INT, \
default: _DEBUG_MSG_STR \
)(strs)
#define _DEBUG_MSG_INT(val) printf("%d\n", val)
#define _DEBUG_MSG_STR(str) printf("%s\n", str)
int main()
{
DEBUG_MSG("str");
DEBUG_MSG(5);
}
uj5u.com熱心網友回復:
問題在于_DEBUG_MSG_INT
和_DEBUG_MSG_STR
都是類似函式的宏,因此只有在它們后面跟著 . 時才會擴展它們()
。
請注意,宏擴展發生在實際 C 編譯之前,因此_Generic
只不過是前處理器階段的通用識別符號。
我建議_Generic
不要使用函式指標的選擇,而是要在printf()
. 嘗試:
#define _DEBUG_MSG_GENERIC(arg) printf( _DEBUG_MSG_FMTSPEC(arg), arg)
#define _DEBUG_MSG_FMTSPEC(arg) \
_Generic( (arg), int: "%d\n", default: "%s\n")
uj5u.com熱心網友回復:
我相信你的問題是因為前處理器只對源代碼進行一次傳遞,所以printf
' 不會被替換。
一個快速的解決方案是將_DEBUG_MSG_INT(val)
和定義_DEBUG_MSG_STR(str)
為真正的函式,如下所示:
void _DEBUG_MSG_INT(int val) {
printf("%d\n", val);
}
void _DEBUG_MSG_STR(char * str) {
printf("%s\n", str);
}
編譯器將優化額外的函式呼叫開銷,并且表現得就像您printf
直接呼叫一樣。
uj5u.com熱心網友回復:
_Generic
不是前處理器操作,不能用于選擇前處理器宏功能。在它的情況下, a 之后的代碼:
必須是 C 運算式(特別是assignment-expression)。
您在這些位置的代碼是_DEBUG_MSG_INT
and _DEBUG_MSG_STR
。這些是前處理器宏名稱。
這些前處理器宏是類似函式的宏。僅當它們后跟 a 時,它們才會被宏替換(
。在您的代碼中,(
它們后面沒有,因此它們不會被替換。
這意味著重新處理后的代碼看起來像int : _DEBUG_MSG_INT,
. 所以編譯器試圖解釋_DEBUG_MSG_INT
為一個運算式。由于_DEBUG_MSG_INT
不是已宣告的識別符號,因此編譯器會報告一個未宣告的錯誤。
總之,您的代碼_Generic( (strs), int: _DEBUG_MSG_INT, default: _DEBUG_MSG_STR )(strs)
嘗試使用預處理后_Generic
選擇來選擇預處理時宏(_DEBUG_MSG_INT
或_DEBUG_MSG_STR
),然后將該宏視為類似函式的宏,并(strs)
在_Generic
. 那根本行不通;后預處理_Generic
不能選擇預處理宏名稱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/470327.html
上一篇:將連接的整數串列拆分為其原始形式
下一篇:動態分配模塊名稱作為別名