Menu

setting value of GPIO pin

miniTesla
2026-05-07
18 hours ago
1 2 3 > >> (Page 1 of 3)
  • miniTesla

    miniTesla - 2026-05-07

    I have the following subroutine. (The entire code is attached below.)

    SUB SendByte(In bb AS BYTE, In rb AS BYTE) 'rb > 0 read MISO
        FOR bIdx = 7 TO 0 STEP -1        'MSB first
            TARGET_SCK = 0
            TARGET_MOSI = bb.bIdx
            NOP
            NOP
            NOP
            TARGET_SCK = 1
            IF rb >= 1 THEN
                'SHIFT MISObyte, left, 1
                SET C OFF
                ROTATE MISObyte left
                IF TARGET_MISO=1 THEN MISObyte.0 = 1
            ELSE  'a dummy else branch to make execution time the same for both cases
                'SHIFT dummy, left, 1
                SET C OFF
                ROTATE dummy left
                IF TARGET_MISO=1 THEN dummy.0 = 1
            END IF
        NEXT
    END SUB
    

    Look at the line where TARGET_MOSI is set to the bit value of the variable BB. TARGET_MOSI is defined as such

    #DEFINE TARGET_MOSI PORTB.2
    

    The assembler created for this subroutine is

    SENDBYTE:
        ldi SysValueCopy,8
        sts BIDX,SysValueCopy
    SysForLoop2:
        lds SysTemp1,BIDX
        dec SysTemp1
        sts BIDX,SysTemp1
        cbi PORTB,1
        cbi PORTB,2
        ldi SysStringA, low(BB)
        ldi SysStringA_H, high(BB)
        lds SysReadA,BIDX
        ldi SysReadA_H,0
        andi    SysReadA, 7
        rcall   SysReadBit
        brbs    Z,PC + 2
        sbi PORTB,2
        nop
        nop
        nop
        sbi PORTB,1
        lds SysCalcTempA,RB
        cpi SysCalcTempA,1
        brlo    ELSE5_1
        clc
        lds SysValueCopy,MISOBYTE
        rol SysValueCopy
        sts MISOBYTE,SysValueCopy
        sbis    PINA,7
        rjmp    ENDIF7
        lds SysValueCopy,MISOBYTE
        sbr SysValueCopy,1<<0
        sts MISOBYTE,SysValueCopy
    ENDIF7:
        rjmp    ENDIF5
    ELSE5_1:
        clc
        lds SysValueCopy,DUMMY
        rol SysValueCopy
        sts DUMMY,SysValueCopy
        sbis    PINA,7
        rjmp    ENDIF8
        lds SysValueCopy,DUMMY
        sbr SysValueCopy,1<<0
        sts DUMMY,SysValueCopy
    ENDIF8:
    ENDIF5:
        ldi SysCalcTempA,0
        lds SysCalcTempB,BIDX
        cp  SysCalcTempA,SysCalcTempB
        brlo    SysForLoop2
    SysForLoopEnd2:
        ret
    

    The problem is this portion

        cbi PORTB,2
        ldi SysStringA, low(BB)
        ldi SysStringA_H, high(BB)
        lds SysReadA,BIDX
        ldi SysReadA_H,0
        andi    SysReadA, 7
        rcall   SysReadBit
        brbs    Z,PC + 2
        sbi PORTB,2
    

    Instead of setting the port pin to whatever the value of the bit has, the generated assembler code first clears the pin, meaning sets it to 0, (cbi PORTB,2) and then checks the bit and if necessary sets it to 1. This is not what the BASIC instruction say should be done.

    The instructions say to set it either 0 or 1 depending on the value of the bit. It is not instructing to set it first to 0 and then check the value of the bit to change the pin if necessary.

    Imagine the pin is 1 before the routine is called. Rather than leaving it at 1 it first becomes 0 and then later 1. This routine is used for bitbanging, which produces an incorrect signal at that pin. There may be other problems with this routine. The BASCOM equivalent works perfectly. The GCBASIC created completely fails. This is one problem I noticed.

     
  • Anobium

    Anobium - 2026-05-07

    Please use #option votatile {bit}. I think this may resolve.

     
    • miniTesla

      miniTesla - 2026-05-07

      Doesn't do anything. Even with

      #OPTION VOLATILE TARGET_MOSI
      

      The generated assembler is the same. It first clears the port with "cbi PortB,2" and then later sets it with "sbi PortB,2".

       

      Last edit: miniTesla 2026-05-07
  • Anobium

    Anobium - 2026-05-08

    That is odd. because I get a Two-Pass Bit-Copy Pattern

    The compiler generates both a clear and set path for every bit assignment, ensuring the pin is always actively driven.

    Pass 1 — Clear if bit is 0:

    rcall   SysReadBit       ; Read bb.bIdx into Z flag
    brbc    Z, PC+2          ; If Z clear (bit=1), skip cbi
    cbi     PORTB,2          ; Executes only if bit = 0 → PIN LOW
    

    Pass 2 — Set if bit is 1:

    rcall   SysReadBit       ; Read bb.bIdx into Z flag
    brbs    Z, PC+2          ; If Z set (bit=0), skip sbi
    sbi     PORTB,2          ; Executes only if bit = 1 → PIN HIGH
    

    The pin is a direct, stable copy of bb.bIdx at all times.


    Or, you can use

            If bb.bIdx = 1 Then
              TARGET_MOSI = 1
            Else
              TARGET_MOSI = 0
            End If
    
     
    • miniTesla

      miniTesla - 2026-05-08

      Thank you! I was looking at the wrong .asm file. Your second suggestion

      If bb.bIdx = 1 Then
            TARGET_MOSI = 1
      Else
            TARGET_MOSI = 0
      End If
      

      should be the preferred one because it produces much smaller code than the #option volatile. 16 bytes less to be exact. This may in fact be a worthwhile change in the compiler. Whenever a bit value is asigned to a port, it could apply this IF-ELSE solution. That avoids shooting onself in the foot and produces much smaller code than the volatile workaround.

      But the larger question is why does this SendByte subroutine not properly work when compiled by GCBASIC but works when compiled by BASCOM. I am at the end of my wits. No idea why the GCBASIC one fails. Here is the BASCOM basic and assembler with some annotations to make it clearer what happens.

      SUB SendByte(byval b AS BYTE, byval rb AS BYTE) 'rb>0 read MISO
         FOR bIdx = 7 TO 0 STEP -1        'MSB first
            TARGET_SCK = 0
            TARGET_MOSI = b.bIdx
            NOP
            NOP
            NOP
            TARGET_SCK = 1
            IF rb >= 1 THEN
               SHIFT MISObyte, left, 1
               IF TARGET_MISO=1 THEN SET MISObyte.0
            ELSE  'a dummy else branch to make execution time the same for both cases
               SHIFT dummy, left, 1
               IF TARGET_MISO=1 THEN SET dummy.0
            END IF
         NEXT
      END SUB
      

      and here the assembler code including the helper subroutines

      168:    87 e0           ldi r24, 0x07   ; 7
       16a:   80 93 1f 01     sts 0x011F, r24 ;  0x80011f     start BIDX with value 7
       16e:   40 91 1f 01     lds r20, 0x011F ;  0x80011f
       172:   00 e0           ldi r16, 0x00   ; 0
       174:   04 17           cp  r16, r20    ;           compare BIDX against 0
       176:   10 f0           brcs    .+4         ;  0x17c
       178:   09 f0           breq    .+2         ;  0x17c
       17a:   39 c0           rjmp    .+114       ;  0x1ee
       17c:   c1 98           cbi 0x18, 1     ; 24            clear bit PORTB.1, TARGET_SCK = 0
       17e:   80 91 1f 01     lds r24, 0x011F ;  0x80011f     load BIDX into r24 
       182:   aa 81           ldd r26, Y+2    ; 0x02
       184:   bb 81           ldd r27, Y+3    ; 0x03
       186:   12 d2           rcall   .+1060      ;  0x5ac        divide by 8
       188:   07 d2           rcall   .+1038      ;  0x598        calculate bitmask
       18a:   0c 90           ld  r0, X
       18c:   08 22           and r0, r24
       18e:   68 94           set
       190:   09 f4           brne    .+2         ;  0x194
       192:   e8 94           clt
       194:   a8 e3           ldi r26, 0x38   ; 56
       196:   b0 e0           ldi r27, 0x00   ; 0
       198:   8c 91           ld  r24, X
       19a:   82 f9           bld r24, 2
       19c:   8c 93           st  X, r24
       19e:   00 00           nop
       1a0:   00 00           nop
       1a2:   00 00           nop
       1a4:   c1 9a           sbi 0x18, 1     ; 24            TARGET_SCK = 1
       1a6:   a8 81           ld  r26, Y
       1a8:   b9 81           ldd r27, Y+1    ; 0x01
       1aa:   0c 91           ld  r16, X
       1ac:   01 30           cpi r16, 0x01   ; 1
       1ae:   08 f4           brcc    .+2         ;  0x1b2
       1b0:   0c c0           rjmp    .+24        ;  0x1ca
       1b2:   91 e0           ldi r25, 0x01   ; 1
       1b4:   ac e1           ldi r26, 0x1C   ; 28
       1b6:   b1 e0           ldi r27, 0x01   ; 1
       1b8:   cc d1           rcall   .+920       ;  0x552        left shift MISOBYTE by 1 bit
       1ba:   cf 9b           sbis    0x19, 7     ; 25            skip if bit PINA.7 is set
       1bc:   05 c0           rjmp    .+10        ;  0x1c8
       1be:   70 91 1c 01     lds r23, 0x011C ;  0x80011c         load MISOBYTE into r23
       1c2:   71 60           ori r23, 0x01   ;           set last bit to one with bitwise OR
       1c4:   70 93 1c 01     sts 0x011C, r23 ;  0x80011c         store r23 back in MISOBYTE 
       1c8:   0b c0           rjmp    .+22        ;  0x1e0
       1ca:   91 e0           ldi r25, 0x01   ; 1
       1cc:   ad e1           ldi r26, 0x1D   ; 29
       1ce:   b1 e0           ldi r27, 0x01   ; 1
       1d0:   c0 d1           rcall   .+896       ;  0x552        left shift DUMMY by 1 bit
       1d2:   cf 9b           sbis    0x19, 7     ; 25            skip if bit PINA.7 is set
       1d4:   05 c0           rjmp    .+10        ;  0x1e0
       1d6:   70 91 1d 01     lds r23, 0x011D ;  0x80011d     load DUMMY into r23
       1da:   71 60           ori r23, 0x01   ; 1         set last bit to one with bitwise OR
       1dc:   70 93 1d 01     sts 0x011D, r23 ;  0x80011d     store r23 back in DUMMY
       1e0:   80 91 1f 01     lds r24, 0x011F ;  0x80011f     load BIDX into r24
       1e4:   81 50           subi    r24, 0x01   ; 1         substract 1 from r24
       1e6:   80 93 1f 01     sts 0x011F, r24 ;  0x80011f     store r24 in BIDX
       1ea:   08 f0           brcs    .+2         ;  0x1ee
       1ec:   c0 cf           rjmp    .-128       ;  0x16e
       1ee:   08 95           ret
      
      
      ;=======================
      ;left shift byte
      ;number of shifts in r25
      ;byte to be shifted at the address X (r27:r26) is pointing to
      ;r24 working register
       552:   90 30           cpi r25, 0x00   ; 0
       554:   29 f0           breq    .+10        ;  0x560
       556:   8c 91           ld  r24, X
       558:   88 0f           add r24, r24
       55a:   9a 95           dec r25
       55c:   e9 f7           brne    .-6         ;  0x558
       55e:   8c 93           st  X, r24
       560:   08 95           ret
      
      ;=======================
      ;calculate bitmask and its inverse for byte
      ;
       598:   91 e0           ldi r25, 0x01   ; 1
       59a:   88 23           and r24, r24
       59c:   21 f0           breq    .+8         ;  0x5a6
       59e:   88 94           clc
       5a0:   99 1f           adc r25, r25
       5a2:   8a 95           dec r24
       5a4:   e9 f7           brne    .-6         ;  0x5a0
       5a6:   89 2f           mov r24, r25
       5a8:   90 95           com r25
       5aa:   08 95           ret
      
      ;=======================
      ;Divide by 8
      ;input value in r24
      ;output r26 quotient, r24 remainder
       5ac:   88 30           cpi r24, 0x08   ; 8
       5ae:   18 f0           brcs    .+6         ;  0x5b6
       5b0:   11 96           adiw    r26, 0x01   ; 1
       5b2:   88 50           subi    r24, 0x08   ; 8
       5b4:   fb cf           rjmp    .-10        ;  0x5ac
       5b6:   08 95           ret
      

      The SendByte() function is used in an ATtiny841 to program another AVR via its MOSI/MISO/SCK/RES interface. To enter the programming mode, after RESET has been set low, one sends the command 0xAC, 0x53, 0x00, 0x00, and the target microcontroller responds during the third byte with 0x53. This works perfectly with the BASCOM generated code. However, with the GCBASIC generated code I am reading back 0x7E and sometimes 0x7C. The fact that it reads back different values suggests some kind of race condition or timing issue that is absent from the BASCOM generated code. But more fundamentally, why is it producing the wrong value in MISObyte?

      If anybody has ideas or suggestions of what I could try, let me know. I am testing this on the same hardware at the same speed. The problem must therefore be somewhere in the code.

       
  • Anobium

    Anobium - 2026-05-08

    Check your GCBASIC program by compiling with AVRASM. Select this in Prefs Editor. Do you get the same error?

    Do you have a protocol analyser? what does that show?


    You have shared the BASCOM code but not the current GCBASIC code.

     
    • miniTesla

      miniTesla - 2026-05-08

      I have used AVRASM but it doesn't fix the problem.

      I do not have a logic analyzer to measure the signals on the pins directly.

       
      • Anobium

        Anobium - 2026-05-08

        So, using AVRASM tells me that the ASM is valid. As AVRASM would have rejected.


        I believe from my experience that GCBASIC is operating faster than BASCOM.

        I would rewrite the sub to use the GCBASIC operations to create delays.

        Does this clock the data out? I just lifted this from the forum, changing the vars.

        SUB SendByte(In bb AS BYTE, In rb AS BYTE) 'rb > 0 read MISO
        
          repeat 8
        
            if bb.7 = ON  then
              set TARGET_MOSI  ON
            else
              set TARGET_MOSI  OFF
            end if
            set TARGET_SCK  On
            rotate bb left
            set TARGET_SCK  Off
        
          end repeat
          set TARGET_SCK  ON
        
         End Sub
        
         
        • miniTesla

          miniTesla - 2026-05-08

          Yes, this routine clocks the data out but also, if rb is 1, reads at the same time the data on the TARGET_MISO pin into the MISObyte variable. It looks like the reading is the issue because if the target microcontroller would not get the correct "enter program mode" command, it wouldn't respond at all on the MISO line. The fact that it does, and we get something different to all zero or all 1 back at TARGET_MISO, suggests that the sending part works ok.

           
          • Anobium

            Anobium - 2026-05-08

            I think you are talking about your routine? I was asking about the one I posted.

            I just wanted to confirm the send works. With routine I posted.


            But, you code cannot read back at the 'same time' because of the else statement. You routine is either clocking a byte out OR clock ing a byte in. Is this correct?

            If correct.. then routine name is not correct. Should be mySPITransfer()
            In the routine, which is very typical across many libraries, the sub sends and gets a byte. There is no need for a secondary parameter as the data is clock in regardless and is sent back out via SPITempOut ( the 2nd parameter ).

            So, this uses the inhernent cycles of the rotates to give sufficent clock cycles to the target device. BASCOM looks like it is using the SHIFT calls - but, this is all about timing.

            To use

            Send: mySPITransfer ( bytetosend, somevariableyoudontcareaboutbutitcannotbeaconstant)
            Get: mySPITransfer ( somevariableyoudontcareaboutbutitcannotbeaconstant, bytereceived )
            Both... mySPITransfer( bytetosend, bytereceived)

            sub  mySPITransfer( IN SPISendByte as byte, OUT SPITempOut as byte )
            
                SPITempOut = 0
                set TARGET_SCK  Off
            
                repeat 8
            
                  if SPISendByte.7 = ON  then
                    set TARGET_MOSI   ON
                  else
                    set TARGET_MOSI   OFF
                  end if
            
                  'Device is cpol = 0. Invert SCK if cpol = 1
                  SET TARGET_SCK  ON
                  rotate SPISendByte left
            
                  rotate SPITempOut left
                  if TARGET_MISO = On then
                    set SPITempOut.0 On
                  Else
                    set SPITempOut.0 Off
                  end if
            
                  SET TARGET_SCK  OFF
            
                end repeat
            
            end Sub
            
             
            • miniTesla

              miniTesla - 2026-05-08

              But, you code cannot read back at the 'same time' because of the else statement. You routine is either clocking a byte out OR clock ing a byte in. Is this correct?

              My code does both send (to TARGET_MOSI) and read back from TARGET_MISO and stores it in the global variable MISObyte.

               
  • Anobium

    Anobium - 2026-05-08

    OK.

     
  • miniTesla

    miniTesla - 2026-05-08

    I think I have identified the bug in the compiler that is causing the problem. I don't want to believe it, and maybe I am going crazy working for 2 days on this problem, but here it is for the compiler experts to take a look.

    The difference is only how I name the second parameter in the function. Here is the version that works as intended:

    SUB SendCmd(In rb AS BYTE) 'a four byte command sent out via SCK and MOSI
       FOR I1=1 TO 4
          withRead = 0
          IF rb = I1 THEN withRead = 1
          SendByte(CMD(I1),withRead)
       NEXT
       TARGET_SCK = 0
    END SUB
    
    SUB SendByte(In bb AS BYTE, In rbx AS BYTE) 'rb > 0 read MISO
        REPEAT 8
            TARGET_SCK = 0
            If bb.7 = 1 Then
              TARGET_MOSI = 1
            Else
              TARGET_MOSI = 0
            End If
            TARGET_SCK = 1
            IF rbx >= 1 THEN
                SET C OFF
                ROTATE MISObyte left
                IF TARGET_MISO=1 THEN MISObyte.0 = 1
            ELSE  'a dummy else branch to make execution time the same for both cases
                SET C OFF
                ROTATE dummy left
                IF TARGET_MISO=1 THEN dummy.0 = 1
            END IF
            ROTATE bb left
        END REPEAT
    END SUB
    

    and here is the version that does not work

    SUB SendCmd(In rb AS BYTE) 'a four byte command sent out via SCK and MOSI
       FOR I1=1 TO 4
          withRead = 0
          IF rb = I1 THEN withRead = 1
          SendByte(CMD(I1),withRead)
       NEXT
       TARGET_SCK = 0
    END SUB
    
    SUB SendByte(In bb AS BYTE, In rb AS BYTE) 'rb > 0 read MISO
        REPEAT 8
            TARGET_SCK = 0
            If bb.7 = 1 Then
              TARGET_MOSI = 1
            Else
              TARGET_MOSI = 0
            End If
            TARGET_SCK = 1
            IF rb >= 1 THEN
                SET C OFF
                ROTATE MISObyte left
                IF TARGET_MISO=1 THEN MISObyte.0 = 1
            ELSE  'a dummy else branch to make execution time the same for both cases
                SET C OFF
                ROTATE dummy left
                IF TARGET_MISO=1 THEN dummy.0 = 1
            END IF
            ROTATE bb left
        END REPEAT
    END SUB
    

    As you can see, the only difference is that in the version that works, the second parameter of SendByte is called rbx, whereas in the version that does not work, it is called rb. I thought that parameter names are local and should not interfere with other subroutines that use the same parameter name.

    I am attaching the full code file of the non-working version below.

     
  • Anobium

    Anobium - 2026-05-09

    Why RBX Worked and RB did not. You know all this but I writing up for those that read this in years to come.

    1. The two versions

    Works

    SUB SendByte(In bb AS BYTE, In rbx AS BYTE)
    

    Breaks

    SUB SendByte(In bb AS BYTE, In rb AS BYTE)
    

    **Key fact about GCBASIC **

    All variables — including parameters — are stored in global SRAM.

    There are no true locals.
    The compiler assigns each parameter a global SRAM address.


    What went wrong with rb

    You already have a global variable:

    RB = 294   ; global SRAM address
    

    When you declare:

    SUB SendByte(..., In rb AS BYTE)
    

    GCBASIC sees the parameter name rb, and because it matches the global name RB, the compiler assigns the same SRAM address to the parameter.

    Result
    Inside SendByte, the parameter rb and the global RB are the same byte.

    This breaks the SENDCMD/SENDBYTE logic, because SENDCMD expects RB to be its own working variable.


    4. Why rbx works

    SUB SendByte(..., In rbx AS BYTE)
    
    • rbx does not match any global variable name
    • So GCBASIC assigns it a different SRAM address
    • The global RB is no longer overwritten

    Everything works again.


    5. How to make RB work safely

    Option 1 — Rename the parameter
    Recommended and simplest:

    SUB SendByte(In bb AS BYTE, In rb_param AS BYTE)
    

    Option 2 — Rename the global variable
    If you must use rb as the parameter name:

    DIM ReadFlag AS BYTE   'instead of RB
    

    Then:

    SUB SendByte(In bb AS BYTE, In rb AS BYTE)
    

    No name collision → separate SRAM addresses → works.


    6. Summary

    • GCBASIC stores all variables in global SRAM.
    • If a parameter name matches a global variable name, they share the same SRAM address.
    • rb collided with global RB, so the parameter overwrote the global.
    • rbx avoided the collision, so it worked.
    • To fix: rename either the parameter or the global.
     
    • miniTesla

      miniTesla - 7 days ago

      But that is not how a BASIC compiler is supposed to work. Function and Subroutine parameters should be local and shadow global variables with the same name. If all these subroutine parameters become global variables, how are you supposed to build and use libraries? How can one know which variable names have already been used as parameters in some library function? This can create all kinds of unexpected conflicts and failures.

      Subroutine parameters need to be handled via a stack or buffer in SRAM where they are stored temporarily while the subroutine is executed, and then released when it has finished.

      To be frank, with this everything-is-a-global-variable, GCBASIC is entirely useless for anything but the most trivial applications.

       

      Last edit: miniTesla 7 days ago
      • Anobium

        Anobium - 7 days ago

        Not sure how to reply. Just to say awareness and use of parameters has enabled 10000 of solutions to be build over the last 20 years.

        Local variables is on the development roadmap, along with structures.

         
        • miniTesla

          miniTesla - 7 days ago

          Then please explain to me, how would I know that I am using the same parameter name as some other library function so that I can avoid a conflict?

          Example, I opened the first source file that gets included when this example is compiled. It is picas.h. It has subroutines that use a parameter with the name LineX1. If I would use the same name in one of my subroutines, a conflict could take place that breaks the code. How would I know?

           
          • Anobium

            Anobium - 7 days ago

            The issue is much larger.

            The AVR architecture is a flat namespace architecture. Registers, register bits, compiler tool, include file must ALL have unique names.

            Addressing needs to ensure uniqueness.

            In GCBASIC we provide the following which could be used to inspect.

            1. chip specific DAT file. We ensure uniqueness is this file. Also, see AVRINFO/PICINFO
            2. Constant Definition File (CDF) for constants
            3. HTML report for RAM variables. Usage etc
            4. When using GCASM or any assembler see the LST file
            5. The ASM shows the variables

            I do not know of any compiler that provides such extensive access to the inner working for RAM or Constants.

             

            Last edit: Anobium 7 days ago
            • miniTesla

              miniTesla - 7 days ago

              We do not need to complicate this. The issue is function and subroutine parameter name conflicts. If GCBASIC is treating every parameter as a global variable, then it must at least issue notices or warnings when reuse takes place. Simply have the compiler output a table that shows any parameter name that is used in more than one function/subroutine. That way the code developer has a straightforward way to know if a conflict may be present.

              HTML report for RAM variables. Usage etc

              The html report only provides information about subroutines, not variables/parameters.

              There is currently no simple way I can see, to identify such variable name conflicts.

               

              Last edit: miniTesla 7 days ago
              • Anobium

                Anobium - 7 days ago

                Yes, all doable. This is an Open Source project. That is the sort of functionality that could be added, in the context that this is the first request for this I have seen since 2013.

                For now. I would use ASM as a great reference.

                And, I should mention that option explicit will provide a level of protection for undeclared variables,

                 
                • miniTesla

                  miniTesla - 7 days ago

                  Name conflicts are a core issue for compilers. Why this has not been address at the very beginning is not understandable to me. You are relying on luck that a variable or parameter name does not conflict with some library. Avoiding conflicts in one's own code is one isse, but extending that to all the libraries and internal functions one may use is insane. It is not some nice-to-have feature, it is essential to writing software.

                   
                  • Anobium

                    Anobium - 7 days ago

                    Not a question that I can answer. Hugh, the original architect never included that. If he were to do it all again then I guess he would. He would have implemented naming structure also.

                     
            • miniTesla

              miniTesla - 7 days ago

              GCBASIC already does some name conflict checking. For example, if I #define the same name twice, the compiler issues a warning. The same should be done for DIM and function/subroutine parameters since they all are global variables. A warning should be issued so that the application developer can decide if this is intentional or if it is a conflict that has to be fixed.

               
              • Anobium

                Anobium - 7 days ago

                A good approach. A neat solution.

                 
                • miniTesla

                  miniTesla - 7 days ago

                  It is a necessity. Anything else is like playing russian roulette. You would never know if a conflict breaks your code. Such conflicts usually break the code in subtle ways that are hard to debug, as this one example above has shown. Two days spent of debugging when it came down to a simple name conflict that the compiler could have flagged, particularly since the compiler works in a non-standard way to any other BASIC compiler I am aware of. Treating parameters as global variables is highly unusual.

                  Where in the documentation is that highlighted? Such out of norm behavior needs to be highlighted and mentioned more than once.

                   
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.

MongoDB Logo MongoDB