1

我正在使用 XCode 用 C 语言编写程序。我很少使用C,通常我使用C++。我以前从未使用过 XCode。

编译错误很简单,以下代码行没有被编译器视为编译时常量。

const double PI = 4.0 * atan(1.0);
const double TAU = 8.0 * atan(1.0);

我确信这在 C++ 11 中是允许的,尽管我不能确定,因为我几个月前最后一次使用它。

我的猜测是 XCode 编译器/C 标准不允许以这种方式计算常量。

有没有我可以使用的替代方案?我不太喜欢“定义”的替代方案......

#define PI 4.0 * atan(1.0);

因为这会(可能?)导致不必要的运行时开销。

4

2 回答 2

3

编译器不会将以下代码行视为编译时常量。

编译器是对的,因为它们不是编译时常量:它们都调用标准 C 库的运行时部分。

我不太喜欢“定义”的替代方案......

没错,#define不是替代方案,因为它强制在您拥有的每个表达式中重新评估一个常量。

有没有我可以使用的替代方案?

当然 - 您可以使用常量*M_PI的定义,以及:π2*M_PITAU

const double TAU = 2 * M_PI;

我确定这在 C++ 11 中是允许的

这是正确的:与 C 不同,C++ 并不要求初始化器是编译时常量。

为什么atan()不允许调用,但允许数学运算2 * M_PI

这是因为该标准要求编译器在编译期间对常量表达式执行所有数值运算。但是,单个运行时调用,例如atan(...),将“毒化”整个事物,因此编译器将尽可能多地求值,但表达式将保持运行时表达式,而不是编译时常量。

*它不是标准的,但许多库都定义了它。

于 2014-01-27T18:18:42.863 回答
1

这在 C 中是不允许的。与 C++ 不同,C 要求全局变量由编译时常量初始化。 atan(1.0)不是编译时常量,因为它需要atan()在运行时调用函数。

简单的解决方案是不调用atan(),只使用 pi 和 tau 的实际数值作为初始化器:

const double PI = 3.141592653589793;
const double TAU = 2*PI;

一些数学库也M_PI已经为您提供了常量,因此您可以这样做:

const double PI = M_PI;

但这不是标准的 C(C89 或 C99),所以不要依赖所有具有该常量的实现。

于 2014-01-27T18:19:32.343 回答