c++ - pointer - Significado de int(*)(int*)=5(o cualquier valor entero)
ptr function c (4)
Como han señalado otras respuestas, es un error que
int (*) (int *) = 5;
compila Una aproximación razonable de esta declaración que se espera que tenga un significado es:
int (*proc)(int*) = (int (*)(int*))(5);
Ahora
proc
es un puntero a función que espera que la dirección
5
sea la dirección base de una función que toma un
int*
y devuelve un
int
.
En algunos microcontroladores / microprocesadores,
5
podría ser 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) son intencionalmente inválidas (sin asignar) para capturar accesos de puntero
null
.
Por lo tanto, aunque el comportamiento depende de la plataforma, es razonable esperar que ocurra un error de página cuando se invoca
*proc
(por ejemplo,
(*proc)(&v)
).
Antes del momento en que se invoca
*proc
, no ocurre nada inusual.
A menos que esté escribiendo un vinculador dinámico, es casi seguro que no debería calcular numéricamente las direcciones y asignarlas a variables de puntero a función.
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 *)
como argumento y devuelve un int, pero no entiendo cómo podría igualarlo 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 la función apunta a la ubicación de memoria 5, pero eso no funciona, claramente, y tampoco lo hacen los valores hexadecimales.
Pensando que podría ser porque 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 del 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 compila para este puntero de función.
Entonces, ¿qué significa la tarea?
Actualización 1
Tenemos 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 explicación (buena) sobre eso 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 a 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, le permitirá compilar, como
std::string (*) () = 5.6;
Pero tan pronto como el puntero de la función es una función que devuelve algún puntero, no se compila, como con
some_data_type ** (*) () = any_value;
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 compila:
int (*) (int *);
pero ambas son declaraciones inválidas.
EDITAR :
T.C.
menciona en los comentarios
gcc.gnu.org/bugzilla/show_bug.cgi?id=60680
bug
gcc.gnu.org/bugzilla/show_bug.cgi?id=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 puede emitir el diagnóstico en el alcance del bloque).
EDITAR3 :
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).
No es válido C ++. Recuerde que debido a que su compilador en particular compila, no lo hace válido. Los compiladores, como todo el software complejo, a veces tienen errores y esto parece ser uno.
Por el contrario,
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 válida C ++.
Pretende ser una asignación (debido a
=
) pero no contiene ningún identificador.
/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 lo que sucede exactamente, pero debería ser un paso en la dirección correcta.