4

Why am I getting this error?

implicit declaration of function 'gets' is invalid in C99 [-Werror,-Wimplicit-function-declaration]

Code:

#include <stdio.h>
#include <stdlib.h>

typedef struct myStruct
{
    char name[20];
    char tel[20];
}contact;

int main(void)
{
    contact *mycont[3];

    for(int i=0; i<3; i++)
    {
        mycont[i] = (contact*)malloc(sizeof(contact));
        printf("Enter Name Of The Contact No.%d\n",i+1);
        gets(mycont[i]->name);
        printf("Enter The Contact Telephone Number\n");
        gets(mycont[i]->tel);
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
H. Jay
  • 51
  • 1
  • 1
  • 2
  • 2
    Because `gets` is not a part of `c99` standard and should not be used. So it is excluded from the standard libraries. – Eugene Sh. Jun 15 '16 at 17:09
  • 7
    @EugeneSh.: The `gets` standard function is perfectly valid part of C99 standard. It has become obsolescent (deprecated) in C99 and it was removed in C11. – Grzegorz Szpetkowski Jun 15 '16 at 17:15
  • Really? I guess I've confused the standards. Sorry then. – Eugene Sh. Jun 15 '16 at 17:16
  • 1
    @EugeneSh: Precisely, deprecation of `gets` was added in C99 TC3 (see [N1235](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1235.pdf)). – Grzegorz Szpetkowski Jun 15 '16 at 17:20
  • 7
    The message "implicit declaration of function 'gets' is invalid" suggests there is no function prototype in `stdio.h` (and an implicit declaration assumes `int` argument). – Weather Vane Jun 15 '16 at 17:20
  • 3
    Perhaps the code is compiled with a flag that disables declarations of deprecated functions. – John Bollinger Jun 15 '16 at 18:12
  • 2
    use `scanf` instead. using `gets` is dangerous. – Ajeet Shah Jun 15 '16 at 18:34
  • 4
    Function `gets()` is deprecated. You are discouraged from using it because it is considered _insecure_. What does it mean? In your program you pass it just a name of a _receiver array_, and it is impossible to know how long the input will be. If your user bears in mind that (s)he shouldn't write names longer than 20 characters, it's OK. However, if (s)he goes past that limit, so will `gets()`: **it will continue writing past the array boundary into memory it doesn't own**. – user3078414 Jun 15 '16 at 19:03
  • in C, when calling any of the memory allocation functions: (malloc, calloc, realloc), 1) do not cast the returned value. The returned value has type `void*` so can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, maintain. 2) always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Jun 16 '16 at 14:16
  • 1
    strongly suggest using: `fgets()` rather than `gets()` as `fgets()` has a max length parameter, so does not allow input buffer overruns like `gets()` does. – user3629249 Jun 16 '16 at 14:17
  • 2
    See [Why `gets()` is so dangerous it should never be used](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used). That doesn't explain why it was not declared when you have `` included. It should be, especially under C99 rules — it was a part of the C99 standard as of 1999, and was not deprecated until later, and was only removed from the standard in C11. To understand what was happening, we'd probably need more information about the platform you're using (o/s, version, C compiler, version, command line used to compile). – Jonathan Leffler Aug 07 '16 at 22:27
  • Possible duplicate of [Why is implicit declaration of gets() not allowed in C99?](https://stackoverflow.com/questions/49256131/why-is-implicit-declaration-of-gets-not-allowed-in-c99) – YtvwlD Jun 14 '19 at 21:17

1 Answers1

3

It's a safe bet that, even though the error message mentions C99, you are in fact using a compiler following a later standard, one in which gets was removed rather than just deprecated.

For example, when I try to compile the following simple program:

#include <stdio.h>
char buff[1000];
int main(void) {
    gets(buff);
    return 0;
}

with clang under Ubuntu 18.04:

clang -Werror --std=c11 -o qq qq.c

I get that same error:

qq.c:4:2: error: implicit declaration of function 'gets' is invalid in C99
                 [-Werror,-Wimplicit-function-declaration]

This is actually only tangentially related to the deprecation and removal of gets (in that it's no longer declared anywhere). It's more to do with the fact you shouldn't be trying to use any function without an active declaration, as per ISO C99 Foreword /5 (paraphrased):

This second edition cancels and replaces C90, as amended and corrected by various other ISO gumpf. Major changes from the previous edition include:

  • remove implicit function declaration.

  • lots of other stuff, irrelevant to this question.

You can see this if you replace gets with xyzzy, which results in the same error:

qq.c:4:2: error: implicit declaration of function 'xyzzy' is invalid in C99
                 [-Werror,-Wimplicit-function-declaration]

In fact, if you actually try to use gets with the C99 flags set, you'll get a totally different message (or none at all if your compiler implements C99 before they deprecated gets - that wasn't done until TC3):

qq.c:4:2: error: 'gets' is deprecated
                 [-Werror,-Wdeprecated-declarations]
Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953