Author Topic: UDT Caution  (Read 3895 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
UDT Caution
« 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.
« Last Edit: September 30, 2019, 04:07:28 pm by bplus »

Offline Dimster

  • Forum Resident
  • Posts: 500
    • View Profile
Re: UDT Caution
« Reply #1 on: September 30, 2019, 03:57:46 pm »
So how did you solve it? Option Base 1?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: UDT Caution
« Reply #2 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

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: UDT Caution
« Reply #3 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.)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: UDT Caution
« Reply #4 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!
Programming isn't difficult, only it's  consuming time and coffee

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: UDT Caution
« Reply #5 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.
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: UDT Caution
« Reply #6 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.
« Last Edit: October 01, 2019, 12:42:25 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: UDT Caution
« Reply #7 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.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: UDT Caution
« Reply #8 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

  [ You are not allowed to view this attachment ]  
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: UDT Caution
« Reply #9 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.