Normal olarak, constexpr'in herhangi bir yan etkisi olmamalıdır. Bununla birlikte, atılan istisnaların yapıcılarında yan etkilerin kullanılmasının mümkün olduğunu keşfettim. Bu teknik, aşağıdaki programda gösterildiği gibi, constexpr işlevleri için assert() öykünmesi için kullanılabilir.Constexpr tarafından atılan istisnalarda yan etkileri kullanmak yasal mıdır?
#include <iostream>
#include <cstdlib>
#include <stdexcept>
struct constexpr_precond_violated : std::logic_error
{
constexpr_precond_violated(const char* msg) :
std::logic_error(msg)
{
std::cerr << msg << '\n';
abort(); // to get a core dump
}
};
#define TO_STRING_IMPL(x) #x
#define TO_STRING(x) TO_STRING_IMPL(x)
#define CONSTEXPR_PRECOND(cond, value) \
((!(cond)) ? throw constexpr_precond_violated(\
"assertion: <" #cond "> failed (file: " \
__FILE__ ", line: " TO_STRING(__LINE__) ")") \
: (value))
constexpr int divide(int x, int y)
{
return CONSTEXPR_PRECOND(y != 0, x/y);
}
int main(int argc, char** argv)
{
// The compiler cannot know argc, so it must be evaluated at runtime.
// If argc is 2, the precondition is violated.
return divide(100, argc - 2);
}
G ++ 4.7.2 ve clang ++ 3.1 ile test ettim. Ön koşullar başarısız olduğunda, hata konumunu ve bir çekirdek dökümünü alırsınız.
./constexpr_assert some_arg
assertion: <y != 0> failed (file: constexpr_assert.cpp, line: 26)
Aborted (core dumped)
Geçerli derleyicilerle çalışıyor, ancak yasal C++ 11 mi?
Out divide() 'işlevinin 2. argümanı olarak" 0 "derleme zamanı sabiti sağladığınızda ne olur? * Derleyici * "bir istisna atar" mı? :) –
static_assert (böl (1, 0)> = 0, "test"); sadece geri dönüşünü derleyemez (1, 0); Clang ile derler ve yalnızca çalışma zamanında başarısız olur. –
Sabit ifadeler ile 'constexpr' işlevi arasında ayrım yapmak için dikkatli olmalısınız. "Constexpr 'gibi yan etkilerden arınmış olmalı" bir şey kesin değildir. "Constexpr" kelimesini bir anahtar kelime olarak düşünmeyin (“statik” akla gelir). –