簡體   English   中英

預處理器無效的預處理器令牌錯誤

[英]Preprocessor invalid preprocessor token error

我正在讀書學習C。 該書中的以下示例代碼給出了gcc(Debian 4.7.2-4)4.7.2的預處理器錯誤。 錯誤是:

file.c:在函數“ main”中:
file.c:16:14:錯誤:令牌““我知道C語言。\\ n”“在預處理程序表達式中無效
file.c:20:14:錯誤:令牌““我知道BASIC。\\ n”“在預處理程序表達式中無效

代碼是:

#include <stdio.h>

#define C_LANG    'C'
#define B_LANG    'B'
#define NO_ERROR  0

int main(void)
{
   #if C_LANG == 'C' && B_LANG == 'B'
     #undef C_LANG
     #define C_LANG "I know the C language.\n"
     #undef B_LANG
     #define B_LANG "I know BASIC.\n"
     printf("%s%s", C_LANG, B_LANG);
   #elif C_LANG == 'C'
     #undef C_LANG
     #define C_LANG "I only know C language.\n"
     printf("%s", C_LANG);
   #elif B_LANG == 'B'
     #undef B_LANG
     #define B_LANG "I only know BASIC.\n"
     printf("%s", B_LANG);
   #else
     printf("I don't know C or BASIC.\n");
   #endif

   return NO_ERROR;
}

gcc預處理器不能正確執行此操作嗎?還是需要更改的代碼有問題?

正如@cebarth所指出的那樣,問題在於,在第一個#if重新定義C_LANGB_LANG之后, #elif子句失敗,因為擴展是:

   #elif "I know the C language.\n" == 'C'
   /*...*/
   #elif "I know BASIC.\n" == 'B'

C標准對#if#elif (C99 6.10.1)進行了說明:

表單的預處理指令
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
檢查控制常量表達式的計算結果是否為非零。

沒有提到由於較早的檢查成功而沒有對表達式求值。

解決此問題的一種方法是在printf()之后重新定義它們。

     #undef C_LANG
     #define C_LANG "I know the C language.\n"
     #undef B_LANG
     #define B_LANG "I know BASIC.\n"
     printf("%s%s", C_LANG, B_LANG);
     #undef C_LANG
     #define C_LANG 'C'
     #undef B_LANG
     #define B_LANG 'B'

解決此問題的另一種方法是顯式使用#else而不是#elif

   #if C_LANG == 'C' && B_LANG == 'B'
     #undef C_LANG
     #define C_LANG "I know the C language.\n"
     #undef B_LANG
     #define B_LANG "I know BASIC.\n"
     fprintf(stdout, "%s%s", C_LANG, B_LANG);
   #else
     #if C_LANG == 'C'
       #undef C_LANG
       #define C_LANG "I only know C language.\n"
       printf("%s", C_LANG);
     #elif B_LANG == 'B'
       #undef B_LANG
       #define B_LANG "I only know BASIC.\n"
       printf("%s", B_LANG);
     #else
       printf("I don't know C or BASIC.\n");
     #endif
   #endif
#include <stdio.h>

#define C_LANG    'C'
#define B_LANG    'B'
#define NO_ERROR  0

int main(void)
{
   #if C_LANG == 'C' && B_LANG == 'B'
     #define C_LANG_VALUE "I know the C language.\n"
     #define B_LANG_VALUE "I know BASIC.\n"
     printf("%s%s", C_LANG_VALUE, B_LANG_VALUE);
   #elif C_LANG == 'C'
     #define C_LANG_VALUE "I only know C language.\n"
     printf("%s", C_LANG_VALUE);
   #elif B_LANG == 'B'
     #define B_LANG_VALUE "I only know BASIC.\n"
     printf("%s", B_LANG_VALUE);
   #else
     printf("I don't know C or BASIC.\n");
   #endif

   return NO_ERROR;
}

通常,混合預處理程序代碼和非預處理程序代碼不是一個好主意,因為很難遵循執行路徑(大多數情況下)。

對於您的特定示例,您可以采取一些措施來簡化操作:

#define C_LANG 
#define B_LANG  
#define NO_ERROR

#if defined(C_LANG) || defined (B_LANG)
   #if defined(C_LANG)
       printf ("I know the C language.\n");
   #else
       printf ("I know the BASIC language.\n");
   #endif
#else
   printf("I don't know C or BASIC.\n");
#endif

無需使用宏定義。 您只需在C_LANG或B_LANG中添加一個字符即可更改打印出的內容:

#define C_LANGn
#define B_LANGn 

這樣,代碼更具可讀性。

暫無
暫無

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

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