On 6/14/23 9:00 AM, Cecil Ward wrote:
>The compilers should surely be able to use the presence of static asserts to enable better code generation since the direction of some later conditional branches can be known, value ranges can be known, all kinds of potential good stuff. Is that correct?
A static assert is telling the compiler if the condition isn't true at compile time, to halt compilation. That is, static asserts have no bearing on semantic meaning other than to say "this isn't compilable". By definition, the compiler knows whether the assert is true or not, so there is no "hint" here for better code generation that it couldn't already gain from it's own knowledge.
In contrast, an assert is saying a condition should be true at runtime. This can testify for something that the compiler can't know at compile time. In this case, the compiler can take hints from the assert to alter code generation (i.e. skip some code that is redundant given the assert).
>If assert without the static is implemented as debug assert then unless the compiler makes an exception and does not all the ‘debug’-conditional to simply wipe out the assert entirely the compiler won’t gain the benefit of the information available from an assert.
The compiler can use the hint of the assert whether it generates code to perform the assert or not.
>There is of course the difficulty that the non-static assert can not (necessarily) be evaluated at compile-time. But of course the bool value of the assert text-expression is always known.
I'm not sure what you mean here.
>Is there a way of testing whether or not something can be evaluated at compile-time or really requires run-time evaluation? If so, is it something we could use routinely? I could really use this in certain templates, for the case where there are several specialisations that use parameters with special constant values and then there is the ‘otherwise’ default expansion of the template, which has an argument that is not a known compile-time constant.
static if(__traits(compiles, () {enum x = someExprToEvalAtCompileTime;})) {...}
> So could non-static asserts that do not in fact require run-time evaluation be convertible to an effective status assert, with all the benefits possible in code generation?
A static assert is not evaluated the same as a runtime assert. They aren't interchangeable because they aren't solving the same problem.
To give you an example:
void foo1()
{
if(condThatShouldAlwaysBeTrue)
{
performSomeWork();
return;
}
assert(false, "Should not get here");
}
void foo2()
{
if(condThatShouldAlwaysBeTrue)
{
performSomeWork();
return;
}
static assert(false, "Should not get here");
}
foo1 will compile and run just fine, as long as the asserted condition is always true.
foo2 will not compile. Why? Because even to compile static assert(false)
means to halt compilation. It doesn't matter if at runtime it will never get there.
-Steve