2015-03-18 55 views
12

Tôi đã đi qua đoạn mã sau trong nguồn nhân Linux (2.6.32).`return x là gì? : 1` có nghĩa là trong ngôn ngữ C?

do_wait_for_common(struct completion *x, long timeout, int state) 
{ 
     if (!x->done) { 
     /* some code here */ 
     } 
     x->done--; 
     return timeout ?: 1; <--- What it returns? 
} 

Để hiểu được hành vi này, tôi đã tự thử đoạn code sau

#include <stdio.h> 
int f(int x) 
{ 
     return x?:1; 
} 
int main() 
{ 
     printf("f %d\n", f(0)); 
     printf("f %d\n", f(1)); 
     return 0; 
} 

Và có đầu ra sau đây

f 1 
f 1 

Và khi tôi thay đổi nó để

int f(int x) 
{ 
     return x?:2; 
} 

Tôi đang nhận được

f 2 
f 1 

Tôi chỉ muốn biết liệu hành vi này (trở về 1 nếu không có gì đề cập) được đề cập trong tiêu chuẩn.

Trả lời

15

Hành vi này không được đề cập trong tiêu chuẩn C. Đó là GCC extension.

Các toán hạng trung trong một biểu thức điều kiện có thể được bỏ qua. Sau đó, nếu toán hạng đầu tiên là nonzero, giá trị của nó là giá trị của biểu thức điều kiện.

Do đó, khái niệm

x ? : y 

có giá trị của x nếu đó là khác không; nếu không, giá trị của y.

Ví dụ này là hoàn toàn tương đương với

x ? x : y 

Trong trường hợp đơn giản này, khả năng bỏ qua các toán hạng trung không phải là đặc biệt hữu ích. Khi nó trở nên hữu ích là khi toán hạng đầu tiên thực hiện, hoặc có thể (nếu nó là một đối số macro), chứa một tác dụng phụ. Sau đó lặp lại toán hạng ở giữa sẽ thực hiện tác dụng phụ hai lần. Bỏ qua toán hạng giữa sử dụng giá trị đã được tính toán mà không có tác động không mong muốn của việc tính toán lại nó.

+4

@Downvoter; Một bình luận sẽ được đánh giá cao? – haccks

13

Đây là GCC extension. x?:2 giống với x?x:2 (với số sau đó một phần được đánh giá một lần)

3

Theo GCC extension

Các toán hạng trung trong một biểu thức điều kiện có thể được bỏ qua

return x?:1; là một phương pháp ngắn tay để viết return x?x :1;

5

Đây là một GNU C mở rộng của toán tử ternary bình thường. X ?: Y giống với X ? X : Y ngoại trừ X chỉ được đánh giá một lần.