"_CRT_SECURE_NO_WARNINGS" 实际上是什么意思?

8

我在使用scanf()函数时,在 Visual Studio 中一直遇到 C4996 错误。

解决这个问题的方法是在“配置属性”->“C/C++”->“预处理器”->“预处理器定义”->“编辑”中添加 _CRT_SECURE_NO_WARNINGS 这一行。

这完美地解决了问题,但我找不到对这个东西实际意义的适当解释。如果它禁用了警告,那么我的程序为什么会崩溃呢?什么是“CRT”?

以下是一个崩溃程序的示例:

#include <stdio.h>
main()
{
    int number;
    printf("enter a number\n");
    scanf("%d", &number);
}

错误信息如下: The _CRT_SECURE_NO_WARNINGS error message


4
CRT是C运行时库。"_CRT_SECURE_NO_WARNINGS"的意思是当你使用 "scanf" 时,你不想让编译器建议使用库函数的安全版本,例如 "scanf_s"。 - user3386109
请参见 https://dev59.com/AXE95IYBdhLWcg3wKqsk。 - jamieguinan
1
MSVC希望您使用其自己的版本函数,例如scanf_s等,以便更安全地使用。但是它们同样难以使用,并且它们不是直接替换(它们的参数不同),因此可以说它们并不更安全。而且它们是非标准的。该定义抑制了编译器的“警告”。 - Weather Vane
scanf存在风险。MSVC更喜欢您使用C11 Annex K标准提供的替代方案。参数相同,通过要求格式化字符串指定缓冲区大小,更加安全。虽然库编写者可以忽略标准,但它是一个标准。他们没有这样做,他们的库长期以来一直受到攻击。 - Hans Passant
@HansPassant MS 版本 的参数是不同的。*"与 scanf 不同,scanf_s 对于所有类型为 c、C、s、S 或包含在 [] 中的字符串控制集的输入参数都需要指定缓冲区大小。字符缓冲区大小作为一个附加参数紧跟在指针或变量后面传递。"* 缓冲区大小不在格式化字符串中。 - Weather Vane
1
@HansPassant,“scanf”并不比C语言的其他部分更危险:也就是说,只要正确使用,它就是完全安全的。实际上,如果您对字符串使用常量格式字符串和长度说明符,并且不使用“%n”,那么它可能比C语言的其他部分更安全 - Peter - Reinstate Monica
1个回答

4
在Windows上,CRT是C运行时库,它提供了诸如scanf之类的函数。在Linux上,这是通过GNU LibC (GLibc)完成的。
正如@jamieguinan所指出的那样,scanf存在一些安全漏洞,例如缓冲区溢出,用户提供的输入可能比缓冲区的大小还要大,导致其覆盖其他内存。
这就是为什么Visual Studio警告您使用scanf_s,它是scanf的更安全版本。
您可以在代码中放置此预处理器定义以禁用此警告:
#define _CRT_SECURE_NO_WARNINGS

尽管如此,如果您真的知道自己在做什么,这并不是必要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接