QB64 Phoenix Edition
Another issue: Changing one variable instantly changes the value of another variable - 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: Another issue: Changing one variable instantly changes the value of another variable (/showthread.php?tid=560)

Pages: 1 2


Another issue: Changing one variable instantly changes the value of another variable - hanness - 06-17-2022

I have a short subroutine that takes a path and removes the quotes if the path is enclosed in quotes. It then removes any trailing backslash from the path if one exists.

I was getting some unexpected results, so into debug mode I went to find the problem. As I step through the code one line at a time, I find this problem:

As soon as I execute the line that reads Temp$ = "" not only does Temp$ get set to "" but in that very moment Path$ also gets set to "" (an empty string). For the life of me, I cannot make sense of why this happens.

A few notes:

1) Path$ is not defined outside of this subroutine, so it is local to the subroutine only.

2) Temp$ is DIMed at the start of my program as a SHARED string, so that variable should be available globally.

I apologize for not supplying the full code. The problem is that this is a part of a program almost 15,000 lines long now.

Can anyone give me anything to look for here? I simply cannot see how changing one variable would instantly change another variable as well.



Code: (Select All)
Sub CleanPath (Path$)

    ' Remove quotes and trailing backslash from a path

    ' To use this subroutine: Pass the path to this sub, the sub will return the path
    ' without quotes and a trailing backslash in Temp$.

    Dim x As Integer

    ' start by stripping the quotes

    Temp$ = ""

    For x = 1 To Len(Path$)
        If Mid$(Path$, x, 1) <> Chr$(34) Then
            Temp$ = Temp$ + Mid$(Path$, x, 1)
        End If
    Next x

    ' Remove the trailing backslash, if present

    If Right$(Temp$, 1) = "\" Then
        Temp$ = Left$(Temp$, (Len(Temp$) - 1))
    End If

End Sub



RE: Another issue: Changing one variable instantly changes the value of another variable - DSMan195276 - 06-17-2022

Hmm, I gave it a try by making a simple program to call
ClearPath()
, but even with Temp$ as shared I can't get it to do what you're describing.

If you're able, it would help a lot is if you could zip up your
./internal/temp/
folder after compiling the program and attach it to a post. The particular file I'm interested in is
./internal/temp/main.txt
but some others may be relevant too. That file contains the produced C++ code, so if it's an issue with the code generation that would tell us. If you want to look yourself, it's a matter of finding
void SUB_CLEANPATH
in it and then viewing the behavior, but it's a bit hard to read if you don't know what you're looking at Smile


RE: Another issue: Changing one variable instantly changes the value of another variable - hanness - 06-17-2022

I think that I solved this. I need to verify this back on my original system where I encountered to issue, but on my laptop I changed the variable named Path to Path1 and that seems to have solved the issue. Maybe Path is a reserved name that cannot be used as a variable name?


RE: Another issue: Changing one variable instantly changes the value of another variable - SMcNeill - 06-17-2022

First thing I'd try is to pass via a temp variable:

SUB CleanPath (tempPath$)
Path$ = tempPath$

The issue is probably from a call such as :

ClearPath temp$

With passing matching types with SUB/FUNCTION, we pass the offsets to the variable and not the value of the variable. If temp$ is passed, Path$ **IS** temp$.


RE: Another issue: Changing one variable instantly changes the value of another variable - bplus - 06-17-2022

Uhmmm, unless temp$ is shared (which would be kinda odd) your sub doesn't do anything to the state of the program outside the sub???

It certainly doesn't change Path$, you would need a final line Path$ = Temp$.


RE: Another issue: Changing one variable instantly changes the value of another variable - Cobalt - 06-17-2022

Like Steve said, watch what you do with variables passed to FUNCTIONS AND SUBs. Because you do manipulate the original values within the routine. Which if your careful can be a big and powerful feature, if your not careful it can be a living nightmare.

In QB4.5 you could do this with FUNCTIONs alone, but in QB64 it happens in both.


RE: Another issue: Changing one variable instantly changes the value of another variable - hanness - 06-17-2022

Steve, it seems that you were correct. Creating a temporary variable did the trick, although I would love to know where the problem was originating from.

For now, I'll take the win, but I may eventually try to figure out the source of the problem. It's not going to be easy because the flow of the code in this particular are calls a subroutine, which then in turn calls another subroutine, which then finally calls a third subroutine. Following the variables through all those levels may be a little tricky.

In any case, thanks for the idea. I've now modified several of my subroutines to put temp variables in place and hopefully avoid other similar situations.


RE: Another issue: Changing one variable instantly changes the value of another variable - SMcNeill - 06-17-2022

(06-17-2022, 03:12 AM)bplus Wrote: Uhmmm, unless temp$ is shared (which would be kinda odd) your sub doesn't do anything to the state of the program outside the sub???

It certainly doesn't change Path$, you would need a final line Path$ = Temp$.

As per opening post:  2) Temp$ is DIMed at the start of my program as a SHARED string, so that variable should be available globally.

So let's say there's a point in that program that looks like this:

ClearPath Temp$


Now the SUB uses Path$ as the variable name, but they'll share the same offset.  For all intents and purposes Path$ *IS* Temp$...  When Temp$ = "" a few lines into the sub, Path$ will = "" as well.  <-- This is the glitch we're seeing at work.

Now, with the issue diagnosed, I don't think finding it inside the program will be as simple as looking for a ClearPath Temp$.  From my personal experience, I'd imagine the issue to come from something like:

SUB SetSlashes (Link$)
 DO  UNTIL INSTR(Link$, "/") = 0
     MID$(Link$, INSTR(Link$, "/") = "\"
 LOOP
 ClearPath Link$
END SUB

At this point the program then does a SetSlashes Temp$, so Link$ = Temp$, which calls ClearPath which makes Path$ = Temp$, which leads to the roundabout issue of changing Temp$ changing Path$.

Best advice I can give to avoid this issue:
  **Unless you need a return value via your SUB or FUNCTION parameter, pass to a temp variable and only use it to assign to a different value for the sub's exclusive use.  **

Don't change your original variable, and you'll never have to worry about corruption of data that those changes might cause.  Wink


RE: Another issue: Changing one variable instantly changes the value of another variable - bplus - 06-17-2022

(06-17-2022, 03:12 AM)bplus Wrote: Uhmmm, unless temp$ is shared (which would be kinda odd) your sub doesn't do anything to the state of the program outside the sub???

It certainly doesn't change Path$, you would need a final line Path$ = Temp$.

Dang you did DIM Shared Temp$, sorry I suck at reading!

IMHO this is how I would handle this function:
Code: (Select All)
' don't share temp$, temp$ is supposed to be temporary!!!
test$ = "C:\Dir1\Dir2\"
Print CleanPath$(test$)

Function CleanPath$ (Path$) ' this is clearly a Function in my opinion!

    ' Remove quotes and trailing backslash from a path

    ' To use this subroutine: Pass the path to this sub, the sub will return the path
    ' without quotes and a trailing backslash in Temp$.

    Dim x As Integer

    ' start by stripping the quotes

    Temp$ = ""

    For x = 1 To Len(Path$)
        If Mid$(Path$, x, 1) <> Chr$(34) Then
            Temp$ = Temp$ + Mid$(Path$, x, 1)
        End If
    Next x

    ' Remove the trailing backslash, if present

    If Right$(Temp$, 1) = "\" Then
        Temp$ = Left$(Temp$, (Len(Temp$) - 1))
    End If
    CleanPath$ = Temp$
End Function


How do you get double quotes in a path or filename? (Just really curious!)


RE: Another issue: Changing one variable instantly changes the value of another variable - SMcNeill - 06-17-2022

(06-17-2022, 02:08 PM)bplus Wrote: IMHO this is how I would handle this function:
Code: (Select All)
' don't share temp$, temp$ is supposed to be temporary!!!
test$ = "C:\Dir1\Dir2\"
Print CleanPath$(test$)

Function CleanPath$ (Path$) ' this is clearly a Function in my opinion!

    ' Remove quotes and trailing backslash from a path

    ' To use this subroutine: Pass the path to this sub, the sub will return the path
    ' without quotes and a trailing backslash in Temp$.

    Dim x As Integer

    ' start by stripping the quotes

    Temp$ = ""

    For x = 1 To Len(Path$)
        If Mid$(Path$, x, 1) <> Chr$(34) Then
            Temp$ = Temp$ + Mid$(Path$, x, 1)
        End If
    Next x

    ' Remove the trailing backslash, if present

    If Right$(Temp$, 1) = "\" Then
        Temp$ = Left$(Temp$, (Len(Temp$) - 1))
    End If
    CleanPath$ = Temp$
End Function


How do you get double quotes in a path or filename? (Just really curious!)

You'd still end up with the same root issue though when you did a return$ = ClearPath(Temp$).   If I was going the way you're mentioning, I'd do it like so:


Code: (Select All)
Function CleanPath$ (Path$) ' this is clearly a Function in my opinion!


    STATIC Temp$ 'Make certain that Temp$ is local to the sub and we don't use the global variable by accident


    ' Remove quotes and trailing backslash from a path

    ' To use this subroutine: Pass the path to this sub, the sub will return the path
    ' without quotes and a trailing backslash in Temp$.

    Dim x As Integer

    ' start by stripping the quotes

    Temp$ = ""

    For x = 1 To Len(Path$)
        If Mid$(Path$, x, 1) <> Chr$(34) Then
            Temp$ = Temp$ + Mid$(Path$, x, 1)
        End If
    Next x

    ' Remove the trailing backslash, if present

    If Right$(Temp$, 1) = "\" Then
        Temp$ = Left$(Temp$, (Len(Temp$) - 1))
    End If
    CleanPath$ = Temp$
End Function

Notice that Temp$ is now a STATIC variable, forced to be localized to the Function itself, and thus can't ever be corrupted via the global variable named Temp$.  There's a reason why QBASIC offered STATIC and local variables, even if most people never bothered to use them.  Wink