Em C, o protótipo para a função de valor absoluto (que aceita um float) é
float fabsf( float );
Por que esse protótipo não aceita um valor constante, como este:
float fabsf( float const );
O fabsf não altera o valor da entrada, altera?
Se eu tiver uma função que aceite uma entrada e chame fabsf, sou forçado a evitar especificar a entrada como const?
Qual é a maneira apropriada de lidar com a correção const nesta situação?
c
function
const
pass-by-value
user24205
fonte
fonte
const
é redundante aqui, o que você imagina está acontecendo?const
é completamente sem sentido.float const x = -1.0; float y = fabsf(x);
assim parece-me quefabsf
faz aceitar entradas const. Não há como dizer "você pode me passar umfloat
valor, mas não pode passar umconst float
". (E como podemos ver nas respostas, C não fornece uma maneira de exigir que a entrada para uma função ser umfloat const
.)Respostas:
Editar
Como MM comentou, nos parâmetros nos protótipos o
const
é ignorado. A fonte editada da resposta original (veja abaixo) mostra isso:Não há nenhuma mensagem de erro.
De qualquer forma, deixarei o original no lugar, na esperança de que possa ajudar.
Original
O
const
parâmetro at torna esse parâmetro somente leitura dentro da função.Por exemplo:
Esta fonte não será compilada sem mensagem de erro.
A função
correct()
lerá o valor fornecido, alterará seu sinal e retornará o valor negado.A função
erroneous()
parece efetivamente fazer o mesmo, exceto que há uma atribuição ao parâmetro. Mas, como o parâmetro é,const
isso não é permitido.Em seguida, a função
changer()
funcionará como as duas anteriores, mas não apresenta erros.Vejamos o site de chamadas:
A variável
f
dada como um argumento será copiado para o parâmetrovalue
. Isso nunca mudará, mesmo quechanger()
seja chamado.Você pode considerar os parâmetros como algum tipo de variável local. Na verdade, eles são manipulados dessa maneira no código de máquina gerado.
Então, por que você vê
const
às vezes? Você vê se um ponteiro é definido como parâmetro.Quando você não deseja que o valor apontado seja alterado, é necessário adicionar
const
; mas faça-o na posição correta!fonte
float fabsf( float const );
não tem nada a ver com a implementação da função (que não tem de repetir aconst
), de fato, oconst
é ignorado inteiramente no protótipoC usa passagem por valor. O valor para o parâmetro de uma função é uma cópia do argumento que você fornece.
Não há problema em copiar flutuações constantes e não constantes, e o resultado é uma flutuação não const.
É semelhante à atribuição:
De fato, a linguagem especifica que o valor de uma expressão nunca pode ser
const
, ou seja, quando um valor é lido de uma variável, esse valor não é igualconst
se a variável fosse.fonte
Como a linguagem C usa semântica de passagem por valor, qualquer argumento que você passar para ela, embora possa ser modificado internamente, não afeta diretamente o valor que você passa.
Isto significa que do ponto de vista do autor da chamada,
float fabsf( float );
efloat fabsf( const float );
são os mesmos. Portanto, não há sentido em fazer o parâmetroconst
.Onde faz sentido usar
const
é se o parâmetro que você passa é um ponteiro, por exemplo:Esta função, apesar do que o nome sugere, pode desreferenciar o ponteiro especificado e modificar o que aponta, ou seja
str[0] = 'x'
, para resultar em uma alteração visível pela função de chamada. Se esta função foi definida assim:O chamador está garantido de que a função não pode executar nenhuma modificação para o que
str
aponta.fonte
((char*)str)[0] = 'f'
. Aconst ... *
lista de argumentos é, portanto, apenas uma "declaração de intenção".Para adicionar uma perspectiva de advogado de idiomas:
Isso significa que esses dois são compatíveis:
Portanto, você pode escrever o protótipo com ou sem
const
(o que significa que sem faz mais sentido; menos digitar / ler) e pode adicionarconst
a definição de função se desejar evitar modificar acidentalmente o parâmetro (copiado - chamada por valor!) Dentro das funções corpo.fonte