May 21, 2024, 02:49:52 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


String vaule return from SUB

Started by TGN, February 06, 2013, 03:57:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

TGN

Hi

I have noticed, when I call a SUB(String) then the string value from the SUB rutine return to main program.
Does this make any sense.


AUTODEFINE "OFF"
STRING MainString = "Main"
OPENCONSOLE

print tx(MainString)
print MainString
PRINT "Press any key to close"
WAITCON

SUB tx(STRING SubString),int
SubString = SubString + "???"
RETURN 0
ENDSUB

TGN

Perhaps I should start by reading the manual  ::)
Sorry

LarryMc

That's normal operation.
Strings and UDTs are passed by reference, which means only the pointer to where the value is stored in memory.

If you want to pass a string or UDT to a sub and manipulate it within the subroutine only then define if BYVAL
SUB tx(STRING SubString BYVAL),int
Numbers work just the opposite.  They are passed by value.
So, if you want to pass a number to a sub; modigy it in the sub; and have the change appear in the calling program then pass it BYREF.
SUB num(int xx BYREF),int
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

TGN

Thanks Larry

But if I try to manipulate it within the subroutine, the program go bananas.


SUB tx(STRING SubString BYVAL),int
SubString=SubString + "1234567890"


Now I just made a minor modification, and it works


SUB TX(STRING TXLocal),int
INT x:STRING TXData
TXData = RS485_StartFrame + RS485_SrcAddr + RS485_DstAddr + TXLocal
TXData=RS485_StartStop + TXData + CRC_HDLC(DataAsc,ChrHex2Asc(TXData)) + RS485_StartStop
  FOR x = 1 to LEN(TXData) step 2
IWSendport(ComPort, CHR$(Hex2Dec(MID$(TXData,x,2))), 1)
  NEXT x
Return 0
ENDSUB

LarryMc

QuoteBut if I try to manipulate it within the subroutine, the program go bananas.

SUB tx(STRING SubString BYVAL),int
SubString=SubString + "1234567890"
I'm not sure what you are talking about.
The only reason that should cause you problems is if
SubString + "1234567890" exceeds the maxlength that SubString was defined as outside the sub.
This works:
string x="abc"
print x
tx(x)
print x

SUB tx(STRING SubString BYVAL),int
SubString=SubString + "1234567890"
return 1
endsub

This will cause problems:
istring x[11]
string b=""
x="abc"
print x
tx(x)
print x

SUB tx(STRING SubString BYVAL),int
SubString=SubString + "1234567890"
b="q"
return 1
endsub

Then you say:
QuoteNow I just made a minor modification, and it works

SUB TX(STRING TXLocal),int
INT x:STRING TXData
TXData = RS485_StartFrame + RS485_SrcAddr + RS485_DstAddr + TXLocal
TXData=RS485_StartStop + TXData + CRC_HDLC(DataAsc,ChrHex2Asc(TXData)) + RS485_StartStop
  FOR x = 1 to LEN(TXData) step 2
IWSendport(ComPort, CHR$(Hex2Dec(MID$(TXData,x,2))), 1)
  NEXT x
Return 0
ENDSUB

This is a major change; not a minor change.
In this sub you are not modifying the passed in variable in any way.
All you are doing is adding the passed in string to a local string.
Big difference.

The only place this last example can mess up is the length of the passed in string.
In the sub you defined TXData as a string which is a max of 255 characters.
That means that when you add the lengths of all of this up it can have no more than 255 characters.
Quotelength (RS485_StartFrame
+ RS485_SrcAddr
+ RS485_DstAddr
+ TXLocal
+ RS485_StartStop
+ TXData
+ CRC_HDLC(DataAsc,ChrHex2Asc(TXData))
+ RS485_StartStop)
<= 255
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

TGN

Larry

On my computer this code make this output.
Its the same with or with out BYVAL

First Time - BYVAL !!
First Time - BYVAL !!
Press any key to close


AUTODEFINE "OFF"
OPENCONSOLE

STRING MainString
MainString="First Time - "
TX(MainString)
Print MainString

PRINT "Press any key to close"
WAITCON
END

SUB tx(STRING SubString BYVAL),int
SubString=SubString + "BYVAL !!"
Print SubString
Return 0
ENDSUB


LarryMc

My Bad!
I finally found where it says (here in the forums) that BYVAL is ignored for strings.
So the only way to modify a passed string in a subroutine and have it not change the passed string is to use a temp string.
Like this:
AUTODEFINE "OFF"
OPENCONSOLE

STRING MainString
MainString="First Time - "
TX(MainString)
Print "Main program => ",MainString

PRINT "Press any key to close"
WAITCON
END

SUB tx(STRING SubString BYVAL),int
String t=SubString + "BYVAL !!"
Print "subroutine => ",t
Return 0
ENDSUB


or a variation:
AUTODEFINE "OFF"
OPENCONSOLE

STRING MainString
MainString="First Time - "
Print "subroutine => ",TX(MainString)
Print "Main program => ",MainString

PRINT "Press any key to close"
WAITCON
END

SUB tx(STRING SubString BYVAL),string
Return SubString + "BYVAL !!"
ENDSUB
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

Just for fun.
Had I written the 2 blocks of code above from scrath with IWB 2.x they
would have looked something like this:

AUTODEFINE "OFF"

STRING MainString="First Time - "
TX(MainString)
? "Main program => ",MainString
END

SUB tx(STRING SubString BYVAL),int
String t=SubString + "BYVAL !!"
? "subroutine => ",t
Return 0
ENDSUB
and
AUTODEFINE "OFF"

STRING MainString="First Time - "
? "subroutine => ",TX(MainString)
? "Main program => ",MainString
END

SUB tx(STRING SubString BYVAL),string
Return SubString + "BYVAL !!"
ENDSUB
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

TGN

Larry
I did the same in this code with TXLocal
Im happy now, thought I was totally n...

Thanks Larry


SUB TX(STRING TXLocal,int
INT x:STRING TXData
TXData = RS485_StartFrame + RS485_SrcAddr + RS485_DstAddr + TXLocal
TXData=RS485_StartStop + TXData + CRC_HDLC(DataAsc,ChrHex2Asc(TXData)) + RS485_StartStop
  FOR x = 1 to LEN(TXData) step 2
IWSendport(ComPort, CHR$(Hex2Dec(MID$(TXData,x,2))), 1)
  NEXT x
Return 0
ENDSUB

Copex

February 12, 2013, 12:27:31 PM #9 Last Edit: February 13, 2013, 02:18:05 AM by Copex
i'm not going to say, i have read all of the post and maybe i have missed the point, you may need to read up on the Scope of Variables / Visibility of variables.

this is in C but the same principles apply across the board so to speak
Quotehttp://en.wikipedia.org/wiki/Scope_%28computer_science%29


OPENCONSOLE

'GLOBAL myString (not required)

string myString = "this is my string"
print myString
editstring()
print myString

do:until inkey$ <>""

CLOSECONSOLE
END

SUB editstring()
myString = myString + " modifiyed"
RETURN
ENDSUB


maybe ive missed the point

AUTODEFINE "OFF"
STRING MainString = "Main"
OPENCONSOLE

print MainString
print tx(MainString)
print MainString

PRINT "Press any key to close"
WAITCON

SUB tx(STRING SubString),STRING
SubString = SubString + "???"
RETURN SubString
ENDSUB
-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/

LarryMc

Copex - There are some subtle differences between the two examples you posted.
In the first the subroutine can be passed any string to modify.
In the 2nd the subroutine is dedicated to modifying a single string.

Also, in the first, the GLOBAL designation isn't need unless the app is a project and the variable is used in other source files.

What wasn't clear before was the use of BYVAL with string parameters to a sub
Turns out BYVAL is ignored for strings but can be used with other types that are normally passed by reference.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Copex

February 13, 2013, 02:00:22 AM #11 Last Edit: February 13, 2013, 02:16:37 AM by Copex
@larry you are right, i should have just deleted the post. i was looking at it from the scope of Variable been local to the sub routine and forgetting the rules of the programing language, as it is defined outside of the sub routine it is global to the source and as you stated the global command is not required.

though if you run the second example the last print MainString prints the modified text, though i never modified the MainString, so as stated i think i have completely missed the point.
-
I really should learn how to use a spell checker! though im not sure how it will help someone who can not spell?
-
Except where otherwise noted, content Posted By Copex is
licensed under a Creative Commons Attribution 3.0 License

http://creativecommons.org/licenses/by/3.0/

LarryMc

Quote from: Copex on February 13, 2013, 02:00:22 AM
...i should have just deleted the post....
I don't see any need to.  Your comments added to the discussion.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

billhsln

Your question may have helped some one else out who did not have the courage to ask it.

No question is stupid, if you don't know the answer.  Better to ask, because you might be helping some one else out also.

Bill
When all else fails, get a bigger hammer.