我正在使用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);
因为这会(可能?)导致不必要的运行时开销。
答案 0 :(得分:3)
编译器不会将以下代码行视为编译时常量。
编译器是对的,因为它们不是编译时常量:它们都调用标准C库的运行时部分。
我不太喜欢“定义”替代方案......
没错,#define
不是的替代方案,因为它会强制在你拥有的每个表达式中重新计算一个常量。
我可以使用替代品吗?
当然 - 您可以使用M_PI
来定义π
常量 * ,2*M_PI
用于TAU
:
const double TAU = 2 * M_PI;
我确信在C ++ 11中允许这样做
这是正确的:与C不同,C ++不会将初始化程序称为编译时常量。
如何禁止调用
atan()
,但允许使用数学运算2 * M_PI
?
这是因为标准要求编译器在编译期间对常量表达式执行所有数值运算。但是,单个运行时调用(例如atan(...)
)将“中毒”整个事物,因此编译器将尽可能多地进行评估,但表达式将保留为运行时表达式,而不是编译时常量。
* 这不是标准的,但无论如何很多图书馆都会定义它。
答案 1 :(得分: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),所以不要依赖所有具有该常量的实现。