15

I am trying to find what is the combination of gcc flags to use when testing strict C90 conformance. According to previous post: GCC options for strictest C code?, I should only need a --std=c90.

However here is what I tried:

$ cat t.c
#include <stdint.h> /* added in C99 */

int main()
{
  uint64_t t;
  return 0;
}
$ gcc -std=c90 -ansi -pedantic   t.c

The above does work well (no warnings/errors produced).

Does anyone knows of:

  1. gcc flags to have strict ISO/IEC 9899:1990 conformance
  2. A different compiler (tcc, clang...) with different set of flags ?

EDIT:

Sorry for my wording, yes I would really like to mimic a strictly conforming C90 compiler, in other word it should fail if the code tries to use any feature added later (C99 comes to mind). So pthread include header ought to emit a warning when compiled in what GNU/GCC calls C90 mode (just like stdint.h header should produce a warning without C99). -pedantic nicely warns me about usage of long long, I do not see why it should not warn me about uint64_t.

I used the terminology of ISO/IEC 9899:1990 as quoted from:

In 1990, the ANSI C standard (with formatting changes) was adopted by the International Organization for Standardization (ISO) as ISO/IEC 9899:1990, which is sometimes called C90. Therefore, the terms "C89" and "C90" refer to the same programming language.

EDIT2:

GCC documentation are actually quite clear:

Some features that are part of the C99 standard are accepted as extensions in C90 mode, and some features that are part of the C11 standard are accepted as extensions in C90 and C99 modes.

So my question is rephrased into:

  • Is there a compiler + standard include header on a linux system which strictly conforms to C90 ?
Community
  • 1
  • 1
malat
  • 12,152
  • 13
  • 89
  • 158
  • 1
    Please note that C90 is specified in the standard ISO/IEC 9899. You ask for ISO/IEC 9945-1 which is the POSIX standard. – Lundin Oct 22 '14 at 07:41
  • I've not heard of a compiler that allows you to check this. Some compilers, such as gcc and clang together with a 3. party standard library goes to a fair length to support the requested standard, especially at the language level, but they are not meant to be compliance checkers. For library features it's even more moot, since C allows non-standard library/headers to be available, nothing stops an implementation from supplying stdint.h to in a c89 compiler - e.g. gcc and clang does not supply the library/header files - that's left to a 3. party (often glibc on linux) – nos Oct 22 '14 at 08:10
  • 1
    You say *ought* to emit a warning, where's your proof? After combing through the standard I don't see anywhere where it says a compiler is required to emit a diagnostic. –  Oct 22 '14 at 08:10
  • Your statements about strict conformance are incorrect, you are making things up. There is nothing in the standard that states that the compiler should give a notification for this, nor is there anything that prevents the presence of external libraries. The C standard also allows future language extensions to be present in a strictly conforming program, given that none of the compiler identifiers collide with reserved names. See [this](http://stackoverflow.com/questions/8270324/is-a-compiler-allowed-to-add-functions-to-standard-headers). – Lundin Oct 22 '14 at 08:12
  • @Lundin, sorry bogus copy/paste. I used the wrong ISO ref. thx – malat Oct 22 '14 at 08:16
  • 2
    @malat There's nothing in `` that should fail to compile in C90 mode. The implementation is allowed to omit any typedefs/macros for the corresponding type it doesn't provide. If you try to include a C++11 header in C++03 the compiler itself doesn't issue a diagnostic, rather GCC has an `#error` pragma in a header file. –  Oct 22 '14 at 08:21
  • Recommended reading: C90 4.1.2 Standard headers. – Lundin Oct 22 '14 at 08:22
  • 1
    I guess the guys maintaining the headers could trivially implement that by adding something like `#if (__STDC_VERSION__ < 199901 && __PEDANTIC__)` followed by an `#error` directive to e.g. `stdint.h`. It's doubtful that they will, however, since I don't think the vast majority of users really need that feature and they'll likely not be bothered to patch two dozen headers "just in case". Though of course, you could always try and submit a patch. – Damon Oct 22 '14 at 10:09
  • If I write my own header and include it, you would want that to emit a warning? Including (Valid) headers is part of the C-90 spec is it not? – Baldrickk Oct 22 '14 at 11:24

2 Answers2

14

C90 compliance doesn't mean that the compiler can't offer other headers that aren't mentioned in the C90 standard. (sys/socket.h, for instance.) If you want to disallow these for some strange reason, you can pass the -I option to add an extra include path, and in that path put versions of all the C99-only headers which are simply #error Don't include me.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • 4
    "for some strange reason" - the reason is not strange at all. If OP wants to test their code so as to ensure that it doesn't have any C99- or OS-specific dependencies, then they most definitely **does** want to restrict themselves from using those headers. – The Paramagnetic Croissant Oct 22 '14 at 07:42
  • It's also possible for the compiler to parse a given header, resolve the macros if there are any, and not include anything, because after expanding the macro and evaluating the conditionals the header doesn't generate any text/code to be included as the result of the options passed to the compiler . After all it's not that hard to use `#ifdef` or `ifndef` or other options to protect your headers against unwanted inclusions . – user2485710 Oct 22 '14 at 08:15
  • @TheParamagneticCroissant I don't know of any compilers/runtimes which exist specifically for the purpose of disallowing C99 constructs. That would be a wholly unrewarding compiler to maintain. Even in the C90 headers provided by GCC, I'm certain there are function definitions which were not part of the C90 standard. – Sneftel Oct 23 '14 at 21:46
2

Keep in mind here that GCC itself is a conforming freestanding implementation of the C standard specified; such an implementation only supplies a small subset of the standard header files, and practically none of the actual functionality of the C standard library, instead relying on another party -- glibc on Linux systems, for instance -- to supply the C standard library's functionality.

What you seek is something that not only warns you when you are using a C99/C11/GNU language feature that is not in C90, but when you use a library function that is not defined by C90 itself. Sadly, the compiler alone cannot do this for the reason stated above -- it is aloof to what libc it is used with. On glibc systems, the C standard library will pick up on the macros defined by -std=c90 or -ansi:

The macro __STRICT_ANSI__ is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.

and give you some help by turning off gratuitous extensions:

If you compile your programs using ‘gcc -ansi’, you get only the ISO C library features, unless you explicitly request additional features by defining one or more of the feature macros.

However, this only covers extensions and POSIX-but-not-ISO C functions; it will not save you if a function's behavior is specified differently in ISO C and POSIX.1!

LThode
  • 1,843
  • 1
  • 17
  • 28