Mục đích của từ khóa tĩnh trong tham số mảng của hàm như là char char s [static 10].


144

Trong khi duyệt một số mã nguồn, tôi đã bắt gặp một chức năng như thế này:

void someFunction(char someArray[static 100])
{
    // do something cool here
}

Với một số thử nghiệm, có vẻ như các vòng loại khác cũng có thể xuất hiện ở đó:

void someFunction(char someArray[const])
{
    // do something cool here
}

Dường như các vòng loại chỉ được phép bên trong [ ]khi mảng được khai báo là tham số của hàm. Những điều này làm gì? Tại sao nó khác nhau cho các tham số chức năng?

Câu trả lời:


127

Việc kê khai đầu tiên cho trình biên dịch mà someArrayít nhất dài 100 yếu tố. Điều này có thể được sử dụng để tối ưu hóa. Ví dụ, nó cũng có nghĩa someArraylà không bao giờ NULL.

Lưu ý rằng Tiêu chuẩn C không yêu cầu trình biên dịch chẩn đoán khi một lệnh gọi hàm không đáp ứng các yêu cầu này (nghĩa là đó là hành vi không xác định im lặng).

Khai báo thứ hai chỉ đơn giản là khai báo someArray(không phải someArraylà các phần tử!) Là const, tức là bạn không thể viết someArray=someOtherArray. Nó giống như nếu tham số là char * const someArray.

Cú pháp này chỉ có thể sử dụng được trong phạm vi trong cùng []của một bộ khai báo mảng trong danh sách tham số hàm; nó sẽ không có ý nghĩa trong các bối cảnh khác.

Văn bản Tiêu chuẩn, bao gồm cả hai trường hợp trên, nằm trong C11 6.7.6.3/7 (là 6.7.5.3/7 trong C99):

Một khai báo của một tham số là '' mảng loại '' sẽ được điều chỉnh thành '' con trỏ đủ điều kiện để nhập '', trong đó các loại vòng loại (nếu có) là những loại được chỉ định trong []dẫn xuất loại mảng. Nếu từ khóa tĩnh cũng xuất hiện bên trong []của đạo hàm kiểu mảng, thì với mỗi lệnh gọi hàm, giá trị của đối số thực tế tương ứng sẽ cung cấp quyền truy cập vào phần tử đầu tiên của một mảng có ít nhất nhiều phần tử như được chỉ định bởi biểu hiện kích thước.


35
Về chủ đề này: Tôi tự hỏi liệu nó có nên được coi là thích hợp hơn để sử dụng int foo(struct bar [static 1]);thay vì int foo(struct bar *);làm chữ ký cho các chức năng không chấp nhận con trỏ NULL. (Tôi biết gcc có cú pháp không chuẩn thay thế để gắn cờ các chức năng đó để trình biên dịch có thể đưa ra cảnh báo ..)
R .. GitHub DỪNG GIÚP ICE

2
Tôi vừa kiểm tra gcc và clang và không cho rằng someArray luôn không rỗng khi tôi yêu cầu họ so sánh với 0. Ngoài ra, tôi đấu tranh để tìm mệnh đề chính xác trong C99 định nghĩa nó. Có một ghi chú trong 6.7.5.3-21 trong đó đề cập đến ý nghĩa dự định và đó là ý nghĩa. Tôi nghi ngờ rằng chúng ta có thể dựa vào điều này. Hơn nữa, tất cả điều này không phải là một phần của chữ ký hàm, vì vậy chúng tôi không thực thi nhiều thông qua nó.
Mainframe Bắc Âu

5
Liên kết đó dường như đã bị thối đi, đây có phải là những gì nó được trỏ đến? pic.dhe.ibm.com/infocenter/zos/v1r12/ Khăn
Ross Aiken

13
@NordicMainframe: Đã có lúc, nhưng phiên bản clanghiện tại bây giờ cảnh báo chính xác khi bạn cố gắng chuyển một đối số NULL đã biết đến một hàm với [static 1]khai báo tham số.
dreamlax

1
@CiroSantilli 巴拿馬 件if (!someArray) { somecode... }có thể bị xóa
MM
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.