Eu não consigo descobrir isso:
int main() {
int (*) (int *) = 5;
return 0;
}
A atribuição acima é compilada com g ++ c ++ 11. Eu sei que int (*) (int *)
é um ponteiro para uma função que aceita um (int *)
como argumento e retorna um int, mas não entendo como você poderia igualá-lo a 5. No início, pensei que fosse uma função que retornava constantemente 5 (do meu aprendizado recente em F #, provavelmente, haha), então pensei, brevemente, que o ponteiro de função aponta para o local de memória 5, mas isso não funciona, claramente, e nem os valores hexadecimais.
Pensando que poderia ser porque a função retorna um int e que atribuir um int está ok (de alguma forma), eu também tentei isso:
int * (*) (int *) = my_ptr
onde my_ptr
é do tipo int *
, o mesmo tipo deste segundo ponteiro de função, como no primeiro caso com o tipo int. Isso não compila. Atribuir 5 ou qualquer valor int, em vez de my_ptr
, também não compila para este ponteiro de função.
Então, o que significa a atribuição?
Atualização 1
Temos a confirmação de que se trata de um bug, conforme demonstrado na melhor resposta. No entanto, ainda não se sabe o que realmente acontece com o valor que você atribui ao ponteiro de função, ou o que acontece com a atribuição. Quaisquer (boas) explicações sobre isso seriam muito apreciadas! Consulte as edições abaixo para obter mais clareza sobre o problema.
Editar 1
Estou usando o gcc versão 4.8.2 (no Ubuntu 4.8.2)
Editar 2
Na verdade, igualar a qualquer coisa funciona no meu compilador. Mesmo igualando-o a uma variável std :: string, ou um nome de função que retorna um duplo, funciona.
Editar 2.1
Curiosamente, torná-lo um ponteiro de função para qualquer função que retorna um tipo de dados que não seja um ponteiro, permitirá que ele seja compilado, como
std::string (*) () = 5.6;
Mas assim que o ponteiro de função é para uma função que retorna algum ponteiro, ele não compila, como com
some_data_type ** (*) () = any_value;
fonte
error: expected identifier or '(' before ')' token
int *x = 5
você o nomeoux
. Comint * (*x) (int *) = 5
ele não vai compilar. (embora isso seja compilado como código C).int(*) = 5;
eint(*);
Respostas:
É um bug no g ++.
é um nome de tipo.
Em C ++, você não pode ter uma declaração com um nome de tipo sem um identificador.
Portanto, isso compila com g ++.
e isso também compila:
mas ambas são declarações inválidas.
EDITAR :
TC menciona nos comentários o bugzilla bug 60680 com um caso de teste semelhante,
mas ainda não foi aprovado. O bug é confirmado no bugzilla.EDIT2 :
Quando as duas declarações acima estão no escopo do arquivo, o g ++ emite corretamente um diagnóstico (ele falha em emitir o diagnóstico no escopo do bloco).
EDIT3 :
Eu verifiquei e posso reproduzir o problema na última versão do g ++ versão 4 (4.9.2), na última versão de pré-lançamento 5 (5.0.1 20150412) e na última versão experimental 6 (6.0.0 20150412).
fonte
error C2059: syntax error : ')'
int (*int_func)(int *);
que declara um ponteiro de função chamadoint_func
.int x[5];
e nãoint[5] x;
Não é C ++ válido. Lembre-se de que, como seu compilador específico compila, ele não o torna válido. Compiladores, como todo software complexo, às vezes têm bugs e este parece ser um.
Em contraste,
clang++
reclama:Este é o comportamento esperado porque a linha incorreta não é C ++ válido. Ele pretende ser uma atribuição (devido ao
=
), mas não contém nenhum identificador.fonte
Como outras respostas apontaram, é um bug que
compila. Uma aproximação razoável desta declaração que se esperaria ter um significado é:
Agora
proc
é um ponteiro para função que espera que o endereço5
seja o endereço base de uma função que recebe umint*
e retorna umint
.Em alguns microcontroladores / microprocessadores
5
pode haver um endereço de código válido e pode ser possível localizar essa função lá.Na maioria dos computadores de uso geral, a primeira página de memória (endereços
0-1023
para páginas de 4 K) é propositalmente inválida (não mapeada) para capturarnull
acessos de ponteiro.Assim, embora o comportamento dependa da plataforma, pode-se esperar razoavelmente que uma falha de página ocorra quando
*proc
for invocado (por exemplo,(*proc)(&v)
). Antes da hora em que*proc
é invocado, nada de anormal acontece.A menos que você esteja escrevendo um vinculador dinâmico, quase certamente não deveria estar calculando endereços numericamente e atribuindo-os a variáveis de ponteiro para função.
fonte
Esta linha de comando gera muitos arquivos intermediários. O primeiro deles
so.cpp.170r.expand
, diz:Isso ainda não responde exatamente ao que acontece, mas deve ser um passo na direção certa.
fonte