2011-12-18 8 views
7

Me preguntaba si hay algún problema al pasar un puntero a putchar, o cualquier otra función estándar que se pueda implementar como una macro, a un función que acepta un puntero a la función. A continuación hay un ejemplo de lo que estoy haciendo.Pasando un puntero a putchar a una función que recibe un int (*) (int)

#include <stdio.h> 

static int print(const char *s, int (*printc)(int)) 
{ 
     int c; 

     while (*s != '\0') { 
       if ((c = printc(*s++)) < 0) 
         return c; 
     } 
     return printc('\n'); 
} 

int main(void) 
{ 
     print("Hello, world", putchar); 
     return 0; 
} 

que no tienen ningún problema en la compilación de este con GCC y Sonido metálico bajo GNU/Linux, así como GCC bajo OpenBSD. Me pregunto si tendrá el mismo comportamiento en cualquier otra implementación compatible estándar, ya que putchar se puede implementar como una macro. He buscado a través del estándar, particularmente las secciones sobre punteros de función y putchar, y no he podido encontrar nada que especifique si esto es legal o no.

Gracias.

+0

Si su "función" es en realidad una macro, entonces su código no se compilará. –

+0

No estoy seguro si esto cumple con las normas, pero con 'gcc' esto parece ser el comportamiento esperado: http://gcc.gnu.org/onlinedocs/cpp/Function_002dlike-Macros.html – RageD

+0

Haga que * solo * una macro .. –

Respuesta

6

A raíz de mis comentarios basados ​​en la @pmg , Encontré la sección correspondiente de la norma (C99, 7.1.4 p.1):

... está permitido tomar las direcciones s de una función de biblioteca incluso si también se define como una macro. 161)


161) Esto significa que una aplicación deberá proporcionar una función real para cada función de la biblioteca, aunque también proporciona un macro para esa función.

+0

+1 para pescar el pasaje relevante del Estándar :) – pmg

+0

@pmg: +1 por tu respuesta también, por hacerme aprender algo hoy ... –

2

Es legal, porque se refiere a la función de biblioteca, no a la macro. Cuando se define como una macro, esa macro toma un argumento, y por lo tanto putchar sin paréntesis siguiente no se refiere a ella. Esta es una instancia del uso de una macro para funciones en línea, y no debe tomarse como una buena práctica ahora que los compiladores soportan la incorporación.

2

La macro solo se "invoca" cuando a su identificador le sigue un paréntesis abierto (. De lo contrario, se invoca/usa la función real del mismo nombre.

definición
#include <stdio.h> 
#define macro(x) 42 
int (macro)(int x) { return x; } 
int main(void) { 
    printf("%d %d\n", macro(1), (macro)(1)); 
} 

La función tiene paréntesis "extra" para evitar que la macro de ser ampliado

Ver código que se ejecuta en Ideone: discusión http://ideone.com/UXvjX

+0

De hecho. Pero no creo que eso realmente ayude al PO con su problema. –

+1

El estándar establece explícitamente que 'putchar' debe ser una función (también puede ser una macro), por lo que el código del OP funciona. – pmg

+0

Ah sí, tienes razón, acabo de encontrar la sección relevante del estándar. –

Cuestiones relacionadas