Normalmente, constexpr deve essere privo di effetti collaterali. Tuttavia, ho appena scoperto che è possibile utilizzare gli effetti collaterali nei costruttori di eccezioni generate. Questa tecnica può essere utilizzata per emulare assert() per le funzioni di constexpr, come è dimostrato nel seguente programma.È legale utilizzare gli effetti collaterali nelle eccezioni generate da constexpr?
#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);
}
L'ho provato con g ++ 4.7.2 e clang ++ 3.1. Quando le precondizioni falliscono, si ottiene il percorso dell'errore e un core dump.
./constexpr_assert some_arg
assertion: <y != 0> failed (file: constexpr_assert.cpp, line: 26)
Aborted (core dumped)
Quindi funziona con i compilatori correnti, ma è legale C++ 11?
Fuori interesse, cosa succede se si fornisce una costante in tempo di compilazione '0' come secondo argomento a' divide() '? Il * compilatore * "genera un'eccezione"? :) –
static_assert (divide (1, 0)> = 0, "testing"); semplicemente non compila divisione di restituzione (1, 0); compila con Clang e non riesce solo in fase di esecuzione. –
È necessario fare attenzione a distinguere tra espressioni costanti e una funzione 'constexpr'. Qualcosa come "constexpr" deve essere privo di effetti collaterali "è impreciso. Pensa a 'constexpr' come non più di una parola chiave (viene in mente' static'). –