【问题标题】:Understanding legacy C++ #define了解旧版 C++ #define
【发布时间】:2012-03-27 12:56:27
【问题描述】:

我有一些遗留的 C++ 代码,我正试图更好地理解它们。我感到困惑的一个问题是这样一行:

#define LOG_TRACE_ERROR(s)  LOG_traceError( _T(__FILE__), __LINE__, s )

在头文件中。我可以看到 LOG_TRACE_ERROR 是代码正在调用的内容并将其传递给一个字符串,并且我可以看到 LOG_traceError 是一个实际完成工作的函数,所以我假设这一行将函数的两个不同名称映射在一起?令我困惑的是为什么参数列表不同(LOG_TRACE_ERROR 只是一个字符串,LOG_traceError 是 (_T(FILE), LINE, s))。我也找不到在任何地方定义的 _FILE__LINE_s那么程序如何知道它们是什么?

【问题讨论】:

    标签: c++ legacy


    【解决方案1】:

    _FILE_ 扩展为文件名。

    _LINE_ 扩展为行号。

    s 是您传递给宏的参数。

    当你写作时:

    //file.cpp
    //...
    LOG_TRACE_ERROR("error here"); //line 13
    

    预处理器会将其转换为:

    //file.cpp
    //...
    LOG_traceError( _T("file.cpp"), "13", "error here" );
    

    _T() 是一个与 UNICODE 相关的宏。如果在 unicode 环境中,它会将您的字符串转换为 wchar_t*

    【讨论】:

      【解决方案2】:

      __FILE____LINE__ 是编译器定义的内部值,它们会扩展到正在编译的文件和当前行(宏正在被扩展)。

      使用宏,当你说(例如):

      #define YOUR_MACRO(param1, param2) some_function_here(param1 + param2, 0)
      

      您正在定义一个带有两个参数param1param2 的宏(在您的情况下,只有一个参数,它的名称是s)。然后,您可以在您认为合适的任何情况下在宏定义中使用这些参数。

      注意:在编写宏时应该小心,因为它们可能会很棘手。在上面的例子中,如果你调用:

      YOUR_MACRO(x << 2, y << 2)
      

      它会扩展为:

      some_function_here(x << 2 + y << 2, 0);
      

      实际上是:

      some_function_here(x << (2 + y) << 2, 0);
      

      当然不是你的意思!编写好的宏涉及大量括号,并且可能使用编译器的非标准特性来确保它们的安全。

      【讨论】:

        【解决方案3】:

        __FILE____LINE__ 以及 __DATE____TIME__ 和其他一些是在 ISO/IEC 9899:1990 (C89) 标准中首次为 C 编程语言定义的预定义宏, §6.10.8 节:

        6.10.8 预定义的宏名称

        以下宏名称应由实现定义:

        __DATE__ 预处理翻译单元的翻译日期:一个字符 “Mmm dd yyyy”形式的字符串文字,其中月份的名称与 由 asctime 生成的那些 函数,并且 dd 的第一个字符是空格字符,如果 值小于 10。如果翻译日期不可用,则 应提供实施定义的有效日期。

        __FILE__ 当前源文件的假定名称(字符串文字)。

        __LINE__ 当前源行的假定行号(在当前源文件中)(一个整数常量)。

        __STDC__ 整数常量 1,用于指示符合标准的实现。

        __STDC_HOSTED__ 如果实现是托管实现,则为整数常量 1;如果不是,则为整数常量 0。

        __STDC_VERSION__ 整数常量 199901L。

        __TIME__ 预处理翻译单元的翻译时间:与时间一样的“hh:mm:ss”形式的字符串文字 由 asctime 函数生成。如果翻译时间不 可用,应提供实现定义的有效时间。

        与所有宏一样,它们在编译代码之前由预处理器进行评估。

        【讨论】:

          【解决方案4】:

          _FILE__LINE_ 来自您的预处理器。如果您不希望用户在每次调用 LOG_traceError(.. .).

          【讨论】:

            猜你喜欢
            • 2018-01-21
            • 1970-01-01
            • 2014-07-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多