QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: bplus on September 30, 2019, 02:51:18 pm

Title: UDT Caution
Post by: bplus on September 30, 2019, 02:51:18 pm
Maybe I should have known this already but I didn't or have forgotten.

If you don't assign an UDT item an initial value it could start with anything. I just found and fixed a problem where I assumed an integer item would start at 0 if not assigned. It does not behave like normal variables that haven't been assigned initial values. You can't assume an unassigned integer item of UDT will be at 0.

To be more specific I found the problem in Dynamic array of UDTs where the first one in the array did seem to be consistently starting at 0 and I was REDIM _PRESERVE expansions of the UDT array.
Title: Re: UDT Caution
Post by: Dimster on September 30, 2019, 03:57:46 pm
So how did you solve it? Option Base 1?
Title: Re: UDT Caution
Post by: bplus on September 30, 2019, 04:06:16 pm
So how did you solve it? Option Base 1?

Simply set the value to 0 or whatever initial value I want to assume before using it.
nUDT = nUDT + 1
REDIM _PRESERVE UDT(1 to nUDT) as UDTtype
UDT(nUDT).integerItem = 0 'now I can assume it is 0
Title: Re: UDT Caution
Post by: SMcNeill on September 30, 2019, 04:39:16 pm
Maybe I should have known this already but I didn't or have forgotten.

If you don't assign an UDT item an initial value it could start with anything. I just found and fixed a problem where I assumed an integer item would start at 0 if not assigned. It does not behave like normal variables that haven't been assigned initial values. You can't assume an unassigned integer item of UDT will be at 0.

To be more specific I found the problem in Dynamic array of UDTs where the first one in the array did seem to be consistently starting at 0 and I was REDIM _PRESERVE expansions of the UDT array.

MEM works the same way with _MEMNEW — it just allocates an area of memory for your needs, without initiating it to zero/null.  This can save a good bit of processing time, (After all, why take the time and effort put blank data in your fields, if you’re just going to put another set of information into it right afterwards?), but it can cause you issues if you’re expecting to read the data before writing to it (such as how you were doing and assuming it’d default to zero).

Solution is, of course, as you presented it: Make certain to fill that memory with 0 before using it.  (_MEMFILL is an excellent tool for this job.)
Title: Re: UDT Caution
Post by: TempodiBasic on September 30, 2019, 06:09:56 pm
Thanks Bplus!
Useful information!
Yes I often uses UDT and I presume that they have initialization by compiler as for normal variables.
I think that I have not fallen in this issue because it is not so often to use a DYNAMIC UDT array!

Information memorized!
Title: Re: UDT Caution
Post by: Cobalt on September 30, 2019, 11:44:24 pm
I'm going to say its the REDIM's fault here, I have always used UDTs and have never had an element of one pop up with a 'noise' value.

or else I have just been lucky the last several years.
Title: Re: UDT Caution
Post by: bplus on October 01, 2019, 12:36:31 am
I'm going to say its the REDIM's fault here, I have always used UDTs and have never had an element of one pop up with a 'noise' value.

or else I have just been lucky the last several years.

OK I've investigated the problem further and discovered the culprit is STRING item in the UDT:
Code: QB64: [Select]
  1. DIM d(100)
  2.  
  3. FOR i = 0 TO 100
  4.     PRINT i; ","; d(i),
  5. PRINT " That was straight up DIM, press any..."
  6.  
  7. FOR i = 0 TO 100
  8.     PRINT i; ","; B(i),
  9. PRINT "That was REDIM, looks fine too!,  press any..."
  10.  
  11. PRINT "Now for UDT with String, worked fine wo string"
  12. PRINT "but starting to see mess up with string in UDT"
  13. PRINT "for me item 0 is not 0's."
  14. TYPE typo
  15.     a AS INTEGER
  16.     b AS INTEGER
  17.     s AS STRING
  18.  
  19. REDIM AA(100) AS typo
  20. FOR i = 0 TO 100
  21.     PRINT i; ","; AA(i).a; ","; AA(i).b; ","; AA(i).s,
  22. PRINT " press any..."
  23.  
  24.  
  25. REDIM AA(0) AS typo
  26. FOR i = 0 TO 100
  27.     IF UBOUND(AA) < i THEN REDIM _PRESERVE AA(LBOUND(AA) TO i) AS typo
  28.  
  29. FOR i = 0 TO 100
  30.     PRINT i; ","; AA(i).a; ","; AA(i).b; ","; AA(i).s,
  31. PRINT: PRINT: PRINT "Aha! here it is in Spades!"
  32.  
  33.  

The arrays were working fine, all zero's until I added a STRING item to the UDT.

Maybe I found the thing Petr couldn't replicate?
 
Maybe I should go back and try the UDT with STRING on DIM and REDIM.
Title: Re: UDT Caution
Post by: bplus on October 01, 2019, 01:10:39 am
OK the problem is pretty obvious with REDIM _PRESERVE but there seems to be an issue with first item of UDT with String with REDIM (no _PRESERVE)

Code: QB64: [Select]
  1. TYPE typo
  2.     a AS INTEGER
  3.     b AS INTEGER
  4.     s AS STRING
  5.  
  6. TYPE typoAllInt
  7.     a AS INTEGER
  8.     b AS INTEGER
  9.     c AS INTEGER
  10.  
  11. DIM d(50) AS typo
  12. FOR i = 0 TO 50
  13.     PRINT i; ","; d(i).a; ","; d(i).b; ","; d(i).s,
  14. PRINT " That was straight up DIM for UDT with STRING Item, press any..."
  15.  
  16. REDIM B(50) AS typoAllInt
  17. FOR i = 0 TO 50
  18.     PRINT i; ","; B(i).a; ","; B(i).b; ","; B(i).c,
  19. PRINT "That was REDIM, UDT with all integers,  press any..."
  20.  
  21. REDIM AA(0) AS typoAllInt
  22. FOR i = 0 TO 50
  23.     IF UBOUND(AA) < i THEN REDIM _PRESERVE AA(LBOUND(AA) TO i) AS typo
  24.  
  25. FOR i = 0 TO 50
  26.     PRINT i; ","; AA(i).a; ","; AA(i).b; ","; AA(i).c,
  27. PRINT "That was REDIM _PRESERVE, UDT with all integers,  press any..."
  28.  
  29. REDIM C(50) AS typo
  30. FOR i = 0 TO 50
  31.     PRINT i; ","; C(i).a; ","; C(i).b; ","; C(i).s,
  32. PRINT "That was REDIM, UDT with a string and integers,  press any..."
  33.  
  34. REDIM AB(0) AS typo
  35. FOR i = 0 TO 50
  36.     IF UBOUND(AB) < i THEN REDIM _PRESERVE AB(LBOUND(AB) TO i) AS typo
  37.  
  38. FOR i = 0 TO 50
  39.     PRINT i; ","; AB(i).a; ","; AB(i).b; ","; AB(i).s,
  40. PRINT: PRINT: PRINT "REDIM _PRESERVE of UDT with STRING here it is in Spades!"
  41.  
  42.  
Title: Re: UDT Caution
Post by: TempodiBasic on October 01, 2019, 05:58:23 pm
Hi Bplus
it seems to me that the issue is a STRING not fixed in UDT

if you add for example  *20 after declaration of string
as here
Code: QB64: [Select]
  1. TYPE typo
  2.     a AS INTEGER
  3.     b AS INTEGER
  4.     s AS STRING * 20
  5.  
it seem to me to get a good result

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: UDT Caution
Post by: bplus on October 01, 2019, 06:41:17 pm
Thanks TempodiBasic,

Well I've always known fixed strings are more secure but I want variable length strings to act as containers for Arrays I can Split out of a UDT. I am very OK with being sure to assign values before using, a small price to pay for arrays from a UDT.