2011-10-18 15 views
36

Trong 3.0.4 Linux kernel, mm/filemap.c có dòng mã này:sử dụng Bizarre của nhà điều hành có điều kiện trong Linux

retval = retval ?: desc.error; 

tôi đã cố gắng biên soạn một trường hợp thử nghiệm tối thiểu tương tự với gcc -Wall và không nhận được bất kỳ cảnh báo nào; hành vi có vẻ giống hệt với:

retval = retval ? retval : desc.error; 

Nhìn vào chuẩn C99, tôi không thể tìm ra chính xác những gì mô tả hành vi này. Tại sao điều này OK?

+9

Hãy xem http://stackoverflow.com/questions/2806255/why-would-you-use-the-ternary-operator-without-assigning-a-value-for-the-true – vhallac

+3

Cảm ơn, vhallac . Theo như tôi có thể nói, sử dụng phần mở rộng GCC này là một phím tắt nhỏ mà hoàn toàn phá hủy tính di động. –

+0

Chính xác những gì tôi đã nói với một đồng nghiệp đã cố gắng sử dụng nó trên một trong các dự án của chúng tôi. :) – vhallac

Trả lời

35

Như nhiều người khác đã nói, đây là phần mở rộng GCC, không phải là một phần của bất kỳ tiêu chuẩn nào. Bạn sẽ nhận được cảnh báo cho nó nếu bạn sử dụng công tắc -pedantic.

Các điểm của phần mở rộng này là không thực sự rõ ràng trong trường hợp này, nhưng hãy tưởng tượng nếu thay vào đó là

retval = foo() ?: desc.error; 

Với phần mở rộng, foo() được gọi là chỉ một lần. Nếu không có nó, bạn phải giới thiệu một biến tạm thời để tránh gọi số foo() hai lần.

+13

nhưng retval = foo(); retval = retval? retval: desc.error; là MUCH tốt hơn và là 100% di động. – akappa

+0

Tôi thực sự thích phản ứng của David Given, nhưng điều này làm rõ các ngữ nghĩa đánh giá đơn và nói với tôi về '-pantic' gây ra một cảnh báo. Được chọn. –

+1

@akappa: Sẽ không tốt hơn nếu bạn không muốn giới thiệu các biến tạm thời. Đây là một trong những phần mở rộng * thực sự cũ * cho GCC, và nó phản ánh thị hiếu ngôn ngữ chức năng của các nhà phát triển ban đầu của GCC. Ngoài ra, tại thời điểm đó, tất cả các khai báo biến cục bộ phải ở trên cùng của hàm; "các tuyên bố và mã hỗn hợp" không đạt tiêu chuẩn cho đến C99. – zwol

3

Đây là phần mở rộng theo gcc cụ thể cho C và không phải là tiêu chuẩn.

7

Đây là phần mở rộng GCC được gọi là Conditionals with Omitted Operands. Bỏ qua toán hạng giữa có tác dụng của việc sử dụng giá trị của điều kiện là toán hạng đã bỏ qua mà không đánh giá lại nó. Nó là an toàn để sử dụng ngay cả khi điều kiện là một vĩ mô.

19

Đó là tiện ích mở rộng gcc. x ?: y tương đương với x ? x : y --- xem http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals.

Vâng, tôi nghĩ nó cũng là điều xấu.

+0

Tại sao bạn nói nó là ác? Nonportable, vâng, nhưng nó có tác dụng bạn không thể có được bất kỳ cách nào khác (xem câu trả lời của tôi). – zwol

+0

Không, nó không phải là điều ác! Nó khá tiện dụng. – sidyll

+8

@Zack: nó là điều xấu vì nó gây nhầm lẫn cho những người không biết cú pháp không cần thiết và không cần thiết. – akappa