¿Cuál es el propósito de la palabra clave estática en el parámetro de matriz de la función como "char s [static 10]"?

144

Mientras navegaba por el código fuente, me encontré con una función como esta:

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

Con algo de experimentación, parece que otros calificadores también pueden aparecer allí:

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

Parece que los calificadores solo se permiten dentro de [ ]la matriz cuando se declara como parámetro de una función. ¿Qué hacen estos? ¿Por qué es diferente para los parámetros de función?

dreamlax
fuente

Respuestas:

127

La primera declaración le dice al compilador que someArraytiene al menos 100 elementos de longitud. Esto se puede usar para optimizaciones. Por ejemplo, también significa que someArraynunca es NULL.

Tenga en cuenta que el Estándar C no requiere que el compilador diagnostique cuando una llamada a la función no cumple con estos requisitos (es decir, es un comportamiento silencioso indefinido).

La segunda declaración simplemente declara someArray(¡no someArraylos elementos!) Como constante, es decir, no puede escribir someArray=someOtherArray. Es lo mismo que si el parámetro fuera char * const someArray.

Esta sintaxis solo se puede utilizar en el interior []de un declarador de matriz en una lista de parámetros de función; no tendría sentido en otros contextos.

El texto estándar, que cubre los dos casos anteriores, está en C11 6.7.6.3/7 (era 6.7.5.3/7 en C99):

Una declaración de un parámetro como '' matriz de tipo '' se ajustará a '' puntero calificado para escribir '', donde los calificadores de tipo (si los hay) son los especificados dentro [y ]de la derivación de tipo de matriz. Si la palabra clave static también aparece dentro de [y ]de la derivación del tipo de matriz, entonces, para cada llamada a la función, el valor del argumento real correspondiente proporcionará acceso al primer elemento de una matriz con al menos tantos elementos como especifique el Expresión de tamaño.

Mainframe nórdico
fuente
35
Sobre este tema: Me pregunto si debería considerarse preferible usarlo en int foo(struct bar [static 1]);lugar de int foo(struct bar *);como la firma para funciones que no aceptan punteros NULL. (Sé que gcc tiene una sintaxis alternativa no estándar para marcar tales funciones para que el compilador pueda dar advertencias ...)
R .. GitHub DEJAR DE AYUDAR A ICE
2
Acabo de comprobar gcc y clang y tampoco supongo que someArray siempre es nulo cuando les pido que comparen con 0. También me cuesta encontrar la cláusula exacta en C99 que la define. Hay una nota en 6.7.5.3-21 que menciona el significado deseado y eso es todo. Dudo que podamos confiar en esto. Además, todo esto no es parte de la firma de la función, por lo que no hay mucho que apliquemos a través de ella.
Mainframe nórdico el
55
Ese enlace parece haberse podrido, ¿es esto a lo que apuntaba? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken
13
@NordicMainframe: ha pasado algún tiempo, pero la versión actual de clangahora advierte correctamente cuando intenta pasar un argumento NULL conocido a una función con una [static 1]declaración de parámetro.
dreamlax
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功if (!someArray) { somecode... }podría ser eliminado
MM