Bu şekilde oluşan üç fonksiyonumuz (foo, bar ve baz) varsa ...
foo(bar(), baz())
C ++ standardının bazdan önce değerlendirileceğine dair herhangi bir garanti var mı?
Bu şekilde oluşan üç fonksiyonumuz (foo, bar ve baz) varsa ...
foo(bar(), baz())
C ++ standardının bazdan önce değerlendirileceğine dair herhangi bir garanti var mı?
Yanıtlar:
Hayır, böyle bir garanti yok. C ++ standardına göre belirtilmemiştir.
Bjarne Stroustrup, bazı nedenlerle bunu "C ++ Programlama Dili" 3. basım bölüm 6.2.2'de açıkça belirtmektedir:
İfade değerlendirme sırasına ilişkin kısıtlamaların olmaması durumunda daha iyi kod üretilebilir
Teknik olarak bu, aynı bölümün bir ifadenin bölümlerinin değerlendirme sırasının da belirtilmediğini söyleyen daha önceki bir kısmına atıfta bulunsa da, yani
int x = f(2) + g(3); // unspecified whether f() or g() is called first
[5.2.2] İşlev çağrısından,
Argümanların değerlendirme sırası belirtilmemiştir. Bağımsız değişken ifade değerlendirmelerinin tüm yan etkileri, fonksiyon girilmeden önce yürürlüğe girer.
Bu nedenle, bar()
daha önce çalışacağına dair bir garanti yoktur baz()
, sadece bu bar()
ve baz()
daha önce çağrılacaktır foo
.
Ayrıca [5] 'den şu ifadelere dikkat edin:
belirtildiği durumlar dışında [örneğin
&&
ve için özel kurallar||
], tek tek operatörlerin işlenenlerinin ve tek tek ifadelerin alt ifadelerinin değerlendirme sırası ve yan etkilerin meydana gelme sırası belirtilmemiştir.
böylece bile olmadığını soran olsaydı bar()
önce çalışacaktır baz()
içinde foo(bar() + baz())
, sipariş hala belirsizdir.
&
, &&
soldan sağa değerlendirmeyi garanti eder: ikinci işlenen, birinci işlenen ise değerlendirilmez false
."
Bar () ve baz () için belirli bir sıra yoktur - Standardın söylediği tek şey, foo () çağrılmadan önce ikisinin de değerlendirileceğidir. C ++ Standardından, bölüm 5.2.2 / 8:
Argümanların değerlendirme sırası belirtilmemiştir.
bar
, sonra 1. satırını baz
, sonra 2. satırı bar
vb. Çalıştıramaz ) ki bu da güzel. :-)
C ++ 17, C ++ 17'ye kadar belirtilmeyen operatörler için değerlendirme sırasını belirtir. Şu soruya bakın : C ++ 17 tarafından sunulan değerlendirme emri garantileri nelerdir? Ama ifadene dikkat et
foo(bar(), baz())
hala belirtilmemiş değerlendirme sırasına sahip.
C ++ 11'de ilgili metin 8.3.6 Varsayılan bağımsız değişkenler / 9 (Vurgu benimki) içinde bulunabilir.
Varsayılan bağımsız değişkenler, işlev her çağrıldığında değerlendirilir. İşlev bağımsız değişkenlerinin değerlendirme sırası belirtilmemiş . Sonuç olarak, bir işlevin parametreleri, değerlendirilmeseler bile, varsayılan bir bağımsız değişkende kullanılmamalıdır.
Aynı söz, C ++ 14 standardı tarafından da kullanılır ve aynı bölümde bulunur .
Başkalarının daha önce de belirttiği gibi, standart bu özel senaryo için değerlendirme sırası konusunda herhangi bir rehberlik sağlamaz. Bu değerlendirme sırası daha sonra derleyiciye bırakılır ve derleyicinin bir garantisi olabilir.
C ++ standardının bir derleyiciye derleme / makine kodu oluşturma konusunda talimat vermek için gerçekten bir dil olduğunu hatırlamak önemlidir. Standart, denklemin yalnızca bir bölümüdür. Standardın belirsiz olduğu veya özel olarak tanımlandığı durumlarda, derleyiciye dönmeli ve C ++ talimatlarını gerçek makine diline nasıl çevirdiğini anlamalısınız.
Dolayısıyla, değerlendirme sıralaması bir gereklilikse veya en azından önemliyse ve çapraz derleyici uyumlu olmak bir gereklilik değilse, derleyicinizin nihayetinde bunu nasıl bir araya getireceğini araştırın, cevabınız nihai olarak orada olabilir. Derleyicinin gelecekte metodolojisini değiştirebileceğini unutmayın