簡體   English   中英

是否可以定義另一個預處理器指令?

[英]Is it possible to define another preprocessor directive?

我一直在尋找代碼高爾夫,並有一個想法嘗試這個代碼:

#define D #define添加此行后,一切正常,但我將其擴展為:

#define D #define
D VALUE

在這里我得到了5個編譯錯誤。 如果我把D改成#define一切都很好,有人可以解釋,為什么這段代碼是非法的?

注意:我使用的是VS2008編譯器。

編輯:經過一些答案,我看到我需要給出編譯錯誤列表:

  1. 錯誤C2121:'#':無效字符:可能是宏擴展的結果
  2. 錯誤C2146:語法錯誤:缺少';' 在標識符“VALUE”之前
  3. 錯誤C4430:缺少類型說明符 - 假定為int。 注意:C ++不支持default-int
  4. 錯誤C2144:語法錯誤:'void'前面應加';'
  5. 錯誤C4430:缺少類型說明符 - 假定為int。 注意:C ++不支持default-int

第一個錯誤顯示D不僅僅是define ,還包括#

C 2011(N1570)6.10.3.4 3:“得到的完全宏替換的預處理標記序列不會被處理為預處理指令,即使它類似於一個......”

C ++ 2010(N3092)16.3.4 [cpp.rescan] 3具有完全相同的文本。

看起來您的預處理器正在進行您想要的替換,但您可能無法獲得所需的行為 - 預處理器通常只是單個傳遞操作。 示例(使用clang,但您應該能夠使用適當的VS2008標志重現):

$ cat example.c 
#define D #define
D VALUE
$ cc -P -E example.c 

 #define VALUE

#define VALUE直接進入編譯器,編譯器不知道如何處理它 - 畢竟它是一個預處理器指令。 Clang的錯誤,供參考,與您的相似:

$ cc -c example.c 
example.c:2:1: error: expected identifier or '('
D VALUE
^
example.c:1:11: note: expanded from macro 'D'
#define D #define
          ^
1 error generated.

此代碼是非法的,因為語言規范說它是非法的。 根據C和C ++預處理器規范,使用預處理器構建的任何代碼都不會被解釋為另一個預處理器指令。 簡而言之,您無法使用預處理器構建預處理程序指令。 期。

(另外,您無法使用預處理器構建注釋。)

這是行不通的,因為預處理是在一次通過中執行的。 例如,考慮下一個代碼:

#define MYDEFINEWEIRD #define

MYDEFINEWEIRD N 6

int main() {

  return 0;
}

預處理后,您的代碼將如下所示:

 #define N 6
int main() {

  return 0;
}

和“#define”不是C或C ++上的有效語法。 此外,由於不會處理生成的預處理程序指令,因此它不會解析代碼中對“N”宏的后續引用。

只是為了好玩,您可以使用g ++ / gcc從命令行調用預處理器兩次。 考慮下一個代碼(define.cpp):

#include <iostream>

#define MYDEFINEWEIRD #define
MYDEFINEWEIRD N 6

using namespace std;

int main() {
  cout << N << endl;
  return 0;
}

然后你可以這樣做:

$ g++ -E define.cpp | g++ -o define -x c++ - && ./define

並將輸出:

6

預處理器眼中的代碼行是預處理器語句(因此沒有對它們進行任何替換)或正常的文本語句(並且已經完成替換)。 你不能同時擁有一個,所以一旦你'D'被替換,它只會查看是否還有更多的宏需要替換。 由於沒有,它只是在C ++代碼中留下'#define',然后C ++編譯器在看到它時會出錯(因為'#define'不是有效的C ++代碼)。

所以更多地表明我的觀點,這是預處理器的無效代碼:

#define D define
#D value

因為預處理器不對預處理器語句進行任何宏替換,並且“#D”不是可識別的預處理器命令。 和這個:

#define D #define
D value

結果在這個C ++代碼中:

#define value

這是無效的,因為預處理器已經完成運行。

查看16 [cpp]段1中的語法, 替換列表pp-tokens組成,其中可包括生產#no-directive ,該指令在同一段的第2段中描述為

非指令不應以列表中出現的任何指令名開頭。

也就是說,某種形式

#define NAME # define

恰好是非法的! 另請注意,此上下文中的# 不會將下一個單詞轉換為字符串: #只會在#函數樣式宏中緊跟一個宏參數名后發生。

暫無
暫無

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

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