实施新的strcpy函数重新定义了库函数strcpy? [英] Implementing a new strcpy function redefines the library function strcpy?

查看:212
本文介绍了实施新的strcpy函数重新定义了库函数strcpy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人说,我们可以写多个声明,但只有一个定义。现在,如果我实现我自己的strcpy函数有相同的原型:

 的char *的strcpy(字符*目的地,为const char *源);

然后我不能重新定义现有的库函数?不应该这样显示错误?抑或是它在某种程度上与在对象code形式提供的库函数的事实?

编辑:运行在我的机器上的以下code说:分割故障(核心转储)。我工作的Linux和不使用任何标志编译。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;字符*的strcpy(字符*目的地,为const char *源);诠释主(){
    字符* S =的strcpy(一,B);
    的printf(\\ n此功能已成功运行的\\ n);
    返回0;
}字符*的strcpy(字符*目的地,为const char *源){
    的printf(一式两份函数strcpy);
    返回A;
}

请注意,我不是要实现的功能。我只是想重新定义一个函数,并要求对后果。

编辑2:
应用由垫所建议的修改后,该程序不再给出了一个分段错误,虽然我还是重新定义的功能。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;字符*的strcpy(字符*目的地,为const char *源);诠释主(){
    字符* S =的strcpy(一,B);
    的printf(\\ n此功能已成功运行的\\ n);
    返回0;
}字符*的strcpy(字符*目的地,为const char *源){
    的printf(一式两份函数strcpy);
    返回A;
}


解决方案

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


  

- 任一下列条款的每一个宏名(包括未来图书馆
  方向)被保留用于如果任何相关标头包括按照指定;
  除非明确说明,否则


  
  

- 在任何以下小节的外部连接(包括所有的标识符
  未来图书馆方向)总是保留用于与外部标识符
  联动。


  
  

- 在任何以下小节上市文件范围内每个标识符(包括
  未来图书馆方向)被保留用于为宏名称和与标识符
  如果任何相关报头被包括在相同的名称空间的文件范围。


如果该程序声明或定义在它被保留,或保留标识符定义为宏名的上下文的标识符,行为是不确定的。请注意,这并不意味着你不能这样做,因为这个帖子< /一>所示,它可以gcc和glibc的内进行。

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


  

所有图书馆的类型,宏,变量和函数来自ISO C标准的无条件保留的名称;你的程序不能重新定义这些名字。所有其它的库名称被保留,如果你的程序明确包括定义或声明他们的头文件。有几个原因,这些限制:


  
  

其他人阅读你的code,如果你使用的是名为函数退出做一些事情从标准输出函数做什么,例如完全不同可以得到非常困惑。 preventing这种情况有助于使你的程序更容易理解,并有助于模块化和可维护性。


  
  

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


  
  

它可以让编译器做什么高兴的特殊优化上调用这些函数,没有他们可能被重新定义用户的可能性。一些图书馆设施,如处理可变参数(见可变参数功能)和非本地退出(参见非本地退出),实际上需要相当数量的C编译器的部分合作,并与对于实施中,它可能是对于编译器把这些作为语言的内置零件容易。


It is said that we can write multiple declarations but only one definition. Now if I implement my own strcpy function with the same prototype :

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

Then am I not redefining the existing library function? Shouldn't this display an error? Or is it somehow related to the fact that the library functions are provided in object code form?

EDIT: Running the following code on my machine says "Segmentation fault (core dumped)". I am working on linux and have compiled without using any flags.

#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";
}

Please note that I am not trying to implement the function. I am just trying to redefine a function and asking for the consequences.

EDIT 2: After applying the suggested changes by Mats, the program no longer gives a segmentation fault although I am still redefining the function.

#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";
}

解决方案

C11(ISO/IEC 9899:201x) §7.1.3 Reserved Identifiers

— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise.

— All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.

— Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

If the program declares or defines an identifier in a context in which it is reserved, or defines a reserved identifier as a macro name, the behavior is undefined. Note that this doesn't mean you can't do that, as this post shows, it can be done within gcc and glibc.

glibc §1.3.3 Reserved Names proveds a clearer reason:

The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:

Other people reading your code could get very confused if you were using a function named exit to do something completely different from what the standard exit function does, for example. Preventing this situation helps to make your programs easier to understand and contributes to modularity and maintainability.

It avoids the possibility of a user accidentally redefining a library function that is called by other library functions. If redefinition were allowed, those other functions would not work properly.

It allows the compiler to do whatever special optimizations it pleases on calls to these functions, without the possibility that they may have been redefined by the user. Some library facilities, such as those for dealing with variadic arguments (see Variadic Functions) and non-local exits (see Non-Local Exits), actually require a considerable amount of cooperation on the part of the C compiler, and with respect to the implementation, it might be easier for the compiler to treat these as built-in parts of the language.

这篇关于实施新的strcpy函数重新定义了库函数strcpy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆