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

OMG*_*chy 65 c macros gcc 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; \
})
Run Code Online (Sandbox Code Playgroud)

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

(void) "" name; \
Run Code Online (Sandbox Code Playgroud)

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

Lun*_*din 76

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

如果这样做,(void)"" "hello";那么它是一个有效的C表达式.

但是如果你做的话(void)"" 1;就会出现语法错误.

  • 值得一提的是,在(无效)`之前加上"未使用"(或其他)警告. (32认同)
  • 也许值得一提的是,这使用了相邻字符串文字由预处理器连接的事实,因此如果右侧(`name`)不是字符串文字,它将无法工作.强制转换应用于连接的结果,而不是"""本身.编辑:哦,没有看到其他答案.嘿. (9认同)

mil*_*bug 45

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

(void) 演员会压制警告,如"声明无效".

  • @OMGtechy一般来说,你可以自由地接受任何答案,而不是找借口.只是说...... :) (2认同)

sup*_*cat 7

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

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

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