GCC具有pure和const屬性,其中const實際用於真正的純函數(純爲idempotent functions which are also side-effect free)。如何在gcc中聲明和定義純函數?
那麼我該如何聲明和定義一個函數使用常量屬性?
編輯:我對真正的純函數感興趣,這些純函數是用const屬性聲明的,而不是用純屬性聲明的。
GCC具有pure和const屬性,其中const實際用於真正的純函數(純爲idempotent functions which are also side-effect free)。如何在gcc中聲明和定義純函數?
那麼我該如何聲明和定義一個函數使用常量屬性?
編輯:我對真正的純函數感興趣,這些純函數是用const屬性聲明的,而不是用純屬性聲明的。
實施例:
// Declaration:
int square (int x) __attribute__ ((const));
// Definition:
int __attribute__ ((const)) square (int x)
{
return x*x;
}
的語法的所有屬性是非常相同:__attribute__ ((<attribute-name>))
,或__attribute__ ((<attribute-name> (<attribute-options>)))
。從您鏈接到的文檔中引用:
關鍵字
__attribute__
允許您在進行聲明時指定特殊屬性。該關鍵字後面跟着一個雙括號內的屬性規範。
有您鏈接到其他幾個屬性的文檔中的例子,包括pure
:
int square (int) __attribute__ ((pure));
因此,所有你需要的,語法的角度來看,使用const
,是改變pure
到const
:
int square (int) __attribute__ ((const));
正如在評論中指出:如果你在一個定義使用它,那麼你需要把__attribute__ ((const))
在不同的位置:
int square (int) __attribute__ ((const)) { ... } // doesn't work
int __attribute__ ((const)) square (int) { ... } // does work
但const
和pure
屬性是幾乎唯一有用如果它們適用於外部聲明,那麼這應該不成問題。如果定義可見,GCC通常可以在沒有您的幫助的情況下確定該功能是否可以被視爲const
/pure
。
根據本this article,語法與@hvd說什麼相匹配:
int square (int) __attribute__ ((pure));
然而,似乎gcc
當我編譯下面的例子並不強制不檢查全局狀態的財產。
#include <stdio.h>
int square (int) __attribute__ ((pure));
int outerX = 7;
int square(int x) {
return outerX * x;
}
int main(){
printf("%d\n", square(5));
return 0;
}
以下打印沒有錯誤,代碼運行併產生35
。
gcc -Wall -Werror -pedantic -O3 Pure.c
gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
更奇怪的是,gcc
也沒有,如果我們發生變異函數內部的全局狀態和每個調用返回,因爲它在全球所引起的狀態變化的不同值在意。
#include <stdio.h>
int square (int) __attribute__ ((pure));
int outerX = 7;
int square(int x) {
outerX++;
return outerX * x;
}
int main(){
printf("%d\n", square(5));
printf("%d\n", square(5));
printf("%d\n", square(5));
return 0;
}
輸出:
40
45
50
從C++ 11開始,可以使用attribute specifier sequence來指定這些屬性。例如:
[[ gnu::const ]]
int square (int x)
{
return x * x;
}
另外,從C++ 17開始,編譯器未知的所有屬性都會被忽略而不會導致錯誤。所以上面的代碼可以在不同的編譯器和平臺之間移植。
是的,文檔有點誤導我認爲:函數是否純粹取決於它的功能,而不是它是如何實現的。如果函數是純粹的,即使它讀取全局變量(例如,因爲這些變量永不改變),那麼它可能被聲明爲純粹的。因此,編譯器不能強制執行該屬性。 – hvd 2015-02-09 09:01:02
它仍然是有意義的,你的編輯:'純粹(無效)__attribute __((純)); int pure(void){static bool pureInited = false; static int pureValue;如果(!pureInited){pureValue = ...; pureInited = true; }返回pureValue; }'我認爲可以在那裏應用'pure'屬性,即使函數使用靜態存儲持續時間來修改變量:效果仍然是該函數始終返回完全相同的值。 ('const'也可能在這裏有意義,而不是'pure')。 – hvd 2015-02-09 09:08:38
@hvd,你認爲如果函數在每次調用時都返回不同的值並且參數相同,編譯器就會大聲嚷嚷? – merlin2011 2015-02-09 09:10:43