2017-05-31 15 views
22

tôi đã nhận thấy ở một số mã nguồn dòng:niềng răng Quăn như là đối số của hàm

if(pthread_create((pthread_t[]){}, 0, start_thread, pthread_args)) { 
... 

Nó hoạt động một cách chính xác, nhưng làm thế nào để hiểu đối số đầu tiên? Dường như, các dấu ngoặc nhọn chuyển thành loại pthread_t[].

P.s. Tôi googled, nhưng không tìm thấy câu trả lời, chỉ có một số dự đoán (một số hình thức khởi tạo, hoặc tính năng di sản của c?)

+13

Đó là [* compound literal *] (http://en.cppreference.com/w/c/language/compound_literal). –

+0

@Someprogrammerdude Cảm ơn! Đó là, tôi muốn. – ltWolfik

Trả lời

19

Đây là một compound literal, với một sự vi phạm hạn chế kể từ initializer braces cannot be empty:

(pthread_t[]){} 

Sử dụng gcc -std=c99 -Wall -Wextra -Wpedantic này tạo ra các cảnh báo:

compound_literal_pthread.c:6:36: warning: ISO C forbids empty initializer braces [-Wpedantic] 
    pthread_t *ptr = (pthread_t []){}; 

Kết quả có vẻ là một con trỏ đến pthread_t, mặc dù tôi don không thấy hành vi này được ghi lại trong hướng dẫn gcc. Lưu ý rằng dấu ngoặc rỗng được phép làm khởi tạo trong C++, trong đó chúng tương đương với { 0 }. Hành vi này dường như được hỗ trợ cho C, nhưng không có giấy tờ, bởi gcc. Tôi nghi ngờ đó là những gì đang xảy ra ở đây, làm cho sự biểu hiện tương đương ở trên để:

(pthread_t[]){ 0 } 

Trên hệ thống của tôi, pthread_t là một typedef cho unsigned long, vì vậy biểu thức này sẽ tạo ra một mảng của pthread_t chỉ chứa một yếu tố 0. Mảng này sẽ phân rã thành con trỏ đến pthread_t trong cuộc gọi hàm.

+5

Và như một hiệu ứng phụ bị hỏng, luồng không thể nối được vì mã không lưu 'pthread_t' có thể truy cập được. Trong thực tế, các sợi được tách ra, mà không có lợi ích của chính thức được tách ra. Như một cách tạo ra một sợi, nó để lại rất nhiều điều mong muốn. –

+0

@ JonathanLeffler-- lưu ý tốt. –

+0

Tôi nghĩ * mọi loại trong C có thể được khởi tạo đúng với '{0}', nhưng không rõ ràng tại sao các dấu ngoặc rỗng không được phép: cho rằng bất kỳ phần tử riêng lẻ nào của đối tượng được khởi tạo được cho phép ngầm định , tại sao không làm điều đó đúng cho tất cả cùng một lúc? (và '{0}' có thể được cho phép về mặt kỹ thuật cho nhiều loại, nhưng không phải là "đúng" trong ý nghĩa của việc được sạch sẽ để đọc) – Leushenko

0

Bạn đang tạo một mảng với pthread[]. Bạn có thể chuyển giá trị trong dấu ngoặc nhọn nếu bạn xác định độ dài cho đối số.

0

Những gì bạn đang xử lý có bộ khởi tạo mảng, xảy ra là mảng trống. Bạn sẽ thường thấy nó như:

int my_array[] = (int[]){10, 20, 30}; 

Và nó sẽ khởi tạo my_array để chứa ba yếu tố. Ở đây không có yếu tố, do đó cú pháp khó xử.

+2

là một danh sách ngoặc đơn trống có được coi là cú pháp hợp lệ không? AFAIR, nó phải chứa ít nhất một phần tử. –

+0

Có, đó là cú pháp hợp lệ. Bạn không cần phải viết các dấu ngoặc nhọn trong trường hợp đó nhưng bạn có thể. –

+3

@ JohannesMols-- nó không phải là cú pháp hợp lệ, nó là một sự vi phạm ràng buộc để sử dụng dấu ngoặc rỗng với một initializer. –

1

Đây là số compound literal như đã đề cập bởi @ some-programmer-dude.

Trong trường hợp cụ thể này, nó được sử dụng để tạo một mảng để lưu trữ thread_id và xả nó sau này mà không cần tạo thêm biến. Điều đó là cần thiết vì pthread_create không chấp nhận NULL làm đối số cho thread_id.

Các vấn đề liên quan