Set of Char in XE8 gives compiler warnings - how to re-code? [Edit]

I have code like this:

{code}
const
  {Characters not allowed in file names.}
  FileNameForbiddenChars: set of Char = ['<', '>', '|', '"', '\', '/', ':', '*', '?','&']; // note: Some of these, while technically legal, cause issues elsewhere


function IsValidFileName(Filename:String):Boolean;
{
  Returns "True" if file name is legal/valid in Windows.

  Note: This is for FILE NAMES not full file paths, so will return false
        for a path like "C:\MyFile.txt"
}
var
  I: integer;
begin
  Result:=Filename<>'';
  for I:=1 to Length(Filename) do
      Result:=Result and not (Filename[I] in FileNameForbiddenChars);

end;
{code}


This gives the compiler warning:

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

What would you suggest I change in order to eliminate this compiler warning, while still keeping my constant defined outside of the function as a set?

Note: The above is just a sample of code for a general issue.

Thanks!

Carl.

Edited by: Carl Olsen on Jun 30, 2015 11:39 AM
0
Carl
6/30/2015 6:40:23 PM
embarcadero.delphi.general 4258 articles. 0 followers. Follow

5 Replies
1645 Views

Similar Articles

[PageSpeed] 37

Carl wrote:

> I have code like this:
<snip>
> This gives the compiler warning:
> 
> +[dcc32 Warning] Unit1.pas(312): W1050 WideChar reduced to byte char
> in set expressions.  Consider using 'CharInSet' function in 'SysUtils'
> unit.+

As it should be.  In Delphi 2009, Char was changed from AnsiChar to WideChar. 
 A "Set of Char" would thus produce a Set of up to 65535 elements, not 256 
elements like before.  However, a Set cannot hold more than 256 elements, 
so the compiler has no choice but to truncate your Char values to 8bit instead, 
thus the warning.  Which is fine as long as your filenames only contain ASCII 
characters.  But if they contain non-ASCII characters, you are going to lose 
precision in your comparisons.

> What would you suggest I change in order to eliminate this compiler
> warning, while still keeping my constant defined outside of the
> function as a set?

You could do what the compiler warning says - use the SysUtils.CharInSet() 
function:

{code}
const
  {Characters not allowed in file names.}
  FileNameForbiddenChars: TSysCharSet = ['<', '>', '|', '"', '\', '/', ':', 
'*', '?', '&']; // note: Some of these, while technically legal, cause issues 
elsewhere

function IsValidFileName(Filename:String):Boolean;
{
Returns "True" if file name is legal/valid in Windows.

Note: This is for FILE NAMES not full file paths, so will return false
for a path like "C:\MyFile.txt"
}
var
  I: integer;
begin
  Result := Filename <> '';
  for I := 1 to Length(Filename) do
    Result := Result and not CharInSet(Filename[I], FileNameForbiddenChars);
end;
{code}

However, that is not really any better, as each Char will still be truncated 
to 8bit, CharInSet() merely hides the warning from you.

If you support Unicode characters, you can't use a Set anymore.  Re-write 
the code, eg:

{code}
const
  {Characters not allowed in file names.}
  FileNameForbiddenChars: string = '<>|"\/:*?&'; // note: Some of these, 
while technically legal, cause issues elsewhere

function IsValidFileName(Filename:String):Boolean;
{
Returns "True" if file name is legal/valid in Windows.
Note: This is for FILE NAMES not full file paths, so will return false
for a path like "C:\MyFile.txt"
}
var
  I, J: integer;
begin
  Result := Filename <> '';
  for I := 1 to Length(Filename) do
    Result := Result and (Pos(Filename[I], FileNameForbiddenChars) = 0);
end;
{code}

However, there is a small performance hit when passing a single Char to Pos(). 
 You might not notice it for small filenames.  But, if you want to avoid 
that hit, you can do this instead:

{code}
const
  {Characters not allowed in file names.}
  FileNameForbiddenChars: string = '<>|"\/:*?&'; // note: Some of these, 
while technically legal, cause issues elsewhere

function IsValidFileName(Filename:String):Boolean;
{
Returns "True" if file name is legal/valid in Windows.
Note: This is for FILE NAMES not full file paths, so will return false
for a path like "C:\MyFile.txt"
}
var
  I: integer;
  Tmp: String;
begin
  Result := False;
  if Filename <> '' then
  begin
    SetLength(Tmp, 1);
    for I := 1 to Length(Filename) do
    begin
      Tmp[1] := Filename[I];
      if Pos(Tmp, FileNameForbiddenChars) <> 0 then
        Exit;
    end;
    Result := True;
  end;
end;
{code}

Or this:

{code}
const
  {Characters not allowed in file names.}
  FileNameForbiddenChars: string = '<>|"\/:*?&'; // note: Some of these, 
while technically legal, cause issues elsewhere

function IsValidFileName(Filename:String):Boolean;
{
Returns "True" if file name is legal/valid in Windows.
Note: This is for FILE NAMES not full file paths, so will return false
for a path like "C:\MyFile.txt"
}
var
  I, J: integer;
  C: Char;
begin
  Result := False;
  if Filename <> '' then
  begin
    for I := 1 to Length(Filename) do
    begin
      C := Filename[I];
      for J := 1 to Length(FileNameForbiddenChars) do begin
        if FileNameForbiddenChars[J] = C then Exit;
      end;
    end;
    Result := True;
  end;
end;
{code}

-- 
Remy Lebeau (TeamB)
0
Remy
6/30/2015 8:36:08 PM
Wow, Remy - you are a fountain of awesomeness!

Thank you once again!

> Remy Lebeau (TeamB)
0
Carl
6/30/2015 8:51:01 PM
Remy,

Thanks for your earlier reply on this.  I have things working nicely on my side thanks to your input.  One thing has been bugging me a bit, though, that I don't understand in your statement below:

>As it should be. In Delphi 2009, Char was changed from AnsiChar to WideChar. 
>A "Set of Char" would thus produce a Set of up to 65535 elements, not 256 
>elements like before. However, a Set cannot hold more than 256 elements, 
>so the compiler has no choice but to truncate your Char values to 8bit instead, 
>thus the warning. 

I would think that a set would still be 256 elements regardless of whether Char, AnsiChar, WideChar, etc., and that the penalty of a set of WideChar vs AnsiChar is that you would have a set of 256 Words instead of a set of 256 bytes, but in both cases, a set would be limited to 256 elements.

Why is it that a set of WideChar would become 65535 elements all of a sudden?  I would think that each individual element would be able to store a value of 65535, since it's two bytes, but I would not expect the set to become an array[0..65535] of WideChar.
0
Carl
7/6/2015 8:32:18 PM
Carl wrote:

> I would think that a set would still be 256 elements regardless of
> whether Char, AnsiChar, WideChar, etc., and that the penalty of
> a set of WideChar vs AnsiChar is that you would have a set of
> 256 Words instead of a set of 256 bytes

Only if you explicitly restrict the Set to 256 elements, but you are not 
doing that.  You are declaring an unbound "Set of Char", which creates a 
Set that encompasses the entire range of Low(Char)..High(Char) (and you are 
then populating the Set with only a few select characters, but space for 
the other characters still has to be allocated).  When Char was an alias 
for AnsiChar in Delphi 2007 and earlier, High(Char) was 255, and all was 
fine as Low(Char)..High(Char) was 256 elements.  But now that Char is an 
alias for WideChar in Delphi 2009+, High(Char) is 65535 now, so Low(Char)..High(Char) 
is 65536 elements, which is too many.

> Why is it that a set of WideChar would become 65535 elements all of
> a sudden? I would think that each individual element would be able to
> store a value of 65535, since it's two bytes, but I would not expect
> the set to become an array[0..65535] of WideChar.

Because High(WideChar) is 65535, thus Low(Char)..High(Char) (0..65535) is 
65536 elements.

It seems you have a fundamental misunderstanding what how a Set really works. 
 A Set is not an array of values, like you are thinking.  It is actually 
an array of bits, where each allowed value within the Set's range is represented 
by a single bit, the Set does not hold the actual values.  So, 8 values in 
the Set can be stored in a single Byte in memory, up to 32 bytes total for 
a 256-element Set.  Set operations like Include()/Exclude(), "value in Set", 
"Set +/- [values]", etc are very fast and efficient, because they are simply 
querying/twiddling individual bits, not whole values.

A Set is physically restricted to 256 bits max, and thus can only represent 
256 values, regardless of the byte size of the element type.  So, when Char 
is WideChar, a "Set of Char" cannot represent all of the values that a WideChar 
can contain, thus the compiler warning when it has to truncate WideChar values 
in Set expressions.

If Sets larger than 256 elements were allowed, a "Set of Char" for WideChar 
values would take up 8K of memory (65536 bits) max.  With your thinking, 
an array of 65536 2-byte whole values would take up 128K of memory, and be 
extremely slow in comparison.

-- 
Remy Lebeau (TeamB)
0
Remy
7/6/2015 9:36:49 PM
>It seems you have a fundamental misunderstanding what how a Set really works.

Wow - you are absolutely right!  I am glad we had this conversation, because I had it all wrong in my head.  Thanks!!
0
Carl
7/6/2015 10:22:29 PM
Reply:

Similar Artilces:

Re: Delphi 2011
Since my reply was aimed at a message which seems to be to deleted by the OP, I deleted the contents of my reply also. Edited by: Pieter Zijlstra on May 8, 2010 2:49 AM I didn't delete any messages. But this reply seems to be missing: ----- You are watching the user "NickHodges", who just posted a message at May 7, 2010 3:48:54 PM: .... ----- It is a reply from Mr. Hodges to Ms. Carter that he, or someone else, removed from the thread. ...

Re: Is Delphi 2010 a big compile bugs? [Edit]
This message is no longer available. Pieter Zijlstra wrote: > Rudy Velthuis (TeamB) wrote: > > > TinTin TinTin wrote: > > > > > This is not joke,I use delphi 10 years. > > > TComponent.Name==Form1.Caption ???? > > > > YOU ARE NOT CREATING A COMPONENT! THERE IS NO COMPONENT YET, SO YOU > > CAN'T SET ITS NAME YET! What happens is undefined. > > Ssssssshhhttt!!! The kids just fell asleep ... > > <quote> > MMWHHEEEEHH!!!!! > </quote> > > ... Oh ... F!@#$%^u&*()*&^c%$#@k!...

Re: Delphi for the Mac [Edit] [Edit]
Rudy Velthuis (TeamB) wrote: > > <hides under desk as fire storm about TeamB editing other people's > > posts re-ignites> > > I was thinking the same. :-) -- Andy Syms Technosoft Systems Ltd ...

SEPA components for Delphi with Source Code (Delphi 5
Hi all, in the european union change next year the Bankingformat to the SEPA Format. All peoples and companies must change the bankingssoftware and the costumer data form acountnummers in the new IBAN and BIC numbers. See: http://www.arma-it.de/shop/artikelueber.php?wgruppeid=211&wgruppe_offen=211 Functions: - generate SEPA XML'S - Calc IBAN - BIC Database (DE,AT and CH) Questions: vertrieb@arma-it.de PS: Bankinssoftware for Develpoers (Germany only) http://www.arma-it.de/shop/artikelueber.php?wgruppeid=212&wgruppe_offen=212 El 26/10/13 21:38, A...

Delphi No Compile -> Object reference not set to an instance of an object [Edit]
This sort of follows from threadID=68492 .... I've just installed Delphi XE2 When I try to compile anything at all I get is "[Fatal Error] Object reference not set to an instance of an object" I've tried compiling some of the Delphi samples - no :( I've tried creating a new console application - but that wont compile I've tried simple pascal - that compiles with Delphi v2 - butr not with XE2 I've tried re-intsalling Delphi XE2 I've tried repairing Delphi XE2 But all I get is that "[Fatal Error] Object reference not set to an instan...

Double-click to go to a compiler warning in code: No longer works (XE8)
When I do a "build all", Delphi XE8 generates a list of compiler hints and warnings. It used to be the case that I could double click on one of them, and it would take me to the offending line of code. Now, it just ignores me, even if I have that unit open in the code editor. I don't think I have done anything to disable such a feature, but maybe I did. How do I restore this functionality? Thanks! Carl. ...

Delphi code thowing errors within IDE (but not in compiled exe) [Edit]
Rad Studio - Delphi 2010 (Windows 7, 64 bit laptop) I started to get some issues with my delphi code not running within my Rad Studio (Delphi) 2010. I have been days trying to figure out why. Working with one installed package after another, trying to decide if it was the culprit or not. After finally uninstalling all packages, and even uninstalling the entire Rad Studio (and re-installing just Rad-Studio), i can't seem to figure what can be causing my Delphi IDE to act as it does. I even cleaned the registry of all things related to my component package a nd Rad Studio (before re-inst...

Re: [MacPerl] Re: [OT?] Code Editing
> 1. Test or assignment? in the one case ($v =~ m//) it's a test, and if that test fails the subroutine fails ($1..n are used later and so if the match fails there'll be other muck-ups). In the other case ($v = $$ref) it's an assignment, and if the assignment fails (i.e. the reference is bad) then the subroutine fails. > 2. Likewise, are you testing $error [...] In the case of the first part (preceding 'or') failing, then I'm setting $error and exiting the subroutine. From what I can discern this assignment is what -w is complaining about. Using ...

vc++ code compiling in code gear [Edit]
I am trying to compile an open source code in borland c++. The open source is developed in vc++. I see that the code is compiling in vc++ fine. The open source code generates a few libraries ex vc1.lb, vc2.lib. Also it uses some windows utilities such as winsock2.h, ws2_32.lib etc. In order to get going with my code, I converted vc1.lib and vc2.lib and to vc1BC.lib and vc2BC.lib using coff2omf utility. I also converted ws2_32.lib to ws2_32BC.lib. In next step I added these libraries into the project. The code compiling only gives few warning. When I run the code, it just executes and...

Re-compiling vcl170.dpk of Delphi XE3 Update 2 (17.0.4770.56661) [Edit]
We want to migrate from Delphi 7 to Delphi XE3. After migrate, all things okay but we set Application.BiDiKeyboard and Application.NonBiDiKeyboard, when user want to switch between controls, there is a delay about 1 sec for each transition. I search and review the problem and see that it is a bug! of Windows 7 and above. When VCL call LoadKeyboardLayout in TWinControl.CMEnter(var Message: TCMEnter); this delay occurred. Considering a form with a lots of controls, loading the form was very slow and switching between controls are hard, specially for users that work alot with keyboard. I try t...

Re: calling a c++ function from Delphi [Edit] [Edit]
costa basil wrote: > Sorry, I posted it here because different people read different lists > and c++ guys might not read the delphi lists and vice-versa and I > want to pick-up all brains... And yet, it is not allowed. -- Rudy Velthuis (TeamB) http://www.teamb.com "This isn't right, this isn't even wrong." -- Wolfgang Pauli (1900-1958), upon reading a young physicist's paper ok, understood. ...

Code works in Delphi 7 but not in Delphi 2010 [Edit]
hello, i have a procedure that open's a file by passing the file name as the parameter to the executable. something like this {code} C : \ P r o g r a m F i l e s \ Da c k e r \ D r a c k e r . e x e " G : \ D E l p h i 7 \ D e l p h i 7 A p p _ l o g . t " {code} The source code is {code} procedure OpenFileWithExe var hReg: HKEY; Ret: Longint; RegDataType, RegDataSize: DWORD; CmdLine: array [0..560] of Char; Len: Integer; SInfo: TStartupInfo; PInfo: TProcessInformation; begin Ret := windows.RegOpenKeyEx(HKEY_CURRENT_USER, ...

Re: Maybe is a new life for Delphi? [Edit] [Edit]
Cesar Romero wrote: > > This is not ad. Sparta is not commercial product. > > Any product announcement should be in 3rd party group, comercial or > not, that is part of newsgroup guidelines. Right. -Craig [moderator] -- Craig Stuntz · Vertex Systems Corp. · Columbus, OH Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz/ ...

Re: compile problem c++ 2009 [Edit] [Edit]
Antonio Estevez <amelsoft@terra.es> wrote: >> Again a bit further, but now the next errors: >> >> static unsigned int nr_of_links = ((sizeof( log_link_array )) / >> (sizeof(log_link_array[0]))); >> >> [BCC32 Warning] PatsupFunctionelelaag.h(405): W8058 Cannot create >> pre-compiled header: initialized data in header > >That's a warning, not an error. Agreed, but it's probably worth trying to clear up, just for build times. In this case, (and bearing in mind I don't have CB2009, so I'm unsure quite how fussy...

Attempting to compile Delphi 5 code in Delphi XE5 is failing
Greetings All, If I'm not in the correct formum please tell me which one I should be in. Just upgraded to Delphi XE5 and am attempting to compile one of my Delphi 5 projects. I used Interbase Express I use either TDataSource -> TCDSProvider -> TDataSetProvider -> TIBQuery or TDataSource -> TClientDataSet -> TDataSetProvider -> TIBQuery Also used TIBDatabase, TIBTransaction, and TIBStoredProc I open the smallest project I have and click compile and almost immediately I receive this error Checking project dependencies... Compiling CITranEngine.dproj...

Delphi 2006 product activation (re end of support for Delphi 2006) [Edit]
Apologies if this question has been asked and answered elsewhere, but I recently got an email informing me support for Delphi 2006 was going to be dropped. I have mostly converted to Delphi 2009 now, but I'll still be able to activate my copy of 2006 on any future installation right? Edited by: David Howes on Jul 18, 2009 9:53 AM David Howes wrote: > Apologies if this question has been asked and answered elsewhere, but I recently got an email informing me support for Delphi 2006 was going to be dropped. I have mostly converted to Delphi 2009 now, but I'll still be able to acti...

FastScript in Delphi XE8
I am converting from Delphi 2006 to Delphi XE8, and am now nearing the finish line, but have one remaining major roadblock: FastScript I use Fastscript very heavily as a way to allow our users to write scripts that can extend our software as much as they like, including creating forms and adding buttons. This is not working. A specific problem that I have, is that code that works great in Delphi 2006 does not work in Delphi XE8. Specifically, if my script contains a reference to a "TForm", or "TBitBtn" (as well as many other components), then FastScript will return ...

FastScript in Delphi XE8
*Edit: This is now solved, but I leave the original message below for reference. The solution was essentially to delete all traces of FastReports (That's "Reports", not "Script") from the computer, as it was interfering with FastScript. This was actually fairly involved to do, and we did it under the supervision of someone from FastScript tech support, who was extremely helpful. If you run into the problem described below, be sure to contact their technical support and see if maybe you are experiencin g the same issue, and how to resolve it. I hope this is helpfu...

Best practice when code should still compile with elder versions of Delphi but also Delphi 2009
When tryung to compile Turbopower Orpheus and other Turbopower products which I still use in my applications and therefor need to convert to Delphi 2009, I get lots of warnings even though others has made it possible to get Orpheus compiled. The problem is checking a char in a set which gives a type cast warning and suggests using a new function instead. [DCC Warning] ovcdbnum.pas(401): W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit. So what would be the best practice here eg. correcting this ro...

Error: "Query: dataset not in Edit mode": in delphi code for Rave Report [Edit]
I am trying to write a Delphi code (Delphi 2010) to print a rave report from the access database; I am using RVSystemprint method; q1 is a query name. I get error message " q1: dataset not in edit or insert mode", at the line: while not q1.Eof. Even though I added q1.Edit or q1.insert, it doesn't work. Database's readonly property is FALSE. What is missing in the code? Thanks. procedure TForm1.rsysPrint(Sender: TObject); begin with Sender as TBaseReport do begin ..... q1.Open; q1.Edit; q1.first; while not q1.Eof do begin ... end; .... ...

YOU RE-SET MY SETTINGS!!
Name: Product: Firefox Summary: YOU RE-SET MY SETTINGS!! Comments: I AM VERY, VERY UNHAPPY THAT YOUR UM-ANNOUNCED DOWNLOAD TO MY COMPUTER DHANGES MY FIREFOX SETTINGS!!!!! ENOUGH SO... THAT IF / WHEN IF HAPPENS AGAIN? I WILL PERMANENTLY SWITCH TO ANOTHER BROWSER!! WHAT IS PARTICULARLY GALLING IS HAT I HAVE CONVINCED DOZENS OF FRIENDS TO FIREFOX! STOP ^%$^*%$& WITH MY FIREFOX SETTINGS!!!!!!!!!!!!!! Browser Details: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) From URL: http://hendrix.mozilla.org/ Note to...

RE: RE: RE: RE: [wxperl-users] wxTreeCtrl, edit an treeItem
>>Found a fix ( I hope ); download the modified wx22_9.dll from >>http://wwwstud.dsi.unive.it/~mbarbon/wx/wx22_9.dll.gz >>uncompress it and put it in $PERL/site/lib/auto/Wx >>( make a backup of the original one, of course ). >>This fixes your problem with tree control, but may introduce >>new ones ( it is a fix backported from wxWIndows 2.3 ). >> >>Regards >>Mattia > >hey thanks man! >i had no time to work on my application but i checked the wxwindows >mailinglist archive. you asked for a code change as workaround......

set of char and Delphi 2009
In delphi, it is not possible to use 'set of word' because of its big memory requirement (But I think 64KB is not a big memory nowadays and it is applicable). Therefore, 'set of char' will not be compiled in Delphi 2009 (I haven't tried D2009 yet). myset:=['a','d'..'x']; if mychar in myset then ... What do you recommend, how to change this code to be compiled in Delphi 2009 without speed decrease? "Samir Shagavatov" <samir105@gmail.com> skrev i meddelelsen news:10065@forums.codegear.com... > In delphi, it is not possibl...

compiled code has grown again! [Edit]
Every new version of cbuilder makes the compiled code grow. xe2 6,025,728 xe 4,922,368 and I remember being shocked at how big it was moving to xe. and I remember being shocked at how big it was moving to rad studio. and so on. The code hasn't changed substantially over the last couple of years, yet it has more then doubled in size. Is there a way go move back to smaller code while keeping xe2? > {quote:title=Chris Bruner wrote:}{quote} > Every new version of cbuilder makes the compiled code grow. > > xe2 6,025,728 > xe 4,922,368 > Is there a wa...

Web resources about - Set of Char in XE8 gives compiler warnings - how to re-code? [Edit] - embarcadero.delphi.general

Compiler - Wikipedia, the free encyclopedia
... , or external linking . The most common reason for wanting to transform source code is to create an executable program. The name "compiler" ...

Compiler - Wikipedia, the free encyclopedia
"Compile" and "compiling" redirect here. For the software company, see Compile (publisher) . For other uses, see Compilation . This article has ...

Facebook Open-Sources HipHop PHP Compiler Software
Earlier this morning, Facebook officially made their new PHP “compiler,” called HipHop, available as open source software. In the blog post by ...

Art in the Age of Matter Compilers
jurvetson posted a photo: Sheba may be the harbinger of art in the digital age — a mathematical sculptor with digital matter. She manipulates ...

Interpreters and Compilers (Bits and Bytes, Episode 6) - YouTube
This animation explains the difference between interpreters and compilers. It is from Episode 6 of the classic 1983 television series, Bits and ...

Typesafe cofounder forking Scala compiler
The main contributor to the Scala compiler, Paul Phillips, has announced on GitHub that he is forking the compiler to “fix some of the innumerable ...

Does Apple's new developer agreement ban Adobe's Flash-to-iPhone compiler?
Given that any kind of formal truce between Apple and Adobe was essentially blown out of the water by Steve Job's very public slating of Flash ...

Apple seeds devs with Safari 5.2 for Lion, Xcode 4.4 with new LLVM compiler
... to the general public this summer. Among the new features: According to Apple, Xcode 4.4 includes an editor for Collada 3D files, compiler support ...

NVIDIA and Continuum Analytics Announce NumbaPro, A Python CUDA Compiler
... are announcing that they are bringing Python support to CUDA. Specifically, Continuum Analytics’ will be introducing a new Python CUDA compiler, ...

IntelliJ Releases IDEA 12, Brings Improved UI, New Compiler Mode, Android UI Designer, And More
I'm not going to pretend to be a developer here, and I'll openly admit that the bulk of what IDEA 12 does is over my head. However, I do understand ...

Resources last updated: 2/16/2016 10:09:51 PM