![](/img/trans.png)
[英]implementing a strcpy() function without using <string.h> in C
[英]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()
,但它不提供函数本身,而是位于库中并自动与程序链接。
如果函数在到达函数时尚未声明,则编译器将基于默认值和您使用函数的方式假定一个声明。
编译器接受您编写的内容,因此message
和Hello, 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.