0

I have the following code:

#include <stdio.h>

int main() {
    putc_unlocked('a', stdout);
    return 0;
}

I get no error when I compile it using gcc file.c, however, if I use gcc -std=c11 file.c, I get:

file.c: In function ‘main’:
file.c:4:2: warning: implicit declaration of function ‘putc_unlocked’ [-Wimplicit-function-declaration]
  putc_unlocked('a', stdout);
  ^

Why?

dario2994
  • 48
  • 6
  • Possible duplicate of [Are prototypes required for all functions in C89, C90 or C99?](http://stackoverflow.com/questions/434763/are-prototypes-required-for-all-functions-in-c89-c90-or-c99) – Sami Kuhmonen Nov 27 '15 at 09:51
  • There is no function `putc_unlocked` in standard C, so what did you expect? You have told the compiler to compile the code according to the standard, so misc GNU crap will get excluded. The compiler is not allowed to dump GNU crap in standard headers. – Lundin Nov 27 '15 at 09:54

2 Answers2

3

Compiling using -std=cxx where xx is 99 or 11 depending on what version of C you are using will use different header files than compiling with -std=gnuxx (where again xx = 99 or 11).

The default setting (if you don't specify a command line argument) for GCC 5.2 is for -std=gnu11.

The gnu settings define the macros:

  1. _GNU_SOURCE, which turns on GNU only features;
  2. _POSIX_SOURCE, which turns on POSIX features;
  3. and maybe others? (_BSD_SOURCE is a possibility but I'm not sure).

If you compile with -std=cxx then you get standard C and not any extensions.

So this warning is because that function is not part of the C standard. Thus you get an implicit declaration of the function (which was allowed by the old C standards and kept for backwards compatibility).

You can edit your file to have #define _POSIX_SOURCE if you want to compile with -std=cxx.

dave
  • 4,812
  • 4
  • 25
  • 38
0

Because -std=c11 enforces a strict name space (as did C89 and C99).

Any identifier not mandated by C11 must not be visible. Since putc_unlocked is not a C11 identifier, there is no declaration visible and hence the declaration is implicit.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • @FUZxxl http://stackoverflow.com/questions/8270324/is-a-compiler-allowed-to-add-functions-to-standard-headers – Lundin Nov 27 '15 at 09:57
  • What is a "C11 identifier"?? You mean it enforces warnings about missing prototypes. But that started with C99 already. – too honest for this site Nov 27 '15 at 10:02
  • @Lundin I wonder how POSIX-style feature test macros are allowed then as the C standard does not make this rule conditional, i.e. defining macros before including headers should not alter the behaviour of headers or did I miss anything? – fuz Nov 27 '15 at 10:06
  • @FUZxxl I think a compiler can add macros that are not in any header and remain a conforming implementation. They just can't dump their own non-standard junk inside the standard headers, nor re-define identifiers already reserved by standard headers. – Lundin Nov 27 '15 at 10:09
  • @Lundin But the libc header files add non-standard junk like `fileno` in `stdio.h` when you define feature test macros like `_POSIX_C_SOURCE` before including them. I want to know on which ground such feature test macros are allowed. Is there a clause like “If the program defines macros beside `NDEBUG` before including standard headers, behaviour is implementation defined?” But if there was, standard compiler options like `-D` would suddenly be dodgy. – fuz Nov 27 '15 at 10:38
  • @FUZxxl GCC is probably not 100% standard compliant, simple as that. – Lundin Nov 27 '15 at 10:46
  • @FUZxxl **C11 7.1.3 Reserved identifiers, #2 "No other identifiers are reserved"**. This means a program is free to use all unreserved identifiers. If a header declares `putc_unlocked`, a program is no longer free to use that identifier (since that use may cause a type conflict or even a syntax error). – Jens Nov 27 '15 at 10:52
  • @Olaf A C11 identifier is any identifier (function, object, macro, type) that C11 specifies. – Jens Nov 27 '15 at 10:54
  • @Lundin: gcc as such is only a freestanding implementation, because it does not provide the C library, which is required for a hosted implementation. And as a freestanding implementation, it is free to provide other features. – too honest for this site Nov 27 '15 at 10:59
  • @Lundin I'm not talking about gcc, I'm talking about IEEE 1003.1 (POSIX), which a) specifies not to be in conflict with ISO/IEC 9899:1999 and b) that you can access POSIX functionality in standard headers by defining `_POSIX_C_SOURCE` before including any header files. On what basis is this legal considering ISO 9899:2011 §7.1.3? – fuz Nov 27 '15 at 11:02
  • @Jens: The C(11) standard requires an identifier to start with letter or underscore, followed by .... That's all the standard requires. However, you might think of the C library. But your claim "Any identifier not mandated by C11 must not be visible" is nonsense. If that was true, you could not add your own identifers or use system libraries. The standard just requires a hosted implementation to provide a certain set of _definitions_ (i.e. names plus code or objects, resp. macros) which have a specific behaviour. An implementation is free to add additional definittions. – too honest for this site Nov 27 '15 at 11:03
  • And note there is only one global name space. C does not have seperate name spaces for global names, only for `union`, `struct` and `enum` tags. – too honest for this site Nov 27 '15 at 11:07
  • @Olaf It's not nonsense; it's a fact. Library implementers *are* facing a problem. They have to either invade the implementation namespace (the non-reserved identifiers), or the C99 namespace (the reserved identifiers). Please inform yourself before accusing others of writing nonsense. In particular, read comp.std.c for a while or ask there if you don't believe what I wrote. – Jens Nov 27 '15 at 11:14
  • @Jens: Again: There is **no** "C99 name space". Are you really talking about C, or do you have C++ in mind? You are still to provide an authoritative reference for your claims. Here is the [C standard](http://port70.net/~nsz/c/c11/n1570.html); Just provide a link to the paragraph. And note that "a program" may very well include external libraries. – too honest for this site Nov 27 '15 at 11:42
  • The C standard categorizes identifiers after scope (6.2.1) linkage (6.2.2) and name space (6.2.3). Name space in C refers to a few special case areas where local identifiers can be used, such as struct/enum tags, struct members and labels. It has nothing to do with C++ namespace, the closest term to that in C is _scope_. – Lundin Nov 27 '15 at 11:58
  • @Olaf C11 6.2.3 "Name spaces of identifiers" talks about labels, tags, members and then "all other identifiers". If an identifier is reserved in some context, I call it *in the C11 name space* (so it's my term for something else; it is in contrast to the *application namespace* of all identifiers a program is free to use). But it does not change the fact that in a C11 program I must be able to use `int putc_unlocked;` and if I can't the implementation is not C11 conforming. Most 3rd party libs aren't C11-conforming, *because they invade the application name space* C11 guarantees I'm ok to use. – Jens Nov 27 '15 at 12:20
  • The term "name space" is well-defined in the C standard. using it for your own meaning is a bad idea and leads to missunderstanding you. You still forgot to think about my second part. The program is not just the code **you** wrote, but includes all additional libraries you use. And as gcc along is a freestanding implementation, it actually is free to provide whatever additional names it wants. – too honest for this site Nov 27 '15 at 12:31
  • @Olaf Well, that might be true in an ideal world. In comp.std.c the terms "implementation name space" and "application name space" as well as "name space pollution" are used for more than two decades. As for your second part: it doesn't matter what program I write and which libraries I link. If I can't use certain identifiers that makes that header/library non-conforming to C11 (e.g. POSIX90 adding `PIPE_BUF` to ``). And I doubt that the OP uses gcc in freestanding mode. – Jens Nov 27 '15 at 13:17