Posts: 65
Threads: 22
Joined: Apr 2022
Reputation:
2
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
Posts: 303
Threads: 10
Joined: Apr 2022
Reputation:
44
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
Posts: 65
Threads: 22
Joined: Apr 2022
Reputation:
2
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?
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
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$.
Posts: 3,987
Threads: 178
Joined: Apr 2022
Reputation:
222
06-17-2022, 03:12 AM
(This post was last modified: 06-17-2022, 03:15 AM by bplus.)
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$.
b = b + ...
Posts: 42
Threads: 11
Joined: Apr 2022
Reputation:
0
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.
Posts: 65
Threads: 22
Joined: Apr 2022
Reputation:
2
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.
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
06-17-2022, 02:01 PM
(This post was last modified: 06-17-2022, 02:05 PM by SMcNeill.)
(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.
Posts: 3,987
Threads: 178
Joined: Apr 2022
Reputation:
222
06-17-2022, 02:08 PM
(This post was last modified: 06-17-2022, 02:10 PM by bplus.)
(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!)
b = b + ...
Posts: 2,700
Threads: 328
Joined: Apr 2022
Reputation:
219
(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.
|