簡體   English   中英

gcc 預處理器變量到字符串文字

[英]gcc preprocessor variables to string literals

我知道有無數這樣的問題,但我找不到好的答案。 我正在使用 CFLAGS 中定義的預處理器標記編譯源代碼:

-DX=字符串 1 -DY=字符串 2

我正在嘗試在我的 header 文件中創建一個字符串文字,它結合了這兩個值並在我的源代碼中使用它,例如:

printf("%s", COMBINED);

但這不起作用:

 #define _COMBINED(x, y) x ## y
 #define COMBINED _COMBINED(X, Y)

謝謝

你沒有展示你如何調用編譯器的例子,所以我做了一些實驗。 由於逗號(和其他非字母數字字符)會妨礙,歸結為需要傳遞引號作為宏替換文本的分隔符。

所以我認為你真正的問題是如何以等效的方式傳遞字符串:

#define X "hello, "
#define Y "world!"

注意:由於逗號和感嘆號,這里特別困難。

如果包含引號的宏替換文本被傳遞,則 C 源代碼變得簡單。 在 C 中,您無需任何中間運算符即可連接字符串。 "abc" "def""abcdef"相同。

#include <stdio.h>

#define COMBINED X Y

int main(void) {
    printf("%s\n", COMBINED);
}

根據您的實際用例,您甚至可以將其簡化為:

#include <stdio.h>

int main(void) {
    printf("%s\n", X Y);
}

在 Bash 中,您需要像這樣轉義命令行 arguments,例如:

gcc -Wall -pedantic -D 'X="hello, "' -D 'Y="world!"' combine.c -s -O3 -o combine

在 Windows 的 CMD 中,您可以像這樣轉義引號,例如:

gcc -Wall -pedantic -D "X=\"hello, \"" -D "Y=\"world!\"" combine.c -s -O3 -o combine.exe

要將字符串化標記傳遞給串聯宏,您需要一個間接級別。 這意味着您將它傳遞給不同的宏。

#define COMBINED(a, b) (a##b)
#define COMBINE(a, b) COMBINED(a, b)

然后你傳遞 COMBINE 中的參數,在你的情況下,X 和 Y

int main (void)  // best practice is to void-erize non-param-ed functions
{
    printf("%s\n", COMBINE(X,Y));
}

如果你真的想“直接”做,你可以這樣做:

#define DEFAULT_COMBINE COMBINE(X,Y)

並致電:

printf("%s\n", DEFAULT_COMBINE);

現在,讓我們以一個警告結束,因為這也是關於“最佳實踐”的,所以它非常重要,盡管對您來說可能不是那樣,但相信我。 從來沒有,我的意思是永遠不要用下划線開始你自己的預處理器定義或常量。 從來沒有,在任何情況下。 即使你的兄弟在微軟工作或在 Linux kernel 上工作。

在標准和最佳實踐 C 和 C++ 世界中,_COMBINED 宏是非法的。 不,不是無效,這只是意味着你不應該那樣命名。 簡短的版本是以下划線開頭的常量、內部變量和宏是編譯器或內部的。 知道它不是某人設置的東西是一個“標記”。

更新:

要將它們連接起來而不是字符串,您還需要一個中間步驟來進行字符串化:

#define COMBINED(x1, x2)        x1##x2
#define COMBINE_STRINGS(x1, x2) COMBINED(#x1,#x2)
#define COMBINE(x1, x2)         COMBINE_STRINGS(x1, x2)

-DX=string1創建類似於#define X string1的預處理器標記。 到目前為止,還沒有什么能使它成為字符串文字,您需要在類似函數的宏中使用# "stringinizing" 運算符才能做到這一點。

此外,在處理字符串文字時,無需使用帶有##的標記連接,因為在彼此之后鍵入兩個字符串文字意味着它們會被預處理器連接起來。

###一樣,應用它們的任何宏參數都需要在使用運算符之前提前展開,因為這些運算符總是在標記替換之前應用。 所以我們不能這樣做:

#define STRCAT(x,y) #x #y
#define COMBINED STRCAT(X,Y)
// bad: result will BE "XY"

而是使用額外的輔助宏:

#define STR(x) #x
#define STRCAT(x,y) STR(x) STR(y)
#define COMBINED STRCAT(X,Y)
// good: result will be "string1string2"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM