2014-01-27 88 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

相關問題