* * *

Author Topic: Very unimportant, small request..  (Read 1651 times)

darksky666

  • New member
  • *
  • Posts: 30
Very unimportant, small request..
« on: April 26, 2018, 12:41:58 pm »
This is unimportant, i know the thing i did here is/was stupid and dumb, and this is just a request..

I wanted to know when what would happen if i put a character subrange inside a case statement that tests for string equality (i know string b is not same as character b)..

Code: Pascal  [Select]
  1. program prog;
  2.  
  3. var
  4.   s1 : string;
  5.  
  6. begin
  7.  s1 := 'b''';
  8.  
  9.   case s1 of
  10.   'Hello', 'Hello2' : begin
  11.                       Writeln ('Hello or Hello2');
  12.                       Writeln ('IInd Statement');
  13.                       end;
  14.   'A', 'a'..'z' : begin
  15.                   Writeln ('A or a..z');
  16.                   Writeln ('Ch IInd Statement');
  17.                   end;
  18.   else
  19.     Writeln ('Neither HAHA!');
  20.     Writeln ('NONE OF THOSE HAHA');
  21.   end;
  22. end.
  23.  

i expected it to either (1) not to compile at all or (2) compile and work fine in all cases, but the result is not consistent, it broke the whole thing apart..

It printed A or a..z.

Tried it with string z' and it compiled and worked fine screenshot .

Tried it with string hello2 that printed the A or a..z string!

Like i said I know nobody does such a dumb thing in their code, but the behavior was inconsistent (string b' vs string z', so It'd be nicer if fpc didn't compile code in case where character subrange is encountered in case of statements that deal with strings..

Thanks

howardpc

  • Hero Member
  • *****
  • Posts: 2684
Re: Very unimportant, small request..
« Reply #1 on: April 26, 2018, 12:57:35 pm »
If you add
Code: Pascal  [Select]
  1. {$H+}
as the second line of your program, so ansistrings become the default string type, you will get results that are closer to what you might expect.

darksky666

  • New member
  • *
  • Posts: 30
Re: Very unimportant, small request..
« Reply #2 on: April 26, 2018, 01:09:48 pm »
Um, which version are you using? Got the same result even with the directive.

rvk

  • Hero Member
  • *****
  • Posts: 3440
Re: Very unimportant, small request..
« Reply #3 on: April 26, 2018, 01:34:58 pm »
Seems to be a bg in FPC 3.0.4.

I get this with tunk:
Code: [Select]
C:\dev32\fpc\test>..\bin\i386-win32\fpc.exe test.pp
Free Pascal Compiler version 3.1.1 [2018/04/24] for i386
Copyright (c) 1993-2018 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling test.pp
Linking test.exe
21 lines compiled, 0.0 sec, 28608 bytes code, 1348 bytes data

C:\dev32\fpc\test>test
Neither HAHA!
NONE OF THOSE HAHA


C:\dev32\fpc\test>
and this with Laz 1.8.2 FPC 3.0.4:
Code: [Select]
C:\dev32\fpc\test>c:\laz.1.8\fpc\3.0.4\bin\x86_64-win64\fpc test.pp
Free Pascal Compiler version 3.0.4 [2018/02/25] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling test.pp
Linking test.exe
21 lines compiled, 0.1 sec, 33136 bytes code, 1364 bytes data

C:\dev32\fpc\test>test
A or a..z
Ch IInd Statement


C:\dev32\fpc\test>
« Last Edit: April 26, 2018, 01:37:42 pm by rvk »

howardpc

  • Hero Member
  • *****
  • Posts: 2684
Re: Very unimportant, small request..
« Reply #4 on: April 26, 2018, 01:37:40 pm »
Yes, like you I get inconsistent results.
The 'a'..'z' syntax (which is for character types, not strings) seems to confuse the compiler so it accepts strings under the 'A' case option that the case statement should regard as matching the "else" condition.
Probably the compiler should reject the 'a'..'z' syntax when mixed with strings as case selectors (or else correctly convert the characters so defined into 1-character strings).

Bart

  • Hero Member
  • *****
  • Posts: 2980
    • Bart en Mariska's Webstek
Re: Very unimportant, small request..
« Reply #5 on: April 26, 2018, 06:27:54 pm »
'a'..'z' is translated as (>= 'a') and (<= 'z').
This may give unexpected results (any string that starts with the first letter being 'a' to 'y' (like 'qwerty') will fit that requirement as does the string 'z'.).

Bottomline: it's unwise to use ranges with strings in a case statement.

Bart

engkin

  • Hero Member
  • *****
  • Posts: 1984
Re: Very unimportant, small request..
« Reply #6 on: April 26, 2018, 07:02:24 pm »
'a'..'z' is translated as (>= 'a') and (<= 'z').

This seems a bug to me. I would expect (>= 'a') and (<= 'z') AND (length(s1)=1)


Moreover, FPC v3.1.1-r37889, based on the generated assembly,  translated 'a'..'z' as ='a' leaving the rest out!!

Bart

  • Hero Member
  • *****
  • Posts: 2980
    • Bart en Mariska's Webstek
Re: Very unimportant, small request..
« Reply #7 on: April 26, 2018, 07:20:34 pm »
Why "and lenght(s)=1"?
This is a case statement with strings.
Basically case statments can be translated to several if then else statments using the case labels as boundaries.
A case label like 9..15 translates as >=9 and <= 15.

A string comparison of (>= 'a') and (<='z') will result in TRUE for 'qwerty', but not for 'zoom' or ^B.

This is how it works in 3.0.4.
And to me it's logical.
It's also logical that using ranges with strings is dangerous and should not be done.

The behaviour of trunk defies al logic IMO.

I asked on the fpc-devel ML why.

Bart
« Last Edit: April 26, 2018, 07:30:01 pm by Bart »

howardpc

  • Hero Member
  • *****
  • Posts: 2684
Re: Very unimportant, small request..
« Reply #8 on: April 26, 2018, 08:03:00 pm »
It's also logical that using ranges with strings is dangerous and should not be done.

Why then does FPC syntax allow it?

Thaddy

  • Hero Member
  • *****
  • Posts: 6130
Re: Very unimportant, small request..
« Reply #9 on: April 26, 2018, 08:59:30 pm »
It's also logical that using ranges with strings is dangerous and should not be done.

Why then does FPC syntax allow it?
Bart, 'A', 'a'..'z' is AnsiChar syntax - not string syntax - and always allowed because AnsiChars are enumerable.
Howard, FPC has the option to use strings for case (I was against it but it was accepted and works somewhat).

Maybe another case that UTF8 hick-ups? I'll have to test this some more...Because UTF8 char is NOT enumerable....It needs to be an enumerable type.
So explicitly AnsiChar, otherwise the stupid "string" case statements kick in.

But that does not explain the behavior in pure FPC... I agree with that. It would explain a Lazarus project, though....
I noticed the switch was already made with string syntax, which I am not a fan of and was in my opinion not thought through as a "feature".
See the mess up here..... And Delphi doesn't support it a all...
"Hello" made the compiler look at the string case, hence the complete case is evaluated as strings.

Suggestion: hide the documentation for "case string"... O:-)
« Last Edit: April 26, 2018, 09:17:26 pm by Thaddy »
I might not give the answer that you want me to.. Peter Green 1969

Bart

  • Hero Member
  • *****
  • Posts: 2980
    • Bart en Mariska's Webstek
Re: Very unimportant, small request..
« Reply #10 on: April 26, 2018, 11:18:07 pm »
Bart, 'A', 'a'..'z' is AnsiChar syntax - not string syntax - and always allowed because AnsiChars are enumerable.

Case of string is supposed to compare input (string) against labels, which then logically should be treated as string also. The fact that one writes 'a' does not mean that the range specified must be a range of ansichars in a case of string.
Ever since this was introduced, case labels (for case of strings) were treated as strings.

Current trunk behaviour cannot be right, even if your explanation were true:  in that case if s were 'q', the output should be 'A or a..z', but this is only the case if input is a single 'a'.

Bart

engkin

  • Hero Member
  • *****
  • Posts: 1984
Re: Very unimportant, small request..
« Reply #11 on: April 27, 2018, 03:22:47 am »
Why "and lenght(s)=1"?
Because, IMHO, it makes this case statement produce correct1 results when the case variable is string, if this syntax to be supported. The other alternative, for the programmer, would be to expand 'a'..'z' manually as 'a','b','c' etc. or to have two case statements for s and s[1].

1 Correct here in the sense of what darksky666 and myself would expect from this case statement.

darksky666

  • New member
  • *
  • Posts: 30
Re: Very unimportant, small request..
« Reply #12 on: April 27, 2018, 04:36:05 am »
Yeah, the length check would have prevented this error.

I had assumed it compiled because it'd work by treating each character in the subrange as a shortstring of length 1 and compare that with the given string value. But it seems that isn't the case.

Character subrange should have been disallowed inside case string of statement, similar to how strings are not allowed inside case char of statement. But since it's allowed, a length check should have been done.

Bart

  • Hero Member
  • *****
  • Posts: 2980
    • Bart en Mariska's Webstek
Re: Very unimportant, small request..
« Reply #13 on: April 27, 2018, 11:46:43 am »
No, no, no, no, no!
Ranges in case labels are ranges of the type in question, not of a subrange of the type.

So, what you want is totally not logical at all.

I agree thoug that ranges for case of string are ab bad idea, and the compiler should warn or flat out forbid this (but I expect the devels will not alter that part of this problem).

Bart

darksky666

  • New member
  • *
  • Posts: 30
Re: Very unimportant, small request..
« Reply #14 on: April 27, 2018, 03:44:02 pm »
Okay okay, i shouldn't have said "subrange", you're right that denotes a type, but you get what i mean..

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus