Why the Pro*C/C++ Oracle precompiler can not parse the windows.h header file?

4.3k views Asked by At

I’m working on Windows Server 2008 R2 Standard (SP1), using the MSVC Ultimate 2012. I’m trying to compile one my „C“ project for 64 bit platform (but it seems that the problem is not target related). The project includes one *.pc file, which has to be precompiled by Pro*C/C++ precompiler. Problem is, that I’m not able to precompile that file. The precompilation fails during parsing of windows.h header file. Please help!!!

More details:

1) Source file: My my.pc file begins as follows:

 #include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>  
 #include <string.h>
 #include <time.h>
 #include <assert.h>
 #include <sqlca.h>
 #include <sqlcpr.h>

…..

Note: The first #include <windows.h> is sufficient for error invocation.

2) Configuration files: The default pcscfg.cfg file is empty, the project configuration file my.cfg looks like follows:

sys_include=(d:\Progra~1\Micros~2.0\VC\include,c:\Progra~2\WI3CF2~1\8.0\Include\um,c:\Progra~2\WI3CF2~1\8.0\Include\shared,$PROC11_ORACLE_HOME\PRECOMP\PUBLIc)
sqlcheck=full
parse=FULL
define=_WIN64 (or without this line)

Note: d:\Progra~1\Micros~2.0\VC\include = D:\Program Files\Microsoft Visual Studio 10.0\VC\include, c:\Progra~2\WI3CF2~1\8.0\Include\um = C:\Program Files (x86)\Windows Kits\8.0\Include\um, c:\Progra~2\WI3CF2~1\8.0\Include\shared = C:\Program Files (x86)\Windows Kits\8.0\Include\shared, $PROC11_ORACLE_HOME = d:\oracle\product\11.2.0\client_2. Those paths are there to find all the needed header files.

3) Command line: I have defined the following Command line for my my.pc file in the Custom Build Tool/General options:

$(PROC11_ORACLE_HOME)\bin\proc config=.\my.cfg iname=%(Filename).pc oname=.\%(Filename).c include="$(MSDEV_HOME)\vc\include".

Note: The $(MSDEV_HOME) = D:\Program Files\Microsoft Visual Studio 10.0.

4) Platform: The MSVC platform is set to x64, but I obtained similar results for Win32 also.

5) Error messages: Error messages received during precompilation if there is define=_WIN64 involved in my.cfg file:

1>  Syntax error at line 46, column 1, file d:\Progra~1\Micros~2.0\VC\include\vadefs.h:
1>  Error at line 46, column 1 in file d:\Progra~1\Micros~2.0\VC\include\vadefs.h
1>  typedef unsigned __int64    uintptr_t;
1>  1
1>  **PCC-S-02201, Encountered the symbol "typedef" when expecting one of the following:**
1>     ; , = ( [
1>  The symbol ";" was substituted for "typedef" to continue.

6) Error messages: Error messages received during precompilation if the define=_WIN64 is NOT involved in my.cfg file:

1>  Syntax error at line 48, column 1, file d:\Progra~1\Micros~2.0\VC\include\vadefs.h:
1>  Error at line 48, column 1 in file d:\Progra~1\Micros~2.0\VC\include\vadefs.h
1>  typedef _W64 unsigned int   uintptr_t;
1>  1
1>  **PCC-S-02201, Encountered the symbol "typedef" when expecting one of the following:**
1>  ; , = ( [

7) File vadefs.h: The critical lines in the vadefs.h header file look like follows:

 #ifndef _UINTPTR_T_DEFINED
 #ifdef  _WIN64
 typedef unsigned __int64    uintptr_t; (this is line no. 46)
 #else
 typedef _W64 unsigned int   uintptr_t; (this is line no. 48)
 #endif
 #define _UINTPTR_T_DEFINED
 #endif

Question is, why the precompilation fails in the standard Microsoft header file. May be there is some mess in macros, e.g. something related to the _WIN64 one? Or should I add another macro to the configuration file? I have read plenty of discussions but without progress. Any ideas would be very appreciated!

1

There are 1 answers

0
maxschlepzig On

The general issue is that Oracle 11 Pro*C's ANSI-C parsing capabilities are quite limited.

Basically, Oracle is lying when claiming that Pro*C is able to parse ANSI-C source files.

For example, it can't even parse stuff like:

  • for (int i=0; i<n; ++i)
  • C99 style struct/array initializations that are a little bit more sophisticated than a simple = {0}
  • temporary initializer assignments
  • ...

Thus, one has following options when running into a parse error like described above:

  • report it as bug to Oracle
  • workaround it, by
    • refactoring your code such that all windows.h related code is in its own non-.pc translation unit, which provides functions that can be called safely from .pc files - or -
    • guarding the #include <windows.h> directive and all of its uses with C pre-processor conditional constructs like #ifndef ORA_PROC and #endif - the ORA_PROC macro is only defined when the files are pre-processed by Pro*C, not when the C compiler compiles the generated file - or -
    • experimenting with the Pro*C option PARSE=PARTIAL or PARSE=NONE (the default is PARSE=FULL) - note that this makes esql declare sections mandatory (and probably also suppresses other useful warnings) - or -
    • looking into windows.h and finding perhaps some set of system macros that are supplied by default with the standard C compiler (but not by Pro*C) and which would make Pro*C happy when supplied via the Pro*C DEFINE= option