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

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

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

目录

一.引言

二.不安全代码

三.解决方案

四.练习与答案

案例1:保留标识符的使用

案例2:头文件保护宏的命名冲突

案例3:使用errno的保留标识符


一.引言

根据C语言标准:

    所有以下划线和一个大写字母开始,或者以两个下划线开始的标识符总是保留标识符。

    所有以下划线开始的标识符总是保留,在常规和标签命名空间中当成具有文件作用域的标识符使用。

    后续子条款(包括未来的库指向)中,任何包含与其相关头文件的宏名称都按规定保留,除非明确指定其他情况。

    所有具有外部链接(包括未来的库指向)的标识符和errno总是保留,用作具有外部链接的标识符。

    在任何后续的子条款(包括未来的库指向)中列出的任何具有文件作用域的标识符保留用作宏名,以及在包含相关头文件的情况下相同命名空间中具有文件作用域的标识符。

二.不安全代码

    一种常见但不安全的做法,是为预处理器条件语句中用于防止头文件重复包含的宏选择一个保留名称。这种做法存在风险,因为所选名称可能与C语言标准库实现中定义的保留名称发生冲突,甚至在没有显式包含C语言标准库头文件的情况下,也可能与编译器隐含的预定义保留名称产生冲突。

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_

/* Contents of <my_header.h> */
#endif /* _MY_HEADER_H_ */

三.解决方案

#ifndef MY_HEADER_H
#define MY_HEADER_H

/* Contents of <my_header.h> */
#endif /* MY_HEADER_H */

四.练习与答案

案例1:保留标识符的使用

问题描述
编写一个C程序,其中使用了一个以下划线和大写字母开始的标识符作为变量名。程序编译时出现了错误,提示该标识符是保留的。

案例代码

#include <stdio.h>  
  
int main() {  
    int _MyVar = 10;  
    printf("%d\n", _MyVar);  
    return 0;  
}

答案
根据C语言标准,所有以下划线和一个大写字母开始的标识符是保留的。因此,_MyVar作为变量名是不合适的。应该改为不使用下划线和大写字母开始的命名,如myVar

修改后的代码:

#include <stdio.h>  
  
int main() {  
    int myVar = 10;  
    printf("%d\n", myVar);  
    return 0;  
}

案例2:头文件保护宏的命名冲突

问题描述
在编写一个C程序时,使用了_MY_HEADER_H_作为头文件保护宏。程序在没有显式包含C标准库头文件的情况下编译失败,提示_MY_HEADER_H_是保留的。

案例代码

// my_header.h  
#ifndef _MY_HEADER_H_  
#define _MY_HEADER_H_  
  
void myFunction();  
  
#endif /* _MY_HEADER_H_ */  
  
// main.c  
#include "my_header.h"  
  
int main() {  
    myFunction();  
    return 0;  
}

答案
_MY_HEADER_H_这种以下划线和大写字母开始的宏名称是保留的。为了避免潜在的命名冲突,应该使用不会与保留名称冲突的宏名称,如MY_HEADER_H

修改后的头文件my_header.h

#ifndef MY_HEADER_H  
#define MY_HEADER_H  
  
void myFunction();  
  
#endif /* MY_HEADER_H */

案例3:使用errno的保留标识符

问题描述
在C程序中,尝试定义一个名为errno的变量,但编译时出现了错误,提示errno是保留的。

案例代码

#include <stdio.h>  
  
int main() {  
    int errno = 0;  
    // 使用errno变量  
    return 0;  
}

答案
errno是一个保留的标识符,用作具有外部链接的标识符。因此,不能将其作为变量名使用。应该选择另一个名称,如myErrno

修改后的代码:

#include <stdio.h>  
  
int main() {  
    int myErrno = 0;  
    // 使用myErrno变量  
    return 0;  
}

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

👇热门内容👇 

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

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

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

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

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

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

👇个人网站👇

安城安的云世界

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值