在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内

Is it bad practice to specify an array size using a variable instead of `#define` in C++? (C error: variably modified at file scope)

本文关键字:quot 一种 范围内 错误 文件 变量 C++ 数组 #define 是不是      更新时间:2023-10-16

在C中,不允许使用变量声明数组大小,即使它是const变量。示例:这无法在C:中编译

#include <stdio.h>
const int SIZE = 2;
int a[SIZE];
int main()
{
a[0] = 1;
a[1] = 2;
printf("%i, %i", a[0], a[1]);
return 0;
}

在C.中运行此代码

gcc -o main *.c

输出:

main.c:5:5: error: variably modified ‘a’ at file scope
int a[SIZE];
^

然而,在C++中,它运行得很好。

用C++运行上面的代码。

g++ -o main *.cpp
main

输出:

1, 2

要使它在C中运行,必须使用#define而不是变量。即:

这在CC++中运行得很好:

#include <stdio.h>
#define SIZE 2
// const int SIZE = 2;
int a[SIZE];
int main()
{
a[0] = 1;
a[1] = 2;
printf("%i, %i", a[0], a[1]);
return 0;
}

在C.中运行此代码

因此,在C++中,我几乎总是使用变量而不是#define来声明我的数组大小。我只是将数组大小设为变量const,一切都很好!然而,最近我开始用纯C进行大量的微控制器编程,当我遇到这个错误并解决了问题时,一位资深开发人员告诉我,使用#define-ed常量(或者可能是硬编码数字)以外的任何东西来声明数组大小都是不好的做法。

这是真的吗?在C++中,指定数组大小时使用const变量而不是#define是否是一种糟糕的做法?如果是,为什么

在C中,显然你被#define卡住了:你别无选择。但在C++中,你显然至少有两个选择,那么一个比另一个好吗使用其中一个会有风险吗?

相关:

  1. 在C中的文件范围内可变修改的数组
  2. static const#define&lt这是一个很有帮助的问题。这肯定与我的问题有关,但我的问题*不是重复的,因为尽管它们都是关于const和#define的,但我问题是一个非常特殊的情况,其中一个选项甚至在一种通常被认为是C++子集的语言中都不起作用。这很不寻常,使我的问题成为一个更窄的子集,它符合另一个问题的广泛范围。因此,不重复
  3. C++核心准则,ES.31:不要将宏用于常量或";函数">
  4. "静态常量";vs"#定义";vs";enum">
  5. 可变长度阵列,C99

在这件事上最好听从Scott Meyer的建议。从他的书"有效的C++":
第2项:比起#defines,更喜欢常量、枚举和内联

根据您的示例调整的项目摘要。

此项可以更好地称为"更喜欢编译器而不是预处理器,"因为#define可能被视为不是语言的一部分这就是它的问题之一。

当你做这样的事情时,

#define SIZE 2

符号名称CCD_ 12可能永远不会被编译器看到;它可以在源代码获得之前由预处理器删除到编译器。因此,可能无法输入名称SIZE进入符号表。如果您在涉及使用常量的编译,因为错误消息可以指代2而不是SIZE。如果SIZE定义在一个你没有写的头文件中,你不知道它在哪里2来自,你会浪费时间去追踪它。这个问题也可能出现在符号调试器中,因为名称您使用的编程可能不在符号表中。解决方案是用常量替换宏:
const double SIZE = 2; // uppercase names are usually for macros, hence the name change
作为一个语言常量,SIZE肯定会被编译器和肯定会被输入到他们的符号表中。

✦对于简单常量,更喜欢const对象或枚举,而不是#defines
✦对于类似函数的宏,更喜欢内联函数而不是#defines。

另请参阅"第3项:尽可能使用常量。"以了解有关其用法和用法例外的更多信息。

因此,要回答标题中的问题:
,在C++中使用变量而不是#define来指定数组大小并不是一种坏做法。

因为SIZE被定义为const变量。在C中,与C++不同的是,const值不是真正的常量。它们存储在内存中,可以间接引用和修改(通过修改内存中的内容)。这就是为什么,在C++中有const可以允许const int SIZE = 2;工作,但在C.中即使是const也不够

C11-§6.7.9/3:

要初始化的实体的类型应为未知的数组大小或不是可变长度数组的完整对象类型类型

预处理器宏在编译时替换,这就是它工作正常的原因。

参考链接:https://stackoverflow.com/a/35162075/5612562

我喜欢你的问题!C++正在向一种不再需要#define的语言发展。根据版本的不同,可以替换其他构造。造成这种情况的原因有几个,包括IDE的问题、枚举值的变量名意外替换为其他常量、(不要将ERROR和)以及缺少命名空间,因为这都是预处理器的替换。

对于本例,您将创建一个C样式数组,该数组需要一个常量。然而,写入const int SIZE = 2并不会创建一个常量,而是创建一个不可变的变量。这可以用很多方法来使用,并且可以用几乎任何代码来初始化,包括通过读取文件来计算的代码。

你正在搜索的是constexpr。关键字,用于将变量提升为编译时常量,并将初始化选项限制为可以在编译时执行的所有代码。所以:常数,用它们进行的计算,以及将这些计算分组的constexpr函数。如果你想了解更多关于它的信息,可以用谷歌搜索constexpr(或者使用不同的搜索引擎)。

注意constexpr需要C++11,当您想要编写constexpr函数时,建议使用C++14。对于constexpr标准库函数,如果我记得很清楚的话,您将不得不等待C++20。

constexpr int SIZE = 2;
int a[SIZE];
相关文章: