理解遗留的C++定义

Understanding legacy C++ #define

本文关键字:C++ 定义      更新时间:2023-10-16

我有一些遗留的C++代码,我正在努力更好地理解这些代码。我感到困惑的一个问题是,这句话的意思是:

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

其在头文件中。我可以看到LOG_TRACE_ERROR是代码调用的内容,它向它传递了一个字符串,我可以看到,LOGO_traceError实际上是一个函数,所以我假设这一行将函数的两个不同名称映射在一起?让我困惑的是,为什么参数列表不同(只是LOG_TRACE_ERROR的字符串和LOG_traceError的(_T(FILE),LINE,s))。此外,我在任何地方都找不到定义的_FILE__LINE_或者s,那么程序如何知道它们是什么呢?

_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*

__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);

当然不是你的意思!编写好的宏需要大量的括号,也许还需要使用编译器的非标准功能来确保它们的安全。

__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函数生成。如果翻译时间不是如果可用,则应提供实施规定的有效时间。

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

_FILE__LINE_来自预处理器。如果您不希望用户每次调用Log_traceError(…)时都键入_FILE__LINE_,那么像这样的宏是访问调用Log_traceError(…)的行的这些值的唯一方法。