4

I am starting to learn programming in C language the book I am refering to code shows some source code with gets() and my IDLE recognises it as well. But still while compiling it, my compiler doesn't agree with it.

Can anyone help me out? I am using gets() in the main function and using clang as the compiler.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Mr. Anderson
  • 49
  • 1
  • 1
  • 3
  • 8
    Probably because `gets` has been removed alltogether. What is the __exact__ error message you get? I'm pretty sure it's a linker error. And __never__ use implicit declararions, they are a leftover from the last century. – Jabberwocky Mar 13 '18 at 12:25
  • 2
    @Mr. Anderson The function gets is unsafe and is not supported by the C Standard any more. Use instead the function fgets. You can find its description in internet. – Vlad from Moscow Mar 13 '18 at 12:27
  • string0.c:8:5: error: implicit declaration of function 'gets' is invalid in C99 [-Werror,-Wimplicit-function-declaration] gets(s1); ^ – Mr. Anderson Mar 13 '18 at 12:28
  • 4
    @Mr.Anderson OK, so that' is actually a compiler error. Apparently the C compiler you use doesn't allow implicit declarations at all, which is s good thing. The `gets` function has bee deprecated some 20 years ago. Just don't use it. Read [__this__](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Jabberwocky Mar 13 '18 at 12:30
  • @VladfromMoscow it did work. Thank you very much. :-) – Mr. Anderson Mar 13 '18 at 12:32
  • @MichaelWalz Thank you very much for help. :-) – Mr. Anderson Mar 13 '18 at 12:34
  • 2
    Three things. 1: Implicit declarations were only ever valid for functions returning `int`; `gets()` returned `char *`, so an implicit declaration of `gets()` is wrong regardless. 2: As of C99, implicit declarations are no longer allowed *at all*. 3: `gets()` has been removed from the standard library as of C2011 because it is *dangerous* and *will* introduce a point of failure in your code. Never use it, not even in toy code. – John Bode Mar 13 '18 at 13:56
  • @JohnBode I wish modern C libraries would implement `gets` as `char *gets(char *s) { return strcpy(s, "Never use gets!"); }`. – Steve Summit Mar 13 '18 at 14:02
  • "the book I am refering to code shows some source code with gets()" Try to burn the book and see if that solves the problem. Get a book written this millennia instead. – Lundin Mar 13 '18 at 14:41
  • Possible duplicate of [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – phuclv Mar 13 '18 at 14:47

3 Answers3

7

Expanding on my comment:

First, never use gets(), for any reason, even in toy code. If you see it in an example program, ignore the example and move on. It was deprecated in C99 and removed from the standard library completely in C2011 because it was a major security hole. The heartburn caused by that one function was worth breaking 30-some-odd years of legacy code.

Second, under C89 and earlier, if the compiler saw a function call before it saw a declaration or definition, it would assume the function returned int - IOW, the function had an implicit declaration of int. If you had a function definition later in the same translation unit, and the function returned an int, you were fine:

int foo( void )
{
  int x = bar(); // bar *implicitly* declared to return int
}

int bar( void ) // implicit declaration matches definition, we're good
{
  return some_integer_value;
}

However, if bar did not return an int, you'd get an error because the implicit int declaration did not match up with the non-int definition.

gets() returns char *, not int, so an implicit declaration of gets is incorrect regardless.

C99 removed implicit int declarations entirely - since then, all functions must be declared or defined before they are called.

EDIT

The most likely reason you're getting that implicit declaration error is that your compiler is recent enough that it no longer has a declaration for gets in stdio.h.

John Bode
  • 119,563
  • 19
  • 122
  • 198
1

You're getting a message like "implicit declaration of gets is not allowed" for the same reason you'd get the message "implicit declaration of my_undeclared_function is not allowed" if you tried to call my_undeclared_function. These days, gets is not a standard C library function.

To explain in more detail: in modern C, if you write

int main()
{
    f();
}

int f()
{
    return 0;
}

you will typically get a message like "implicit declaration of function 'f' is invalid in C99". Once upon a time, if you called a function the compiler hadn't heard of (yet), it assumed it was going to be a function returning int, but that assumption was removed in C99.

On the other hand, if you write

#include <stdio.h>

int main()
{
    char line[100];
    printf("type something:\n");
    fgets(line, sizeof(line), stdin);
    printf("you typed: %s", line);
    return 0;
}

you will not get that message about the functions printf and fgets. These are functions that the compiler has heard of: their declarations are in <stdio.h>.

But if you write

#include <stdio.h>

int main()
{
    char line[100];
    printf("type something:\n");
    gets(line);
    printf("you typed: %s", line);
    return 0;
}

you will get the message again, about function gets(), because gets is not a function the compiler has heard of. It is not a standard function; it is not declared in <stdio.h>.

Now, once upon a time, gets was a standard function and it was declared in <stdio.h>, but it was a spectacularly ill-conceived and dangerous function, so it has been removed from the standard. The book you read recommending it is quite out-of-date.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • This isn't correct. `gets` was just flagged as obsolete in C99, it was not removed from the language. – Lundin Mar 13 '18 at 14:30
  • @Lundin I didn't say that `gets` was removed from the language in C99. I wasn't sure when it was removed, but if you say it was C11, I believe you. – Steve Summit Mar 13 '18 at 14:41
0

You didn't #include <stdio.h>, simple as that.

In C99, you get the error if you use this exact code:

int main (void)
{
  char buf[10];
  gets(buf);
  return 0;
}

Including stdio.h fixes the problem. Though notably, gets was flagged as an obsolete function in C99 and removed entirely from the language in C11. So the following code will not compile in standard C (C11):

#include <stdio.h>

int main (void)
{
  char buf[10];
  gets(buf);
  return 0;
}

So possibly you could get the error because you compile as standard C instead of C99.

(Note that the Windows Mingw compiler specifically might use a C11 compiler but a C99 standard lib, so you may get some odd outcomes with that one.)

See Why is the gets function so dangerous that it should not be used? for details.

Lundin
  • 195,001
  • 40
  • 254
  • 396