Macro expansion and the DECLARE SECTION of C and C++ embedded SQL applications

The C or C++ precompiler cannot directly process any C macro that is used in a declaration within a declare section. You must first preprocess the source file with an external C preprocessor by specifying the exact command for invoking a C preprocessor to the precompiler through the PREPROCESSOR option.

When you specify the PREPROCESSOR option, the precompiler first processes all the SQL INCLUDE statements by incorporating the contents of all the files referred to in the SQL INCLUDE statement into the source file. The precompiler then invokes the external C preprocessor using the command you specify with the modified source file as input. The preprocessed file, which the precompiler always expects to have an extension of .i, is used as the new source file for the rest of the precompiling process.

Any #line macro generated by the precompiler no longer references the original source file, but instead references the preprocessed file. To relate any compiler errors back to the original source file, retain comments in the preprocessed file. This helps you to locate various sections of the original source files, including the header files. The option to retain comments is commonly available in C preprocessors, and you can include the option in the command you specify through the PREPROCESSOR option. You must not have the C preprocessor output any #line macros itself, as they can be incorrectly mixed with ones generated by the precompiler.

Notes on using macro expansion:
  1. The command you specify through the PREPROCESSOR option must include all the required options, but not the name of the input file. For example, for IBM® C on AIX® you can use the option:
       xlC -P -DMYMACRO=1
  2. The precompiler expects the command to generate a preprocessed file with a .i extension. However, you cannot use redirection to generate the preprocessed file. For example, you cannot use the following option to generate a preprocessed file:
       xlC -E > x.i
  3. Any errors the external C preprocessor encounters are reported in a file with a name corresponding to the original source file, but with a .err extension.
  4. For compilers (gcc/clang/OpenXLC) that do not automatically generate the .i file and do not recognize the file suffix as C/C++ file, the options -x c and -o <inputfile_name_without_suffix>.i need to be included:
    ibm-clang -E -x c -o <inputfile_name_without_suffix>.i
    For example, if the input file is named myprogram.sqc, the PREPROCESSOR command using ibm-clang is:
    ibm-clang -E -x c -o myprogram.i
    For more details refer to the compiler documentation for the -x and -o options.

For example, you can use macro expansion in your source code as follows:

  #define SIZE 3

  EXEC SQL BEGIN DECLARE SECTION;
    char a[SIZE+1];
    char b[(SIZE+1)*3];
    struct
    {
      short length;
      char  data[SIZE*6];
    } m;
    SQL TYPE IS BLOB(SIZE+1) x;
    SQL TYPE IS CLOB((SIZE+2)*3) y;
    SQL TYPE IS DBCLOB(SIZE*2K) z;
  EXEC SQL END DECLARE SECTION;

The previous declarations resolve to the following example after you use the PREPROCESSOR option:

  EXEC SQL BEGIN DECLARE SECTION;
    char a[4];
    char b[12];
    struct
    {
      short length;
      char  data[18];
    } m;
    SQL TYPE IS BLOB(4) x;
    SQL TYPE IS CLOB(15) y;
    SQL TYPE IS DBCLOB(6144) z;
  EXEC SQL END DECLARE SECTION;