有没有一种方法可以引用从未 defined/declared 的 C 常量?
Is there a way of referring to a C constant that was never defined/declared?
我认为答案是否定的,我通常不会在浏览源代码时遇到麻烦,但我对 C/C++ 有点陌生,找不到声明此常量的位置。
我正在 The hiredis-vip client library for Redis 寻找 CMD_REQ_REDIS_MGET
。我对此进行了 github/google 搜索,结果正好出现在两个文件中,出现了五次。我还尝试在源代码中搜索字符串。
$ 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。
编辑:想指出这段代码实际上会按原样编译。
无法使用之前未声明的常量。但在那种情况下,常量被声明了,但不是平凡的。
您在任何地方都找不到该字符串(它应该在头文件中),因为这些值是在 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 )
这样的宏对于避免 copy/paste 非常有用,但是当您尝试使用 grep
.
在代码中找到自己的方式时,它们就是地狱
我认为答案是否定的,我通常不会在浏览源代码时遇到麻烦,但我对 C/C++ 有点陌生,找不到声明此常量的位置。
我正在 The hiredis-vip client library for Redis 寻找 CMD_REQ_REDIS_MGET
。我对此进行了 github/google 搜索,结果正好出现在两个文件中,出现了五次。我还尝试在源代码中搜索字符串。
$ 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。
编辑:想指出这段代码实际上会按原样编译。
无法使用之前未声明的常量。但在那种情况下,常量被声明了,但不是平凡的。
您在任何地方都找不到该字符串(它应该在头文件中),因为这些值是在 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 )
这样的宏对于避免 copy/paste 非常有用,但是当您尝试使用 grep
.