2015-02-09 44 views

cevap

6

Örnek: __attribute__ ((<attribute-name>)) veya __attribute__ ((<attribute-name> (<attribute-options>))): Tüm özellikler için

// Declaration: 
int square (int x) __attribute__ ((const)); 
// Definition: 
int __attribute__ ((const)) square (int x) 
{ 
    return x*x; 
} 

sözdizimi hemen hemen aynıdır. Bağlan belgelerin alıntılanması:

__attribute__ anahtar kelimesi, bir bildirim yaparken özel öznitelikleri belirtmenize izin verir. Bu anahtar kelimeyi çift parantez içinde bir özellik belirtimi takip eder.

pure içinde bazı diğer özellikler için bağlantı veren belgelerinde örneği vardır:

int square (int) __attribute__ ((pure)); 

yüzden tek const kullanmak, sözdizimi-bilge ihtiyaç pure değiştirmektir const için:

int square (int) __attribute__ ((const)); 

olarak Açıklamalarda belirttiği:

int square (int) __attribute__ ((const)) { ... } // doesn't work 
int __attribute__ ((const)) square (int) { ... } // does work 

ama const ve pure nitelikleri hemen hemen sadece yararlıdır: Bir tanımında kullandığınız eğer, o zaman farklı bir konumda __attribute__ ((const)) koymak gerekir dış beyanlara uygulanırlarsa, bu bir sorun olmamalıdır. Tanım görünürse, GCC, genellikle, sizin yardımınız olmadan fonksiyonun const/pure olarak değerlendirilip değerlendirilemeyeceğini belirleyebilir.

5

bu this article göre, sözdizimi @hvd dediklerinde bir eşleşir:

int square (int) __attribute__ ((pure)); 

Ancak, ben şu örneği derleme yaparken gcc küresel durumunu inceleyerek değil özelliğini zorlamaz gibi görünüyor.

#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; 
} 

aşağıdaki baskılar hiçbir hata ve kod çalışır ve 35 üretir. Biz işlevi içinde küresel durumunu mutasyon geçirip çünkü küresel halde neden olduğu bir değişimin her çağrıda farklı bir değer dönerseniz

gcc -Wall -Werror -pedantic -O3 Pure.c 


gcc --version 
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 

Daha merakla, gcc da önemsemiyor.

#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; 
} 

Çıktı:

40 
45 
50 
+0

Evet, belgeler biraz yanıltıcı, bence: bir işlevin saf olup olmadığı, ne yaptığına bağlı değil. Eğer bir fonksiyon global değişkenleri okuyor olsa da (örneğin, bu değişkenler asla değişmediği için) saf ise, o zaman saf olarak ilan edilebilir. Bu nedenle, derleyici özniteliği zorlayamaz. – hvd

+0

Düzenlemeyle hala mantıklı: int (void) __attribute __ ((pure)); int pure (void) {statik bool pureInited = false; statik int pureValue; if (! pureInited) {pureValue = ...; pureInited = true; geri dönüş pureValue; } 'Fonksiyonun statik depolama süresi ile değişkenleri değiştirmesine rağmen,' pure' özniteliğinin burada uygulanabileceğini düşünüyorum: efekt yine de fonksiyonun her zaman aynı değeri döndürmesidir. ('const ',' pure' yerine, burada da mantıklı olabilir.) – hvd

+0

@hvd, Bu işlev, her bir çağrıda aynı argümanlarla farklı değerler döndürürse, derleyicinin bağıracağını düşünüyor musunuz? – merlin2011

1

C++ 11 ile başlayarak, bu öznitelikleri belirtmek için attribute specifier sequence kullanabilirsiniz. Örneğin:

[[ gnu::const ]] 
int square (int x) 
{ 
    return x * x; 
} 

Ayrıca C++ 17 ile başlayan tüm bir derleyici bilinmeyen bir hata neden olmadan göz ardı edilir bağlıyor. Bu nedenle yukarıdaki kod farklı derleyiciler ve platformlar arasında taşınabilir hale gelir.

İlgili konular