Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Determining if variable or static string is passed to a Sub
#1
Is there a way that I can determine from within the Sub (or Function) if a variable string was passed or a static string was passed?

Code: (Select All)

a$ = "DataThatIsPassed"

SomeRoutine (a$)
SomeRoutine (" DataThatIsPassed ")



Sub SomeRoutine (a$)
    Print "processing goes here to determine what was sent..."
    Print "If a variable was sent then VariableWasSent% = 1"
    Print "Otherwise VariableWasSent%=0"

    If VariableWasSent% = 1 Then Print "Variable string was sent"
    If VariableWasSent% = 0 Then Print "Static string was sent"
End Sub


If there exists a way to do this, the example above would provide the following results:

Variable string was sent
Static string was sent


The reason I need this is because I am adding functionality to a very old library routine that is entrenched in so many programs that is would be a monumental task to change.  In order to bring the new functionality to the old routine I need to be able to determine what was sent.
Reply
#2
SUB SomeRoutine (a$, state)
   IF state THEN PRINT "Variable" ELSE PRINT }Static"
END SUB

Then just send the sub a call with the flag desired.

SomeRoutine a$, -1
SomeRoutine "Hello World", 0

There's no auto detection, but it's simple enough to pass a flag with that information.
Reply
#3
I cannot do that since that would require changing the number of parameters to the routine.  Since this routine is in use almost everywhere I cannot change that.

Thanks for the suggestion though!
Reply
#4
In my experiments even if you Dim a string as fixed and then change it to another length, no error is thrown and the change is made. (Not something you can do with Arrays!) In fact all processing of fixed length strings seem to be treated as variable length. I guess its up to coder to keep the length fixed when resetting a value.

So I don't understand how any String processing, fixed or variable, will throw error but you might try making sure the string going out is same size as string going in? That will keep fixed strings the same length.
  724  855  599  923  575  468  400  206  147  564  878  823  652  556 bxor cross forever
Reply
#5
Hi Dano
Code: (Select All)

Dim GlobalString$, GlobalFixedString$7

GlobalString$ = "123456789012345"
GlobalFixedString$7 = "1234567890"
Print "Global variable", "In function variable" + "  Kind 0=fixed/ -1=variable"
Print GlobalString$, WhatKindOfString%(GlobalString$)
Print GlobalFixedString$7, , WhatKindOfString%(GlobalFixedString$7)
End

Function WhatKindOfString% (FunctionString$5)
    '-1 = Fixed lenght, 0 = variable lenght
    Print FunctionString$5, ;
    If Len(FunctionString$5) > 7 Then WhatKindOfString% = -1 Else WhatKindOfString% = 0
End Function

here screenshot that confirms affirmations of Bplus

I dunno if compiler must control this kind of data type with distinguish between fixed string and string.
In the same manner if you declare into the Function a SHARED variable, the compiler doesn't test if there is a same variable into main, but I dunno if this is a must for the compile... surely you can bypass this problem using Option _explicit at top of your code.

[Image: String-parameters-to-funciton-issue-by-Bplus.jpg]

So for now you cannot have this information directly from parameters of function!

Please say me:
I have 2 question for you:
 1. if it is difficult to add a parameter to the SUB/FUNCTION , is it difficult too to add a SHARED variable into it?
2. what is the goal to distinguish between Fixed and Variable lenght ?
Reply
#6
it would require a preprocessor.  to catch every single call to the target subprogram.  then notice if the single argument is a vls variable.  or fixed-length string.  or a literal.

this is because string technically is a pointer.  if the subprogram is called with literal string to pass to it.  the system has to make a copy of that string anyway.  to work with it inside the subprogram.  this will be expected by most people.  if a string variable is passed instead.  it could cause more trouble.  because its value could be changed inside the subprogram.  unless the programmer is willing to force the copying and extra memory spent.  work with the copy instead.  if the value going into the subprogram shouldn't be changed.

in the first post of this thread.  the variablewassent% has to be forced honesty by the programmer as smcneill pointed out.  otherwise it needs observation outside the compiler.

if this is the only subprogram that requires this special treatment.  it would be easy to write a basic program.  actually in any programming language.  that reads in the basic code.  looks only for that call of subprogram.  then make necessary adjustments by adding basic code to the output file.  then use the output file.
Reply
#7
Thanks to all.
Since SUBs and FUCTIONs are unaware, I will do what have done in the past when in the same situation - I incorporate a flag @ position 1 in the string (probably the pipe character) that alerts the routine to make the necessary adjustments.  Not perfect, but close enough and definitely workable.
Reply
#8
Sorry to intersect... I was snooping around the forums for interesting stuff and came across your thread.
Is it correct that your question is actually "how to distinguish between a variable passed by reference vs. passed by value"? Because that is essentially what you're asking IMHO.

When you pass a literal string in normal BASICs, you actually pass a (internal) variable "by value".
This means changing its value inside the SUB has no reflection on the 'outside world'; there is no way to catch the change outside the sub. This in contrast to passing "by reference". Which means you actually pass a pointer to a variable. And as such, if you change the contents of the variable inside the SUB, the change WILL reflect outside the sub; the parameter variable has changed.

The big question I have is:  *Why?* Why would you want to know that difference? I really can not think of a proper reason that you would want to know if it is a literal or not. ie. IF it was a literal, nothing would change anyways, so why bother?
I really would like to see this subroutine of yours to understand WHY it is needed/so important, if possible.

(well, TBH, the only reason I can think of is because of performance: If you pass a literal string to a routine which manipulates that parameter, and that routine takes a lot of time, that time would be completely wasted because you wouldn't be able to pass anything back anyways... So you might want to skip everything in the routine if a literal was passed. But other than that, I am truly stumped for the reason and *VERY* curious about the source of that routine; what it exactly does..... Then again, if you're going to solve it by adding a sort of marker somewhere in the string, then the whole 'performance reason' is out of the window, since: why calling that SUB to begin with if you are able to add a marker to notify it is a literal to begin with. In that case, just skip the routine....Then again, if you do that, then the parameter wouldn't be a literal anymore anyways as it would ALWAYS be a variable... so what gives????? Yeah, I'm truly lost here in the logic...lol)

PS: this problem does bring up a nice suggestion for QB64 though: allow optional parameters! This would make it so that your 'marker' can be an extra parameter in the new calls, and all the existing old calls would all still work as usual.
Who remembers QB30, GWBASIC, C64, ZX80?
Reply
#9
Yes, that is actually what I am asking.  The reason is that I have an old keyboard input routine that is used just about everywhere. I am rewriting it and must maintain the same format as the original routine:

     Sub KB_input a$, controlString$


I am also wanting the new routine to be compatible with QB64 input routine's format:

     Input "Input Descriptor Here: ", a$


If I could know whether or not a parameter was sent static then it would be easy to decipher which format was being used.  Yes, I could set a variable to tell the routine which is which - but that defeats the purpose because it is no longer a direct replacement if I have to set a variable first.  It was just a desire if QB64 supported this.  I have a work around, it was just going to be easier if this was supported by QB64.
Reply
#10
Hmmm, in that case it is NOT to distinguish between 'by reference' or 'by value'...
but NOR is it distinguishing between 'a literal' or 'a variable' like you orginally asked!!
And NOR is it to checking if a parameter is static or not.

A parameter IS a variable, ALWAYS

And STATIC does not mean what you think it means, I think.
Also, a LITERAL is something you type yourself as parameter enclosed in quotes as the programmer during coding.
The moment you assign it to a variable name in code, or use it as a parameter in code, or let the user input something during execution it is... well, a variable...

Code: (Select All)
A$ = "this string will become a variable"
CALL MySub(A$, "this WAS a literal, and is now a variable in the sub")
PRINT A$       ' wil show "let's change A$ to something else"

'-------------------------------------------------------------------------------
SUB MySub(PARA_A$, PARA_B$)
    PRINT PARA_A$    ' will show "this string will become a variable"
    PRINT PARA_B$    ' will show "this WAS a literal, and is now a variable in the sub"
    PARA_A$ = "let's change A$ to something else"
    PARA_B$ = "you can do this, but it wont change anything"
END SUB

So, now I think, what your actual question should have been is: how to distinguish between a variable and a variable?.
And as you can see... that is kind of a strange question. Which, at first, doesn't make much sense at all. Hence my confusion and trying to make sense of it Tongue

So.... there is absolutely no fool-proof and elegant way to solve your problem.... until optional parameters get supported by QB64.

The only possible, "kind-of", solution for now, is by adding a 'magic marker' to one of the parameters of your SUB.

The downside is, depending on what those parameters potentially can be, is that you could have a situation where the marker is the same as something the user has typed with that new input line. And in that case, again, you really can not know which is which.

So, if one of those parameters is always going to be of a certain fixed or maximum size, then you can add a marker to that parameter so it is bigger than it used to be in the normal 'old' circumstances.

eg.
If A$ in your original SUB is always only 1 character long, then you could add a marker to A$ so that it is longer than 1 character. The marker itself doesn't much matter in this case (can be a space, whatever). Or if A$ can be longer, but is still finite and thus has a known maximum possible length... simply make it so it is always longer than that maximum length... same principle. That would be the only sure way to make the difference. Not elegant, but it would always work.

But, if both A$ and CONTROLSTRING$ can have arbitrary unknown lengths, then you might have a situation where your marker is typed in by that user input!!! And then your SUB wouldn't be able to tell the difference again, you'd have a false positive. To circumvent that a little bit, you could make the marker as close as impossible to type as you can. Something like CHR$(0) + CHR$(1) + CHR$(2) + CHR$(3) or something rare and difficult to type (or an illegal unicode codepoint/pair as a wide character, but that might open a whole other can of worms as I don't know how QB64 acts with that).

I hope all this makes sense and helps.
It is very hard to explain without having access to the actual code in question.
That would make things A LOT more easy to show and explain.

Wink
Who remembers QB30, GWBASIC, C64, ZX80?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable length type declarations dano 5 675 08-06-2025, 09:53 PM
Last Post: dano
  Most efficient way to build a big variable length string? mdijkens 9 1,855 01-17-2025, 11:36 PM
Last Post: ahenry3068
  Huge array of variable length strings mdijkens 9 1,802 10-17-2024, 02:01 PM
Last Post: mdijkens
  REDIM, TYPE, and STRING Woes TerryRitchie 16 3,109 04-13-2023, 05:17 AM
Last Post: DSMan195276
Lightbulb To mimic "cmd.exe" behavior with eg. "DIRCMD" env. variable mnrvovrfc 4 1,168 09-29-2022, 02:51 AM
Last Post: mnrvovrfc

Forum Jump:


Users browsing this thread: 1 Guest(s)