繁体   English   中英

为什么strcpy()在不包含的情况下工作<string.h>

[英]Why strcpy() is working without including <string.h>

我正在使用一些C示例,并使用功能strcpy() ,但是忘记了包含<string.h> ,尽管我已经包含了<stdio.h> 令我惊讶的是,代码成功运行了。 以下是我正在执行的代码:

#include <stdio.h>

int main() {
   char message[10];
   int count, i;

   strcpy(message, "Hello, world!");

   printf("Repeat how many times? ");
   scanf("%d", &count);

   for(i=0; i < count; i++) {
      printf("%3d - %s\n", i, message);
   }
}

我正在使用gcc version 3.3.6 (Ubuntu 1:3.3.6 - 15ubuntu1)

我什至没有收到任何编译警告。

在此处输入图片说明

为什么我的代码在不包含<string.h>情况下<string.h>正常工作?

提前致谢。

编译器采用int strcpy()并调用古老的向后兼容行为。 指针参数是可以工作的类型之一,所以很好。

不要依赖它。 安全导轨已关闭。

我记得,GCC 3默认为C89一致性以及GNU扩展。 C89允许在不事先声明的情况下调用函数-假定它们返回int ,并且从参数类型推断出它们的参数类型。 如果结果隐式类型恰好与被调用函数的实际类型相匹配(在旧版C代码中比在现代代码中更有可能),那么一切都很好。 如果不是这样,则该行为是不确定的,但是任何未定义的行为都可能发生,甚至是编写代码的程序员所期望发生的一切。

此外,尽管标准未指定任何标准标头包含其他标头,但并不禁止这样做,并且实际上,在某些C实现中,其中一些标头也是如此。 如果您的实现的stdio.h包含string.h或以其他方式为strcpy()提供了兼容的定义,那么该实现就可以 但是,如果这是您所依赖的,则无论您是否有意依赖,那么当您尝试将程序与其他实现一起使用时,您就有发生意外失败的风险。

最后,请注意GCC 3.3的版本旧。 如果有可能,您应该升级到较新的版本。 即使是不稳定的,长期稳定的Linux也倾向于至少在4.x系列中使用较晚的版本,而最新的版本是GCC 8.3。

string.h包含文件通过给出函数声明来告诉编译器如何定义strcpy() ,但它不提供函数本身,而是位于库中并自动与程序链接。

如果函数在到达函数时尚未声明,则编译器将基于默认值和您使用函数的方式假定一个声明。

编译器接受您编写的内容,因此messageHello, world!的地址Hello, world! 并假设函数返回一个int 由于include您不必告诉编译器如何编译代码就冒了风险。 结果是不确定的行为。

顺便问一下Hello, world! 占用14个字符,加13 +尾随\\0 ,比您的message声明多4个字符。 这是未定义的行为,因为多余的4个字符将被写在不应包含的位置。 似乎正在工作,当机...

您不能依靠显示预期结果的程序。 这是未定义的行为。

始终使用-Wall类的警告选项进行编译,并考虑修复所有警告。

编译器知道一些“内置”函数( printf()是某些编译器的另一个示例),并通过提供它来弥补您的错误。 依靠它是一个坏习惯,因为即使您今天的编译器这样做,也不能保证您另一个编译器也会这样做,因此编译后的代码将不可预测。

尝试使用-Wall -Wextra进行编译,以使编译器显示更多警告,包括您忘记的标头的警告: gcc -o input input.c -Wall -Wextra

另请参见此处: 警告:内置函数'xyz'的不兼容隐式声明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM