2014-01-27 50 views
1

我正在用C编写一个使用XCode的程序。我不使用C,通常我使用C++。我从来没有使用过XCode。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); 

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

+1

为什么不从'math.h'或者'3.141592653589'使用'M_PI'?这应该是'双精度'。 – Kninnug

回答

3

以下代码行不被编译器视为编译时间常量。

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

我没有太多花哨的“定义”另类......

这是正确的,#define替代方案,因为它会迫使恒定在每个进行重新评估表达,你有它。

有没有其他方法可以使用?

当然 - 你可以使用M_PIπ不断*的定义,并2*M_PITAU

const double TAU = 2 * M_PI; 

我敢肯定,这是允许在C++ 11

这是正确的:与C不同,C++不会要求初始化程序为编译时控制stants。

这是怎么回事atan()是不允许的,但允许数学运算2 * M_PI

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

*这不是标准的,但很多图书馆无论如何定义它。

+0

为什么我允许在C++中执行此操作? M_PI听起来不像一个严格的解决方案......它是什么,它有多少位数的精度? – user3728501

+0

实际上,另一个问题是:如何调用atan()是不允许的,但是数学运算2 * M_PI是允许的吗? – user3728501

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),所以不依赖于所有的实现具有恒定的。

+0

啊,所以这是一种巧妙的语言。如果C2014(这样的事情存在吗?)会非常好,扩展语言以允许这样做。 – user3728501

相关问题