2013-04-01 26 views
6

Can C++ 11 derleyicileri (ve onlar) bir işlevin constexpr olduğunu ve constexpr olarak bildirilmese bile bunları işleme tabi tuttuklarını fark edebilirler mi?örtülü bir constexpr?

Ben Wikipedia'dan düz örneği kullanarak birisiyle constexpr kullanımını gösteren edildi: Benim için sürpriz

int get_five() {return 5;} 

int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++ 

derleyici onunla Tamam oldu. Bu yüzden, birkaç int parametresini almak, onları çoğaltmak ve constexpr olarak açık bir şekilde bildirilmediğinde sonucu döndürmek için get_five() öğesini değiştirdim. Derleyici de bununla tamam oldu. Derleyici bunu yapabilirse, açıkça constexpr bir şey bildirmek için gerekli kısıtlamalara sahip olmak için fazla bir nokta yoktur.

+4

Belki de derleyiciniz VLA'yı bir uzantı olarak destekler. Bunu düşündün mü? – 0x499602D2

+1

Bu ne derleyici? – SomeWittyUsername

+0

[C++ kitaplarının olası kopyası, dizi dizisi sabit ifade olmalı, ancak aşağıdaki kod neden çalışıyor?] (Http://stackoverflow.com/questions/5947661/in-c-books-array-bound-must-be -constant-expression-ama-why-the-takip-cod) –

cevap

6

Düzgün çalışan bir C++ 11 derleyicisinde, kodunuz reddedilir.

Kabul edilmesine bağlı olarak, neredeyse gcc (ya da hatalarını yakından öykünen bir şey) kullanıyorsunuzdur. gcc [bayraklara bağlı olarak] C++ cinsinden C99 değişken uzunluklu dizilerin bir benzerini desteklediğinden, herhangi bir ölçü ile sabit olmayan (örneğin kullanıcı tarafından çalışma zamanı girişine bağlı olarak) dizi boyutlarını kabul edebilir. onlar olduğunda bile

+0

'g ++' 4.6.3, 4.7.2 & 4.8 bunu reddeder. En azından liveworkpace sürümünde – SomeWittyUsername

+0

@icepack: Evet, bunu seçerseniz VLA'yı kullanan kodları reddedebileceğinizi düşünüyorum (ancak varsayılan olarak C++'yı VLA'ları kabul eder). –

+1

@icepack Bir işlevdeyken onu reddetmiyor: [LWS] (http://liveworkspace.org/code/1QPoBc$2) - yine de bir uyarı veriyor! – us2012

1

bir derleyici (yani derleme zamanında bir fonksiyonun sonucunu işlem) optimizasyon amacıyla, bir işlev constexpr ile bildirilen olabilirdi olup olmadığını tespit eder. Derleyiciler bunu C++ 11'den önce yaptı.

Ancak, tümleşik türde şablon parametreleri gibi sabit ifadeler gerektiren yerlerde kullanmak için, constexpr anahtar sözcüğüyle bildirilmemiş işlevlerin çağrılmasına izin vermek standartlara aykırıdır.

+0

"__A derleyici, bir işlevin constexpr__ ile bildirilmiş olup olmadığını algılayabilir" Bunu destekleyecek herhangi bir başvuru var mı? – cseder

+3

@cseder Modern bir derleyicinin bunu yapamayacağını hayal etmek zor. Derleyicilerin nasıl çalıştığı hakkında temel bilgiler. –

+0

Bu pek kanıt değil.Ve "modern derleyiciler" dediğinizde, otomatik olarak [memoization] (http://en.wikipedia.org/wiki/Memoization) desteklemediği için en son Visual C++ 2013 derleyicisini ekarte etmektesiniz. Bir constexpr yalnızca, constexpr işlevinden döndürülen sonuç her seferinde aynıysa ve derleme hakkında çok fazla bilgi içermesi gerekmediğinde kullanılabilir. – cseder