pu$�le

Jonathan M Davis jmdavisprog at gmail.com
Sat Jul 17 22:17:39 PDT 2010


On Saturday 17 July 2010 21:48:30 strtr wrote:
> == Quote from Jonathan M Davis (jmdavisprog at gmail.com)'s article
> 
> > On Saturday 17 July 2010 18:59:18 strtr wrote:
> > > That is [dollar sign, euro sign]
> > > 
> > > The reason I post it is because I expected the stash to be 3 lower.
> > 
> > As to why it's not working right, change th foreach loop to this:
> > foreach(dchar coin; coins)
> > {
> > ...
> > }
> > Otherwise, instead of looping over each code point, you're looping over
> > each code unit. char[] and string are encoded in utf-8, so each char is
> > a code unit, and 1 - 4 code units are put together to form a code point,
> > which is what you'd normally think of as a character.
> > The dollar sign takes one code unit in utf-8, but the euro sign takes 3.
> > So, you're looping 4 times instead of 2. By specifying dchar, the
> > compiler automatically processes the code units correctly to make it so
> > that you loop over each code point (i.e. character) rather than each
> > code unit (i.e. char). You should pretty much never deal with each
> > individual char or wchar in a string or wstring. Do the conversion to
> > dchar or dstring if you want to access individual characters. You can
> > also use std.utf.stride() to iterate over to the next code unit which
> > starts a code point, but you're still going to have to make sure that
> > you convert it to a dchar to process it properly. Otherwise, only ASCII
> > characters will work right (since they fit in a single code unit).
> > Fortunately, foreach takes care of all this for is if we specify the
> > element type as dchar.
> > As for why it's 4 rather than 2 in the corrected version (or 8 instead of
> > 4 in the incorrect version), that's because you have both scope(exit)
> > and scop(success) there. Both will be run, so both will increment stash,
> > and you get double the increments that you seem to be expecting.
> > - Jonathan M Davis
> 
> Wasn't it obvious the puzzle was about exceptions, with half of the lines
> being scope guards and all?
> Part of the puzzle is the realization that chars aren't code points but
> code units. The other part is understanding the order of scope guard
> execution. I'm not sure whether the linux or the windows version of writef
> is the correct one, but here I get a nice utf-exception. (Or did you maybe
> use D2? if not then we have a discrepancy bug)

All I ever use is D2. I have no idea what D1 would be doing differently. In D2, 
writef(), the "f" is for format or formatted, and you have to have a "format" 
string like printf would in order for it to work. write() is the version which 
doesn't require a format string. I am using Linux if that changes anything, but 
as far as I can tell, you're using writef() incorrectly. In any case, I 
obviously don't quite get what you're trying to do since (at least in D2), I 
don't believe that you have any functions in that loop which will every throw an 
exception. If you were using File's writef() because you were writing to a file, 
then that would be different. But writef() by itself is to stdout and won't 
throw.

Now, as you're using D1, that may change things. But you gave no indication that 
you were using D1. In future questions, you should probably be more specific 
about that, since I think that most people around here are using D2, and they 
will likely assume that you're using D2 unless you say otherwise. I certainly 
did.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list