2013-07-18 39 views
21

Tôi đang tái cấu trúc một số mã số cũ rất cũ có đầy đủ các lỗi và thực tiễn rất có vấn đề, ít nhất là cho các tiêu chuẩn hiện đại. Bây giờ tôi chạy ngang qua một dòng mà tôi chỉ đơn giản là không thể giải mã:Đường khó hiểu "??! ??!" trong mã cũ

pk là loại int *

return p??!??!k?p?*p:sizeof(*k):0; 

Khi tôi nhìn thấy nó, tôi không thể tin vào mắt mình - Tôi biết các nhà điều hành ?, nhưng cú pháp của nó là bool ? trueresult : falseresult và một nhà điều hành ?? không có ý nghĩa (đánh giá lười biếng thực sự không áp dụng ở đây), không phải tôi có thể tìm thấy một tham chiếu của nhà điều hành bí ẩn đó bất cứ nơi nào.

Sẽ rất tuyệt nếu ai đó làm sáng tỏ vấn đề này.

+2

http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C – qrdl

+0

nào biên dịch bạn đang sử dụng ? gcc, ví dụ, bỏ qua các dấu vết theo mặc định. Và vâng, điều này phải là * rất, rất cũ * mã, thực sự. – devnull

+0

@devnull Đó là gcc nhưng được biên dịch bằng Makefile. Và bây giờ tôi biết những gì trigraphs là tôi cũng biết tại sao có một lá cờ '-trigraphs' thông qua trình biên dịch;) – user2573221

Trả lời

37

Nó được gọi là Trigraph:

C11 (ISO/IEC 9899: 201x) §5.2.1.1 Trigraph trình tự

Trước khi chế biến khác xảy ra, mỗi khi xảy ra một trong các cách sau trình tự của ba ký tự (được gọi là trigraph sequences17)) được thay thế bằng ký tự đơn tương ứng .

??= # 
??( [ 
??/ \ 
??) ] 
??' ^
??< { 
??! | 
??> } 
??- ~ 

Nó cũng trong C++ 11 (ISO/IEC 14882: 2011) § 2.3 chuỗi Trigraph

Vì vậy, sau khi thay thế trigraph, dòng return p??!??!k?p?*p:sizeof(*k):0; biến thành

return p || k ? p ? *p : sizeof(*k) : 0 

Vì toán tử bậc ba có mức ưu tiên khá thấp, thực tế là:

return (p || k) ? (p ? (*p) : sizeof(*k)) : 0; 
6

Đó dòng mã tương đương với:

return p || k? p? *p : sizeof(*k) : 0; 

Hoặc rõ ràng hơn:

return (p || k)? (p? (*p) : sizeof(*k)) : 0; 
Các vấn đề liên quan