pu$�le

Jonathan M Davis jmdavisprog at gmail.com
Sun Jul 18 00:38:38 PDT 2010


On Saturday 17 July 2010 22:52:21 strtr wrote:
> 
> I think I'll start subject tagging my posts: [D1/D2]
> std.stdio in D1 doesn't mention a write function and feeding the writef
> function an illegal UTF string will result in a UTF exception.
> With this information, what do you think the output should be?

Well, I certainly think that throwing an exception for bad UTF-8 values makes 
sense, though D2's docs for writef say nothing about exceptions, and on my 
machine, running Linux, they just fail to print anything. Throwing an exception 
would likely have been better.

In any case, I would have expected it to increment stash by 2 on the first loop 
because $ would be valid and would hit both scope(exit) and scope(success). 
After that... That continue makes me awfulling nervous. You'd expect the scope 
statements to be run in reverse order with continue and then stash--. However, 
to run that continue statement would have to skip the other scope statements...

I think that we'll have to lower the body of that foreach loop to have any clue 
what's going on here. It should come out to something like this, I would think:

const char[] coins = `$�`;

void main()
{
        writef(`I made `);
        int stash = 0;
        scope(exit) writefln(stash,`.`);
        scope(failure) stash--;

        foreach(coin;coins)
        {
            try
            {
                try
                {
                    try
                    {
                        try
                        {
                            writef(coin);
                        }
                        catch
                        {
                            continue;
                            throw;
                        }
                    }
                    catch
                    {
                        stash--;
                        throw;
                    }

                    stash++;
                }
                catch
                {
                    throw;
                }
            }
            finally
            {
                stash++;
            }
        }
}


That being the case, the exception from writef() will always get eaten by the 
continue because the throw that rethrows the exception would never occur. 
Normally, code like that should result in a compilation error, but it might not 
given that it's the compiler creating the try-catch block. My guess is that this 
is a bug in dmd. It makes no sense to me to allow any kind of goto, break, or 
continue statements in a scope statement's body.

Regardless, that continue would mean that the first stash++ would be skipped, but 
the second would still happen because it's in a finally block. That means that 
each of the 3 bad UTF-8 values which make up the euro symbol would each 
increment stash once. So, the overall result would then be 5.

It's possible that I lowered those scope statements incorrectly, but it looks to 
me like that's what the code should be doing. Regardless, continue in a scope 
statement should be an error.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list