在GNU C宏envSet(名称)中,做什么(void)""名字的意思?

时间:2016-09-30 13:21:19

标签: c gcc macros c-preprocessor

我今天遇到了这种语法,无法理解其含义:

// Uses the GNU C statement expression extension
#define envSet(name) ({ \
static int initialised; \
static bool set; \
(void) "" name; \
if (!initialised || !g_cacheEnv) { \
    const char *value = getenv(name); \
    set = value != NULL; \
    initialised = true; \
} \
set; \
})

我无法理解的具体路线是:

(void) "" name; \

有人可以对此有所了解吗?

3 个答案:

答案 0 :(得分:76)

它看起来像是一种静态地确保name是字符串文字而不是其他类型的方法。

如果你(void)"" "hello";,那么它是一个有效的C表达式。

但如果您执行(void)"" 1;之类的操作,则会出现语法错误。

答案 1 :(得分:45)

连接两个连续的字符串文字。据推测,它正在检查name是否是字符串文字。如果不是,编译器将报告错误。

(void)演员会压制警告,例如“声明无效”。

答案 2 :(得分:7)

查看代码,我认为其目的是让它在第一次调用时调用getenv,缓存结果,然后使用缓存的结果而不必调用getenv了。如果getenv与字符串文字一起使用,则所有后续调用将要求相同的环境变量;如果没有什么可以改变那个环境变量,那么它们将返回相同的结果。如果代码被赋予了一个指向随后更改的字符串的指针,则缓存的结果可能对新字符串不正确,因此“”技巧的目的是确保不会发生。

因为可能使用的每个字符串文字都需要有自己的静态变量,所以指定的代码片段不能合理地制作成函数。另一方面,每次重复所需的代码量似乎有点多。此外,如果在代码中的多个位置测试相同的变量,则每个变量最终都会有自己的变量集和环境检查代码。

根据函数的使用方式,它可能比每次调用环境变量时需要测试环境变量的代码快得多,并且它可以在循环内调用的函数中使用而无需提前设置(如果客户端代码称为“高级设置”功能,则应在那里进行名称查找,无需在循环内检查是否已完成查找)。