2017-12-15 98 views
5

Tôi nghĩ câu trả lời là không, và tôi thường không gặp khó khăn khi xem mã nguồn, nhưng tôi hơi mới với C/C++ và không thể tìm thấy nơi mà hằng số này được khai báo.Có cách nào đề cập đến hằng số C không bao giờ được xác định/khai báo không?

Tôi đang tìm kiếm CMD_REQ_REDIS_MGET trong The hiredis-vip client library for Redis. Tôi đã làm một github/google tìm kiếm cho điều này và có kết quả trong chính xác hai tập tin cho năm lần xuất hiện. Tôi cũng đã cố gắng grep cho chuỗi trong mã nguồn.

$ 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) { 

Mã nguồn không chứa bất kỳ tệp nhị phân nào và được cho là độc lập. Nó không bao gồm bất kỳ thư viện nào từ các nguồn bên ngoài có liên quan đến Redis, và vì vậy tôi vừa bị nhầm lẫn trong một vài giờ. Lý do tôi cần biết là tôi đang cố gắng thêm một hằng số khác giống như nó, và tôi tiếp tục nhận được lỗi mà tuyên bố đã không được tìm thấy, vì vậy tôi tự hỏi nếu có bất kỳ ma thuật đen xảy ra ở đây với C mà tôi không biết.

EDIT: Bạn muốn chỉ ra rằng mã này trên thực tế sẽ biên dịch như vậy.

+0

bạn có chắc chắn bạn đang thực hiện grep ở mức phù hợp không? các định nghĩa như vậy thường nằm trong tệp .h. –

+0

@ Jean-FrançoisFabre Tôi đang thực hiện nó ở gốc của git repo –

Trả lời

10

Không thể sử dụng hằng số không được khai báo trước đó. Nhưng trong trường hợp đó, hằng số được tuyên bố, nhưng không phải là tầm thường.

Bạn không tìm thấy chuỗi bất cứ nơi nào (nó phải ở trong tập tin tiêu đề) vì những giá trị được định nghĩa trong một macro từ command.h sử dụng dán thẻ (## điều hành tạo ra nhận dạng mới bằng cách kết hợp những cái cũ):

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

để bạn không bao giờ tìm thấy CMD_ + hậu tố của bạn. Sau đó, bằng một số kỳ diệu (tên macro có lẽ là định nghĩa lại tại một số điểm), sau đây xác định tất cả các yếu tố:

#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)   

macro như vậy là rất hữu ích để tránh sao chép/dán, nhưng là địa ngục khi bạn đang cố gắng tìm đường của bạn trong mã sử dụng grep.

+0

Oh người đàn ông, không biết điều gì đó như thế có thể có thể .. Tôi sẽ nghiên cứu thêm về macro C. Tôi thực sự đánh giá cao bạn nhìn vào điều này cho tôi! (Tôi sẽ chấp nhận ngay khi tôi được phép) –

+2

'##' là toán tử * token-pasteing *. Ký tự '#' đơn (không được sử dụng ở đây) là toán tử * stringifying * (not "* stringing *") (tôi không nghĩ tiêu chuẩn sử dụng thuật ngữ đó). –

+0

@KeithThompson có, tôi không phải là rất tốt với tên. Tôi sẽ chỉnh sửa. –

Các vấn đề liên quan