C++ 编码标准 #define 头文件

c++ coding standard #define header files

本文关键字:文件 #define 标准 编码 C++      更新时间:2023-10-16

我正在阅读《编码标准:101 Rules, Guidelines, and Best Practices》一书C++书,它说使用#define不好用。当我查看一些头文件时,它们有很多#define。如果使用#define不好,为什么有这么多?谢谢。

>#define是一种不好的做法,因为:

它们没有任何范围:

#define不尊重作用域,因此无法创建类作用域命名空间。虽然变量可以在类中限定范围。

编译错误期间奇怪的神奇数字:

如果您使用的是#define则在预编译时将其替换为预处理器 因此,如果在编译过程中收到错误,则会令人困惑,因为错误消息不会引用宏名称,而是引用值,并且它会出现一个突然的值,并且会浪费大量时间在代码中跟踪它。

调试问题:

同样出于#2中提到的相同原因,虽然调试#define实际上不会提供太多帮助。

因此,最好使用 const 变量而不是#define
它们在上述所有方面都优于#define。只有#define真正有用的领域才是需要在代码中或定义包含标头保护时实际替换文本的地方。

为什么#define在 C 标准头文件中广泛使用?

我想到的一个原因是,在 C(与 C++ 不同(中,const声明不产生常量表达式。这意味着在 C 标准中引入可变长度数组之前,不能编写类似以下内容的内容:

const int max_val = 100;  
int foos[max_val]; 

因为在 C 中max_val不是编译时常数,并且在引入 VLA 的数组下标之前需要编译时常数。
所以人们不得不把它写成:

#define MAX_VAL 100  
int foos[MAX_VAL]; 

这可能指的是定义常量的旧 C 方法:

#define MAX_SOMETHING 100
int x = MAX_SOMETHING;

这些常量不是类型化的,它们使用字符串替换就地扩展,并且使调试变得更加困难,因为一旦编译了源代码,就不清楚该定义的来源。

一种更C++方法是:

const int max_something = 100;
int x = max_something;

由于这是一个强类型值,因此需要对其进行所有必需的检查和适当的转换。

另一个好处是,出于组织目的,可以将const值放入命名空间和类中。#define的范围是全球性的,因此冲突是一个问题,这会导致名称过长以避免冲突。

consttemplate 之间,允许一种元编程形式 C 本身不做,需要#define的场合大大减少。不过,它并没有完全消除,因为如果没有#import指令,您仍然需要添加旧的#ifndef __HEADER_FILE_NAME__防护装置,以确保不会包含两次。

这本书的宽泛陈述不是那么正确 - #define在宏等中占有一席之地,但对于定义常量,现在使用它不是一个好主意

例如

 #define FOO 257

最好在

const int FOO=257;

允许类型检查,因为随着 #define 这变得有点奇怪

char c=FOO;