Este es mi código:
#include <stdlib.h> #include <stdio.h> int sum(int,int); int sum(int x, int size) { int sum = 0; printf("%p\n", &x); printf("%p\n", &size); printf("%p\n", &sum); sum(x,size); return 0; } int main() { sum(2,4); return 0; }Y el error que me sale es:
hello.c:11:5: error: called object type 'int' is not a function or function pointer sum(x,size); ~~~^Cambiaste el significado de sum aquí:
int sum = 0; De ahora en adelante, en el ámbito en el que fue declarado, sum es un int , y esto se convierte en una tontería:
sum(x,size); /* Wat? sum is an int!!! */No hagas eso, y tu código se compilará. Una vez que compila, puede preocuparse por detener la recursividad.
Si define dos identificadores separados del mismo nombre para diferentes entidades en el mismo espacio de nombres, es posible que se superpongan. El estándar C11 , capítulo §6.2.1 establece,
Si un identificador designa dos entidades diferentes en el mismo espacio de nombres, los ámbitos pueden superponerse....
Consulte la nota al pie: por qué en este escenario, ambas sum están en el mismo espacio de nombres
Entonces, una vez que redefina el identificador con algún otro tipo,
....Si es así, el alcance de una entidad (el alcance interno ) terminará estrictamente antes que el alcance de la otra entidad (el alcance externo ). Dentro del ámbito interior, el identificador designa la entidad declarada en el ámbito interior; la entidad declarada en el ámbito externo está oculta (y no visible) dentro del ámbito interno.
Eso significa, esencialmente, en su caso, dentro de la función sum() , cuando está definiendo int sum , básicamente está sombreando la función sum . Después de la redefinición, sum es un identificador de tipo int , en el ámbito de esa función . Por lo tanto, dentro de la función sum() , no puede realizar una llamada a sum() ya que ahora es un tipo int .
Sin embargo, FWIW, la llamada a sum() en main() (o, más bien, fuera de sum() en sí misma) debería ser válida, ya que en ese punto, int sum estará fuera del alcance.
Solución: Cambie el nombre de la variable int sum a otra cosa.
Gracias a @pmg por la corrección.
EDITAR:
Como se menciona en la otra respuesta de @juanchopanza , después de cambiar el nombre de la variable de sombreado , su programa se compilará y una vez que lo ejecute, enfrentará una recursión infinita debido a la llamada incondicional a sum() dentro de sum() . Debe agregar alguna condición de interrupción para finalizar ( return desde) la recursividad.
Nota:
Con referencia a C11 , capítulo §6.2.3 , espacios de nombres , podemos decir que hay espacios de nombres separados para varias categorías de identificadores, por ejemplo, 1) nombres de etiquetas 2) las etiquetas de estructuras, uniones y enumeraciones, 3) los miembros de estructuras o uniones y 4) todos los demás identificadores.
Entonces, en este caso particular, la función sum() y la definición int sum residirán en el mismo espacio de nombres, para el alcance de la función sum()
El alcance importa
sum aquí tiene un alcance global. La variable sum es local y tiene alcance local.
El conflicto se debe a que dentro sum() llamas a sum() . Ahora dentro de la función sum() tiene 2 objetos del mismo nombre y de diferente tipo, de ahí el error.
Si tuvieras algo como
int sum() { int sum = 0; sum = 10; printf("%d\n",sum); } Entonces tu código habría estado bien. Dado que la variable sum es local para la función sum() y es el único objeto dentro de la función sum() con ese nombre.
En lugar de preocuparse por esto, es mejor cambiar el nombre de la variable y asegurarse de que el nombre de la variable y el nombre de la función sean diferentes.