Is this a bug?

Steven Schveighoffer schveiguy at yahoo.com
Fri Apr 20 12:29:47 PDT 2012


On Fri, 20 Apr 2012 15:21:12 -0400, Robert Clipsham  
<robert at octarineparrot.com> wrote:

> I've been staring blankly at this for a while now and want some input  
> from others:
>
> ----
> void foo(T, U...)(bool arg)
> {
>      if (arg)
>      {
>          assert(T.tupleof.length == U.length);
>          assert(arg); /* Line 6 */
>          // Or some other code here
>      }
> }
> struct A {}
> void main()
> {
>      foo!(A, int)(false);
> }
> ----
>
> When compiled with warnings:
>
> $ dmd -w test.d
> test.d(6): Warning: statement is not reachable
>
> So what appears to be happening here is that dmd is constant folding  
> T.tupleof.length == U.length to false, then assert(arg) can never  
> happen, so the warning is given.

Also note that assert(0), which is what that line reduces to, is *not*  
removed for release builds.

>
> It is obvious, however, that the assertion will never be executed anyway.

No it isn't. this:

foo!(A, int)(true);

compiles to the same exact template function instantiation.  arg is a  
runtime parameter, not determinable at compile-time, and therefore the  
compiler must include the branch.

> Is there some way around this? (other than compiling without -w)
> I can't help but feel what I'm doing isn't right some how.

Use static assert/static if when you expect something that is determined  
at compile time to be a certain way.  Not only will it be more efficient  
code, but if it's *not* compile-time determined, you will get an error  
 from the compiler.

-Steve


More information about the Digitalmars-d mailing list