实现一个新的strcpy函数重新定义了库函数strcpy?

Nik*_*nka 6 c

据说我们可以编写多个声明但只能编写一个定义.现在,如果我使用相同的原型实现我自己的strcpy函数:

char * strcpy ( char * destination, const char * source );
Run Code Online (Sandbox Code Playgroud)

那么我不是在重新定义现有的库函数吗?这不应该显示错误吗?或者它是否以某种方式与库函数以目标代码形式提供的事实有关?

编辑:在我的机器上运行以下代码说"分段故障(核心转储)".我正在使用linux并且已经编译而没有使用任何标志.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *strcpy(char *destination, const char *source);

int main(){
    char *s = strcpy("a", "b");
    printf("\nThe function ran successfully\n");
    return 0;
}

char *strcpy(char *destination, const char *source){
    printf("in duplicate function strcpy");
    return "a";
}
Run Code Online (Sandbox Code Playgroud)

请注意,我不是要尝试实现该功能.我只是想重新定义一个函数并询问后果.

编辑2:在应用Mats建议的更改后,程序不再提供分段错误,尽管我仍在重新定义函数.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *strcpy(char *destination, const char *source);

int main(){
    char *s = strcpy("a", "b");
    printf("\nThe function ran successfully\n");
    return 0;
}

char *strcpy(char *destination, const char *source){
    printf("in duplicate function strcpy");
    return "a";
}
Run Code Online (Sandbox Code Playgroud)

Yu *_*Hao 11

C11(ISO/IEC 9899:201x)§7.1.3 保留标识符

- 如果包含任何相关标头,则保留以下任何子条款中的每个宏名称(包括未来的库方向)以供指定使用; 除非另有明确说明.

- 以下任何子条款中包含外部链接的所有标识符(包括未来的库方向)始终保留用作具有外部链接的标识符.

- 如果包含任何相关标头,则保留下列任何子条款(包括未来库方向)中列出的具有文件范围的每个标识符,以用作宏名称和具有相同名称空间的文件范围的标识符.

如果程序在保留它的上下文中声明或定义标识符,或者将保留标识符定义为宏名称,则行为是未定义的.请注意,这并不意味着你不能这样做,正如这篇文章所示,它可以在gcc和glibc中完成.

glibc的§1.3.3保留名称 proveds更清晰的理由:

来自ISO C标准的所有库类型,宏,变量和函数的名称都是无条件保留的; 您的程序可能不会重新定义这些名称.如果您的程序明确包含定义或声明它们的头文件,则保留所有其他库名.这些限制有几个原因:

如果您使用名为exit的函数执行与标准退出函数完全不同的操作,那么阅读代码的其他人可能会非常困惑.防止这种情况有助于使您的程序更易于理解,并有助于模块化和可维护性.

它避免了用户意外重新定义其他库函数调用的库函数的可能性.如果允许重新定义,那些其他功能将无法正常工作.

它允许编译器在调用这些函数时进行任何特殊的优化,而不会被用户重新定义.一些库设施,例如用于处理可变参数(参见Variadic函数)和非本地出口(参见非本地退出)的设施,实际上需要C编译器方面的大量合作,并且相对于实现,编译器可能更容易将它们视为语言的内置部分.

  • 所以我们在这里处理的是"未定义的行为[u] r",我猜 (2认同)

Mat*_*son 7

这几乎肯定是因为你传递的是一个"字符串文字"的目的地.

char*s = strcpy("a","b");

随着编译器知道"我可以做strcpy内联",所以你的函数永远不会被调用.

您正试图复制"b"字符串文字"a",这将无法正常工作.

创建一个char a[2];并且strcpy(a, "b");它将运行 - 它可能不会调用您的strcpy函数,因为strcpy即使您没有可用的优化,编译器也会内联.