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,