Cú pháp “[0… 255] =” này trong C là gì?


108

Đề cập đến js0n.c

Cú pháp mã như sau:

    static void *gostruct[] =
    {
        [0 ... 255] = &&l_bad,
        ['\t'] = &&l_loop, [' '] = &&l_loop, ['\r'] = &&l_loop, ['\n'] = &&l_loop,
        ['"'] = &&l_qup,
        [':'] = &&l_loop, [','] = &&l_loop,
        ['['] = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
        ['{'] = &&l_up, ['}'] = &&l_down,
        ['-'] = &&l_bare, [48 ... 57] = &&l_bare, // 0-9
        [65 ... 90] = &&l_bare, // A-Z
        [97 ... 122] = &&l_bare // a-z
    };

........
.......

l_bad:
    *vlen = cur - json; // where error'd
    return 0;

........
........

Bất cứ ai có thể giải thích những gì đang được thực hiện ở đây? Cú pháp [0 ... 255]&&l_badlàm gì ở đây?

Câu trả lời:


109

... là một phần mở rộng được cung cấp bởi GCC

https://gcc.gnu.org/onlineocs/gcc/Designated-Inits.html#Designated-Inits

Để khởi tạo một dải phần tử có cùng giá trị, hãy viết [first ... last] = value. Đây là một phần mở rộng GNU. Ví dụ,

 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

&& là một phần mở rộng khác

https://gcc.gnu.org/onlineocs/gcc/Labels-as-Values.html#Labels-as-Values

Bạn có thể lấy địa chỉ của nhãn được xác định trong hàm hiện tại (hoặc một hàm chứa) bằng toán tử một ngôi &&. Giá trị có loại void *. Giá trị này là một hằng số và có thể được sử dụng ở bất cứ nơi nào một hằng số thuộc loại đó là hợp lệ. Ví dụ:

 void *ptr;
 /* ... */
 ptr = &&foo;

22
tập hợp tất cả lại với nhau rằng mã đang tạo một bảng nhảy sử dụng các giá trị ascii cho các chỉ số, có lẽ là cho trình phân tích cú pháp.
ratchet freak

1
Cụ thể là một trình phân tích cú pháp JSON, theo như tôi có thể nói.
Kevin

1
@KevinM có lý. Đã khi nào việc áp dụng toán tử address-of (&) cho một rvalue đã trở thành một lỗi cú pháp? Tôi đoán ở C99, có lẽ? Lần cuối cùng tôi sử dụng Visual C ++ thường xuyên là vào khoảng năm 1998, đó sẽ là tiêu chuẩn ANSI trước C99 và trình biên dịch đã cho phép nó sau đó (tôi biết vì tôi nhớ lỗi đánh máy hai lần &vào mã sản xuất!).
dodgethesteamroller

3
@dodgethesteamroller &&là một mã thông báo hoàn toàn riêng biệt &, vì vậy không có cách nào ngữ pháp C chuẩn có thể diễn giải &&xlà "địa chỉ của địa chỉ của x" bất kể danh mục giá trị của &x.
Tavian Barnes

4
@dodgethesteamroller: --luôn được phân tích cú pháp là --&&luôn được phân tích cú pháp là &&. C99 §6.4¶4: mã thông báo tiền xử lý tiếp theo là chuỗi ký tự dài nhất có thể tạo thành mã thông báo tiền xử lý
ninjalj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.