有没有办法引用从未定义/声明的C常量?

Sid*_*gal 5 c redis hiredis

我认为答案是否定的,我通常不会遇到麻烦的源代码,但我对C/C++稍微有些新意,无法找到声明此常量的位置.

我要寻找CMD_REQ_REDIS_MGET对Redis的的hiredis VIP的客户端库.我做了一个github/google搜索,并在五次出现时得到了两个文件的结果.我也尝试在源代码中grep查找字符串.

$ grep -rnw ./ -e "CMD_REQ_REDIS_MGET"
./command.c:241:    case CMD_REQ_REDIS_MGET:
./command.c:574:                    r->type = CMD_REQ_REDIS_MGET;
./hircluster.c:3257:        if (command->type == CMD_REQ_REDIS_MGET) {
./hircluster.c:3446:        if (command->type == CMD_REQ_REDIS_MGET) {
./hircluster.c:3480:    if (command->type == CMD_REQ_REDIS_MGET) {
Run Code Online (Sandbox Code Playgroud)

源代码不包含任何二进制文件,应该是自包含的.它不包括任何与Redis相关的外部资源库,所以我只是困惑了几个小时.

我需要知道的原因是我正在尝试添加另一个常量,就像它一样,我一直得到错误,声明还没有找到,所以我想知道是否有任何黑魔法在这里发生C我是只是没有意识到.

编辑:想要指出这个代码实际上将按原样编译.

Jea*_*bre 10

不可能使用之前未声明的常量.但在那种情况下,常数被宣布,但不是微不足道的.

您没有在任何地方找到该字符串(它应该在头文件中),因为这些值是在宏中command.h使用标记粘贴定义的(##通过组合旧标记创建新标识符的运算符):

#define DEFINE_ACTION(_name) CMD_##_name,
typedef enum cmd_type {
    CMD_TYPE_CODEC(DEFINE_ACTION)
} cmd_type_t;
#undef DEFINE_ACTION
Run Code Online (Sandbox Code Playgroud)

所以你永远找不到CMD_+你的后缀.然后通过一些魔术(宏名称可能在某些时候重新定义),以下定义所有元素:

#define CMD_TYPE_CODEC(ACTION)                                                                      \
    ACTION( UNKNOWN )                                                                               \
    ACTION( REQ_REDIS_DEL )                    /* redis commands - keys */                            \
    ACTION( REQ_REDIS_EXISTS )                                                                      \
    ACTION( REQ_REDIS_EXPIRE )                                                                      \
    ACTION( REQ_REDIS_EXPIREAT )                                                                    \
    ACTION( REQ_REDIS_PEXPIRE )                                                                     \
    ACTION( REQ_REDIS_PEXPIREAT )                                                                   \
    ACTION( REQ_REDIS_PERSIST )                                                                     \
    ACTION( REQ_REDIS_PTTL )                                                                        \
    ACTION( REQ_REDIS_SORT )                                                                        \
    ACTION( REQ_REDIS_TTL )          
Run Code Online (Sandbox Code Playgroud)

这些宏对于避免复制/粘贴非常有用,但是当你试图在代码中找到自己的方式时,它们就是地狱grep.

  • `##`是*token-pasting*运算符.单个`#`字符(此处未使用)是*stringifying*(不是"*stringing*")运算符(我不认为该标准使用该术语). (2认同)