glibc 源代码中的 L_ 宏

L_ macro in glibc source code

我正在阅读 glibc 的源代码,我发现它有两个同名的宏
这个在第105行
#define L_(Str) L##Str
这是第 130
#define L_(Str) Str

这些宏的真正含义是什么?用法仅用于比较两个字符
例如在第 494 行,您可以看到它用于比较 *f 和 '$'
之间的字符值 if(*f == L_('$'))。如果我们想比较这两个字符,我们可以直接比较它们,而不是通过宏来引导它们?另外,第 105 行宏的用例是什么?

它在宏参数前加上 L 前缀(wchar_t 文字 - 它使用尽可能大的数据类型来表示每个可能的字符代码点,而不是 char 类型中的正常 8 位)如果你正在编译 wscanf函数的版本(第 105 行)。否则它只是按原样传递参数(第 130 行)。

##是c预处理器中的字符串连接运算符,L##'$'最终会扩展为L'$'。

总结一下:它用于编译两个互斥版本的 vscanf 函数 - 一个在 wchar_t 上运行,一个在 char.

上运行

查看此答案:What exactly is the L prefix in C++?

让我们阅读代码。 (我不知道它的作用,但我可以阅读代码)

首先,为什么你指出的有两个定义?其中一个在定义 COMPILE_WSCANF 时使用,另一个在其他情况下使用。什么是 COMPILE_WSCANF?如果我们进一步查看文件,我们可以看到定义了不同的函数。当定义 COMPILE_WSCANF 时,我们最终得到的函数(通过各种宏)是 vfwscanf 否则我们得到 vfscanf。这很好地表明该文件可能用于编译两种不同的函数,一种用于普通字符,一种用于宽字符。最有可能的是,构建系统使用不同的定义编译文件两次。这样做是为了让我们不必将同一个文件写入两次,因为普通字符函数和宽字符函数都非常相似。

我很确定这意味着这个宏与宽字符有关。如果我们看一下它的使用方式,它用于在比较等中包装字符常量。当'x'为普通字符常量时,L'x'为表示相同字符的宽字符常量(wchar_t类型)。

所以宏是用来把字符常量包裹在代码里面的,这样我们就不用#ifdef COMPILE_WSCANF.