2012-10-02 44 views
7

versiones recientes de gcc y sonido metálico en Fedora Linux compilar el programa siguiente sin error:llamada Función de sentencia if sin paréntesis

#include <ctype.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) { 
    char c = 'a'; 
    if islower(c) 
     printf("%d", c); 
    else 
     printf("%c", c); 
    return 0; 
} 

Esto es con gcc 4.7.2 y 3.0 sonido metálico. En mi Mac, en cambio, tanto gcc 4.2.1 como Apple clang 4.1 se quejan de que faltan paréntesis en la línea "if islower (c)", como se esperaba. En todos los casos, ejecuté los compiladores con "-std = c99".

¿Es esto un error en las versiones recientes de gcc y clang, una peculiaridad en el lenguaje C, o alguna otra cosa? El estándar C99 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf p.133) parece indicar paréntesis alrededor de las expresiones if en todos los casos.

+0

¿Compilará 'si 42 printf (" 42! \ N ");'? Si lo hace, es una versión interesante de las expresiones. Formalmente, si olvidamos 'if',' 42' y '(42)' son idénticos. Ídem con 'islower (c)' y '(islower (c))'. –

+0

Alexey, eso no es del todo cierto, ya que la gramática C requiere paréntesis en este contexto particular. Resulta que los paréntesis están aquí provistos por una macro. –

+0

Jelle, es por eso que dije "es una versión interesante de las expresiones" porque, según mi leal saber y entender, los parens son obligatorios. –

Respuesta

10

Yo miraba a través del archivo ctype.h situado en /usr/include/ctype.h y encontré la siguiente definición para islower:

#define islower(c) __isctype((c), _ISlower) 

ir a la definición de __isctype() encuentro:

#define __isctype(c, type) \ 
    ((*__ctype_b_loc())[(int) (c)] & (unsigned short int) type) 

lo que el código if islower(c) se expande a:

if ((*__ctype_b_loc())[(int) (c)] & (unsigned short int) _ISlower) 

Que, como se relajó, agregó el paréntesis durante la expansión.

+0

relájate y tienes razón, gracias! Debería haber supuesto que ese era el caso. gcc -E produce "if ((* __ ctype_b_loc()) [(int) ((m))] & (unsigned short int) _ISalpha)", como dijiste. –

13

Es probable que islower() sea una macro y que la expansión agregue el paréntesis.

Coloque la salida preprocesada de GCC, que puede obtener compilando con la opción -E.

Cuestiones relacionadas