Why is implicit declaration of gets() not allowed in C99?

旧街凉风 提交于 2019-12-12 18:24:48

问题


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.


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/49256131/why-is-implicit-declaration-of-gets-not-allowed-in-c99

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!