A string variable in GCBASIC has a fixed size, set when you declare it:
'Dim myString As String * 16'
When you assign a string to it, GCBASIC copies the whole string. It does not check whether the string fits. If the string is too long, the extra characters are written into the RAM after the variable.
That RAM belongs to other variables. There is no warning: the program compiles and runs, and something else goes wrong later.
Example on a PIC16F886:
#DEFINE LONGCONSTANT "12345678901234567890"
Dim myString1 As String * 16 = "ABC"Dim myString2 As String * 16 = LONGCONSTANT
LONGCONSTANT has 20 characters, but myString2 holds 16. All 20 are copied, and the last 4 overwrite myString1. Afterwards myString1 is no longer "ABC".
This happens with:
a constant: myString = "a long text"
another string: myString = otherString
joined strings: myString = "abc" + otherString
The fix
The new build 1657 adds an option:
#option StringLimitCheck
With this option, a string is never copied past the end of the variable it goes into. A string that is too long is cut to fit.
In the example, myString2 becomes "1234567890123456" and myString1 stays "ABC".
How to use it
Install the new build of the compiler.
Add this line near the top of your program, with your other #option lines:
#option StringLimitCheck
Compile as usual. You do not need to change anything else.
What it covers
Assigning a constant to a string.
Copying one string to another.
Joining strings with +. Each part only gets the space that is left.
It does not cover:
A string passed to a sub by reference.
Writing single characters yourself, for example myString(20) = 65.
Which chips
PIC18: yes.
PIC16, for example the 16F886 and 16F1827: yes.
12-bit PICs, for example the 16F57: yes for constants. String variables on these chips have problems with or without the option, and the compiler already warns about this.
AVR: yes.
What it costs
About one instruction for each string assignment.
No extra RAM on PIC18 and AVR, and one byte on other PICs.
USB programs can even get smaller. The USB libraries no longer need Left() for their name strings when the option is on.
Also in this build
Strings use less RAM. The compiler no longer reserves temporary strings it does not use, and sizes the others to fit. One test program went from 1936 to 1502 bytes of RAM.
The .asm file now lists the length of every string variable, under ;STRING LENGTHS, for exEQU 16.
Questions
If a string still overflows with the option on, please reply with the chip and a short program example.
This now works as expected.
#CHIP16f886#optionExplicit#OPTIONStringLimitCheck#DEFINEUSART_BAUD_RATE9600#DEFINEUSART_TX_BLOCKING#DEFINEUSART_DELAYOFF#DEFINELONGCONSTANT"12345678901234567890"// #DEFINE LONGCONSTANT "12345678901234567"// #DEFINE LONGCONSTANT "1234567890123456"DimmyString1AsString*2="ABC"// RAM too small for StringRAM too small for assignmentDimmyString2AsString*16=LONGCONSTANT// HserprintmyString1HserSend13HserSend10HserprintmyString2
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem
A string variable in GCBASIC has a fixed size, set when you declare it:
'Dim myString As String * 16'
When you assign a string to it, GCBASIC copies the whole string. It does not check whether the string fits. If the string is too long, the extra characters are written into the RAM after the variable.
That RAM belongs to other variables. There is no warning: the program compiles and runs, and something else goes wrong later.
Example on a PIC16F886:
LONGCONSTANT has 20 characters, but myString2 holds 16. All 20 are copied, and the last 4 overwrite myString1. Afterwards myString1 is no longer "ABC".
This happens with:
The fix
The new build 1657 adds an option:
#option StringLimitCheckWith this option, a string is never copied past the end of the variable it goes into. A string that is too long is cut to fit.
In the example, myString2 becomes "1234567890123456" and myString1 stays "ABC".
How to use it
#option StringLimitCheckWhat it covers
It does not cover:
Which chips
What it costs
USB programs can even get smaller. The USB libraries no longer need Left() for their name strings when the option is on.
Also in this build
Questions
If a string still overflows with the option on, please reply with the chip and a short program example.
This now works as expected.