5

我认为答案是否定的,而且我通常不会在浏览源代码时遇到问题,但是我对 C/C++ 有点陌生,找不到该常量的声明位置。

CMD_REQ_REDIS_MGETThehiredis-vip 客户端库中寻找 Redis。我对此进行了 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) {

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

我需要知道的原因是我正在尝试添加另一个像它一样的常量,并且我不断收到声明尚未找到的错误,所以我想知道这里是否发生了与 C 相关的任何黑魔法只是不知道。

编辑:想指出这段代码实际上会按原样编译。

4

1 回答 1

10

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

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

#define DEFINE_ACTION(_name) CMD_##_name,
typedef enum cmd_type {
    CMD_TYPE_CODEC(DEFINE_ACTION)
} cmd_type_t;
#undef DEFINE_ACTION

所以你永远找不到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 )          

这样的宏对于避免复制/粘贴非常有用,但是当您尝试使用grep.

于 2017-12-15T21:22:04.163 回答