Q(uick)BASIC Statement (Non-BASIC): DECLARE

Quick View

DECLARE (Non-BASIC)

Declares calling sequences for external procedures written in other languages

Worth knowing

Useful and cross-version information about the programming environments of QBasic and QuickBasic.

Description/Parameter(s)
  • Syntax 1
  • DECLARE FUNCTION name [CDECL] [ALIAS "aliasname"][([parameterlist])]
  • Syntax 2
  • DECLARE SUB name [CDECL] [ALIAS "aliasname"][([parameterlist])]
Argument Description
FUNCTION Indicates that the external procedure returns a value and can be used in an expression.
SUB Indicates that the external procedure is invoked like a BASIC SUB.
name The name used in the BASIC program to invoke the procedure. Names may have up to 40 characters. FUNCTION names can include an explicit type character (%, &, !, #, or $) indicating the type of value the FUNCTION returns.
CDECL Indicates that the procedure uses the C-language argument order. CDECL passes the arguments from right to left, rather than using the BASIC convention of left to right. CDECL also affects the name used in searches of object files and libraries.
  • If there is no ALIAS clause in the DECLARE, the type-declaration character is removed from the name of the procedure, and an underscore is added to the beginning. This becomes the name used when searching libraries and external files.
  • If CDECL is used with an ALIAS, the aliasname is used.
ALIAS Indicates that the procedure has another name in the .OBJ or library file.
aliasname The name the procedure has in the file or library.
parameterlist Lists the variables to be passed to the called procedure and has the following syntax:
  • [{BYVAL|SEG}] variable [AS type][,[{BYVAL|SEG}] variable [AS type]]…
  • The following list describes the parts of a parameterlist:
Part Description
BYVAL BYVAL indicates that the parameter is passed by value, rather than by reference. Reference is the default. BYVAL can be used only with INTEGER, LONG, SINGLE, and DOUBLE parameters. When BYVAL appears in front of a parameter, the actual argument is converted to the type indicated in the DECLARE statement before being passed.
SEG Indicates the parameter is passed as a segmented address (far pointer).
variable A valid BASIC variable name. Only the variable's type is significant. If the variable is an array it may be followed by the number of dimensions in parentheses (to maintain compatibility with older versions of BASIC):
DECLARE SUB EigenValue (A(2) AS DOUBLE)
The number of dimensions is optional.
AS type Indicates the variable's type. The type element may be either INTEGER, LONG, SINGLE, DOUBLE, STRING, ANY, or a user type. You can also indicate the variable's type by including an explicit type character (%, &, !, #, or $) in the variable name or by relying on the default type. When declaring external procedures written in other languages, you can use the ANY keyword in the AS clause. ANY overrides type checking for that argument. You cannot use ANY with arguments passed by value.
Note: When neither BYVAL nor SEG is used, arguments are passed as near addresses (offsets).

This form of the DECLARE statement lets you reference procedures written in other languages. The DECLARE statement also causes the compiler to check the number and type of arguments used to invoke the procedure. A DECLARE statement can appear only in module-level code and affects the entire source file.

The form of the parameter list determines whether or not argument type checking is done:

Declaration Meaning
DECLARE SUB First CDECL No argument checking is done when there is no parameter list.
DECLARE SUB First CDECL () First has no parameters. Arguments in a CALL to First are flagged as an error. Empty parentheses indicate that the SUB or FUNCTION has no parameters.
DECLARE SUB First CDECL (X AS LONG) First takes one long integer argument. When a parameter list appears, the number and type of the arguments are checked in each invocation.

A procedure that appears in a DECLARE statement can be invoked without the CALL keyword.

Note: You cannot have fixed-length strings in DECLARE statements because only variable-length strings can be passed to SUB and FUNCTION procedures. Fixed-length strings can appear in an argument list but are converted to variable-length strings before being passed.

Be careful when using the SEG keyword to pass arrays because BASIC may move variables in memory before the called routine begins execution. Anything in a CALL statement's argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables, arithmetic expressions, or arrays indexed without the use of intrinsic or user-defined functions.

Example

The following example shows a BASIC program that calls a short C function. The C program would be separately compiled and stored in a Quick library or explicitly linked to form the .EXE file.

'*** Programming example: DECLARE (Non-BASIC procedure) *** ' ' Do not attempt to run this program unless you have already ' separately compiled the C function and placed it in a ' Quick library or linked it to the BASIC program. ' DEFINT a-z ' The function addone uses C argument passing and takes ' a single integer argument passed by value. DECLARE FUNCTION addone CDECL (BYVAL n AS INTEGER) INPUT x y=addone(x) PRINT "x and y are ";x;y END /* C function addone. Returns one more than the value of its integer argument. */ int far addone(n) int n; { return(++n); }
Description/Parameter(s)

This DECLARE statement declares calling sequences for external procedures written in other languages. For the DECLARE statement used to declare references to BASIC procedures, see DECLARE (BASIC Procedures) .

  • Syntax:
  • DECLARE FUNCTION name [CDECL] [ALIAS "aliasname"] [([parameterlist])]
  • DECLARE SUB name [CDECL] [ALIAS "aliasname"] [([parameterlist])]

  • The argument name can have up to 40 characters. A FUNCTION procedure name can include an explicit type character (%, &, !, #, @, or $) that indicates the type of value the procedure returns.
  • The CDECL passes the arguments from right to left, rather than using the BASIC convention of left to right. CDECL also affects the name used in searches of object files and libraries:
    • If there is no ALIAS clause in the DECLARE statement, the type-declaration character is removed from the name of the procedure, and an underscore is added to the beginning. This becomes the name used when searching libraries and external files.
    • If CDECL is used with ALIAS, aliasname is used as is.
  • parameterlist has this syntax:

  • [{BYVAL|SEG}] variable [AS type][,[{BYVAL|SEG}] variable [AS type]]…
BYVAL The parameter is passed by value, rather than by reference. Reference is the default. BYVAL can be used only with INTEGER, LONG, SINGLE, DOUBLE, and CURRENCY types. When BYVAL appears in front of a parameter, the actual argument is converted to the type indicated in the DECLARE statement before being passed.
SEG Indicates the parameter is passed as a segmented address (far address).
variable A valid BASIC variable name. Only the variable's type is significant. If the variable is an array it can be followed by the number of dimensions in parentheses (to maintain compatibility with older versions of BASIC). For example:
  • DECLARE SUB EigenValue (a() AS DOUBLE)
AS type The variable's type. The type can be INTEGER, LONG, SINGLE, DOUBLE, STRING, CURRENCY, ANY, or a user-defined type. You also can indicate the variable's type by including an explicit type character (%, &, !, #, @, or $) in the variable name or by relying on the default type. When declaring external procedures written in other languages, you can use the ANY keyword in the AS clause. ANY overrides type checking for that argument. You cannot use ANY with arguments passed by value.
Note: When neither BYVAL nor SEG is used, arguments are passed as near addresses (offsets).
  • This form of the DECLARE statement lets you refer to procedures written in other languages. The DECLARE statement also causes the compiler to check the number and type of arguments used to invoke the procedure. A DECLARE statement can appear only in module-level code and affects the entire source file.
  • The form of the parameter list determines whether or not argument type checking is done, as described in the declarations below:
Declaration Meaning
DECLARE SUB First CDECL No argument checking is done when there is no parameter list.
DECLARE SUB First CDECL () First has no parameters. Arguments in a call to First generate an error. (Empty parentheses indicate that the SUB or function has no parameters and that argument checking should be done.)
DECLARE SUB First CDECL (X AS LONG) First takes one long integer argument. When a parameter list appears, the number and type of the arguments are checked in each invocation.
  • A procedure that appears in a DECLARE statement can be invoked without the CALL keyword.

Important

  • You cannot have fixed-length strings in DECLARE statements because only variable-length strings can be passed to SUB and FUNCTION procedures. Fixed-length strings can appear in an argument list but are converted to variable-length strings before being passed.
  • Be careful when using the SEG keyword, because BASIC may move variables in memory before the called routine begins execution. Anything in a CALL statement's argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables or arithmetic expressions.
  • You cannot pass arrays using the SEG keyword.
Example

This example uses the DECLARE statement to use a C function in a BASIC program. The BASIC program calls the function addone, which uses C argument passing and takes a single integer argument passed by value.
Note: To run this program, you must separately compile the C function and place it in a Quick library or link it to the BASIC program.

DEFINT A-Z DECLARE FUNCTION addone CDECL (BYVAL n AS INTEGER) INPUT x y = addone(x) PRINT "x and y are "; x; y END '/* C function addone. Returns one more than the value of its argument. */ ' 'int far addone(int n) '{ ' return(n+1); '}