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

如何测试预处理器符号是否已定义但没有值?

  •  30
  • galets  · 技术社区  · 14 年前

    #define MYVARIABLE
    #if !defined(MYVARIABLE) || #MYVARIABLE == ""
    ... blablabla ...
    #endif
    

    编辑: 我这样做的原因是因为我正在进行的项目应该从环境中获取一个字符串 /DMYSTR=$(MYENVSTR)

    9 回复  |  直到 8 年前
        1
  •  45
  •   Community Reversed Engineer    4 年前

    #define DO_EXPAND(VAL)  VAL ## 1
    #define EXPAND(VAL)     DO_EXPAND(VAL)
    
    #if !defined(MYVARIABLE) || (EXPAND(MYVARIABLE) == 1)
    
    Only here if MYVARIABLE is not defined
    OR MYVARIABLE is the empty string
    
    #endif
    

    g++ -DMYVARIABLE <file>
    

    这里MYVARIABLE的值是1

    g++ -DMYVARIABLE= <file>
    

    这里MYVARIABLE的值是空字符串

    报价问题解决:

    #define DO_QUOTE(X)        #X
    #define QUOTE(X)           DO_QUOTE(X)
    
    #define MY_QUOTED_VAR      QUOTE(MYVARIABLE)
    
    std::string x = MY_QUOTED_VAR;
    std::string p = QUOTE(MYVARIABLE);
    
        2
  •  13
  •   Starx    12 年前

    我还没有看到这个问题的解决方案,但很惊讶它没有被普遍使用

    #define TRACE
    #if defined(TRACE) && (7-TRACE-7 == 14)
    #error TRACE is defined with no value
    #endif
    
        3
  •  12
  •   Georg Fritzsche    14 年前

    如果用户忘记定义这个字符串,我想确保项目无法编译。

    虽然我会在上一个构建步骤中检查这一点,但您可以在编译时执行此操作。为了简洁起见,使用Boost:

    #define A "a"
    #define B
    BOOST_STATIC_ASSERT(sizeof(BOOST_STRINGIZE(A)) > 1); // succeeds
    BOOST_STATIC_ASSERT(sizeof(BOOST_STRINGIZE(B)) > 1); // fails
    
        4
  •  7
  •   stm rodrigo    5 年前

    迈赫拉德的答案必须扩大,以使其发挥作用。还有他的评论

    /*此处未定义MYVARI(A)BLE*/

    不正确;要测试未定义的变量,有一个简单的测试 #ifndef MYVARIABLE .

    #ifndef MYVARIABLE
        /* MYVARIABLE is undefined here */
    #elif ~(~MYVARIABLE + 0) == 0 && ~(~MYVARIABLE + 1) == 1
        /* MYVARIABLE is defined with no value here */
    #else
        /* MYVARIABLE is defined here */
    #endif
    

    #elif ~(~MYVARIABLE + 0) == 0 && ~(~MYVARIABLE + 1) == 1 工作如下:

    • MYVARIABLE ~(~+0) == 0 && ~(~+1) == 1 ,这是可行的 0==0 && 1==1
    • 我的变量 定义为一个数值,例如n,则扩展为 ~(~n+0)==0 && ~(~n+1)==1 && ,表达式 ~(~n+0)==0 计算结果为 n==0 n==0 ,右侧计算为 ~(~0+1)==1 ,其中~0为-1到 ~(-1+1)==1 ~0==1 最后呢 -1==1 ,显然是假的。
    • 什么时候? 我的变量

    我的完整测试代码(另存为test.c文件):

    #include <stdio.h>
    
    int main() {
        printf("MYVARIABLE is "
    #ifndef MYVARIABLE
         "undefined"
    #elif ~(~MYVARIABLE + 0) == 0 && ~(~MYVARIABLE + 1) == 1
         "defined without a value"
    #else 
         "defined with this value : %i", MYVARIABLE
    #endif
        );
        printf("\n");
    }
    

    cpp公司 您可以通过实验查看生成了什么代码:

    # undefined
    cpp test.c
    #defined without a value
    cpp -DMYVARIABLE= test.c
    #defined wit an implicit value 1
    cpp -DMYVARIABLE test.c
    #defined wit an explicit value 1
    cpp -DMYVARIABLE=1 test.c
    #defined wit an explicit value a
    cpp -DMYVARIABLE=a test.c
    

    $ gcc -o test test.c ; ./test
    MYVARIABLE is undefined
    $ gcc -DMYVARIABLE= -o test test.c ; ./test
    MYVARIABLE is defined without a value
    $ gcc -DMYVARIABLE -o test test.c ; ./test
    MYVARIABLE is defined with this value : 1
    $ gcc -DMYVARIABLE=1 -o test test.c ; ./test
    MYVARIABLE is defined with this value : 1
    $ gcc -DMYVARIABLE=a -o test test.c ; ./test
    test.c: In function ‘main’:
    <command-line>:0:12: error: ‘a’ undeclared (first use in this function)
    ...
    

        5
  •  3
  •   mister why    11 年前

    你可以用 BOOST_PP_IS_EMPTY

    #include <boost/preprocessor/facilities/is_empty.hpp>
    
    #define MYVARIABLE
    #if !defined(MYVARIABLE) || !BOOST_PP_IS_EMPTY(MYVARIABLE)
        // ... blablabla ...
    #endif
    

    这对我来说是个好办法。我要补充的是,这个宏没有文档记录,所以要小心使用。

    资料来源: preprocessor-missing-IS-EMPTY-documentation

        6
  •  3
  •   harper    9 年前

        7
  •  2
  •   Reinderien    14 年前

    我不认为这是可以做到的。尽管如此,我认为没有必要。当你做预处理器的时候 #define 符号时,应建立一个约定,将其定义为1或0,以便在中使用 #if ,或将其留空。

        8
  •  1
  •   Community Reversed Engineer    4 年前

    您可以使用无需额外宏的hack:

    #if ~(~MYVARIABLE + 0) == 0 && ~(~MYVARIABLE + 1) == 1
    /* MYVARIBLE is undefined here */
    #endif
    
        9
  •  0
  •   Kris Morness    6 年前

    #if MYVARIABLE==0 我的答案必须是至少30个字符,这样就可以了!

        10
  •  0
  •   Dr. Alex RE    3 年前

    另一方面,我们通常要检查宏 未定义 ,是 :

    #if ! defined(MYVARIABLE)
      // UNDEFINED:  MYVARIABLE is undefined
    #elif ~ MYVARIABLE + 1
      // TRUE:       MYVARIABLE is defined and is empty or nonzero
    #else
      // FALSE:      MYVARIABLE is defined and is zero
    #endif
    

    • MYVARIABLE 是空的吗 ~ + 1 计算结果为非零(true)
    • 我的变量 1 )那么 ~ 1 + 1 计算结果为非零(true)
    • 如果 我的变量 那么是零 ~ 0 + 1

    此方法适用于的任何整数值 我的变量 . 什么时候? 我的变量

    请注意,如果您只想检查 启用编译时标志时(已定义且为空或非零):

    #if defined(MYVARIABLE) && ~ MYVARIABLE + 1
      // the MYVARIABLE feature is enabled
    #endif