Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function call in if statement without parentheses

Tags:

c

syntax

Recent versions of gcc and clang on Fedora Linux compile the following program without error:

#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;
}

This is with gcc 4.7.2 and clang 3.0. On my Mac, in contrast, both gcc 4.2.1 and Apple clang 4.1 complain about missing parentheses in the "if islower(c)" line, as expected. In all cases, I ran the compilers with "-std=c99".

Is this a bug in recent versions of gcc and clang, a quirk in the C language, or something else? The C99 standard (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf p. 133) appears to mandate parentheses around if expressions in all cases.

like image 348
Jelle Zijlstra Avatar asked Oct 02 '12 15:10

Jelle Zijlstra


2 Answers

It's likely that islower() is a macro, and that the expansion adds the parenthesis.

Post the pre-processed output from GCC, which you can get by compiling with the -E option.

like image 177
unwind Avatar answered Nov 03 '22 15:11

unwind


I just looked through the ctype.h file located in /usr/include/ctype.h and found the following definition for islower:

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

Going to the definition for __isctype() I find:

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

So your code if islower(c) expands to:

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

Which, as unwind said, added the parenthesis during expansion.

like image 27
Kristina Avatar answered Nov 03 '22 15:11

Kristina