void foo()significa "uma função fooque recebe um número não especificado de argumentos de tipo não especificado"
void foo(void)significa "uma função fooque não aceita argumentos"
Em C ++ :
void foo()significa "uma função fooque não aceita argumentos"
void foo(void)significa "uma função fooque não aceita argumentos"
Ao escrever foo(void), portanto, obtemos a mesma interpretação nos dois idiomas e tornamos nossos cabeçalhos multilíngues (apesar de geralmente precisarmos fazer mais algumas coisas com os cabeçalhos para torná-los realmente com linguagem cruzada; ou seja, envolvê-los em um extern "C"se estiver compilando C ++).
Mas se o C ++ exigisse o void, então ele poderia ter evitado o problema "análise mais irritante".
Adrian McCarthy
5
É verdade, mas existem tantas outras análises ruins no C ++ que não há nenhum ponto real no kvetching sobre qualquer uma delas.
DrPizza
16
Em uma pergunta recente, @James Kanze postou um boato interessante. Repita aqui para evitar perdê-lo: as primeiras versões de C não permitiram especificar o número de parâmetros que uma função poderia ter, portanto, void foo()era a única sintaxe a declarar uma função. Quando as assinaturas foram introduzidas, o comitê C teve que desambiguar o parâmetro sem da sintaxe antiga e introduziu a void foo(void)sintaxe. O C ++ tomou isso por uma questão de compatibilidade.
Matthieu M.
3
Você pode me dar um exemplo de C C90 e, posteriormente, onde o uso em void foo()vez de void foo(void)produzirá uma diferença funcional? Ou seja, eu tenho usado a versão sem o vazio por muitos anos e não vi nenhum problema, estou perdendo alguma coisa?
precisa saber é o seguinte
6
@ chacham15 void foo() { if ( rand() ) foo(5); } compila e executa (causando comportamento indefinido, a menos que você tenha muita sorte), enquanto que void foo(void)o mesmo corpo causaria um erro de compilação.
MM
39
Sei que sua pergunta pertence ao C ++, mas quando se trata de C, a resposta pode ser encontrada em K&R, páginas 72-73:
Além disso, se uma declaração de função não incluir argumentos, como em
double atof();
isso também significa que nada deve ser assumido sobre os argumentos de atof; toda a verificação de parâmetros está desativada. Esse significado especial da lista de argumentos vazia destina-se a permitir que programas C mais antigos sejam compilados com novos compiladores. Mas é uma má idéia usá-lo com novos programas. Se a função receber argumentos, declare-os; se não houver argumentos, use void.
Mas a questão é sobre definições; nesse caso, a regra C relevante é: Uma lista vazia em um declarador de função que faz parte de uma definição dessa função especifica que a função não possui parâmetros.
Anexo C "Compatibilidade" C.1.7 Cláusula 8: os declaradores declaram :
8.3.5 Alteração: no C ++, uma função declarada com uma lista de parâmetros vazia não aceita argumentos. Em C, uma lista de parâmetros vazia significa que o número e o tipo dos argumentos da função são desconhecidos.
Exemplo:
int f();// means int f(void) in C ++// int f( unknown ) in C
Fundamentação da petição: É para evitar chamadas de função incorretas (ou seja, chamadas de função com o número ou tipo de argumentos errado).
Efeito no recurso original: mude para a semântica do recurso bem definido. Esse recurso foi marcado como "obsoleto" em C.
8.5.3 funções diz:
4. A cláusula de declaração de parâmetro determina os argumentos que podem ser especificados e seu processamento quando a função é chamada. [...] Se a cláusula de declaração de parâmetro estiver vazia, a função não aceita argumentos. A lista de parâmetros (nula) é equivalente à lista de parâmetros vazia.
C99
Conforme mencionado pelo C ++ 11, int f()não especifica nada sobre os argumentos e é obsoleto.
Em C, você usa um vazio em uma referência de função vazia para que o compilador tenha um protótipo e esse protótipo "não tenha argumentos". No C ++, você não precisa informar ao compilador que possui um protótipo porque não pode deixar de fora o protótipo.
"protótipo" significa a declaração da lista de argumentos e o tipo de retorno. Digo isso porque "protótipo" me confundiu sobre o que você quis dizer no começo.
Respostas:
Em C :
void foo()
significa "uma funçãofoo
que recebe um número não especificado de argumentos de tipo não especificado"void foo(void)
significa "uma funçãofoo
que não aceita argumentos"Em C ++ :
void foo()
significa "uma funçãofoo
que não aceita argumentos"void foo(void)
significa "uma funçãofoo
que não aceita argumentos"Ao escrever
foo(void)
, portanto, obtemos a mesma interpretação nos dois idiomas e tornamos nossos cabeçalhos multilíngues (apesar de geralmente precisarmos fazer mais algumas coisas com os cabeçalhos para torná-los realmente com linguagem cruzada; ou seja, envolvê-los em umextern "C"
se estiver compilando C ++).fonte
void
, então ele poderia ter evitado o problema "análise mais irritante".void foo()
era a única sintaxe a declarar uma função. Quando as assinaturas foram introduzidas, o comitê C teve que desambiguar o parâmetro sem da sintaxe antiga e introduziu avoid foo(void)
sintaxe. O C ++ tomou isso por uma questão de compatibilidade.void foo()
vez devoid foo(void)
produzirá uma diferença funcional? Ou seja, eu tenho usado a versão sem o vazio por muitos anos e não vi nenhum problema, estou perdendo alguma coisa?void foo() { if ( rand() ) foo(5); }
compila e executa (causando comportamento indefinido, a menos que você tenha muita sorte), enquanto quevoid foo(void)
o mesmo corpo causaria um erro de compilação.Sei que sua pergunta pertence ao C ++, mas quando se trata de C, a resposta pode ser encontrada em K&R, páginas 72-73:
fonte
Rascunho padrão do C ++ 11 N3337
Não há diferença.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Anexo C "Compatibilidade" C.1.7 Cláusula 8: os declaradores declaram :
8.5.3 funções diz:
C99
Conforme mencionado pelo C ++ 11,
int f()
não especifica nada sobre os argumentos e é obsoleto.Pode levar ao código de trabalho ou UB.
Interpretei o padrão C99 em detalhes em: https://stackoverflow.com/a/36292431/895245
fonte
Em C, você usa um vazio em uma referência de função vazia para que o compilador tenha um protótipo e esse protótipo "não tenha argumentos". No C ++, você não precisa informar ao compilador que possui um protótipo porque não pode deixar de fora o protótipo.
fonte