C Compiler not throwing error when no type is spec

2019-02-17 11:18发布

Why this below program not throwing an error:

dfljshfksdhfl;
#include <stdio.h>
int main () {
        return 0;
}

gcc would just throw a warning:

test.c:1:1: warning: data definition has no type or storage class [enabled by default]

3条回答
唯我独甜
2楼-- · 2019-02-17 12:14

First of all, gcc is not a conforming C compiler by default. It implements a dialect of C89/C90 with GNU extensions.

You can use -std=cNN -pedantic (where NN can be 90, 99, or 11) to cause it to (attempt to) conform to a specified version of the ISO C standard. C90 permitted implicit int; it was dropped in C99.

But C compilers are not actually required to generate fatal error messages (except for a #error directive). The standard's requirement (N1570 5.1.1.3p1) is:

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.

A non-fatal warning qualifies as a "diagnostic message". A conforming C compiler can print a warning for any error -- even a syntax error -- and then continue to successfully compiler the source file. (This is how some compiler-specific language extensions may be supported.)

Personally, I find gcc to be overly lax about certain errors; in my opinion, a missing int should be treated as a fatal error. But that's just my preference, not a requirement imposed by the standard.

The lesson here is that you should not assume that mere warnings are harmless. Ideally, compiling your code should produce no diagnostics at all. Cases where it's ok to ignore warnings are rare (but they do exist, since compilers are free to warn about perfectly valid code).

查看更多
forever°为你锁心
3楼-- · 2019-02-17 12:21

I've already answered a similar question (actually I'm pretty sure it's a duplicate, but whatever) and the answer is found in the C99 rationale.

A new feature of C99:

In C89, all type specifiers could be omitted from the declaration specifiers in a declaration. In such a case int was implied. The Committee decided that the inherent danger of this feature outweighed its convenience, and so it was removed. The effect is to guarantee the production of a diagnostic that will catch an additional category of programming errors. After issuing the diagnostic, an implementation may choose to assume an implicit int and continue to translate the program in order to support existing source code that exploits this feature.

@Shafik's answers tells you one way to turn the warning into an error (for Clang). If you consider -Werror to be too strict, you can turn that one warning into an error with -Werror=implicit-int. In GCC, it appears that -pedantic-errors is necessary.

查看更多
霸刀☆藐视天下
4楼-- · 2019-02-17 12:24

This is because even though implicit int is no longer part of the C standard since C99 some compilers still support it, mainly to prevent breaking a lot of old code. So this line:

dfljshfksdhfl;

ends up being equivalent to:

int dfljshfksdhfl;

clang gives us a much more informative warning by default:

warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
dfljshfksdhfl;
^~~~~~~~~~~~~

We can use the -pedantic-errors flag to turn this into an error, although oddly enough this does not work for clang and so we have to resort to -Werror and turn all warnings into errors, which is actually a good habit to get into. As remyabel points out for clang we can also use -Werror=implicit-int.

查看更多
登录 后发表回答