Tôi muốn viết macro để viết chuỗi, sử dụng tối ưu hóa thời gian biên dịch để biết độ dài của chuỗi ký tự. Nhưng tôi cần phát hiện sự lạm dụng, sử dụng con trỏ.Cách phân biệt chuỗi không đổi từ char * trong macro C
Đây là những gì tôi muốn nói:
void transmit(const char *data, int length);
#define tx_string(x) transmit((x), sizeof(x) -1)
void func(char *badmsg) {
tx_string("GO"); // ok
tx_string(badmsg); // not OK
}
Với cuộc gọi thứ hai, kích thước sẽ là vô nghĩa (sizeof một con trỏ).
Tôi muốn tạo ra lỗi biên dịch khi tôi cố gắng sử dụng tx_string trên bất kỳ thứ gì khác ngoài chuỗi ký tự. Điều này đang sử dụng gcc; có một số điều gcc tôi có thể sử dụng để làm điều này?
Chỉnh sửa: Tôi làm việc với bộ đệm dữ liệu có thể chứa null hoặc không bị chấm dứt bằng giá trị rỗng. Tôi thực sự muốn ngăn chặn con trỏ được sử dụng cho điều này, và ngăn chặn thời gian chạy strlen()
sử dụng.
Chỉnh sửa 2:
Đây là ví dụ gây ra sự cố. Tôi sẽ phát minh ra một giao thức tưởng tượng nơi tôi phải nói với một vi điều khiển 16 bit một địa chỉ bằng lệnh GO theo sau là một địa chỉ dưới dạng nguyên 16 bit (hai ký tự 8 bit) và tôi muốn đi từ địa chỉ 0.
#define GOSEQ "GO\000\000"
void func(void) {
char *bad = GOSEQ;
tx_string(GOSEQ); // ok, sends 4 bytes: GO and two zero bytes
tx_string(bad); // bad, using runtime strlen sends two characters "GO"
}
Tôi cảm thấy chắc chắn phải có một số loại kiểm tra nội trang gcc cho việc này. Tôi thấy các nguồn nhân Linux sử dụng các thủ thuật phân biệt thời gian biên dịch như thế này rất nhiều .. nhưng không thể đặt bàn tay của tôi lên một cách cụ thể một cách nhanh chóng.
Cho đến nay ý tưởng "Lập trình viên Windows" có vẻ tốt, nhưng lỗi biên dịch có ý nghĩa hơn sẽ là tiền thưởng.
Điều này giống như một người chiến thắng! Tôi sẽ chỉ chờ một chút trong trường hợp ai đó đến với bài kiểm tra nội trang hoàn hảo hoặc một cái gì đó. – blueshift