Qual é o objetivo da palavra-chave estática no parâmetro de matriz da função como "char s [static 10]"?

144

Ao navegar em algum código-fonte, deparei-me com uma função como esta:

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

Com algumas experiências, parece que outros qualificadores podem aparecer lá também:

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

Parece que qualificadores só são permitidos dentro de [ ]quando a matriz é declarada como um parâmetro de uma função. O que eles fazem? Por que é diferente para parâmetros de função?

dreamlax
fonte

Respostas:

127

A primeira declaração informa ao compilador que someArraypossui pelo menos 100 elementos. Isso pode ser usado para otimizações. Por exemplo, também significa que someArraynunca é NULL.

Observe que o padrão C não exige que o compilador diagnostique quando uma chamada para a função não atende a esses requisitos (ou seja, é um comportamento indefinido silencioso).

A segunda declaração simplesmente declara someArray(e não someArrayos elementos!) Como const, ou seja, você não pode escrever someArray=someOtherArray. É o mesmo que se o parâmetro fosse char * const someArray.

Essa sintaxe é utilizável apenas no interior []de um declarador de matriz em uma lista de parâmetros de função; não faria sentido em outros contextos.

O texto padrão, que abrange os dois casos acima, está em C11 6.7.6.3/7 (era 6.7.5.3/7 em C99):

Uma declaração de um parâmetro como '' matriz do tipo '' deve ser ajustada para '' ponteiro qualificado para o tipo '', onde os qualificadores de tipo (se houver) são aqueles especificados na derivação do tipo [e ]na matriz. Se a palavra-chave static também aparecer dentro da derivação do tipo [e ]da matriz, para cada chamada para a função, o valor do argumento real correspondente fornecerá acesso ao primeiro elemento de uma matriz com pelo menos tantos elementos, conforme especificado pelo expressão de tamanho.

Mainframe nórdico
fonte
35
Sobre este tópico: Gostaria de saber se deve ser considerado preferível usar em int foo(struct bar [static 1]);vez de int foo(struct bar *);como a assinatura para funções que não aceitam ponteiros NULL. (Eu sei gcc tem uma sintaxe diferente do padrão alternativo para sinalizar tais funções para que o compilador pode dar avisos ..)
R .. GitHub parar de ajudar ICE
2
Acabei de verificar gcc e clang e nem assumimos que someArray é sempre nulo quando peço que eles comparem com 0. Também luto para encontrar a cláusula exata em C99 que a define. Há uma nota em 6.7.5.3-21 que menciona o significado pretendido e é isso. Duvido que possamos confiar nisso. Além disso, tudo isso não faz parte da assinatura da função; portanto, não há muito o que forçarmos através dela.
Mainframe Nórdico
5
Esse link parece ter apodrecido, é para isso que ele estava apontando? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken
13
@NordicMainframe: já faz algum tempo, mas a versão atual clangagora avisa corretamente quando você tenta passar um argumento NULL conhecido para uma função com uma [static 1]declaração de parâmetro.
dreamlax
1
@CiroSantilli 法轮功 - 六四 事件 法轮功if (!someArray) { somecode... }pode ser removido
MM