Açıklama
Bazı derleyiciler (özellikle GCC), derleme zamanında ifadeleri değerlendirirken daha yüksek hassasiyet kullanır. Bir ifade yalnızca sabit girdilere ve değişmez değerlere bağlıysa, ifade bir constexpr değişkenine atanmamış olsa bile derleme zamanında değerlendirilebilir. Bunun meydana gelip gelmediği şunlara bağlıdır:
- İfadenin karmaşıklığı
- Derleyicinin derleme zamanı değerlendirmesi yapmaya çalışırken kesme olarak kullandığı eşik
- Özel durumlarda kullanılan diğer buluşsal yöntemler (clang elides döngüleri gibi)
İlk durumda olduğu gibi bir ifade açıkça sağlanırsa, karmaşıklığı daha düşüktür ve derleyicinin bunu derleme zamanında değerlendirmesi olasıdır.
Benzer şekilde, bir işlev satır içi olarak işaretlenirse, derleyicinin onu derleme zamanında değerlendirme olasılığı daha yüksektir, çünkü satır içi işlevler değerlendirmenin gerçekleşebileceği eşiği yükseltir.
Daha yüksek optimizasyon seviyeleri, daha yüksek hassasiyetli derleme zamanı değerlendirmesi nedeniyle gcc'de tüm ifadelerin doğru olarak değerlendirildiği -Ofast örneğinde olduğu gibi bu eşiği de artırır.
Bu davranışı burada derleyici gezgininde gözlemleyebiliriz. -O1 ile derlendiğinde, yalnızca satır içi olarak işaretlenen işlev derleme zamanında değerlendirilir, ancak -O3'te her iki işlev de derleme zamanında değerlendirilir.
Not: Derleyici gezgini örneklerinde printfbunun yerine iostream kullanıyorum çünkü ana işlevin karmaşıklığını azaltarak efekti daha görünür kılıyor.
Çalışma inlinezamanı değerlendirmesini etkilemediğini göstermek
Standart girdiden değer elde ederek ifadelerden hiçbirinin derleme zamanında değerlendirilmemesini sağlayabiliriz ve bunu yaptığımızda, 3 ifadenin tümü burada gösterildiği gibi yanlış döndürür: https://ideone.com/QZbv6X
#include <cmath>
#include <iostream>
bool is_cube(double r)
{
return floor(cbrt(r)) == cbrt(r);
}
bool inline is_cube_inline(double r)
{
return floor(cbrt(r)) == cbrt(r);
}
int main()
{
double value;
std::cin >> value;
std::cout << (floor(cbrt(value)) == cbrt(value)) << std::endl;
std::cout << (is_cube(value)) << std::endl;
std::cout << (is_cube_inline(value)) << std::endl;
}
İle Kontrast Bu örnekte aynı derleyici ayarları kullanmak ancak daha yüksek duyarlıklı derleme zamanı değerlendirme sonucunda derleme sırasında değer sağlar.