Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
simplistic misunderstanding about ; + "" in a print
#1
I may have a simplistic misunderstand about the use of semicolon, strings, plus sign and quotes in print statements.

1 q$=chr$(34)
2 print q$; "test"; q$
3 print q$ + "test" + q$

Output is "test" and "test" on separate lines.  I assumed ? q$; "test"; q$ would be an improper use of concatenation in a print statement.  I thought line 3 was the right way. But it works.
If I try to type q$"" the line changes to q$; "".  Auto corrects and makes me wonder.  I checked this output in the mother tongue "qb45".  Works like qb64.

If the +'s are not needed, do they take cycles and code unnecessary ?  Again wondering.
I know PRINT is most code producing and time wasting part of the source in qb64.

Thanks
Reply
#2
(09-19-2024, 01:37 AM)doppler Wrote: I may have a simplistic misunderstand about the use of semicolon, strings, plus sign and quotes in print statements.

1 q$=chr$(34)
2 print q$; "test"; q$
3 print q$ + "test" + q$

Output is "test" and "test" on separate lines.  I assumed ? q$; "test"; q$ would be an improper use of concatenation in a print statement.  I thought line 3 was the right way. But it works.
If I try to type q$"" the line changes to q$; "".  Auto corrects and makes me wonder.  I checked this output in the mother tongue "qb45".  Works like qb64.

If the +'s are not needed, do they take cycles and code unnecessary ?  Again wondering.
I know PRINT is most code producing and time wasting part of the source in qb64.

Thanks

When you use the + sign your creating another string var in memory that the print statement is then outputting.     So in 3 print only has 1 argument.        print can take multiple arguments in MOST BASIC's (and does in QB64PE) so the + construction is allowed but not necessary.    Your instincts are correct in that it does use a little extra CPU time to do the concatenation, though that's probably far outweighed by the CPU time it takes to do the actual output.
Reply
#3
Actually, contrary to what you guys might think and how logic would normally dictate things, it's actually better to use + (Concatenation) than it is to use ; (semicolons) in QB64.  I know that sounds counter intuitive, but I swear, it's true.  Tongue

You have to remember, QB64 is a translator which turns BAS programs into C programs, and ... that's not always pretty.  Let me draw you a picture in code:

Code: (Select All)
a$ = "foo"
b$ = "bar"
c$ = "but"

Print a$; b$; c$
Print a$ + b$ + c$

Now, let's break this down into three sections off the translated code which we can find in internal/temp:

Code: (Select All)
do{
qbs_set(__STRING_A,qbs_new_txt_len("foo",3));
qbs_cleanup(qbs_tmp_base,0);
if(!qbevent)break;evnt(1);}while(r);
do{
qbs_set(__STRING_B,qbs_new_txt_len("bar",3));
qbs_cleanup(qbs_tmp_base,0);
if(!qbevent)break;evnt(2);}while(r);
do{
qbs_set(__STRING_C,qbs_new_txt_len("but",3));
qbs_cleanup(qbs_tmp_base,0);
if(!qbevent)break;evnt(3);}while(r);

The above is basically where we translate the variables into c-code, so those represent the first few lines of the QB64 program.

Code: (Select All)
do{
tqbs=qbs_new(0,0);
qbs_set(tqbs,__STRING_A);
if (is_error_pending()) goto skip1;
makefit(tqbs);
qbs_print(tqbs,0);
qbs_set(tqbs,__STRING_B);
if (is_error_pending()) goto skip1;
makefit(tqbs);
qbs_print(tqbs,0);
qbs_set(tqbs,__STRING_C);
if (is_error_pending()) goto skip1;
makefit(tqbs);
qbs_print(tqbs,0);
qbs_print(nothingstring,1);
skip1:
qbs_free(tqbs);
qbs_cleanup(qbs_tmp_base,0);
if(!qbevent)break;evnt(5);}while(r);

And all the above is basically how we print a$; b$; c$.  That's ONE line of QB64 code translated into all of those.

Code: (Select All)
do{
tqbs=qbs_new(0,0);
qbs_set(tqbs,qbs_add(qbs_add(__STRING_A,__STRING_B),__STRING_C));
if (is_error_pending()) goto skip2;
makefit(tqbs);
qbs_print(tqbs,0);
qbs_print(nothingstring,1);
skip2:
qbs_free(tqbs);
qbs_cleanup(qbs_tmp_base,0);
if(!qbevent)break;evnt(6);}while(r);

And, the above is basically how we translate that last line of BAS code.

It's a little hard to understand that we're seeing with the above, but what it basically breaks down to is:

PRINT a$; b$; c$;    <---- This statement will get translated as if it was actually:
PRINT a$;
PRINT b$;
PRINT c$;

Each of those get printed first to a temp string (for formatting and word wrap and all that), and as you can see from the above, that's a good number of lines.


The second statement (PRINT a$ + b$ + c$) basically gets broke down to:
Print ((a$ + b$) + c$)

One print statement.  One use of a temp string,  One call to the formatting routine.  



The more semicolons you have, the bigger the difference becomes.  

Most would think the PRINT with semicolons would be better.  In most cases, it probably would be.  It *should* be.   But, due to the way we machine translate things and do our formatting and word wrap and everything else, it's NOT. 


Just something to keep in mind, that most folks never consider.  It's behind the scene translation at work on your code.
Reply
#4
like a page out of the QB64 Bible, very nice analysis, Steve
Reply
#5
Yep, I knew "Super moderator" would give an inside look.
I also remembered from his pass comments about PRINT function being the messy-ist procedures.

This has turned out to be very interesting.
Reply
#6
Quote:PRINT a$; b$; c$;    <---- This statement will get translated as if it was actually:
PRINT a$;
PRINT b$;
PRINT c$;
Each of those get printed first to a temp string (for formatting and word wrap and all that), and as you can see from the above, that's a good number of lines.
The reason for this behavior may/could be that in C/C++ every line must end with a semicolon - except main(), loops or the function definition.

Code: (Select All)

//Deklaration
int blabla(int);

int main(void)
{
int feld[10];

for (int i = 1; i <= 10; i++)
{
feld[i] = i;
printf("%3d", feld[i]);
}
return(0);
}

//Definition
int blabla(int i)
{
. . .
}
Reply
#7
No.  The reason is just ease of translating.

PRINT "abc"; 123; TAB(4); USING "###.###", 12.34

Now, try and use concatenation to add all that together into one line to print, word wrap, and screen scroll with.   ...   I'm waiting...   Complex as heck, isn't that concept!

Now, just break it down as independent print statements.
PRINT "abc";
PRINT 123;
PRINT TAB(4);
PRINT USING "###.###", 12.34

Now THOSE are all simple to process and understand...  but that's 4 calls to print, 4 calls to word wrap, 4 calls to screen scroll, 4 calls to free temp variables...

Whereas, as I pointed out above, PRINT a$ + b$ + c$ + d$ only does those things once after it adds the strings together.
Reply
#8
That's right, the semicolon has a different meaning in Basic than in C. So it has nothing to do with C/C++. - Wrong thought! 

Code: (Select All)

a = 3: b = 7

Print 2; "Hallo"; 45; a * b
Reply
#9
This one I was aware of, but late to the party. I didn't get hooked on C/C++ but for the one app I did write I did get some insight into speeding up strings.

;1 to Steve for taking the time to post some sample output. Big Grin 

Pete
Shoot first and shoot people who ask questions, later.
Reply
#10
(09-19-2024, 01:07 PM)SMcNeill Wrote: No.  The reason is just ease of translating.
It's actually a behavior difference Tongue Imagine instead of string literals you're printing the results of some functions:

Code: (Select All)
Print func1$(1); func2$(20)
Print func1$(1) + func2$(20)

Those two lines don't behave the same if func2$(20) produces an error - with the first one you'll see the result of func1$(1) on the screen, with the second you won't see anything.

The same logic applies if func2$(20) just doesn't return for an extended time (maybe it has a SLEEP or does a long computation). In the first case you'll see the partial output from func1$(1) on screen, in the other you won't see anything until func2$(20) finishes.
Reply




Users browsing this thread: 13 Guest(s)