4
votes

How do I use CharInSet() to get rid of this warning?

lastop:=c;
{OK - if op is * or / and prev op was + or -, put the whole thing in parens}
If (c in ['*','/']) and (NextToLastOp in ['+','-']) then
  Result.text:='('+Result.text+')';
Result.text:=Result.text+c;

[dcc32 Warning] U_Calc1.pas(114): W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit.

1
Start with the documentation!David Heffernan
Wow! gr8 answerRaj
Well, if you had read the documentation, it would have been obvious how to call the function. You did look at the documentation right?David Heffernan
@David Heffernan The documentation isn't always clear, especially for beginners.R.J. Dunnill
The official documentation doesn't even have an example of using charinset. This is therefore a reasonable question to ask.rhody

1 Answers

13
votes

CharInSet is necessary due to the fact that WideChar values are too large to be used in actual set operations.

To use it in your code you would use it like this:

If (CharInSet(c, ['*','/']) and (CharInSet(NextToLastOp, ['+','-']) then

However CharInSet doesn't actually do anything special or even useful other than silence the warning.

The code in the function is identical to the code it replaces. The warning is silenced only because the RTL units are pre-compiled. The compiler does not recompile them even if you do a full "Rebuild all". i.e. that code in SysUtils is not actually ever re-compiled. If it were it would emit the exact same warning.

So, you could use that function to avoid the warning but if you can be certain that your character data is ASCII (or extended ASCII), that is with ordinal values in the range #0 to #255, then you could also avoid the warning by typecasting your character variable explicitly to an ANSIChar:

If (ANSIChar(c) in ['*','/']) and (ANSIChar(NextToLastOp) in ['+','-']) then

To reiterate: You should only do this if you are absolutely certain that the character data that you are working with consists only of ASCII characters.

But this same caveat applies equally to using CharInSet since this still requires that you test for membership in an ANSIChar set (i.e. single byte characters).

Explicit type-casting has the advantage (imho) of making it explicit and apparent that your code is intended deliberately to expect and work only with ASCII characters, rather than giving a perhaps misleading impression of being more fully equipped to handle Unicode.