REDIM, TYPE, and STRING Woes - Printable Version +- QB64 Phoenix Edition (https://staging.qb64phoenix.com) +-- Forum: Chatting and Socializing (https://staging.qb64phoenix.com/forumdisplay.php?fid=11) +--- Forum: General Discussion (https://staging.qb64phoenix.com/forumdisplay.php?fid=2) +--- Thread: REDIM, TYPE, and STRING Woes (/showthread.php?tid=1614) Pages:
1
2
|
REDIM, TYPE, and STRING Woes - TerryRitchie - 04-12-2023 Ok, been pulling my hair out for last 4 hours until I realized what was going on. I have a TYPE with 3 integers and a string: TYPE MYTYPE INT1 AS INTEGER INT2 AS INTEGER INT3 AS INTEGER INFO AS STRING END TYPE Then used it as so: REDIM MYVARIABLE(1) AS MYTYPE So far so good. As I start putting data into the array I need to resize it from time to time: REDIM _PRESERVE MYVARIABLE(UBOUND(MYVARIABLE) + 1) AS MYTYPE Still good right? Nope. The previous data gets completely garbled. The problem you ask? INFO AS STRING Change it to: INFO AS STRING * 20 and all is good in QB64 land. It seems variable length strings are a no-no when using REDIM _PRESERVE If this is already a known issue then somehow I have missed it all these years. If it isn't then this is a warning letting others know this happens. I was ready to throw my joystick through my screen until it finally dawned on me as to what may have been happening. The integers I was storing ranged from 1 to 6 but somehow they were changing to 16, 57, 3471, etc.. I thought maybe I was going nuts for a while, LOL. Ugh. RE: REDIM, TYPE, and STRING Woes - mnrvovrfc - 04-12-2023 It's interesting to notice that QBasic flagged an error when an attempt was made to create an UDT field which was variable-length string. The compiler needed to know what was the size of the UDT. This is everywhere, otherwise must use an interpreter able to trick itself and to "be taught". Need to use _MEM in this case and do the string management yourself. RE: REDIM, TYPE, and STRING Woes - bplus - 04-12-2023 I've run into trouble using UDT's when I assume after a ReDim _Preserve that the new values are 0 or "" for numbers or strings. Supposedly the numbers and fixed strings were fixed according to Luke if I recall but variable length strings had to initilized to "" otherwise they pick up garbage from the string pointers to uncleared meomory, something like that. @TerryRichie could it be possible you were assuming new variable length strings were "" after a ReDim _Preserve ? Perhaps also, whatever was fixed back when Luke checked it became unfixed with all the updates made since, like with assumed 0 of new integers created with ReDim _preserve? I will write some test code... RE: REDIM, TYPE, and STRING Woes - TerryRitchie - 04-12-2023 (04-12-2023, 10:24 AM)mnrvovrfc Wrote: It's interesting to notice that QBasic flagged an error when an attempt was made to create an UDT field which was variable-length string. The compiler needed to know what was the size of the UDT. This is everywhere, otherwise must use an interpreter able to trick itself and to "be taught". Need to use _MEM in this case and do the string management yourself. Yes, having fixed-length strings makes sense once I figured out what was going on. I never ran into this during the QuickBasic days so I had no idea fixed-length only allowed in UDTs when using REDIM. The QB64 compiler should warn of this like the QuickBasic compiler did as you point out. RE: REDIM, TYPE, and STRING Woes - TerryRitchie - 04-12-2023 (04-12-2023, 03:50 PM)bplus Wrote: I've run into trouble using UDT's when I assume after a ReDim _Preserve that the new values are 0 or "" for numbers or strings. I just posted a controller library in the library section. If you change the "Name AS STRING * 20" in "TYPE TYPE__SLOT" to "Name AS STRING" in the CONTROLLER.BI file you'll see the errors start to happen. RE: REDIM, TYPE, and STRING Woes - DSMan195276 - 04-12-2023 To clarify, this is allowed, it sounds like you're hitting a bug. Variable-length Strings in UDTs is a new feature in QB64, it should work with ReDim and _Preserve. From what bplus said, QB64 is not properly initializing any new memory added from a ReDim if you use _Preserve(which wouldn't surprise me...). IMO this should be fixed, but it might be a little annoying to implement due to _Preservebeing a bit jank. Manually initializing the new entries sounds like it will solve it for the moment (that's what I unintentionally did in some code I wrote a few days ago, it works fine and uses both ReDim and variable-length strings in a UDT). RE: REDIM, TYPE, and STRING Woes - mnrvovrfc - 04-12-2023 It has to be carefully considered, because people have code with "REDIM _PRESERVE ARRAY(1 TO LIMIT) AS STRING * 1e+06" or something absurd like that. Maybe "reset" each new element created while $CHECKING:ON, and don't do it while $CHECKING:OFF? I understand the code in place was done most of all for speed. I guess the QB64PE developers are confident enough with coding the variable-length strings despite the overhead and the complications. The programmer is the one who decides to waste memory and give up a bit of performance for convenience! But this is also true with Python and other programming languages with libraries "to make it all easier". However, allowing variable-length string as UDT member sort of defeats the role of _MEM and that's why some people are still afraid of _MEM and steer from it as much as possible. It would be until QB64(PE) could have some OOP attributes, at least subprograms allowed as members of UDT without the schmaltz. In the future, with _MEM as UDT member, something like a constructor in OOP-land could become mandatory. Otherwise what is the programmer going to do with it if it's going to occupy some memory over thousands of elements? I don't know, maybe instead go like Pascal and have "New()" and "Dispose()" for a specific datatype and a count of them, a lot like "calloc()" in C. I much preferred the old Turbo Pascal way even though it hindered on the OOP concept, which meant it had to be deprecated by the "Object" of v5.5. Yet the "Class" had to be invented later to keep Pascal/Delphi up with C++. (According to Free Pascal manual, "Objects" were always allocated from the stack, and "Classes" were less limited in memory requirements according to 16-bit mentality.) Yes I'm rambling again, but the thing is that the decision is expected, to be made at any cost to initialize any new elements "automatically", by some people, although rather few in number that come over directly from QuickBASIC and QBasic and use UDT's. RE: REDIM, TYPE, and STRING Woes - mnrvovrfc - 04-12-2023 (04-12-2023, 04:00 PM)TerryRitchie Wrote: I just posted a controller library in the library section. If you change the "Name AS STRING * 20" in "TYPE TYPE__SLOT" to "Name AS STRING" in the CONTROLLER.BI file you'll see the errors start to happen. "NAME" is a reserved word, for sure since QuickBASIC. https://qb64phoenix.com/qb64wiki/index.php/NAME But if it does compile, the compiler should instead indicate what is reserved by it. RE: REDIM, TYPE, and STRING Woes - bplus - 04-12-2023 It is NOT fixed, numbers initialized with ReDim _Preserve do not start at 0 here is code that proves it: Code: (Select All) _Title "UDT assignments with ReDim _Preserve Test" ' b+ 2023-04-12 UDT test 1 is run through code where we don't assume variables start at 0 or "" How it's supposed to go nice and regular pattern. UDT test 2 is run through code where we do assume variables are 0 and add or concat to "initial" value. When variables aren't initialized to 0 or "" get big mess!!! Surprisingly to me, this test worked fine for just concat new string to "initial" string (after ReDim _Preserve) and didn't have problems until added new integer to "initialized" integer. So I was mistaken when Luke said it was fixed for numbers and fixed strings or it has since become unfixed. RE: REDIM, TYPE, and STRING Woes - TerryRitchie - 04-12-2023 Yes, crazy stuff |