¿Por qué la dirección de una función de c ++ es siempre verdadera?

Bueno, ¿por qué?

#include <iostream>

using namespace std;

int afunction () {return 0;};

int anotherfunction () {return 0;};

int main ()
{
    cout << &afunction << endl;
}

da esto,

1

  1. ¿Por qué todas las direcciones de las funciones son verdaderas?
  2. ¿Y cómo puede funcionar entonces un puntero de función si todas las funciones comparten (al parecer) las mismas direcciones?

preguntado el 16 de mayo de 11 a las 20:05

Sospecho que el operador de la secuencia lo interpretó mal. Pruebe (void *) & una función, tal vez con un manipulador hexadecimal antes. -

(void*)&afunction ¡Obras! no necesitas el manipulador. -

7 Respuestas

La dirección de la función no es "verdadera". No hay sobrecarga para un ostream que acepta un puntero de función arbitrario. Pero hay uno para un booleano, y los punteros de función son implícitamente convertibles a bool. Entonces el compilador convierte afunction de cualquiera que sea su valor real para true or false. Dado que no puede tener una función en la dirección 0, el valor impreso es siempre true, cual cout se muestra como 1.

Esto ilustra por qué las conversiones implícitas suelen estar mal vistas. Si la conversión a bool fueron explícitos, habría tenido un error de compilación en lugar de hacer lo incorrecto en silencio.

contestado el 17 de mayo de 11 a las 00:05

+1, lo mismo que dije pero más rápido. "No hay sobrecarga para un ostream que acepta un puntero de función". Al menos, no hay uno que acepte cada puntero de función. Hay tres (plantillas) que aceptan tipos particulares de puntero de función, para manipuladores de flujo, pero no imprimen la dirección de todos modos. - Steve Jessop

Pensé que el type de todos los punteros era numérico. Preguntaría por qué no lo son, pero entiendo que es otra pregunta SO. gracias @Steve jessop y @Dennis Zickefoose. - código shogan

@code shogan: los punteros de función y los punteros de objeto no son lo mismo (porque las funciones no son objetos). Hay un operator<< esperando void*, pero no para int(*)(void). - Steve Jessop

@Steve, mi primer error fue asumir que todo es un objeto ya que C ++ era OO. algo así como el lenguaje * comiendo su propia comida para perros ", por ejemplo, en Python todo es un objeto. - código shogan

El tipo de puntero de función no es compatible con std::ostream fuera de la caja. Tus punteros se convierten al único tipo compatible posible: bool - y todo lo que no es cero es true gracias a la compatibilidad con versiones anteriores de C.

contestado el 17 de mayo de 11 a las 00:05

No hay sobrecarga de operator<< para punteros de función (excepto manipuladores de flujo), pero hay uno para bool, por lo que el puntero de función se convierte a ese tipo antes de mostrarse.

Las direcciones no son iguales, pero ambas no son nulas y, por lo tanto, ambas se ocultan a true.

contestado el 17 de mayo de 11 a las 00:05

No hay función sobrecargada: operator<<(ostream&, int(*)()), por lo que su puntero de función se convierte en el único tipo que funciona, bool. entonces operator<<(ostream&, bool) está imprimiendo el valor convertido: 1.

Es posible que pueda imprimir la dirección de la función así:

cout << (void*)&afunction << endl;

contestado el 17 de mayo de 11 a las 00:05

sí, Christian Rau lo señaló. Tal vez sea mi experiencia en Python, pero asumí que los punteros comparten un tipo (también conocido como herencia) ... pero ahora estoy pensando en C ++ cosas como punteros son el tipo. - código shogan

@code: punteros a objetos tipo de compartir una herencia. Cualquier puntero a un objeto se puede convertir a void*. Los punteros a funciones no se pueden convertir a void*. - Robᵩ

@Rob aha ahora entiendo cómo funciona el ejemplo anterior: no estamos convirtiendo punteros, pero en realidad solo la creación en su lugar, un puntero vacío. Todo finalmente tiene sentido. +1 - código shogan

@code tenga en cuenta que (void&)&func es una extensión de gcc. El estándar C ++ no garantiza que esto funcione. - Robᵩ

Err, quise decir "(void*)&func es una extensión gcc "- Robᵩ

Todas las direcciones en C ++ son distintas de cero, porque cero es el puntero NULL y es un valor reservado. Cualquier valor distinto de cero se considera verdadero.

contestado el 17 de mayo de 11 a las 00:05

No toca por qué el valor siempre es 1 (en lugar de 0x400110 o algo así). - cHao

@cHao, no pensé que necesitaba explicar eso; a juzgar por el título de la pregunta, asumí que el autor de la pregunta sabía que True era igual a 1. - Mark Ransom

Siguiendo solo el título, tienes razón. Sin embargo, la parte 2 de la pregunta real indica que lo esperado casi con certeza no es true o 1, pero la dirección de la función. La confusión no se trata del valor de un booleano, sino de que los punteros de función se convierten misteriosamente en bools en primer lugar. - cHao

No puede haber una sobrecarga de punteros de función para el operador iostream <<, ya que hay un número infinito de posibles tipos de puntero de función. Entonces, el puntero de la función obtiene una conversión aplicada, en este caso a bool. Intentar:

cout << (void *) afunction << endl;

Lo que le dará la dirección en hexadecimal; para mí, el resultado fue:

0x401344

contestado el 17 de mayo de 11 a las 00:05

Has comprobado anotherfunction() ¿también?

De todos modos, las direcciones de puntero de C ++, como las direcciones de puntero de C, suelen ser virtuales en la mayoría de las plataformas y no se corresponden directamente con las ubicaciones de memoria. Por tanto, el valor puede ser muy pequeño o inusual.

Además, siempre serán verdaderas, ya que 0 is NULL, un puntero no válido y todo lo que esté por encima de 0 es verdadero

contestado el 17 de mayo de 11 a las 00:05

No toca por qué el valor siempre es 1 (en lugar de 0x400110 o algo así). - cHao

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.