QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Reggie on February 27, 2021, 11:59:13 pm

Title: C++ Compilation failed passing arrays as parameters
Post by: Reggie on February 27, 2021, 11:59:13 pm
QB64 Version 1.4 from git 0f49b2c (Win10-x64):
"C++ Compilation failed" Error,  when trying to pass an array as a parameter.

(Code attached (same as in the next post below) -- uncommenting the "try" lines cause the internal compiler error)
Title: Re: C++ Compilation failed?
Post by: Reggie on February 28, 2021, 12:03:50 am
C++ Compilation failed -- Code Sample:

Code: QB64: [Select]
  1. '==============================================================================
  2. ' QB64 Version 1.4 from git 0f49b2c
  3. '
  4. '   "C++ Compilation failed" Error,
  5. '   when trying to pass an array as a parameter.
  6. '
  7. '==============================================================================
  8.  
  9. '==============================================================================
  10. 'PS C:\Apps\qb64\internal\temp> .\recompile_win.bat
  11. 'Recompiling...
  12. 'In file included from qbx.cpp:2192:
  13. '..\\temp\\maindata.txt: In function 'void QBMAIN(void*)':
  14. '..\\temp\\maindata.txt:13:2: error: 'pass2' was not declared in this scope
  15. '  pass2;
  16. '  ^~~~~
  17. 'compilation terminated due to -Wfatal-errors.
  18. '==============================================================================
  19.  
  20.  
  21. ' Main
  22. PRINT "Main"
  23.  
  24. ' Declare the cloud() array
  25. CONST SIZE = 8
  26. DIM cloud(1 TO SIZE) AS INTEGER
  27.  
  28. ' Initialize the cloud() array
  29. DIM index AS INTEGER
  30. FOR index = 1 TO SIZE
  31.     cloud(index) = 0
  32.     PRINT "Index = "; index
  33.  
  34. ' Invoke Subroutines
  35. 'try1 (cloud()) ' Uncommenting this line generates C++ Compilation failure error
  36. 'try2 (cloud) ' Uncommenting this line generates C++ Compilation failure error
  37. 'try3 (cloud(3)) ' Uncommenting this line generates C++ Compilation failure error
  38.  
  39.  
  40. SUB try1 (cloud())
  41.     PRINT "Try1"; cloud(1)
  42.  
  43. SUB try2 (cloud())
  44.     PRINT "Try2"; cloud(2)
  45.  
  46. SUB try3 (cloud( 8))
  47.     PRINT "Try3"; cloud(3)
  48.  
  49.  
Title: Re: C++ Compilation failed?
Post by: NOVARSEG on February 28, 2021, 01:47:45 am
@Reggie

An array can't be used as an argument.   Not sure

Code: QB64: [Select]
  1. DIM cloud(3) AS INTEGER
  2.  
  3. cloud(0) = 8
  4. cloud(1) = 9
  5. cloud(2) = 10
  6. cloud(3) = 11
  7.  
  8.  
  9.  
  10. FOR X = 0 TO 3
  11.     try (cloud(X))
  12.  
  13. SUB try (A AS INTEGER)
  14.  
  15.     PRINT A
  16.  
  17.  
Title: Re: C++ Compilation failed?
Post by: SpriggsySpriggs on February 28, 2021, 01:49:20 am
Well for one thing it looks like you didn't set up try3 correctly. It also looks like you didn't use any of the subs correctly either.
Title: Re: C++ Compilation failed?
Post by: SpriggsySpriggs on February 28, 2021, 01:50:11 am
@NOVARSEG An array can be used as an argument. It just has to be used correctly
Title: Re: C++ Compilation failed?
Post by: NOVARSEG on February 28, 2021, 01:55:38 am
@SpriggsySpriggs

I tried  cloud() as the argument , it did not work
Title: Re: C++ Compilation failed?
Post by: SpriggsySpriggs on February 28, 2021, 01:57:32 am
Whatever this issue is, it's not because of QB64. The stable v1.4 release can use arrays as parameters. I know this because I use subs and functions with arrays as parameters and did so in v1.4
Title: Re: C++ Compilation failed?
Post by: SpriggsySpriggs on February 28, 2021, 02:06:02 am
try3 is declared entirely wrong and used incorrectly. try2 is declared incorrectly and used incorrectly. try1 is declared incorrectly and used incorrectly. You have try1 declared as just try1(cloud()).
When you don't put a type behind it then it expects a SINGLE type. Your array is declared as an INTEGER type. Change sub try1 from

Code: QB64: [Select]
  1. Sub try1 (cloud())
  2.     Print "Try1"; cloud(1)

to

Code: QB64: [Select]
  1. Sub try1 (cloud() As Integer)
  2.     Print "Try1"; cloud(1)

And it will work just fine. Again, you can use arrays as parameters, you just have to use them correctly. Also, don't call the sub like try1 (cloud()). Call it like try1 cloud()

Proof that it works:
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Code: QB64: [Select]
  1. Print "Main"
  2.  
  3. ' Declare the cloud() array
  4. Const SIZE = 8
  5. Dim cloud(1 To SIZE) As Integer
  6.  
  7. ' Initialize the cloud() array
  8. Dim index As Integer
  9. For index = 1 To SIZE
  10.     cloud(index) = 0
  11.     Print "Index = "; index
  12.  
  13. ' Invoke Subroutines
  14. try1 cloud()
  15.  
  16.  
  17. Sub try1 (cloud() As Integer)
  18.     Print "Try1"; cloud(1)

If your array had been declared without a type specification then your try1 sub would have worked as it was in your code because it would have defaulted to SINGLE in both the main code and the sub
Title: Re: C++ Compilation failed?
Post by: NOVARSEG on February 28, 2021, 03:09:40 am
@SpriggsySpriggs

A slight variation.  An array used as an argument.

Code: QB64: [Select]
  1. DIM cloud(3) AS INTEGER
  2.  
  3. cloud(0) = 8
  4. cloud(1) = 9
  5. cloud(2) = 10
  6. cloud(3) = 11
  7.  
  8.  
  9. try cloud()
  10.  
  11.  
  12.  
  13. SUB try (A() AS INTEGER)
  14.  
  15.     DIM X AS INTEGER
  16.     FOR X = 0 TO 3
  17.         PRINT A(X)
  18.     NEXT X
  19.  
Title: Re: C++ Compilation failed?
Post by: SpriggsySpriggs on February 28, 2021, 04:07:05 am
@NOVARSEG the code I posted was just his code but edited to actually compile and work. I'll leave you two to it.
Title: Re: C++ Compilation failed?
Post by: RhoSigma on February 28, 2021, 04:23:18 am
The mistake is very simple here:

he tries to invoke the SUB in the form Try2 (array()) --- so what is really wrong here? -- it's the outer paranthesis around the array()

SUB arguments are not passed within paranthesis (like for FUNCTIONs), unless you use the CALL syntax:

CALL Try2 (array())

But he didn't use the CALL instruction, hence the compiler sees the additional paranthesis as a request to pass the array() BYVAL rather than by reference (which is the one and only possible way for strings and arrays to get passed in BASIC). The IDE should warn here, if you use extra paranthesis around string/array arguments. The issue is known and in the Github issues list AKAIK.

So his compilation failue can be solved very easy in his original code, simply remove the extra paranthesis in the SUB call or place the CALL instruction before the sub name.

EDIT:
Well, its not on the Github issues list, then it was probably another discussion on this board, I know I read about this problem before here, I think it was @SMcNeill who discovered it first.

EDIT2:
Oh, just see @SpriggsySpriggs is correct too, he declared cloud as INTEGER but used the default SINGLE in the SUB, that's obviously a type mismatch :), but after that is corrected it works as I said, simply waive to the outer paranthesis or place a CALL in front.

That's the reason, why I use type suffixes always and everywhere, those errors are completely unknown to me since more than 20 years, because I always and everywhere immediately know what I have in front of my eyes.

Title: Re: C++ Compilation failed?
Post by: bplus on February 28, 2021, 07:55:51 am
Quote
That's the reason, why I use type suffixes always and everywhere, those errors are completely unknown to me since more than 20 years, because I always and everywhere immediately know what I have in front of my eyes.

There is sense in this but oy, the top row shifting and extra characters to type, Yikes!

I dream of one world where everything is string! and top row typing is for numbers only.
Oh wait, maybe a command or 2 also  :)

That way I can code with one hand and eat drink coffee with the other ;-))
Title: Re: C++ Compilation failed?
Post by: RhoSigma on February 28, 2021, 08:32:42 am
There is sense in this but oy, the top row shifting and extra characters to type, Yikes!

True & False,
what always brings a smile on my face is that kind of "Stephen King" roman some people type in the beginning of a program to DIM this AS that, and DIM that AS those (just have a look into source\QB64.bas), but on the other hand telling me that it would be to much typing adding the 1 extra char to variables.

So those people spend all that time to write their roman in the beginning, and when finally reaching line 500+ in the code they nevertheless need to scroll back to the top to see what this one particular variable was DIMed as.

I write that 1 extra char wherever and whenever I write a variable, of course depending on the size of the project (just think of GuiTools) that are 1000s of extra key presses, but that's something I don't really realise as these are scattered over the whole source.
But on the other hand, as said, each time when I need to write a variable + suffix during development, I do automatically refresh my memory what type it is and what use it has in my program and when I reach line 500+ or even 5000+ then I don't need to scroll back to top to see what it was.

Even if this sound very arrogant, I'd bet for 90% sure, that you could pick any abitrary variable out of my GuiTools source, and I can tell you its intended purpose without even need to look into the source.

It's just the way I teached programming to myself over the years, using methods which gurantee mostly error free coding on the first run, saving time for bug hunting/fixing. It worked well for more than two decades now, so why change it?

In fact most errors I get todays are simple stupid typos, but not program flow errors which happen because I don't know what I have done or what types my variables are.

In this spirit, I just can anybody wish best luck, that they are able to finetune their personal coding style/skills the same way as I could do over the years.
Title: Re: C++ Compilation failed?
Post by: bplus on February 28, 2021, 09:01:05 am
Yes I confess I missed the $ suffix to string type and missed it in sB (SmallBASIC, the one before M.S., that started on Palm Pilot or some other PDA device.)

Note to self, if I build an Editor for SBx to include a variable table throw-up with keypress combo so I don't loose my place while I remind myself of my variable names. ;-)) but at least I don't have to remember which type it is!

Wait! Notepad++ is already annoying the heck out of me throwing up word tables that start with a couple of letters! ;P
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: Reggie on February 28, 2021, 11:47:01 am
Thank you all for the responses!

(I'm brand new to QB64 -- looking for exciting stuff to do, this is my very first pandemic. The QB64 forum is certainly a lot more alive than I thought it might be -- please nobody take this the wrong way, but you have to admit that we are kind of at one of the extremities of the internet out here! Not unlike the Earth itself, a small but interesting outpost on the edge of the galaxy -- anything to get away from Javascript, amiright? ;-) )

==

Re: try3 is declared entirely wrong and used incorrectly.
Re: try2 is used incorrectly.

Reggie says:
True, but in both cases QB64 "fell down" into the C++ error, so I added them to the sample program while attempting to isolate the compiler bug:

[1] My assumption was/is that any such errors should be picked-up by QB64 proper, and that any fall-through to the internal C++ compiler is probably a reportable bug, regardless of the code that caused it to happen.

[2] I noticed the "Compilation failed" posting a few hours before mine, but the C++ error is different so they might be separate issues?

[3] When I first saw the error, I thought, "Weird, it's QBasic 4.5 compatible, but there's a C++ guy in there trying to get out!" (It was like watching the movie Aliens, quite frankly!)

==
Re: Also, don't call the sub like try1 (cloud()). Call it like try1 cloud()

Reggie says:
Okay...I see now, that's working much better...thanks!
But now I'm confused -- the example on QB64's "FUNCTION" page shows parentheses included in FUNCTION calls. Is it different for SUB calls? Or they are optional?
[Searching...this might be interesting...]

==
Re: When you don't put a type behind it then it expects a SINGLE type. Your array is declared as an INTEGER type.

Reggie says:
Okay...I think this probably explains the problem with the sample code itself...
I see here, from the QB64 documentation:

    When a variable has not been defined or has no type suffix, the value defaults to SINGLE.
    (http://qb64.org/wiki/INTEGER)

    Parameters passed after the procedure call must match the variable types in the SUB parameters in order.
    http://www.qb64.org/wiki/SUB

And so the problem (with my code) was a kind-of subtle combination of the above two conditions...

==
Reggie says:
And so just to confirm though, there is a relatively new or under-explored compiler bug involved here? (Fall-through to C++ error)


Thanks again for all the help!
Reg
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: SMcNeill on February 28, 2021, 12:07:40 pm
SUBs are basically commands like CLS, PRINT, and END.  They don’t require parentheses, and you just call them as they exist.

CLS
PRINT “Hello World”
END

FUNCTIONs, on the other hand, give return values and generally require the use of parentheses with parameters.  Think of commands like SIN, COS, and _PRINTWIDTH.

x = SIN(.2)
y = COS(.6)
w = _PRINTWIDTH(“Hello World”)



The glitch you’ve encountered is a long lasting one that simply hasn’t been hunted down and fixed yet, and the c++ compilation fail is from calling the sub with parentheses around an array element.

Let’s say we have a simple sub like this one:

SUB foo (array())
END SUB

Calling it with foo (x()) will give you the c++ failure.
Calling it as foo x(), and it all works fine.

The IDE doesn’t catch the issue as it’s not actually an invalid syntax — in fact, you might even want to use it from time to time to pass values by reference, to keep values from passing back from the sub.  (Though you can’t right now, due to the glitch in it.)

Someday, somebody might get around to sorting the issue out, but this is one of our long-standing bugs that’s proven rather hard to track down and sort out.  With no foreseeable ETA on a fix, it’s best to just make a mental note of it: Don’t call SUBs and use parentheses around arrays in the parameters.
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: bplus on February 28, 2021, 12:18:46 pm
Thank you all for the responses!

(I'm brand new to QB64 -- looking to exciting stuff to do, this is my very first pandemic. The QB64 forum is certainly a lot more alive than I thought it might be -- please nobody take this the wrong way, but you have to admit that we are kind of at one of the extremities of the internet out here! Not unlike the Earth itself, a small but interesting outpost on the edge of the galaxy -- anything to get away from Javascript, amiright?)

==

Re: try3 is declared entirely wrong and used incorrectly.
Re: try2 is used incorrectly.

Reggie says:
True, but in both cases QB64 "fell down" into the C++ error, so I added them to the sample program while attempting to isolate the compiler bug:

[1] My assumption was/is that any such errors should be picked-up by QB64 proper, and that any fall-through to the internal C++ compiler is probably a reportable bug, regardless of the code that caused it to happen.

[2] I noticed the "Compilation failed" posting a few hours before mine, but the c++ error is different so they might be separate issues?

[3] When I first saw the error, I thought, "Weird, it's QBasic 4.5 compatible, but there's a C++ guy in there trying to get out! (It was like watching the movie Aliens, quite frankly!)

==
Re: Also, don't call the sub like try1 (cloud()). Call it like try1 cloud()

Reggie says:
Okay...I see now, that's working much better...thanks!
But now I'm confused -- the example on QB64's "FUNCTION" page shows parentheses included in FUNCTION calls. Is it different for SUB calls? Or they are optional?
[Searching...this might be interesting...]

==
Re: When you don't put a type behind it then it expects a SINGLE type. Your array is declared as an INTEGER type.

Reggie says:
Okay...I think this probably explains the problem with the sample code itself...
I see here, from the QB64 documentation:

    When a variable has not been defined or has no type suffix, the value defaults to SINGLE.
    (http://qb64.org/wiki/INTEGER)

    Parameters passed after the procedure call must match the variable types in the SUB parameters in order.
    http://www.qb64.org/wiki/SUB

And so the problem (with my code) was a kind-of subtle combination of the above two conditions...

==
Reggis says:
And so just to confirm though, there is a relatively new or under-explored compiler bug involved here? (Fall-through to C++ error)


Thanks again for all the help!
Reg

Yeah when the compiler does not correct my typo's and misuse of tools, it bugs me too! ;-))

A sub is defined with () enclosing the parameters but when called the modern way, no () needed.

You can put parenthesis around an argument so that it is not changed when exiting a sub. Otherwise you change a variable of same type as in definition (SUB or Function), that variable will go out of the sub (or function) a changed variable. This is actually handy but can cause problems to unaware or neglectful. Best to copy it inside sub or function if you are even going to _Trim$() it, unless that is effect you are after.

To do old QB4.5 Call a sub, then you put parenthesis around your arguments. It's there to be compatible with the old way. Call = () like a function,  no Call = no () Not like a function.
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: bplus on February 28, 2021, 12:27:13 pm
Perhaps the confusion arises because when you use a sub you are "calling" it but there is a keyword CALL that has rules that involve () when using the CALL keyword. CALL is so old that we still refer to it as "calling it" even though we no longer use the CALL keyword nor the ().

https://www.qb64.org/wiki/CALL

Who wants to take the old option of typing more stuff to use a sub?

Just people running code from 80's. You can use line numbers too.
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: bplus on February 28, 2021, 12:47:10 pm
I though you could put () around argument, works here:
Code: QB64: [Select]
  1. x% = 4
  2. test x%
  3. ' x% is now 5
  4. test (x%)
  5. PRINT x% 'still 5?
  6.  
  7. SUB test (this AS INTEGER)
  8.     IF this = 1 THEN
  9.         PRINT DATE$
  10.     ELSEIF this = 2 THEN
  11.         PRINT TIME$
  12.     ELSE
  13.         this = this + 1
  14.         PRINT this
  15.     END IF
  16.  

Is it the arrays then?
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: bplus on February 28, 2021, 12:54:15 pm
Yes works for array items too!
Code: QB64: [Select]
  1. REDIM x%(1 TO 20)
  2. FOR i = 1 TO 20
  3.     x%(i) = i
  4. PRINT x%(4)
  5. test x%(4)
  6. PRINT x%(4)
  7. ' x%(4) is now 5?
  8. test (x%(4))
  9. PRINT x%(4) 'still 5?
  10.  
  11. SUB test (this AS INTEGER)
  12.     IF this = 1 THEN
  13.         PRINT DATE$
  14.     ELSEIF this = 2 THEN
  15.         PRINT TIME$
  16.     ELSE
  17.         this = this + 1
  18.         PRINT this
  19.     END IF
  20.  
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: SMcNeill on February 28, 2021, 12:59:39 pm
Yes works for array items too!
Code: QB64: [Select]
  1. REDIM x%(1 TO 20)
  2. FOR i = 1 TO 20
  3.     x%(i) = i
  4. PRINT x%(4)
  5. test x%(4)
  6. PRINT x%(4)
  7. ' x%(4) is now 5?
  8. test (x%(4))
  9. PRINT x%(4) 'still 5?
  10.  
  11. SUB test (this AS INTEGER)
  12.     IF this = 1 THEN
  13.         PRINT DATE$
  14.     ELSEIF this = 2 THEN
  15.         PRINT TIME$
  16.     ELSE
  17.         this = this + 1
  18.         PRINT this
  19.     END IF
  20.  

Doesn’t work for arrays as a parameter.

DIM x(0)
x(0) = 1
foo (x())

SUB foo (array())
    FOR I = 0 TO UBOUND(array)
       PRINT array(I)
    NEXT
END SUB
Title: Re: C++ Compilation failed passing arrays as parameters
Post by: bplus on February 28, 2021, 01:08:51 pm
That has me wondering, it is probably expecting only one item when use () around an argument. Could you pass arrays back in QB4.5 days? I am pretty sure array items were OK to pass.