No puedo resolver esto:
int main() {
int (*) (int *) = 5;
return 0;
}
La asignación anterior se compila con g ++ c ++ 11. Sé que int (*) (int *)
es un puntero a una función que acepta un (int *)
argumento como y devuelve un int, pero no entiendo cómo podrías equipararlo a 5. Al principio pensé que era una función que constantemente devuelve 5 (de mi aprendizaje reciente en F #, probablemente, jaja), luego pensé, brevemente, que el puntero de función apunta a la ubicación de memoria 5, pero eso no funciona, claramente, y tampoco los valores hexadecimales.
Pensando que podría deberse a que la función devuelve un int, y que asignar un int está bien (de alguna manera), también probé esto:
int * (*) (int *) = my_ptr
donde my_ptr
es de tipo int *
, el mismo tipo que este segundo puntero de función, como en el primer caso con el tipo int. Esto no se compila. Asignar 5, o cualquier valor int, en lugar de my_ptr
, tampoco se compila para este puntero de función.
Entonces, ¿qué significa la asignación?
Actualización 1
Tenemos la confirmación de que es un error, como se muestra en la mejor respuesta. Sin embargo, todavía no se sabe qué sucede realmente con el valor que asigna al puntero de función, o qué sucede con la asignación. ¡Cualquier (buena) explicación al respecto sería muy apreciada! Consulte las ediciones a continuación para obtener más claridad sobre el problema.
Editar 1
Estoy usando gcc versión 4.8.2 (en Ubuntu 4.8.2)
Editar 2
En realidad, equipararlo con cualquier cosa funciona en mi compilador. Incluso equipararlo a una variable std :: string, o un nombre de función que devuelve un doble, funciona.
Editar 2.1
Curiosamente, convertirlo en un puntero de función a cualquier función que devuelva un tipo de datos que no sea un puntero, permitirá que se compile, como
std::string (*) () = 5.6;
Pero tan pronto como el puntero de la función es a una función que devuelve algún puntero, no se compila, como con
some_data_type ** (*) () = any_value;
fuente
error: expected identifier or '(' before ')' token
int *x = 5
tu nombrex
. Conint * (*x) (int *) = 5
él no se compilará. (aunque se compilará como código C).int(*) = 5;
yint(*);
Respuestas:
Es un error en g ++.
int (*) (int *)
es un nombre de tipo.
En C ++ no puede tener una declaración con un nombre de tipo sin un identificador.
Entonces esto se compila con g ++.
int (*) (int *) = 5;
y esto también se compila:
int (*) (int *);
pero ambas son declaraciones inválidas.
EDITAR :
TC menciona en los comentarios bugzilla bug 60680 con un caso de prueba similar
pero aún no ha sido aprobado. El error se confirma en bugzilla.EDIT2 :
Cuando las dos declaraciones anteriores están en el alcance del archivo, g ++ emite correctamente un diagnóstico (no emite el diagnóstico en el alcance del bloque).
EDIT3 :
Verifiqué y puedo reproducir el problema en la última versión de g ++ versión 4 (4.9.2), la última versión preliminar 5 (5.0.1 20150412) y la última versión experimental 6 (6.0.0 20150412).
fuente
error C2059: syntax error : ')'
int (*int_func)(int *);
cuál declara un puntero de función llamadoint_func
.int x[5];
y noint[5] x;
No es C ++ válido. Recuerde que debido a que su compilador particular se compila, no lo hace válido. Los compiladores, como todo software complejo, a veces tienen errores y este parece ser uno.
Por el contrario se
clang++
queja:funnycast.cpp:3:11: error: expected expression int (*) (int *) = 5; ^ funnycast.cpp:3:18: error: expected '(' for function-style cast or type construction int (*) (int *) = 5; ~~~ ^ funnycast.cpp:3:19: error: expected expression int (*) (int *) = 5; ^ 3 errors generated.
Este es el comportamiento esperado porque la línea ofensiva no es C ++ válido. Pretende ser una asignación (debido a
=
) pero no contiene ningún identificador.fuente
Como han señalado otras respuestas, es un error que
compila. Una aproximación razonable de esta afirmación que se esperaría que tuviera un significado es:
Ahora
proc
es un puntero a función que espera que la dirección5
sea la dirección base de una función que toma unaint*
y devuelve unaint
.En algunos microcontroladores / microprocesadores
5
podría haber una dirección de código válida, y podría ser posible ubicar dicha función allí.En la mayoría de las computadoras de uso general, la primera página de la memoria (direcciones
0-1023
para páginas 4K) no es válida (sin asignar) a propósito para capturarnull
accesos de puntero.Por lo tanto, aunque el comportamiento depende de la plataforma, es razonable esperar que se produzca un error de página cuando
*proc
se invoca (por ejemplo,(*proc)(&v)
). Antes del momento en el que*proc
se invoca, no ocurre nada inusual.A menos que esté escribiendo un enlazador dinámico, es casi seguro que no debería estar calculando direcciones numéricamente y asignándolas a variables de puntero a función.
fuente
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/cc1plus.exe -da so.cpp
Esta línea de comando genera muchos archivos intermedios. El primero de ellos
so.cpp.170r.expand
, dice:... int main() () { int D.2229; int _1; ;; basic block 2, loop depth 0 ;; pred: ENTRY _1 = 0; ;; succ: 3 ;; basic block 3, loop depth 0 ;; pred: 2 <L0>: return _1; ;; succ: EXIT } ...
Esto todavía no responde exactamente a lo que sucede, pero debería ser un paso en la dirección correcta.
fuente