2013-06-08 20 views
11

Bir constexpr fonksiyonu sadece bir dönüş açıklamada oluşması gerekir ve her argüman derleme zamanında bilinmesi gerekir:constexpr - neden sadece bir iade beyanı?

// constexpr functions use recursion rather than iteration 
constexpr int factorial(int n) 
{ 
    return n <= 1 ? 1 : (n * factorial(n-1)); 
} 

Neden sadece iade ifade? Demek istediğim, bu neden yanlış?

// constexpr functions use recursion rather than iteration 
constexpr int factorial(int n) 
{ 
    int a = 222; //another variable 
    return n <= 1 ? 1 : (n * factorial(n-1)); 
} 
+7

Derleyici uygulamaları için bunu basit tutmak için bir araç olduğundan şüpheleniyorum. – juanchopanza

+10

Çünkü Standart öyle diyor. Daha genel işlevlerin kullanılmasına izin vermek derleyici yazarların yaşamını oldukça zorlaştıracaktır (yine de, C++ 14 bu kısıtlamaların bazılarını kaldırmaktadır) –

+3

Değişkenlere izin vermek, başka birçok (daha karmaşık) kısıtlamanın eklenmesi anlamına gelecektir. Böylece tanıtımları için basit tuttular. Neyse etrafında yolları – Dave

cevap

6

Bu uygulama kolaylaştırır. Bu muhtemelen "Neden" diye cevap veriyor, ama bunu nasıl yaptığını söylemiyor.

Bir tek bir dönüş değeri ile fonksiyon ve yerel değişkenler olmadan daha özel bir, bir derleyici için özel bir durumdur. Bu işlev artık tek bir ifadeden oluşuyor: işlevin AST'sinin yalnızca tek bir köke sahip olması gerekiyor. Değişkenlerin eksik olması, bu ifadenin işlenebilmesi için bir tam-üflemeli sanal makine olmadan değerlendirilebileceği anlamına gelir, bunun yerine basit bir ağaç ifadesi değerlendiricisi kullanılabilir. Muhtelif nedenlerden dolayı derleyicinin büyük olasılıkla böyle bir değerlendiriciye sahip olması ya da nispeten kolay bir tane oluşturabilmesi (bir ağaç sadeleştirme geçişi olur). Sadece constexpr ifade içinde kullanılır bilerek

da önemli bir basitleştirme sağlar. Bu işlev, AST işlevindeki her köşe noktasının, bir işlev çağrısı olsa bile, aynı özelliklere sahip olmasını garanti eder. constexpr mekanizmasının tamamı, daha sonra genelleştirilmiş bir const-katlama şeklidir. Ve her zaman derleyicide bu yüksek düzeyde yapılmasa da, büyük bir çaba olmadan (tam bir VM'ye kıyasla) uygulanabilmesini sağlar. "Neden" sorusuna

Geri. Kısıtlama, öncelikle satıcılar üzerindeki kaynak sınırlamaları tarafından yürütülür. Bu özellik, belirtildiği gibi, büyük bir çaba değildir ve bu nedenle satıcılar, makul bir süre içinde gerçekte uygulayabilirler. Bu tür kısıtlamalar olmasaydı, özellikle yerel değişkenlere izin vermek gerekirse, gereken iş miktarını büyük ölçüde artırır. Kullanıcının bakış açısından (biz, programcılar), kısıtlamalar tamamen keyfidir.

+0

Güzel cevap. 'constexpr' aslında derleyiciyi ** yorumladığını sorar (basitçe derlemek yerine), basitlik için gayret etmek anlaşılabilirdir. Yine de güzel bir eklenti, “emin olsaydım” (sadece şablonlar için değil, “constexpr” için kullanışlıdır), hangi durumda olduğundan emin değilim. – eudoxos

+0

Sanırım başka bir nedenden dolayı. Sonsuz döngülere sahip olamazsınız, ve özyinelemeli aramalar sadece bir yineleme limiti tarafından belirlenebilir. Ayrıca, daha fazla şeye izin veren herhangi bir değişiklik, kullanıcıların neden derlenmediği gibi dolaşmadan kod derlemesini elde etmek için saygı duymaları gereken daha karmaşık değişmezleri de beraberinde getirecektir. Ayrıca, şüphesiz, aynı zamanda, constexpr'in çalıştığını "kanıtlamanız" gerektiğine ve bunu rasgele kod için geliştirmenin de teorik bakış açısından da zor veya imkansız olduğuna şüphe ediyorum. – GameDeveloper

13

Neden: C++ 11'de oldukça yeni ve radikal bir kavramdır ve tamamen yeni bir şey için büyük dil standardını geçiş zordur

constexpr çünkü. Muhafazakarlık kuralları. (Şu anda C++ 14 hedefleyen) C++ 1y için

, sizin örnek yasaldır. Bagaj clangının ucu zaten -std=c++1y bayrağının altında uygular. Andy Sinsi sinsi söylediği gibi