case statements can have the same values?

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Axolotl
Addict
Addict
Posts: 802
Joined: Wed Dec 31, 2008 3:36 pm

case statements can have the same values?

Post by Axolotl »

Thanks to a really stupid coding error made by myself, I have noticed a strange behavior.
Within a select statement you can make any number of identical case queries. Which of course leads to a faulty program.
Shouldn't the compiler detect this and report it?
Maybe I am wrong, maybe not?
I am curious about your opinion.

Code: Select all

;/-------------------------------------------------------------
;| This program demonstates the mentioned behavior. 
;| 
;| No help on the code needed.. :) 
;| 
;\-------------------------------------------------------------

EnableExplicit 

#TIMER_DelayExecution = 0 

If OpenWindow(0, 0, 0, 200, 100, "Window_Caption", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)  
  StickyWindow(0, 1) 

  ButtonGadget(0, 4, 4, 76, 20, "Click me") 
  AddWindowTimer(0, #TIMER_DelayExecution, 2000) 

  Repeat  ; .. main loop 
    Select WaitWindowEvent(1000) 
      Case #PB_Event_None ; == 0 
        Debug "#PB_Event_None " 

  ;>>> next line was my stupid error, but should that be detected by the compiler <<< 
      Case #TIMER_DelayExecution ; == 0 
        Debug "#TIMER_DelayExecution "
      
  ;>>> this is the correct implementation <<< 
      Case #PB_Event_Timer 
        Select EventTimer() 
          Case #TIMER_DelayExecution : Debug "#TIMER_DelayExecution " 
        EndSelect 

  ;>>> this is just to show another case statements which are equal 
      Case #PB_All                  : Debug "#PB_All " + #PB_All     ; == -1 
      Case #PB_Any                  : Debug "#PB_Any " + #PB_Any    

      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case 0                    : Debug "Button clicked " 
        EndSelect 
      Case #PB_Event_CloseWindow 
        Break ; close button on main window --> close application 
    EndSelect 
  ForEver 
  RemoveWindowTimer(0, #TIMER_DelayExecution) 
EndIf 
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
AZJIO
Addict
Addict
Posts: 2141
Joined: Sun May 14, 2017 1:48 am

Re: case statements can have the same values?

Post by AZJIO »

You are using the constants #PB_All and #PB_Any inappropriately
normeus
Enthusiast
Enthusiast
Posts: 470
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: case statements can have the same values?

Post by normeus »

PB is a single pass compiler, here is a simpler example:

Code: Select all

Select 2
    Case 1
      Debug "Value = 1"      
    Case 2 
      Debug "Value = 20"
    Case 2 
      Debug "Value = 2"
    Default
      Debug "I don't know"
  EndSelect
There might be some switches you can use with the C compiler to look for these type of errors

Norm
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: case statements can have the same values?

Post by idle »

@Axolotl think that's a case of selecting another cup of coffee. :wink:
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: case statements can have the same values?

Post by ChrisR »

:lol:
I can confirm that there's a bug. If I go second, I'll miss my coffee :wink:
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: case statements can have the same values?

Post by DarkDragon »

normeus wrote: Thu Mar 14, 2024 5:58 pmPB is a single pass compiler
Which means it knows what it has already seen and thus it can throw an error at the second case with the same value 😉.
bye,
Daniel
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: case statements can have the same values?

Post by ChrisR »

Yes but with all the possible types of case expression, I don't see how it could be complete.

Code: Select all

J = 1 ; Can be a caculated variable, a field in a structured list...
Select I
  Case 0 To 2
    Debug "First Case 0"
  Case J
    Debug "Never fits because I = 0 here, and case J is already done, 0 To 2, lol"
EndSelect
User avatar
mk-soft
Always Here
Always Here
Posts: 6202
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: case statements can have the same values?

Post by mk-soft »

PureBasic Select Case EndSelect is not like 'C'. With 'C' you have to explicitly set a break to stop comparing. PureBasic stops the comparison and continues the code after EndSelect.
This is not a bug, because it has always been like this ;)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
AZJIO
Addict
Addict
Posts: 2141
Joined: Sun May 14, 2017 1:48 am

Re: case statements can have the same values?

Post by AZJIO »

AutoIt3 has the ContinueCase keyword to continue a subexpression without evaluating it. You don't have to rewrite code from #Close statements into #OK statements

Code: Select all

While 1
	Select Event()
		Case 1
			; Anything else
		Case #OK
			; Reading the data and performing code completion
			ContinueCase
		Case #Close
			; a lot of finishing code
			Break
	EndSelect
Wend
User avatar
STARGÅTE
Addict
Addict
Posts: 2226
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: case statements can have the same values?

Post by STARGÅTE »

Axolotl wrote: Thu Mar 14, 2024 5:18 pm Shouldn't the compiler detect this and report it?
The compiler can't do this, because in PureBasic it is also possible to use non-constants like variables in Case statements, which are unknown at compile time.

Code: Select all

Define Case1.i
Define Case2.i

Define MyCase.i
Define I.i

RandomSeed(1)
For I = 1 To 8
	
	Case1 = Random(1)
	Case2 = 1-Case1
	MyCase = Random(1)
	
	Select MyCase
		Case Case1
			Debug "MyCase ("+MyCase+") = Case1 ("+Case1+") "
		Case Case2
			Debug "MyCase ("+MyCase+") = Case2 ("+Case2+") "
	EndSelect
	
Next
Please keep also in mind, Case #PB_All is the same as Case -1, and do not mean "all cases".
#PB_All needs a certain context to be interpreted as "all", like in FreeGadget()
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
AZJIO
Addict
Addict
Posts: 2141
Joined: Sun May 14, 2017 1:48 am

Re: case statements can have the same values?

Post by AZJIO »

#PB_All
we anticipate the user’s desire to receive all events

Code: Select all

Case 0 To $7FFF
Case 0 To $7FFFFFFF
BarryG
Addict
Addict
Posts: 4123
Joined: Thu Apr 18, 2019 8:17 am

Re: case statements can have the same values?

Post by BarryG »

normeus wrote: Thu Mar 14, 2024 5:58 pmPB is a single pass compiler, here is a simpler example:

Code: Select all

Select 2
    Case 1
      Debug "Value = 1"      
    Case 2 
      Debug "Value = 20"
    Case 2 
      Debug "Value = 2"
    Default
      Debug "I don't know"
  EndSelect
PureBasic is a top-down single-pass compiler that uses short-circuit evaluation, so the first "Case 2" is matched and the second ignored. From the manual: "Short-circuit evaluations for expressions are supported, meaning if a test is true, all following tests will be ignored and not even run" (source: https://www.purebasic.com/documentation ... endif.html). This applies to Select/Case as well.
PBJim
Enthusiast
Enthusiast
Posts: 294
Joined: Fri Jan 19, 2024 11:56 pm

Re: case statements can have the same values?

Post by PBJim »

Having also worked with a business BASIC dialect for a while, I find many languages lacking in their simple CASE model which evaluates only a single argument. An equivalent of the below in PureBasic would be nice in my opinion, the "icing on the cake", as one might say...

Code: Select all

begin case
  case acctype = "C" and amount > cutoff
    .. do something

  case delflag = "D" or acctype = "D"
    .. do something

  case amount > limit
    .. do something

  case 1
    .. do the default
end case
The closest that I've found in PureBasic is a series of ElseIf statements, which I find inelegant. Apologies for posting non-PB code, but useful to see by way of comparison.
User avatar
Caronte3D
Addict
Addict
Posts: 1355
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: case statements can have the same values?

Post by Caronte3D »

Workaround:

Code: Select all

EnableExplicit

Define acctype.s="C"
Define delflag.s="D"
Define limit=2
Define amount=1
Define cutoff=0
Define dummy=#True

Select dummy
  Case Bool((acctype = "C") And (amount > cutoff))
    Debug "Case 1"
  Case Bool((delflag = "D") Or (acctype = "D"))
    Debug "Case 2"
  Case Bool(amount > limit)
    Debug "Case 3"
  Default
    Debug "Case Default"
EndSelect
Fred
Administrator
Administrator
Posts: 18161
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: case statements can have the same values?

Post by Fred »

PB supports multicase and the 'To' keyword which allow ranged tests, which is enough for case IMHO. If you need complex compare, If/ElseIf is the way.

About the original request, I agree it should be forbidden to have twice the same constant number, as it doesn't make sens, so I will move this to features and requests.
Post Reply