Double-defining a variable

Everything else that doesn't fall into one of the other PB categories.
User avatar
jacdelad
Addict
Addict
Posts: 1482
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Double-defining a variable

Post by jacdelad »

Hello,
why is it possible to double-define a variable:

Code: Select all

Global testvariable
Global testvariable
Isn't that counterproductive?

BTW, the second "Global" is ignored, so

Code: Select all

Global testvariable=1
Global testvariable
Debug testvariable
...outputs "1".
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Axolotl
Enthusiast
Enthusiast
Posts: 450
Joined: Wed Dec 31, 2008 3:36 pm

Re: Double-defining a variable

Post by Axolotl »

this is probably due to the fact that the compiler recognizes the same names as errors only with different data types.
At least that's my observation.
BTW similar behavior with constants:

Code: Select all

Global testvariable=1
Global testvariable
Global testvariable.l  ; <== compiler error .. different type 
Debug testvariable

#TestConst = 1 
#TestConst = 1 
#TestConst = 2  ; <== compiler error .. different value 
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Captn. Jinguji
User
User
Posts: 92
Joined: Sun Oct 24, 2004 9:25 am

Re: Double-defining a variable

Post by Captn. Jinguji »

With globals,there is some use for this behaviour, in order to remind you inside a procedure that a variable has global scope.
But in long procedures, even the Global definition (usually at the procedure's start ) is a daunting "solution".

(Personally, I prefer a "g_"... prefix for my global variable names ) ;)
Is this an artifact or should it be disposed of ?
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Double-defining a variable

Post by #NULL »

Redeclaration is not consistent across the different keywords and situations.

Some notes that I already posted somewhere:

"Redeclaration errors are not very consitent": Should Define be allowed for procedure parameters?

Code: Select all

; Global does not complain about redeclaration as long as the type does not change. That includes
; the case where the second declaration does not use any type and intends to use the default type

; Define does not complain about redeclaration but gives error for different implicit type

; Protected does not allow redeclaration at all
Similar topic: Protected 'already declared'

My notes about the quirks of the different declaration keywords (including redeclarations) from german thread:

Code: Select all

EnableExplicit

Debug "----------------------------- 1:"

; protected can shadow global

Global d1

Procedure p1()
  Protected d1
  d1 + 1
  Debug d1
EndProcedure

p1()            ; 1
P1()            ; 1
Debug d1        ; 0

Debug "----------------------------- 2:"

; static can shadow global

Global d2

Procedure p2()
  Static d2
  d2 + 1
  Debug d2
EndProcedure

p2()            ; 1
P2()            ; 2
Debug d1        ; 0

Debug "----------------------------- 3:"

; define cannot shadow global

; Global d3
; 
; Procedure p3()
;   Define d3   ; error: Variable already declared with a different scope
;   d3 + 1
;   Debug d3
; EndProcedure
; 
; Define d3     ; error: Variable already declared with a different scope

Debug "----------------------------- 4:"

; procedure-local define does not conflict with main-local define and behaves like protected

Define d4

Procedure p4()
  Define d4
  d4 + 1
  Debug d4
EndProcedure

p4()            ; 1
P4()            ; 1
Debug d4        ; 0

Debug "----------------------------- 5:"

; access to globals is implizit in procedures, even with EnableExplicit

Global d5

Procedure p5()
  d5 + 1
  Debug d5
EndProcedure

p5()            ; 1
P5()            ; 2
Debug d5        ; 2

Debug "----------------------------- 6:"

; access to main-locals in procedures needs explicit Shared

Define d6

Procedure p6()
  Shared d6
  d6 + 1
  Debug d6
EndProcedure

p6()            ; 1
P6()            ; 2
Debug d6        ; 2

Debug "----------------------------- 7:"

; main-locals need to be declared before procedure to be accessible

; Procedure p7()
;   Shared d7     ; error: With 'EnableExplicit', variables have to be declared
;   d7 + 1
;   Debug d7
; EndProcedure
; 
; Define d7
; 
; p7()
; P7()
; Debug d7

Debug "----------------------------- 8:"

; main-globals need to be declared before procedure to be accessible

; Procedure p8()
;   d8 + 1        ; error: With 'EnableExplicit', variables have to be declared
;   Debug d8
; EndProcedure
; 
; Global d8
; 
; p8()
; P8()
; Debug d8

Debug "----------------------------- 9:"

; Global in procedure creates main-global

Procedure p9()
  Global d9
  d9 + 1
  Debug d9
EndProcedure

Procedure p99()
  Debug d9
EndProcedure

p9()            ; 1
P9()            ; 2
Debug d9        ; 2
p99()           ; 2

Debug "----------------------------- 10:"

; Shared does not care if already global

Global d10

Procedure p10()
  Shared d10    ; ok
  d10 + 1
  Debug d10
EndProcedure

p10()           ; 1
P10()           ; 2
Debug d10       ; 2

Debug "----------------------------- 11:"

; you cannot define main-globals and main-locals together inside a procedure

Global d11_global_a           ; main-global
Define d11_local_a            ; main-local

Procedure declareVariables()
  Global d11_global_b         ; main-global
  Define d11_local_b          ; procedure-local
  ;Shared d11_local_c         ; error: With 'EnableExplicit', variables have to be declared
EndProcedure

Debug "----------------------------- 12:"

; Define.<type> without variable to change the default type has been removed as of pb 5.60, 
; the documentation is out-of-date (pb 5.61) but it's mentioned in the history/changelog

;Define.w                    ; Syntax error
;Define d12

Debug "----------------------------- 13:"

; Global does not complain about redeclaration as long as the type does not change. That includes
; the case where the second declaration does not use any type and intends to use the default type

Global g13.a = 255           ; somewhere
; ...
Global g13                   ; assume integer and zero-initialization?
g13 + 1
Debug g13                    ; 0

Procedure p13()
  Global g13
  g13 + 1
  Debug g13                  ; 1
EndProcedure
p13()

Debug "----------------------------- 14:"

; Define does not complain about redeclaration but gives error for different implicit type

Define d14 = 100             ; somewhere
; ...
Define d14                   ; assume zero-initialization?
d14 + 1
Debug d14                    ; 101

Define d14b.a
;Define d14b                 ; error: Variable already declared with another type

Procedure p14()
  Define d14 = 200
  ; ...
  Define d14                 ; assume zero-initialization?
  d14 + 1
  Debug d14                  ; 201
  
  Define d14_.a = 200
  ;Define d14_               ; error: Variable already declared with another type
EndProcedure
p14()

Debug "----------------------------- 15:"

; Protected does not allow redeclaration at all

Procedure p15()
  Protected d15
  ;Protected d15             ; error: Local variable already declared
EndProcedure

Debug "----------------------------- 16:"

; Threaded

; threads share variables by default (one variable instance for all threads)

Global d16_global = 100       ; main-global
Define d16_local  = 200       ; main-local

d16_global + 1
d16_local + 1

Debug d16_global                      ; 101
Debug d16_local                       ; 201

Procedure p16(param)
  Shared d16_local
  d16_global + 1
  d16_local + 1
  Debug "thread: " + d16_global       ; 102
  Debug "thread: " + d16_local        ; 202
EndProcedure

Define thread = CreateThread(@p16(), 0)
WaitThread(thread)

Debug "----------------------------- 17:"

; Threaded ..is like Global, but with separate variable instances per thread
; use Threaded instead of Global for that purpose, don't try to combine Threaded/Define/Shared etc.. in  a declaration

Threaded d17_threaded_a = 100       ; initialized for each thread instance
Threaded d17_threaded_b

d17_threaded_a + 3                  ; affects only main thread instance
d17_threaded_b = 500                ; affects only main thread instance
d17_threaded_b + 3                  ; affects only main thread instance

Debug d17_threaded_a                ; 103
Debug d17_threaded_b                ; 503

Procedure p17(param)
  d17_threaded_a + 1
  d17_threaded_b + 1
  Debug "thread: " + d17_threaded_a ; 101
  Debug "thread: " + d17_threaded_b ; 1
EndProcedure

Define thread = CreateThread(@p17(), 0)
WaitThread(thread)

User avatar
jacdelad
Addict
Addict
Posts: 1482
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: Double-defining a variable

Post by jacdelad »

I'm now as confused as before. Do other languages allow double declaration?
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Double-defining a variable

Post by fsw »

jacdelad wrote: Tue Apr 12, 2022 9:52 pm I'm now as confused as before. Do other languages allow double declaration?
A compiler should either not compile or compile and give a warning about it.

BTW: Go (golang) doesn’t let you having unused variables defined. They need to be deleted or commented out, before the compiler even compiles…

I am to provide the public with beneficial shocks.
Alfred Hitshock
Post Reply