Sempre me perguntei se é uma boa prática sempre preferir const
parâmetros quando possível? Por um lado, você diz ao compilador que essa variável não será mutada dentro do escopo da função para que ele possa fazer otimizações por baixo dos panos, mas, por outro lado, isso não afeta o chamador, já que os argumentos são passados por cópia, então pode deixar o código inchado com const
s em todos os lugares e, portanto, menos legível.
Alguém sabe que tipos de otimizações são feitas por baixo dos panos por compiladores em const
parâmetros? Ele pode otimizar passando a variável como referência sem copiá-la, por exemplo? Há implicações de simultaneidade das quais devemos estar cientes? (por exemplo, ao mutar a variável em outro thread enquanto a função está em execução).
Os prós valem os contras?
Há vantagens de otimização no uso de nível superior
const
em definições de variáveis onde elas são válidas (em qualquer lugar que seja uma definição, não apenas em parâmetros em uma definição de função).O nível superior
const
em uma variável faz com que qualquer tentativa de modificar o valor do objeto tenha um comportamento indefinido. Como consequência, o compilador pode deduzir que seu valor nunca mudará, mesmo se um ponteiro para ele escapar para alguma função desconhecida.Sem isso, qualquer escape de ponteiro exige que o compilador tenha que assumir que o valor do objeto pode ser alterado por qualquer chamada desconhecida. Isso ocorre mesmo se a função receber um ponteiro para
const
, porque, diferentemente do nível superiorconst
em uma definição, issoconst
não tem significado para otimização e existe puramente para o benefício do programador para raciocinar sobre o código e evitar erros semânticos.Não vejo nenhuma desvantagem, exceto que o código às vezes fica mais difícil de ler com mais boiler-plate de palavras-chave. Pode haver um pequeno risco de que algo seja acidentalmente definido com
const
o que realmente é modificado, causando UB. No entanto, se o código for escrito comconst
a correção em mente, isso deve ser improvável. Conversões explícitas são sempre um risco potencial para descartarconst
qualificadores em violação àconst
correção.Do C17 6.5.2.2 parágrafo 2:
Do C17 6.7.6.3 parágrafo 15:
Isso significa efetivamente que qualificadores como os
const
do tipo imediato do parâmetro da função são ignorados pelo chamador e só são significativos para a função chamada em si, onde desempenham a mesma função que os qualificadores em variáveis locais.Isso também significa que essas declarações de função são compatíveis:
Se o parâmetro for declarado
const
na definição da função, o compilador poderá tratar o parâmetro da mesma forma que uma variável definidaconst
com um inicializador:Ao declarar a função em um arquivo de cabeçalho compartilhado, eu recomendaria declarar o parâmetro sem o qualificador, porque ele não é relevante para os chamadores da função.