13

The gets() function has been removed from the C language. No such function exists in the standard.

Yet I compile the following code:

#include <stdio.h>

int main (void)
{
  (void) gets (NULL);
}

using

gcc -std=c11 -pedantic-errors -Wall -Wextra

and it compiles without giving any errors or warnings. Similarly,

#include <stdio.h>

int gets;

int main (void)
{}

will not compile (error: 'gets' redeclared as different kind of symbol).

In the standard 4. Conformance §6 we can read:

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program

Given the above I don't think gcc is standard-compliant, even in pedantic mode. Is there a reason for this? Is this intentional or is it a bug?

GCC version 4.9.1.

Edit:

gcc --version
gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    GCC 4.8.2 here. In pedantic mode the first snippet will not compiler because `gets` is never defined. In non-pedantic mode I get `warning: the \`gets' function is dangerous and should not be used.`. The second snippet is not an issue, because nothing prevents you from declaring a symbol called `gets`. For instance, `int printf;` is perfectly legal. Am I missing the point of the question? – Stefano Sanfilippo Jun 03 '15 at 12:18
  • 1
    What `libc` are you using? In Unix-like systems standard C library is shipped with OS. For example, in Linux it is usually _glibc_, which was removed `gets` in version 2.16 – myaut Jun 03 '15 at 12:21
  • 1
    @StefanoSanfilippo You seem to be missing the point regarding the second half, it shouldn't fail (`gets` shouldn't collide with anything), but it does. – unwind Jun 03 '15 at 12:22
  • 2
    I'm for a bug specific to gcc 4.9.1 as version 4.8.2 and > 4.9.2 do fail. – edmz Jun 03 '15 at 12:23
  • @unwind thanks. Actually in my case it doesn't, so I'd call it a library mismatch or compiler bug, but I don't want to jump to conclusions :\ – Stefano Sanfilippo Jun 03 '15 at 12:25
  • In case it matters, it is Mingw for 64 bit Windows. I'm using the default lib that came with the download. Is there a way I can check the lib version? – Lundin Jun 03 '15 at 12:26
  • 11
    MinGW uses Microsoft's standard library, which does not even support C99 properly. – interjay Jun 03 '15 at 12:32
  • @interjay Seriously? Then how can any modern C at all work in Mingw? I thought MS had dropped C support long time ago, let alone C11 support. – Lundin Jun 03 '15 at 12:46
  • @interjay: It is funny, considering that Microsoft has properly removed `gets` from their libraries. – AnT stands with Russia May 27 '16 at 17:47
  • @Lundin: Microsoft is devotedly supporting C language in their compilers. I don't know where you got the idea that "MS had dropped C support". – AnT stands with Russia May 27 '16 at 17:48
  • 2
    @haccks: No, gcc has never supported `gets` -- or `fgets` for that matter. If `gets` is supported by a given implementation, it's implemented by the library, not by the compiler. – Keith Thompson May 27 '16 at 19:28
  • @KeithThompson; My wording was wrong. It is still present GNU C library. – haccks May 27 '16 at 19:37
  • 2
    @haccks: Yes and no. In the `` header provided by the GNU C library, `gets` is still declared, but the declaration is surrounded by `#if !defined __USE_ISOC1` ... `#endif`. The *implementation* is still there, but in a way that permits user code to define a function with the same name. – Keith Thompson May 27 '16 at 19:42
  • 1
    Backwards compatibility — programs exist that use `gets()`, and it is deemed better to let them run than to prevent them running. – Jonathan Leffler May 28 '16 at 00:20

3 Answers3

12

gcc is just the compiler, not the entire implementation.

On my system (Linux Mint 17.3, gcc 4.8.4, GNU libc 2.19), I get:

$ gcc -std=c11 -pedantic-errors -Wall -Wextra -c c.c
c.c: In function ‘main’:
c.c:5:3: error: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
   (void) gets (NULL);
   ^

To correctly diagnose the error, the implementation needs to be conforming. That means both the compiler (which never provided gets in the first place) and the library.

You're using a library that still provides the gets function. Because of that the implementation as a whole (which consists of the compiler gcc, the library, and a few other pieces) does not conform to C11.

Bottom line: This is not a gcc issue, and there's not much that gcc can do about it. (Well, it could issue a special-case diagnostic for gets, but then it would have to determine that it's not a valid call to a user-defined function with the same name.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • Though C standard library droped `gets`, GNU C library still includes this function. – haccks May 27 '16 at 19:40
  • 2
    Copying my response to your other comment: @haccks: Yes and no. In the header provided by the GNU C library, gets is still declared, but the declaration is surrounded by #if !defined __USE_ISOC1 ... #endif. The implementation is still there, but in a way that permits user code to define a function with the same name. – Keith Thompson May 27 '16 at 19:43
  • OK. Do you consider this as a bug? – haccks May 27 '16 at 19:52
  • 3
    @haccks: It's a failure of this particular implementation (MinGW) to conform to the C11 standard. (See also MinGW's problems with `long double`, something that applies to C90, C99, and C11.) Sure, I'd say it's a bug. (But it's an easily avoidable one -- don't use `gets`, even if your compiler fails to warn you about it.) – Keith Thompson May 27 '16 at 19:55
  • Thanks for correcting me. I am glad you came to this post almost after an year (little bit surprised!!) to share this information. – haccks May 27 '16 at 20:00
  • @haccks: I didn't even notice the date until you mentioned it. I think it showed up on my front page because somebody else posted an answer. – Keith Thompson May 27 '16 at 20:04
  • Oh! I can see now. – haccks May 27 '16 at 20:05
1

The key line of your code is:

#include <stdio.h>

Did you update your system's C library and headers? They're also part of the C implementation, along with the compiler.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • I did run `mingw-get update` and `mingw-get upgrade`, same error afterwards. – Lundin Jun 05 '15 at 12:48
  • As Andrew mentioned, the key line is the #include . You should find and analyze the stdio.h file that is used by gcc to perform the compilation. That file probably still has the gets function defined. – Valy Jun 25 '15 at 08:05
1

update this may not be an answer to the question, I try to make it informational.

I happened to find that gcc mentioned gets is not following C11 standard for some library issue glibc 2.16.

See gcc supporting status of C11: https://gcc.gnu.org/wiki/C11Status croped from the above link

But I cannot find the definition of "library issue" and current status for other versions of glibc.

So I tried on my machine ubuntu16.04 with gcc version 5.3.1 20160413, glibc version Ubuntu GLIBC 2.23 We can get enough warning on compile time, but it's still OK to execute the output object file for "Backwards compatibility".

warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
warning: the `gets' function is dangerous and should not be used.
owlfox
  • 19
  • 1
  • 6
  • 4
    This is misleading. gcc didn't remove `gets` because gcc never provided `gets` in the first place. It's provided by the library, not by the compiler (which why that status page refers to it as a "library issue"). – Keith Thompson May 27 '16 at 19:26
  • @Keith Thompson. Thanks for the answer! That's amazing clear and helpful :). – owlfox May 28 '16 at 00:21