【问题标题】:"#define" vs "#define 1"“#define”与“#define 1”
【发布时间】:2020-06-28 03:00:59
【问题描述】:

1 在以下示例中似乎没有必要(并且可能具有误导性),但在用于检查 #ifdefs 时,我已经多次看到这一点:

#ifndef __NEWLIB_H__

#define __NEWLIB_H__ 1

使用上述内容与普通的#define __NEWLIB_H__ 有区别或原因吗?

【问题讨论】:

  • 这并没有解决问题,但是包含两个连续下划线 (__NEWLIB_H__) 的名称和以下划线后跟一个大写字母的名称保留供实现使用。不要在你的代码中使用它们。
  • @PeteBecker 是的,这段代码实际上来自(或“是”)实现。
  • @abc 要清楚,Pete 所说的“实现”是指 C++ 语言的实现。不实现您的功能(除非您正在编写标准库)。
  • @eerorika Newlib 是嵌入式目标标准库的实现。该文件来自 GNU Arm Embedded 工具链。
  • @abc 啊。那么它确实是允许的,而且实际上有必要使用一个保留的标识符:)

标签: c++ c include c-preprocessor


【解决方案1】:

1 为真,因此您可以在#if 测试中使用宏。这对于头球后卫来说通常不是很有用,但它肯定不会受到伤害。对于其他可能在布尔表达式中测试的宏,真正的值绝对有用。

有些人只是喜欢一致性。如果您将-D TESTME 放在命令行上,这就是gcc 默认选择的定义。

然而,

#define __NEWLIB_H__ 1

除非它在标准库的实现中,否则并不酷,因为以两个下划线(或下划线和大写字母)开头的名称保留供实现使用,并且永远不应该在可移植应用程序中使用。

【讨论】:

  • 好的,是的,cmets 中有人发表了类似的评论,但在这种情况下,它实际上是标准库的实现。
  • 介意指定-DTESTME 的含义吗?令人惊讶的是,我在 ~1000 页的 gcc 文档或互联网上找不到它。
  • @abc:它的意思是“预定义宏TESTME”(在这种情况下为默认值,但通常提供显式值)。用于将配置设置传递到编译中。 (gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/…)
【解决方案2】:

当纯粹用作#include守卫时,两者没有区别

#ifndef __NEWLIB_H__
#define __NEWLIB_H__

#ifndef __NEWLIB_H__
#define __NEWLIB_H__ 1

但是,总的来说,是有区别的。

编译器错误

#ifndef ABCD
#define ABCD
#endif

int main()
{
#if defined(ABCD) && (ABCD == 1)
   std::cout << "ABCD is 1\n";
#else
   std::cout << "ABCD is not 1\n";
#endif
}

输出字符串“ABCD为1”

#ifndef ABCD
#define ABCD 1
#endif

int main()
{
#if defined(ABCD) && (ABCD == 1)
   std::cout << "ABCD is 1\n";
#else
   std::cout << "ABCD is not 1\n";
#endif
}

输出字符串“ABCD is not 1”

#ifndef ABCD
#define ABCD 10
#endif

int main()
{
#if defined(ABCD) && (ABCD == 1)
   std::cout << "ABCD is 1\n";
#else
   std::cout << "ABCD is not 1\n";
#endif
}

【讨论】:

    【解决方案3】:

    #define 本身是will replace the symbol with nothing

    另一方面,#define 1,正如您所说的那样,将在文件中的任何位置将符号替换为 1。因此,例如,以下代码:

    #include <iostream>
    
    #define EXAMPLE "hello"
    
    int main()
    {
        std::cout << EXAMPLE;
    
        return 0;
    }
    

    打印

    hello
    

    这是因为这里的EXAMPLE"hello"替换了,使得print语句相当于:

    std::cout << "hello";
    

    如果我们将#define 语句改为这样:

    #define EXAMPLE
    

    This will give a compile error:

    main.cpp: In function ‘int main()’:
    main.cpp:15:25: error: expected primary-expression before ‘;’ token
         std::cout << EXAMPLE;
    

    至于为什么你会使用#define 的第二种形式,这是因为你可以使用另一个名为#ifdef 的处理器指令:

    #include <iostream>
    
    #define EXAMPLE
    
    int main()
    {
    #ifdef EXAMPLE
        std::cout << "EXAMPLE defined.";
    #endif
    
        return 0;
    }
    

    这将打印:

    EXAMPLE defined.
    

    因为#ifdef(及其相对的#ifndef)只要求定义符号,所以我们不需要给它一个值。它只需要在那里工作。

    你看到这种东西的一个常见地方是header guards(这可能就是你所看到的)。您也可以通过platform identification 甚至to determine whether the compiler is using C++ or not 看到它。

    【讨论】:

      猜你喜欢
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 2011-01-27
      相关资源
      最近更新 更多