【问题标题】:C/C++ cool macro definitions?C/C++ 很酷的宏定义?
【发布时间】:2010-02-06 09:33:16
【问题描述】:

除了__LINE__ 和__FILE__,还有其他有用的预定义宏,比如__FUNCTION_NAME__?

如果不是,但您知道其他很酷/有用的已定义宏(尤其是用于调试目的),我很想听听它们。

有人询问平台:我在 MacOSX 上使用 gcc/g++。

【问题讨论】:

  • 这将是特定于平台的。你在哪个平台上?
  • @dirkgently: __LINE__ 和 __FILE__ 不是特定于平台的。而且我认为还有一些类似宏的东西(__FUNCTION_NAME__ 不是宏)也是 C 和/或 C++ 标准的一部分。
  • @Omnifarious:是的,我知道这些。因为,他正在寻找其他人,所以我的问题。

标签: c++ c macros


【解决方案1】:

我可以找到以下内容(来自 C99 草案的描述,但我认为它们在 C89 中也可用):

  • __DATE__:预处理翻译单元的翻译日期:一个字符 “Mmm dd yyyy”形式的字符串文字,其中 月份与asctime 函数生成的月份相同,并且 如果值小于 10,则 dd 的第一个字符是空格字符。如果 翻译日期不可用,实现定义的有效日期 应提供。
  • __TIME__:预处理翻译单元的翻译时间:一个字符 格式为“hh:mm:ss”的字符串文字,与生成的时间相同 asctime 函数。如果翻译时间不可用, 应提供实现定义的有效时间。

对于当前函数名,C99 定义了__func__,但__FUNCTION_NAME__ 不是标准宏。另外__func__不是宏,是保留标识符(6.4.2.2p1):

标识符__func__ 应由翻译器隐式声明,就好像, 紧跟每个函数定义的左大括号,声明

static const char __func__[] = "函数名";

出现了,其中 function-name 是词法封闭函数的名称。

如果您正在寻找特定于平台的东西:这里是gcc's common predefined macros 的列表。我喜欢__COUNTER__,它是一个从0 开始的唯一的、连续的整数。我认为__INCLUDE_LEVEL__ 也很酷,但我不确定我是否能想到它的用途:-)。

【讨论】:

  • __DATE__ 和 __TIME__ 在 C++ 中也可用。
  • #include 递归可以被__INCLUDE_LEVEL__ 终止。
  • @Potatoswatter:是的,我想过,但无论如何编译器都会为我检测到无限递归。不过,你说的还是有用的。
【解决方案2】:

通用 GCC macros.

【讨论】:

    【解决方案3】:

    您要查找的特定名称称为__func__,但它并不完全是一个宏,因为它的含义会根据看到的位置而变化。不过,它很有用,而且看起来确实像一个宏。

    目前我最喜欢的宏是__STDC_VERSION__,因为它可以让我这样做:

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    # define inline
    # define register
    # if __GNUC__ >= 2 || _MSC_VER >= 1300
    #  define __func__ __FUNCTION__
    # else
    #  define __func__ "<unknown>"
    # endif
    #endif
    

    现在您可以使用 C99 关键字 inline、register 和 __func__ 来声明事物,而不必担心您使用的编译器是否支持 C99 功能!实际上,inline 的位更复杂,因为一些编译器定义了__inline 和其他类似的愚蠢,但你明白了一般的想法。

    此外,可以在here 找到一个有用的用于识别编译器、操作系统和架构的预定义宏列表。

    【讨论】:

    • 克里斯,__LINE__ 的含义也会随着它在哪里出现而变化,因此名称的扩展取决于它在源中的位置并不一定意味着它不能是宏。当然,__func__ 不是宏是对的。
    【解决方案4】:

    此 MSDN 页面列出了 complete set of predefined macros for MSVC。

    我个人认为__COUNTER__ 很酷。

    【讨论】:

      【解决方案5】:

      如果我没记错的话,__func__ 不是宏。它基本上是在使用它的任何函数的顶部声明为static const char * const __func__ = "function_name"; 的名称。您应该使用__func__ 而不是__FUNCTION_NAME__ 之类的东西,因为__func__ 是C99 标准的一部分。

      【讨论】:

      • 你误会了:C99 结构被称为__func__。
      • __FUNCTION__ 是 MSVC 上的宏。
      • 另外,关于我的回答,如果您的编译器不支持 C99,在 GCC 下,如果 __GNUC__ 宏的值大于 2(或者显然如果您使用的是 MSVC),您可以#define __func__ __FUNCTION__ 得到同样的结果。
      【解决方案6】:

      我倾向于制作单行条件。

      #define ZZ_Slash_for_commenting_out /
      #ifdef _DEBUG
      #define D_B_O std::cerr
      #else
      #define D_B_O ZZ_Slash_for_commenting_out/
      #endif
          D_B_O << "Your thing here" << endl;
      

      【讨论】:

      • 如果这行得通,那就是生成评论表单宏的绝妙技巧!
      【解决方案7】:

      您可以像这样从 gcc 中获取所有常规的预定义宏:

      $ gcc -dM -E - < /dev/null
      

      当然这不包括特殊的宏,例如:

      __FILE__, __LINE__ and __FUNCTION__.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-04
        • 1970-01-01
        • 2012-05-12
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 2018-11-12
        相关资源
        最近更新 更多