yoy.be "Why-o-Why"

About x in ['0'..'9'] and CharInSet

2019-11-05 22:42  anticharinset  coding dagboek delphi  [permalink]

I'm still in the (slow) process of letting go of Delphi 7 and embracing the modern version(s) of Delphi, which to be honest was only possible since there's a community edition (that includes the stand-alone compiler(s)). I was in doubt if I would move over to the WideChar based default string, but since Windows internally switched long ago — and you get emoji-support for free — I thought I should switch also and haven't even tried to override the new default and switch string to be AnsiString just to keep things the old way. It works remarkably well. Any code that assumes the length of the string is also the number of bytes to move around needs to change, but that's a good opportunity to change them over to operations that use encoding support. With PChar and char that also changes mapping (to PWideChar and WideChar respectively) any coding use those just keeps working. Except in code like x in ['0'..'9'] which I apparently use a lot. It works except when compiling it throws this warning:

Warning: W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit.

At first I was baffled. Why is it reduced to a byte char? I know set expressions trigger all kinds of compiler optimizations (that's why I like to use them so much), but has someone been too lazy to make them happen with 16-bit values as well? I guess we're talking assembler jump-lists here, so it probably matters if you can limit them to 256 positions, and 65536 positions would add too much of dead chunks of data into your compiled code... But still. x is WideChar, any '0'-style literals should default to WideChar, shouldn't they? So I regret there was no preference to support code re-use here, and CharInSet which appears to be just a wrapper around the in syntax, strange.

I don't like warnings and hints. I typically avoid them at all cost, treating them as compile errors. It helps to keep your code clean, and avoids trouble down the line. (But if you're really into avoiding trouble down the line, you should do decent static code analysis...) I'm kind of strict on myself that way. So I need to know what's the best way to avoid this warning. In someone else's code I saw x in [WideChar('A')..WideChar('Z')] but that doesn't appear to suppress this warning. So I settled on AnsiChar(x) in ['0'..'9','A'..'F'] which probably calls a Unicode conversion routine, but I don't care enough. Old Delphi understands it, new Delphi no longer throws an error, and as far as I know the compiler optimizations still kick in and I haven't seen any performance loss over code like this. So I can sleep again.

Unless someone throws me a much better alternative and I won't sleep for a week because it feels like I should have known that all along...

twitter reddit linkedin facebook