简体   繁体   中英

VS2013 C99 — Why Does This Compile?

Can someone tell me why the following code compiles (see getchar below)? I haven't written C in awhile but I'm pretty sure getchar line shouldn't allow this to compile. Just installed VS2013 Pro compiled with /Za + /Wall as C. Looking for C99 compliance.

int count_lines(void) {
    char c;
    int num_of_lines = 0;

    while ((c = getchar) != EOF)      // compiles as getchar instead of getchar()
        if (c == '\n') ++num_of_lines;

    return num_of_lines;
}

This:

c = getchar

attempts to assign the address of the function getchar to the char object c .

This is a constraint violation , meaning that any conforming C compiler must issue a diagnostic. That diagnostic may legally be a non-fatal warning, and a compiler is still allowed to produce a "working" executable -- though its behavior is not defined by the standard.

If a compiler doesn't reject it outright, it will most likely generate a conversion of the function pointer value to type char . The standard does not define the behavior of such a conversion (but it's likely to take the low-order 8 bits of the address. This is unlikely to match the value of EOF , resulting in an infinite loop.)

As I'm sure you know, the line

while ((c = getchar) != EOF)

should be

while ((c = getchar()) != EOF)

As you might not have noticed, the getchar() function returns a result of type int , not char , precisely so that the value EOF can be distinguished from any valid character value. You should declare c as an int , not as a char . See question 12.1 of the comp.lang.c FAQ .

I'm sure you got a compiler warning for this. But it compiles because what you are doing is setting c to the address of the function getchar (of course you are only getting the lowest byte of the address).

Are you not just assigning to c the value of the address of the getchar function. Which is probably not what you want but not illegal.

gcc -g -o test test.c
test.c: In function ‘count_lines’:
test.c:7:15: warning: assignment makes integer from pointer without a cast [enabled by   default]
     while ((c = getchar) != EOF)      // compiles as getchar instead of getchar()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM