CONST directive

Purpose : CONST can define a named constant and optionally assign a value to the constant. Also, CONST can create macro definitions.

Do not confuse BCX CONST with C language const which is used to signify that a variable's value is not modifiable.


Syntax 1:
 
 CONST ConstantName = Value

Remarks:

Do not append any sigil, (% ! # $), to any variable on the right hand side of the CONST directive.


 CONST ConstantName% = Value%

is invalid and will not compile.

If a CONST is used in an $IF, $ELIF, or $ELSE directive, it must have a value that evaluates to an integer constant. If a constant is defined, but is not given a value, attempting to compile the code will cause a compilation error, as is the case, in the following example.


 $BCXVERSION "7.4.0 (2020/01/19)"
   
 CONST NOVALUE
 
 $IF NOVALUE
   PRINT "This will end your dreams"
 $ENDIF

Result:

Pelles C compiler throws this error


 error #1019: Syntax error in #if/#elif expression.

Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x86 throws this error


 fatal error C1017: invalid integer constant expression


Syntax 2:
 
 CONST MACRONAME = (MacroExpression)

Remarks:

The macro and the variable names in macro definitions must be parenthesized.

Example 1: This example shows the correct parenthesization of a CONST macro.


 DIM A, B
 CONST MACRONAME(C) = ((C) * (C) * (C))
 A = 3
 B = 2007 / MACRONAME(A + 1)
 PRINT " True Macros in BCX ! = ", B

Result:


 True Macros in BCX ! =  31

If the parentheses surrounding the right hand expression are omitted, the result will be different, for example,


 DIM A, B
 CONST CubeInt(C) = (C) * (C) * (C)
 A = 3
 B = 2007 / CubeInt(A + 1)
 PRINT "True Macros in BASIC ! = ", B

Result:


 True Macros in BASIC ! =  8016

And if the parentheses surrounding variable names are omitted, the result again will be different, for example,


 DIM A, B
 CONST CubeInt(C) = (C * C * C)
 A = 3
 B = 2007 / CubeInt(A + 1)
 PRINT "True Macros in BASIC ! = ", B

Result:


 True Macros in BASIC ! =  200

And again if the parentheses surrounding both the macro and variable names are omitted, the result yet again will be different, for example,


 DIM A, B
 CONST CubeInt(C) = C * C * C
 A = 3
 B = 2007 / CubeInt(A + 1)
 PRINT "True Macros in BASIC ! = ", B

Result:


 True Macros in BASIC ! =  676

Here is another example of CONST used to create a function-like macro.

 
 CONST RunEx(lpFile, _
       lpParameters, _
         nShowCmd) = _
     ShellExecute(0, _
             "open", _
             lpFile, _
       lpParameters, _
                  0, _
           nShowCmd)

Remarks:

To use the above macro you must link with SHELL32.LIB. The following shows how RunEx would be called in the application.

 
 RunEx("notepad.exe", "xxx.txt", 1)


Syntax 3:
 
 CONST ConstantName = Expression

Example 2:

Here is a way to use CONST to embed NULL in a string.


 $IPRINT_OFF
  CONST Filter = "Icons(*.ico)\0*.ICO\0All files(*.*)\0*.*"
 $IPRINT_ON

Example 3:

If you have a C code snippet that should look like:


 void* F_CALLBACKAPI WaveformCB(void *originalbuffer,
                                     void *newbuffer,
                                          int length,
                                           int param)

it can be translated to BCX like this:

 
 CONST pF_Callback = (Void*)F_CALLBACKAPI

 FUNCTION WaveformCB(originalbuffer AS void PTR, _
                          newbuffer AS void PTR, _
                              length AS INTEGER, _
                               param AS INTEGER) AS pF_Callback

PRIVATE CONST statement

PRIVATE CONST must be compiled with a C++ compiler and can be used only the -c command line flag or with $CPP or $CPPHDR directives. PRIVATE CONST can not be used with strings or expressions.

Purpose: PRIVATE CONST creates an integer constant that is local in scope within a SUB or FUNCTION.

Example:


 CALL One()
 CALL Two()

 SUB One()
  PRIVATE CONST ONE = 1
  PRIVATE CONST TWO = 2
  PRINT ONE,TWO
 END SUB

 SUB Two()
  PRIVATE CONST ONE = 3
  PRIVATE CONST TWO = 4
  PRINT ONE,TWO
 END SUB

$IF, $IFDEF, $IFNDEF, $ELSE, $ELSEIF, $ENDIF directives

Purpose: To provide conditional compilation. These five preprocessor directives allow you to compile special versions of your final program based on your certain conditions.


 $BCXVERSION "7.4.0 (2020/01/19)"

 CONST FOO = 1
 CONST BAR = 0
 
 $IFDEF FOO
   PRINT "FOO is defined."
 $ENDIF
 
 $IF FOO
   PRINT "FOO has a value of ", FOO
 $ENDIF
 
 $IFDEF BAR
   PRINT "BAR is defined."
 $ENDIF
 
 $IF BAR
   PRINT "BAR has 0 value so this will not print"
 $ENDIF
 
 ' Note that the "==" equality operator must be used
 ' when performing a comparison.

 $IF BAR == 0
   PRINT "BAR has a value of ", BAR
 $ENDIF
 
 $IF FOO == 1
   PRINT "FOO has a value of ", FOO
 $ENDIF
 
 $IF FOO == 5
   PRINT "FOO does not have a value of 5 so this will not print", FOO
 $ENDIF
 
 $IF FOO OR BAR
   PRINT "FOO has a value of ", FOO
   PRINT "BAR has a value of ", BAR
 $ENDIF

Result:


FOO is defined.
FOO has a value of  1
BAR is defined.
BAR has a value of  0
FOO has a value of  1
FOO has a value of  1
BAR has a value of  0

This BCX code


 CONST FooBar
 DIM A
 
 $IFNDEF FooBar
 A = 1
 $ELSE
 A = 2
 $ENDIF
 
 PRINT A

translates to the following C code, showing that the conditional directives are local in scope located in the main function.


// *************************************************
//            User Defined Constants
// *************************************************

#define FooBar 

// *************************************************
//            User Global Variables
// *************************************************

static int     A;

// *************************************************
//                  Main Program
// *************************************************

int main(int argc, char *argv[])
{
#ifndef FooBar
A= 1;
#else
A= 2;
#endif  // Main
printf("% d\n",(int)A);
  return 0;   /* End of main program */
}

Conditional directives can not encase any of the following:

Any conditional directives will be local in scope to any FUNCTION or SUB procedure including the main function.

If you want global preprocessor conditionals, placed at the top of the module level code, executing before anything else, then C style preprocessor code in $HEADER directives must be used as shown below.


 $HEADER
 #define FooBar 
 #ifndef FooBar
 #define A 1 
 #else
 #define A 2
 #endif
 $HEADER
 
 PRINT A
 

Example 1:

As an example, suppose you wanted all the messages in your program to be in a particular language, you could use something like the following sample. There would be only one set of language statements in the final .exe


 '***********************************************************************
 ' Conditional compilation using:  $IFDEF/$ELSE/$ELSEIF/$ENDIF directives
 '***********************************************************************
 '  By uncommenting one of the following CONST statements, the resulting
 '  executable code changes as well.  Only the code that is associated
 '  with the true condition is compiled, the rest is disregarded.
 '*******************************************************************
 
 'CONST ENGLISH
 'CONST SPANISH
 'CONST GERMAN
 
 $IFDEF ENGLISH
  PRINT "Good Day"
  PRINT "What's happening?"
 $ELSEIF SPANISH
  PRINT "Buenas Dias"
  PRINT "Como va?"
 $ELSEIF GERMAN
  PRINT "Guten Tag"
  PRINT "Was ist los?"
 $ELSE
  PRINT "Greetings Earthling"
  PRINT "Where is the cafeteria?"
 $ENDIF

Result:


 Greetings Earthling
 Where is the cafeteria?

Example 2:


 $BCXVERSION "7.5.7"

 CONST APPLES  = 1
 CONST ORANGES = 2
 
 $IF APPLES OR ORANGES '<<-- OR is always Boolean in any IF/ $IF statement 
   PRINT "$IF should translate to (||) and yield 3:", %APPLES OR ORANGES '<<-- otherwise, OR is bitwise 
 $ENDIF
 
 $IF APPLES ORELSE ORANGES '<<-- ORELSE is ALWAYS Boolean 
   PRINT "$IF should translate to (||) and yield 1:", %APPLES ORELSE ORANGES ' <<-- ORELSE is ALWAYS Boolean 
 $ENDIF
 
 $IF APPLES BOR ORANGES '<<-- This is explicitly bitwise 
   PRINT "$IF should translate to (|)  and yield 3:", %APPLES BOR ORANGES '<<-- This is explicitly bitwise 
 $ENDIF

Result:


 $IF should translate to (||) and yield 3: 3
 $IF should translate to (||) and yield 1: 1
 $IF should translate to (|)  and yield 3: 3

BCX Console Sample Programs using CONST directive.

S46.bas, S53.bas, S70.bas, S76.bas, S85.bas, S111.bas, S115.bas, S120.bas, S121.bas, S122.bas, S124.bas,