0


C安全编程教学-声明和初始化-不要声明或者定义保留标识符(五)

注:本课程参考文献《C安全编码标准》

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~

一.引言

根据C语言标准7.5小节第2段[ISO/IEC 9899:2011],在如下情况时程序行为未定义。
  • errno的宏定义被抑制,以便访问实际对象,或者程序用名称errno定义标识符。*
errno

标识符可以被扩展成一个可以修改的左值,这个左值的类型是

int

,但它并不一定要是一个对象的直接标识符。换句话说,它可能代表的是通过某种函数调用(例如

*errno()

)获得的左值。对于

errno

,没有明确规定它必须是一个宏,还是必须是一个声明为具有外部链接的标识符。如果在代码中为了直接访问某个具体的对象而取消了对

errno

宏的定义,或者在程序中定义了名为

errno

的标识符,那么这些操作将导致未定义行为。

二.不安全代码

遗留代码可能包含不正确的声明,如:
extern int errno;

三.修改方案

声明errno的正确方法为包含头文件<errno.h>:
#include <errno.h>
遵循C语言标准的实现必须在<errno.h>中声明errno,但是因为历史遗留原因没有这么做。

注意:如果一个库函数的声明没有引用头文件中定义的任何类型,允许在不包含其头文件的情况下声明该函数,只要声明与标准声明兼容即可。

/* Not including stdlib.h */
void free(void *);

void func(void *ptr){
    free(ptr);
}

四.练习与答案

如果程序显式地声明了标准库中的保留标识符,如
size_t

,并且声明与标准库中的声明不兼容,则程序行为未定义。

遗留代码可能包含不正确的声明,如:
typedef unsigned int size_t;
声明
size_t

的正确方法为包含头文件<stddef.h>:

#include <stddef.h>

遵循C语言标准的实现必须在<stddef.h>中声明

size_t

以及其他一些常用的类型定义和宏。用户代码应当避免重新定义这些标准类型,以防止与标准库中的声明冲突。

在这个案例中,不安全的代码显式地声明了
size_t

unsigned int

,这可能导致与标准库中的声明不兼容。标准库中的

size_t

可能是另一种无符号整数类型,如

unsigned long

,这取决于具体的实现。因此,必须包含<stddef.h>来确保

size_t

的正确声明,以避免未定义行为。

注意:如果一个库函数的声明没有引用头文件中定义的任何类型,允许在不包含其头文件的情况下声明该函数,只要声明与标准声明兼容即可。然而,对于类型定义,如

size_t

,必须包含相应的头文件。

/* Not including stddef.h */

#include <stdlib.h>  
  
void func(void *ptr, unsigned int size){  
    /* Assuming size is of type size_t, which should be declared in stddef.h */  
    free(ptr);  
    /* Other operations using size... */  
}
应当修改为:
#include <stddef.h>  
#include <stdlib.h>  
  
void func(void *ptr, size_t size){  
    free(ptr);  
    /* Other operations using size... */  
}

非常感谢您花时间阅读我的博客,希望这些分享能为您带来启发和帮助。期待您的反馈与交流,让我们共同成长,再次感谢!

👇热门内容👇

python使用案例与应用_安城安的博客-CSDN博客

软硬件教学_安城安的博客-CSDN博客

Orbslam3&Vinsfusion_安城安的博客-CSDN博客

网络安全_安城安的博客-CSDN博客

教程_安城安的博客-CSDN博客

python办公自动化_安城安的博客-CSDN博客

👇个人网站👇

安城安的云世界


本文转载自: https://blog.csdn.net/anananajiushiwo/article/details/141980682
版权归原作者 安小呆 所有, 如有侵权,请联系我们删除。

“C安全编程教学-声明和初始化-不要声明或者定义保留标识符(五)”的评论:

还没有评论