Jaki jest cel słowa kluczowego static w parametrze tablicy funkcji, takim jak „char s [static 10]”?

144

Przeglądając jakiś kod źródłowy natknąłem się na taką funkcję:

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

Po pewnym eksperymentowaniu wydaje się, że mogą się tam również pojawić inne kwalifikatory:

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

Wygląda na to, że kwalifikatory są dozwolone tylko wewnątrz elementu, [ ]gdy tablica jest zadeklarowana jako parametr funkcji. Co to robi? Dlaczego jest inaczej w przypadku parametrów funkcji?

dreamlax
źródło

Odpowiedzi:

127

Pierwsza deklaracja mówi kompilatorowi, że someArrayma co najmniej 100 elementów. Można to wykorzystać do optymalizacji. Na przykład oznacza to również, że someArraynigdy NULL.

Zwróć uwagę, że C Standard nie wymaga od kompilatora diagnozy, kiedy wywołanie funkcji nie spełnia tych wymagań (tj. Jest to ciche niezdefiniowane zachowanie).

Druga deklaracja po prostu deklaruje someArray(nie someArrayelementy!) Jako const, tzn. Nie możesz pisać someArray=someOtherArray. Jest tak samo, jak gdyby parametr był char * const someArray.

Ta składnia jest użyteczna tylko w najbardziej wewnętrznej []części deklaratora tablicy na liście parametrów funkcji; nie miałoby to sensu w innych kontekstach.

Tekst standardowy, który obejmuje oba powyższe przypadki, znajduje się w C11 6.7.6.3/7 (było 6.7.5.3/7 w C99):

Deklaracja parametru jako „tablica typu” powinna być dostosowana do „kwalifikowanego wskaźnika do typu”, gdzie kwalifikatorami typu (jeśli istnieją) są te określone w [i ]w wyprowadzaniu typu tablicy. Jeśli słowo kluczowe static występuje również w [i ]w wyprowadzeniu typu tablicy, to dla każdego wywołania funkcji wartość odpowiedniego rzeczywistego argumentu zapewnia dostęp do pierwszego elementu tablicy zawierającego co najmniej tyle elementów, ile określono w wyrażenie rozmiaru.

Nordic Mainframe
źródło
35
W tym temacie: Zastanawiam się, czy należy uznać, że lepiej jest używać int foo(struct bar [static 1]);zamiast int foo(struct bar *);jako podpisu dla funkcji, które nie akceptują wskaźników NULL. (Wiem, że gcc ma alternatywną niestandardową składnię do oznaczania takich funkcji, aby kompilator mógł dawać ostrzeżenia ...)
R .. GitHub STOP HELPING ICE
2
Właśnie sprawdziłem gcc i clang i żadne z nich nie zakładało, że someArray jest zawsze różna od null, kiedy poproszę ich o porównanie z 0. Również staram się znaleźć dokładną klauzulę w C99, która ją definiuje. W 6.7.5.3-21 jest uwaga, która wspomina o zamierzonym znaczeniu i to wszystko. Wątpię, czy możemy na tym polegać. Co więcej, to wszystko nie jest częścią podpisu funkcji, więc niewiele jest tego, co za jego pośrednictwem wymuszamy.
Nordic Mainframe
5
Wygląda na to, że to łącze zgniło, czy to właśnie na to wskazywało? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken
13
@NordicMainframe: Minęło trochę czasu, ale obecna wersja clangteraz poprawnie ostrzega, gdy próbujesz przekazać argument o wartości NULL do funkcji z [static 1]deklaracją parametru.
dreamlax
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功if (!someArray) { somecode... }może zostać usunięty
MM