代码之家  ›  专栏  ›  技术社区  ›  wilhelmtell

宏分辨率地址

c
  •  1
  • wilhelmtell  · 技术社区  · 15 年前
    #define PLAINTEXT_TARGET "plaintext"
    if( strstr(PLAINTEXT_TARGET, optarg) == PLAINTEXT_TARGET )
        /* ... */
    

    C语言是否保证 PLAINTEXT_TARGET 上面编译成一个实例?如果编译器可以生成宏字符串的两个实例,那么上面的条件会产生误导,并且可能是错误的。

    2 回复  |  直到 15 年前
        1
  •  6
  •   sth ACP    15 年前

    宏执行简单的文本替换。预处理器将替换 PLAINTEXT_TARGET 具有 "plaintext" ,然后编译器查看结果并编译该结果。

    所以编译器会看到两个字符串文本,并且不能保证它们不会被单独存储(参见alok对标准中相应引用的答案)。该准则确实具有误导性,更合理的做法是声明 纯文本\目标 作为常量:

    const char* const PLAINTEXT_TARGET = "plaintext";
    
        2
  •  5
  •   Alok Singhal    15 年前

    不,这不是标准的保证。标准中提到了“字符串文字”(6.4.5p6):

    如果这些数组的元素具有 适当的值。

    这些数组 引用的数组 char 从翻译阶段7中的文本字符串创建。

    由于您使用的是宏,编译器看到的代码是:

    if( strstr("plaintext", optarg) == "plaintext" )
    

    什么时候? optarg "plaintext" ,代码减少到

    if("plaintext" == "plaintext")
    

    如上所述,这在C中不保证是正确的。

    所以,你必须使用 strcmp() 而不是检查指针是否相等,或者像在另一个答案中一样,定义一个 char * 用于代替宏的指针。