I have some programs running on Red Hat Linux 7.3 working with IBM DB2
V6.1 (with all the FixPacks) on my old machine.
I have just installed IBM DB2 V8.1 on this (new) machine running Red Hat
Enterplise Linux 3 ES, and applied FixPack fp5_mi00069.tar to it. After
creating an instance, starting the database, creating a database, and
entering the table definitions, all of which seems to work OK, I entered a
tiny 8-row table and can do queries on it. So the server seems to be
working OK. BTW, I am running Personal Developers' Edition.
However, to go further I must be able to build my client programs to
populate the rest of the database and this requires I recompile my old RHL
7.3 programs that work with DB2 V6.1 to run on this RHEL 3 ES machine with
V8.1.5, and the C++ programs with embedded SQL in them do not compile. A
few of the statements compile, but the important ones do not.
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor
dbBase(const string& db_name)
{
EXEC SQL BEGIN DECLARE SECTION; <---<<<
char dbName[DB_DB2N_SIZE + 1]; | "A"
EXEC SQL END DECLARE SECTION; <---<<<
_connected = false;
_dbName = "";
if(db_name.empty()) {
cerr << "dbBase(" << db_name << "): db_name missing." << endl;
exit(EXIT_FAILURE);
}
if(db_name.size() > DB_DB2N_SIZE) {
cerr << "dbBase(" << db_name << "): db_name too long." << endl;
exit(EXIT_FAILURE);
}
(void) strncpy(dbName, db_name.c_str(), DB_DB2N_SIZE);
dbName[DB_DB2N_SIZE] = EOS;
// Connect to database.
EXEC SQL CONNECT TO :dbName; <---<<< "B"
The stuff marked "A" goes right through the preprocessor and compiler,
but the line marked "B" chokes as follows:
dbBase.i: In constructor `dbBase::dbBase(const string&)':
dbBase.i:9122: `NULL' undeclared (first use this function)
dbBase.i:9122: (Each undeclared identifier is reported only once for each
function it appears in.)
make: *** [dbBase.o] Error 1
Here is dbBase.i line 9122"
EXEC SQL CONNECT TO :dbName;
I cannot go on until I fix this problem (that appears in almost every
function of this class, and I assume for all other classes as well.
In addition to this fatal error, I am getting lots of warning messages I
am not used to, such as:
/usr/bin/g++ -c -g -Wno-deprecated -mcpu=i686 -march=i686 -O2
-I/home/jdbeyer/include -I/home/jdbeyer/stocks/include
-I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include
dbBase.CdbBase.C:4011: warning: `typename
__default_alloc_template<threads, inst>::_Obj
' is implicitly a typename
dbBase.C:5433: warning: `typename basic_string<charT, traits, Allocator>::Rep'
is implicitly a typename
dbBase.C:5607: warning: `typename basic_string<charT, traits,
Allocator>::size_type' is implicitly a typename
even though I include _-Wno-deprecated_ in the compiler command line. I
prefer not to include that, and would like that fixed too.
Since DB2 V8.1.5 is supposedly supported on RHEL 3, I would like to know
how to deal with this. If I need to include some new header flags, use
different flags for the compiler or something, I would be glad to do so
(easy in my makefiles).
I am annoyed that installing fp5_mi00069.tar deleted all the html
documentation from the system, but I put it back.
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 21:05:00 up 9 days, 21:47, 7 users, load average: 4.08, 4.13, 4.10 10 4223
Jean-David Beyer wrote: I have some programs running on Red Hat Linux 7.3 working with IBM DB2 V6.1 (with all the FixPacks) on my old machine.
I have just installed IBM DB2 V8.1 on this (new) machine running Red Hat Enterplise Linux 3 ES, and applied FixPack fp5_mi00069.tar to it. After creating an instance, starting the database, creating a database, and entering the table definitions, all of which seems to work OK, I entered a tiny 8-row table and can do queries on it. So the server seems to be working OK. BTW, I am running Personal Developers' Edition.
However, to go further I must be able to build my client programs to populate the rest of the database and this requires I recompile my old RHL 7.3 programs that work with DB2 V6.1 to run on this RHEL 3 ES machine with V8.1.5, and the C++ programs with embedded SQL in them do not compile. A few of the statements compile, but the important ones do not.
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION; <---<<< char dbName[DB_DB2N_SIZE + 1]; | "A" EXEC SQL END DECLARE SECTION; <---<<<
_connected = false; _dbName = "";
if(db_name.empty()) { cerr << "dbBase(" << db_name << "): db_name missing." << endl; exit(EXIT_FAILURE); } if(db_name.size() > DB_DB2N_SIZE) { cerr << "dbBase(" << db_name << "): db_name too long." << endl; exit(EXIT_FAILURE); } (void) strncpy(dbName, db_name.c_str(), DB_DB2N_SIZE); dbName[DB_DB2N_SIZE] = EOS;
// Connect to database. EXEC SQL CONNECT TO :dbName; <---<<< "B"
The stuff marked "A" goes right through the preprocessor and compiler, but the line marked "B" chokes as follows:
dbBase.i: In constructor `dbBase::dbBase(const string&)': dbBase.i:9122: `NULL' undeclared (first use this function) dbBase.i:9122: (Each undeclared identifier is reported only once for each function it appears in.) make: *** [dbBase.o] Error 1
Here is dbBase.i line 9122"
EXEC SQL CONNECT TO :dbName;
I cannot go on until I fix this problem (that appears in almost every function of this class, and I assume for all other classes as well.
How exactly do you do the "precompile"?
I saw the same error once when I used the compiler's precompiler to resolve
macros in host variable definitions as you have. The precompiler will then
include <stdlib.h> and expand all macros, including the #define for NULL.
Later, the DB2 precompiler pastes some function calls into the generated C
code where "NULL" is used to pass a NULL pointer. That NULL can't be
expanded anymore because <stdlib.h> is not included again.
It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves
your problem. If not, then you should provide some sort if directive to
the DB2 precompiler in such a way that NULL will be resolved (or that
<stdlib.h> is included again).
Either way, I wouldn't use the compiler's precompiler because it garbles all
the line numbers (at the latest after the DB2 prep was ran) and debugging
this stuff will be a mess because the debugger has the incorrect line
information and just shows the wrong things when you step through the code.
For all my things, I wrote a small Perl script that replaces the macros in
the host variable definitions in a file with the extension .SQX, generates
a .SQC and that is given to DB2 prep to do its job.
In addition to this fatal error, I am getting lots of warning messages I am not used to, such as:
/usr/bin/g++ -c -g -Wno-deprecated -mcpu=i686 -march=i686 -O2 -I/home/jdbeyer/include -I/home/jdbeyer/stocks/include -I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include dbBase.CdbBase.C:4011: warning: `typename __default_alloc_template<threads, inst>::_Obj ' is implicitly a typename dbBase.C:5433: warning: `typename basic_string<charT, traits, Allocator>::Rep' is implicitly a typename dbBase.C:5607: warning: `typename basic_string<charT, traits, Allocator>::size_type' is implicitly a typename
even though I include _-Wno-deprecated_ in the compiler command line. I prefer not to include that, and would like that fixed too.
I don't see why the warnings to show deprecated uses of functions would be
relevant to the warnings shown above. What's the code in line 5433 or 5607
where the compiler complains?
p.s: My experience is that newer compilers often raise new warnings/errors
because the old code is not as clean as it should have been.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena
Jean-David Beyer wrote: I have some programs running on Red Hat Linux 7.3 working with IBM DB2 V6.1 (with all the FixPacks) on my old machine.
I have just installed IBM DB2 V8.1 on this (new) machine running Red Hat Enterplise Linux 3 ES, and applied FixPack fp5_mi00069.tar to it. After creating an instance, starting the database, creating a database, and entering the table definitions, all of which seems to work OK, I entered a tiny 8-row table and can do queries on it. So the server seems to be working OK. BTW, I am running Personal Developers' Edition.
However, to go further I must be able to build my client programs to populate the rest of the database and this requires I recompile my old RHL 7.3 programs that work with DB2 V6.1 to run on this RHEL 3 ES machine with V8.1.5, and the C++ programs with embedded SQL in them do not compile. A few of the statements compile, but the important ones do not.
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION; <---<<< char dbName[DB_DB2N_SIZE + 1]; | "A" EXEC SQL END DECLARE SECTION; <---<<<
_connected = false; _dbName = "";
if(db_name.empty()) { cerr << "dbBase(" << db_name << "): db_name missing." << endl; exit(EXIT_FAILURE); } if(db_name.size() > DB_DB2N_SIZE) { cerr << "dbBase(" << db_name << "): db_name too long." << endl; exit(EXIT_FAILURE); } (void) strncpy(dbName, db_name.c_str(), DB_DB2N_SIZE); dbName[DB_DB2N_SIZE] = EOS;
// Connect to database. EXEC SQL CONNECT TO :dbName; <---<<< "B"
The stuff marked "A" goes right through the preprocessor and compiler, but the line marked "B" chokes as follows:
dbBase.i: In constructor `dbBase::dbBase(const string&)': dbBase.i:9122: `NULL' undeclared (first use this function) dbBase.i:9122: (Each undeclared identifier is reported only once for each function it appears in.) make: *** [dbBase.o] Error 1
Here is dbBase.i line 9122"
EXEC SQL CONNECT TO :dbName;
I cannot go on until I fix this problem (that appears in almost every function of this class, and I assume for all other classes as well.
How exactly do you do the "precompile"?
I saw the same error once when I used the compiler's precompiler to resolve
macros in host variable definitions as you have. The precompiler will then
include <stdlib.h> and expand all macros, including the #define for NULL.
Later, the DB2 precompiler pastes some function calls into the generated C
code where "NULL" is used to pass a NULL pointer. That NULL can't be
expanded anymore because <stdlib.h> is not included again.
It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves
your problem. If not, then you should provide some sort if directive to
the DB2 precompiler in such a way that NULL will be resolved (or that
<stdlib.h> is included again).
Either way, I wouldn't use the compiler's precompiler because it garbles all
the line numbers (at the latest after the DB2 prep was ran) and debugging
this stuff will be a mess because the debugger has the incorrect line
information and just shows the wrong things when you step through the code.
For all my things, I wrote a small Perl script that replaces the macros in
the host variable definitions in a file with the extension .SQX, generates
a .SQC and that is given to DB2 prep to do its job.
In addition to this fatal error, I am getting lots of warning messages I am not used to, such as:
/usr/bin/g++ -c -g -Wno-deprecated -mcpu=i686 -march=i686 -O2 -I/home/jdbeyer/include -I/home/jdbeyer/stocks/include -I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include dbBase.CdbBase.C:4011: warning: `typename __default_alloc_template<threads, inst>::_Obj ' is implicitly a typename dbBase.C:5433: warning: `typename basic_string<charT, traits, Allocator>::Rep' is implicitly a typename dbBase.C:5607: warning: `typename basic_string<charT, traits, Allocator>::size_type' is implicitly a typename
even though I include _-Wno-deprecated_ in the compiler command line. I prefer not to include that, and would like that fixed too.
I don't see why the warnings to show deprecated uses of functions would be
relevant to the warnings shown above. What's the code in line 5433 or 5607
where the compiler complains?
p.s: My experience is that newer compilers often raise new warnings/errors
because the old code is not as clean as it should have been.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena
Knut Stolze wrote: Jean-David Beyer wrote:
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
EXEC SQL BEGIN DECLARE SECTION; <---<<< char dbName[DB_DB2N_SIZE + 1]; | "A" EXEC SQL END DECLARE SECTION; <---<<<
_connected = false; _dbName = "";
if(db_name.empty()) { cerr << "dbBase(" << db_name << "): db_name missing." << endl; exit(EXIT_FAILURE); } if(db_name.size() > DB_DB2N_SIZE) { cerr << "dbBase(" << db_name << "): db_name too long." << endl; exit(EXIT_FAILURE); } (void) strncpy(dbName, db_name.c_str(), DB_DB2N_SIZE); dbName[DB_DB2N_SIZE] = EOS;
// Connect to database. EXEC SQL CONNECT TO :dbName; <---<<< "B"
The stuff marked "A" goes right through the preprocessor and compiler, but the line marked "B" chokes as follows:
dbBase.i: In constructor `dbBase::dbBase(const string&)': dbBase.i:9122: `NULL' undeclared (first use this function) dbBase.i:9122: (Each undeclared identifier is reported only once for each function it appears in.) make: *** [dbBase.o] Error 1
Here is dbBase.i line 9122"
EXEC SQL CONNECT TO :dbName;
I cannot go on until I fix this problem (that appears in almost every function of this class, and I assume for all other classes as well.
How exactly do you do the "precompile"?
Like this:
trillian:jdbeyer[~/stocks/src]$ make dbBase.o
/opt/IBM/db2/V8.1/bin/db2 CONNECT TO stock
Database Connection Information
Database server = DB2/LINUX 8.1.5
SQL authorization ID = JDBEYER
Local database alias = STOCK
/opt/IBM/db2/V8.1/bin/db2 PREP dbBase.sqC DEGREE 1 ISOLATION RS QUERYOPT 2
EXPLAIN NO EXPLSNAP NO PREPROCESSOR \"g++296 -x c++ -o dbBase.i -E -P
-I/home/jdbeyer/include -I/home/jdbeyer/stocks/include
-I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include \" bindfile
LINE MESSAGES FOR dbBase.sqC
------ --------------------------------------------------------------------
SQL0060W The "C++" precompiler is in progress.
SQL4017W Preprocessing has completed successfully.
SQL4018W Starting to process the preprocessed file
"/home/jdbeyer/stocks/src/dbBase.i".
SQL4019W Completed processing the preprocessed file
"dbBase.i".
SQL0091W Precompilation or binding was ended with "0"
errors and "0" warnings.
/opt/IBM/db2/V8.1/bin/db2 BIND dbBase.bnd
LINE MESSAGES FOR dbBase.bnd
------ --------------------------------------------------------------------
SQL0061W The binder is in progress.
SQL0091N Binding was ended with "0" errors and "0" warnings.
/opt/IBM/db2/V8.1/bin/db2 DISCONNECT stock
DB20000I The SQL DISCONNECT command completed successfully.
/opt/IBM/db2/V8.1/bin/db2 TERMINATE
DB20000I The TERMINATE command completed successfully.
/usr/bin/g++296 -c -g -mcpu=i686 -march=i686 -O2 -DNULL=0 <---<<<
-I/home/jdbeyer/include -I/home/jdbeyer/stocks/include
-I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include dbBase.C I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that
expands all the Embedded SQL) generates .C files with no #include
statements in it, but with NULL strings in it, there is no way the g++
compiler can deal with it. Yet if it is a bug in the pre-compiler, surely
I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296
compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do
with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L); It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted after all macro expansion is done by
the pre-compiler. So it is too late. I would call this a bug, but it
cannot be as it implies that I am the first person to try to compile C++
with Embedded SQL, and I am not vain enough to believe that. Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code.
Are you implying I should write my own precompiler to convert C++ with
embedded SQL into the transmografied code ultimately delivered to the g++
compiler? I cannot believe you are serious. I would need to know the API
interface for these functions and I cannot find them documented anywhere. For all my things, I wrote a small Perl script that replaces the macros in the host variable definitions in a file with the extension .SQX, generates a .SQC and that is given to DB2 prep to do its job.
In addition to this fatal error, I am getting lots of warning messages I am not used to, such as:
[snip] I don't see why the warnings to show deprecated uses of functions would be relevant to the warnings shown above. What's the code in line 5433 or 5607 where the compiler complains?
p.s: My experience is that newer compilers often raise new warnings/errors because the old code is not as clean as it should have been.
Yes: I got rid of the warnings by using the 2.96 compiler instead of the
3.2.3 compiler that is default on this machine. They have what seems to be
a totally undocumented alternate compiler, gcc296 and g++296 that are
equivalent to the Red Hat Linux 7.3 compiler, and diddling the makefile to
use it gets rid of all those warnings.
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 14:40:00 up 10 days, 15:22, 7 users, load average: 4.26, 4.16, 3.99
Knut Stolze wrote: Jean-David Beyer wrote:
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
EXEC SQL BEGIN DECLARE SECTION; <---<<< char dbName[DB_DB2N_SIZE + 1]; | "A" EXEC SQL END DECLARE SECTION; <---<<<
_connected = false; _dbName = "";
if(db_name.empty()) { cerr << "dbBase(" << db_name << "): db_name missing." << endl; exit(EXIT_FAILURE); } if(db_name.size() > DB_DB2N_SIZE) { cerr << "dbBase(" << db_name << "): db_name too long." << endl; exit(EXIT_FAILURE); } (void) strncpy(dbName, db_name.c_str(), DB_DB2N_SIZE); dbName[DB_DB2N_SIZE] = EOS;
// Connect to database. EXEC SQL CONNECT TO :dbName; <---<<< "B"
The stuff marked "A" goes right through the preprocessor and compiler, but the line marked "B" chokes as follows:
dbBase.i: In constructor `dbBase::dbBase(const string&)': dbBase.i:9122: `NULL' undeclared (first use this function) dbBase.i:9122: (Each undeclared identifier is reported only once for each function it appears in.) make: *** [dbBase.o] Error 1
Here is dbBase.i line 9122"
EXEC SQL CONNECT TO :dbName;
I cannot go on until I fix this problem (that appears in almost every function of this class, and I assume for all other classes as well.
How exactly do you do the "precompile"?
Like this:
trillian:jdbeyer[~/stocks/src]$ make dbBase.o
/opt/IBM/db2/V8.1/bin/db2 CONNECT TO stock
Database Connection Information
Database server = DB2/LINUX 8.1.5
SQL authorization ID = JDBEYER
Local database alias = STOCK
/opt/IBM/db2/V8.1/bin/db2 PREP dbBase.sqC DEGREE 1 ISOLATION RS QUERYOPT 2
EXPLAIN NO EXPLSNAP NO PREPROCESSOR \"g++296 -x c++ -o dbBase.i -E -P
-I/home/jdbeyer/include -I/home/jdbeyer/stocks/include
-I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include \" bindfile
LINE MESSAGES FOR dbBase.sqC
------ --------------------------------------------------------------------
SQL0060W The "C++" precompiler is in progress.
SQL4017W Preprocessing has completed successfully.
SQL4018W Starting to process the preprocessed file
"/home/jdbeyer/stocks/src/dbBase.i".
SQL4019W Completed processing the preprocessed file
"dbBase.i".
SQL0091W Precompilation or binding was ended with "0"
errors and "0" warnings.
/opt/IBM/db2/V8.1/bin/db2 BIND dbBase.bnd
LINE MESSAGES FOR dbBase.bnd
------ --------------------------------------------------------------------
SQL0061W The binder is in progress.
SQL0091N Binding was ended with "0" errors and "0" warnings.
/opt/IBM/db2/V8.1/bin/db2 DISCONNECT stock
DB20000I The SQL DISCONNECT command completed successfully.
/opt/IBM/db2/V8.1/bin/db2 TERMINATE
DB20000I The TERMINATE command completed successfully.
/usr/bin/g++296 -c -g -mcpu=i686 -march=i686 -O2 -DNULL=0 <---<<<
-I/home/jdbeyer/include -I/home/jdbeyer/stocks/include
-I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include dbBase.C I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that
expands all the Embedded SQL) generates .C files with no #include
statements in it, but with NULL strings in it, there is no way the g++
compiler can deal with it. Yet if it is a bug in the pre-compiler, surely
I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296
compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do
with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L); It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted after all macro expansion is done by
the pre-compiler. So it is too late. I would call this a bug, but it
cannot be as it implies that I am the first person to try to compile C++
with Embedded SQL, and I am not vain enough to believe that. Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code.
Are you implying I should write my own precompiler to convert C++ with
embedded SQL into the transmografied code ultimately delivered to the g++
compiler? I cannot believe you are serious. I would need to know the API
interface for these functions and I cannot find them documented anywhere. For all my things, I wrote a small Perl script that replaces the macros in the host variable definitions in a file with the extension .SQX, generates a .SQC and that is given to DB2 prep to do its job.
In addition to this fatal error, I am getting lots of warning messages I am not used to, such as:
[snip] I don't see why the warnings to show deprecated uses of functions would be relevant to the warnings shown above. What's the code in line 5433 or 5607 where the compiler complains?
p.s: My experience is that newer compilers often raise new warnings/errors because the old code is not as clean as it should have been.
Yes: I got rid of the warnings by using the 2.96 compiler instead of the
3.2.3 compiler that is default on this machine. They have what seems to be
a totally undocumented alternate compiler, gcc296 and g++296 that are
equivalent to the Red Hat Linux 7.3 compiler, and diddling the makefile to
use it gets rid of all those warnings.
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 14:40:00 up 10 days, 15:22, 7 users, load average: 4.26, 4.16, 3.99
Jean-David Beyer wrote: Knut Stolze wrote: Jean-David Beyer wrote:
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
I would add this in each and every function/method that uses embedded SQL.
It avoids global variables and can be especially problematic in threaded
applications. How exactly do you do the "precompile"?
Like this:
trillian:jdbeyer[~/stocks/src]$ make dbBase.o /opt/IBM/db2/V8.1/bin/db2 CONNECT TO stock Database Connection Information Database server = DB2/LINUX 8.1.5 SQL authorization ID = JDBEYER Local database alias = STOCK /opt/IBM/db2/V8.1/bin/db2 PREP dbBase.sqC DEGREE 1 ISOLATION RS QUERYOPT 2 EXPLAIN NO EXPLSNAP NO PREPROCESSOR \"g++296 -x c++ -o dbBase.i -E -P -I/home/jdbeyer/include -I/home/jdbeyer/stocks/include -I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include \" bindfile I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that expands all the Embedded SQL) generates .C files with no #include statements in it, but with NULL strings in it, there is no way the g++ compiler can deal with it. Yet if it is a bug in the pre-compiler, surely I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296 compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L); It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted after all macro expansion is done by the pre-compiler. So it is too late.
That is, strictly spoken, not correct. Using the C++ precompiler in the way
you are doing it causes the "#include" directives to be processed and after
that, they are gone.
Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the
file so that the subsequent pre-compile/compile phase can resolve the
"NULL"s - that's what you already did.
(b) Replace the macros before the db2 prep starts (see my explanation below)
(c) write the "#include <stdlib.h> in such a way that it will NOT be
expanded by the DB2 precompiler during the precompile phase done with gcc.
This could be done so, I think:
source file:
-----------------
INCLUDE <stdlib.h>
-----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Note that (C) only works as described if your precompiler is not working
recursively.
I would call this a bug, but it cannot be as it implies that I am the first person to try to compile C++ with Embedded SQL, and I am not vain enough to believe that.
If you want to get this behavior changed, then you should contact IBM
support and open a PMR. Here we can give you suggestions how to work
around the issue... Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code.
Are you implying I should write my own precompiler to convert C++ with embedded SQL into the transmografied code ultimately delivered to the g++ compiler? I cannot believe you are serious. I would need to know the API interface for these functions and I cannot find them documented anywhere.
What APIs do you mean? I don't quite follow you there.
The script I use parses a given header file (that has to adhere to some
restrictions), finds all "#define" directives and their replacement, and
then it goes through the .SQX files, replaces the macros with their values
and writes the results to a .SQC file which is then given to "db2 prep" and
no further PRECOMPILE option is used. The advantage to get the correct
line numbers in the debug output of the compiled file was the most
important factor in using that approach. The script is just 100 lines
long.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena
Jean-David Beyer wrote: Knut Stolze wrote: Jean-David Beyer wrote:
E.g., here is the beginning of a constructor, for example:
dbBase:: // Custom constructor dbBase(const string& db_name) {
You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
I would add this in each and every function/method that uses embedded SQL.
It avoids global variables and can be especially problematic in threaded
applications. How exactly do you do the "precompile"?
Like this:
trillian:jdbeyer[~/stocks/src]$ make dbBase.o /opt/IBM/db2/V8.1/bin/db2 CONNECT TO stock Database Connection Information Database server = DB2/LINUX 8.1.5 SQL authorization ID = JDBEYER Local database alias = STOCK /opt/IBM/db2/V8.1/bin/db2 PREP dbBase.sqC DEGREE 1 ISOLATION RS QUERYOPT 2 EXPLAIN NO EXPLSNAP NO PREPROCESSOR \"g++296 -x c++ -o dbBase.i -E -P -I/home/jdbeyer/include -I/home/jdbeyer/stocks/include -I/usr/include/g++-3 -I/dataA/db2inst1/sqllib/include \" bindfile I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that expands all the Embedded SQL) generates .C files with no #include statements in it, but with NULL strings in it, there is no way the g++ compiler can deal with it. Yet if it is a bug in the pre-compiler, surely I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296 compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L); It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted after all macro expansion is done by the pre-compiler. So it is too late.
That is, strictly spoken, not correct. Using the C++ precompiler in the way
you are doing it causes the "#include" directives to be processed and after
that, they are gone.
Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the
file so that the subsequent pre-compile/compile phase can resolve the
"NULL"s - that's what you already did.
(b) Replace the macros before the db2 prep starts (see my explanation below)
(c) write the "#include <stdlib.h> in such a way that it will NOT be
expanded by the DB2 precompiler during the precompile phase done with gcc.
This could be done so, I think:
source file:
-----------------
INCLUDE <stdlib.h>
-----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Note that (C) only works as described if your precompiler is not working
recursively.
I would call this a bug, but it cannot be as it implies that I am the first person to try to compile C++ with Embedded SQL, and I am not vain enough to believe that.
If you want to get this behavior changed, then you should contact IBM
support and open a PMR. Here we can give you suggestions how to work
around the issue... Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code.
Are you implying I should write my own precompiler to convert C++ with embedded SQL into the transmografied code ultimately delivered to the g++ compiler? I cannot believe you are serious. I would need to know the API interface for these functions and I cannot find them documented anywhere.
What APIs do you mean? I don't quite follow you there.
The script I use parses a given header file (that has to adhere to some
restrictions), finds all "#define" directives and their replacement, and
then it goes through the .SQX files, replaces the macros with their values
and writes the results to a .SQC file which is then given to "db2 prep" and
no further PRECOMPILE option is used. The advantage to get the correct
line numbers in the debug output of the compiled file was the most
important factor in using that approach. The script is just 100 lines
long.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena
Knut Stolze wrote: Jean-David Beyer wrote:
[snip]You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
I would add this in each and every function/method that uses embedded SQL. It avoids global variables and can be especially problematic in threaded applications.
At the time I wrote the programs (for DB2 V6.1 for Red Hat Linux 6.0,
IIRC), once was enough. My programs are not threaded. I have found that
Linux process creation and destruction are efficient enough to use
separate processes instead of threading (recall that memory can be shared
if it is read-only as text segments are), so the total cost is low. As I
understand it, the main _benefit_ to running threaded applications is so
that the different threads can share memory without explicitly setting up
a shared memory segment. And for me, this shared memory is normaly quite
the opposite of a _benefit_, though I can imagine occassions where it
might be useful.
[snip] I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that expands all the Embedded SQL) generates .C files with no #include statements in it, but with NULL strings in it, there is no way the g++ compiler can deal with it. Yet if it is a bug in the pre-compiler, surely I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296 compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L);
It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted _after_ all macro expansion is done by the pre-compiler. So it is too late.
That is, strictly spoken, not correct. Using the C++ precompiler in the way you are doing it causes the "#include" directives to be processed and after that, they are gone.
The way I am doing is right out of the V6.1 books (that I have only on
CD-ROM for V8.1) that have worked for years. I cannot find this in the
V8.1 stuff (though it may well be there: I am just not familiar with the
documentation which has been reorganized and I find it hard to find
things). In any case, I cannot compile the example programs they have
supplied because of the same problem.
And it _should be OK_ that they are gone. It the precompiler chooses to
add NULLs into the program, it better find a way to get them defined, as
it used to do in V6.1.
It seems to me that someone changed the precompiler to invoke sqlasetdata
in V8.1 instead of sqlasetd that was used in V6.1., and the change to the
precompiler was hastily done and no provision was made to get the NULL
expanded. All the precompiler needed to do was put out a 0 instead of a
NULL. There are no other macros in the *.C files produced. Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the file so that the subsequent pre-compile/compile phase can resolve the "NULL"s - that's what you already did.
This will not work any better than including a #include (file with NULL
defined in it), since that has all been expanded long since.
(b) Replace the macros before the db2 prep starts (see my explanation below)
I do not see how, other than in (C), to replace the macros since they are
not there in the code I write; they are introduced by the DB2 precompiler.
(c) write the "#include <stdlib.h> in such a way that it will NOT be expanded by the DB2 precompiler during the precompile phase done with gcc. This could be done so, I think:
source file: ----------------- INCLUDE <stdlib.h> -----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Why is that any better than
... -D'NULL=0' ...
that I already guessed? What I do not know, since I cannot find any
documentation for the
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
function is what the fifth argument is for. I do not know what the other
arguments are for either, but those are the same as V6.1 that works.
Note in the IBM sample programs, they have no -D in the command line for
the g++ compiler after the precompiler has run and the NULLs put in. Note that (C) only works as described if your precompiler is not working recursively.
I would call this a bug, but it cannot be as it implies that I am the first person to try to compile C++ with Embedded SQL, and I am not vain enough to believe that.
If you want to get this behavior changed, then you should contact IBM support and open a PMR. Here we can give you suggestions how to work around the issue...
I do not know if I want the behavior changed or not, though I think I do.
I would settle for having it documented that you must have a -D'NULL=0" in
the command to the compile step. I have since built all libraries and most
client programs, and they all work. So I infer defining NULL to be 0 is
correct.
It is gratifying that V8.1.5 on this machine is so very fast. Partly,
because the hardware is so fast, partly because with RHEL 3 ES I can run
DMS instead of SMS mode, partly because I have four hard drive spindles
and can organize things better than with SMS on two spindles. A 10-hour
job (major part of the initial populating of the database now takes 57
minutes 43 seconds.Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code. Are you implying I should write my own precompiler to convert C++ with embedded SQL into the transmografied code ultimately delivered to the g++ compiler? I cannot believe you are serious. I would need to know the API interface for these functions and I cannot find them documented anywhere.
What APIs do you mean? I don't quite follow you there.
The functions that really get invoked to get SQL done. Below, the ones
called sqlastrt, sqlaaloc, sqlasetdata, sqlacall, and sqlastop, as well as
the definition of the structure built up in qla_setdata_list sql_setdlist.
Now, of course, I should never need to know any of this, but I do need to
know it if I can intelligently pick a value for the NULL that I should not
have to define myself.
When you write embedded SQL in a C++ (or a C, I believe) program, it looks
like this:
EXEC SQL BEGIN DECLARE SECTION;
char db_name[DB_NAME_SIZE+1];
EXEC SQL END DECLARE SECTION;
This is just so that, in this case, db_name can be used as a variable
inside embedded SQL code later in a function. Like this:
EXEC SQL DISCONNECT :db_name;
The colon warns the precompiler that db_name is a variable inside a C++
program and not a literal field name in a tuple.
Now the rest of the program may have #define and #include in it (highly
likely, of course).
When building such a program, the first thing that happens is that the C++
preprocessor is invoked to expand all the #include, #define, #ifdef, and
so on. This must be done so that the C++ precompiler that converts the
Embedded SQL need not include the C++ preprocessor functionality inside
itself. And the preprocessing cannot be deferred because then the
precompiler would not know what code is included and what code is not, nor
would it know the size of arrays, and a lot else. A consequence of this,
however, is that all C++ preprocessing is done, so all source text related
to it is removed. When the C++ preprocessor is complete, there is a .i
file that is equivalent to the .sqC file I originally wrote, but with all
the preprocessing done.
The second thing that happens is that the SQL Precompiler runs and it
replaces all the Embedded SQL stuff (the stuff related to the EXEC SQL
lines) in the .i file with equivalent code to produce a .C file. So the
EXEC SQL DISCONNECT :db_name;
line is replaced by:
/*
EXEC SQL DISCONNECT :db_name;
*/
{
#line 4433 "dbBase.i"
sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
#line 4433 "dbBase.i"
sqlaaloc(2,1,2,0L);
{
struct sqla_setdata_list sql_setdlist[1];
#line 4433 "dbBase.i"
sql_setdlist[0].sqltype = 460; sql_setdlist[0].sqllen = 41;
#line 4433 "dbBase.i"
sql_setdlist[0].sqldata = (void*)db_name;
#line 4433 "dbBase.i"
sql_setdlist[0].sqlind = 0L;
#line 4433 "dbBase.i"
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
}
#line 4433 "dbBase.i"
sqlacall((unsigned short)40,23,2,0,0L);
#line 4433 "dbBase.i"
sqlastop(0L);
}
The third thing that happens is that the g++ compiler is called to compile
the .C file into a .o file. And it is here that the problem exists, since
there are _no_ C++ preprocessor statements in the .C file. The SQL
precompiler should not have put the NULLs in there, since there is no
mechanism to get them expanded. The script I use parses a given header file (that has to adhere to some restrictions), finds all "#define" directives and their replacement, and then it goes through the .SQX files, replaces the macros with their values and writes the results to a .SQC file which is then given to "db2 prep" and no further PRECOMPILE option is used. The advantage to get the correct line numbers in the debug output of the compiled file was the most important factor in using that approach. The script is just 100 lines long.
But db2 prep removes all the macros and replaces them with their values.
And then IT IS TOO LATE because the precompiler sticks NULLs into the file
and the final g++ step cannot expand them!
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 07:35:00 up 12 days, 8:18, 5 users, load average: 4.10, 4.15, 4.07
Knut Stolze wrote: Jean-David Beyer wrote:
[snip]You might want to include this:
EXEC SQL INCLUDE SQLCA;
Trouble is, that is already in the file.
I would add this in each and every function/method that uses embedded SQL. It avoids global variables and can be especially problematic in threaded applications.
At the time I wrote the programs (for DB2 V6.1 for Red Hat Linux 6.0,
IIRC), once was enough. My programs are not threaded. I have found that
Linux process creation and destruction are efficient enough to use
separate processes instead of threading (recall that memory can be shared
if it is read-only as text segments are), so the total cost is low. As I
understand it, the main _benefit_ to running threaded applications is so
that the different threads can share memory without explicitly setting up
a shared memory segment. And for me, this shared memory is normaly quite
the opposite of a _benefit_, though I can imagine occassions where it
might be useful.
[snip] I saw the same error once when I used the compiler's precompiler to resolve macros in host variable definitions as you have. The precompiler will then include <stdlib.h> and expand all macros, including the #define for NULL. Later, the DB2 precompiler pastes some function calls into the generated C code where "NULL" is used to pass a NULL pointer. That NULL can't be expanded anymore because <stdlib.h> is not included again.
Exactly what is happening. Since the the pre-compiler (the one that expands all the Embedded SQL) generates .C files with no #include statements in it, but with NULL strings in it, there is no way the g++ compiler can deal with it. Yet if it is a bug in the pre-compiler, surely I would not be the first person to try to compile C++ with Embedded SQL in it.
The <---<<< above, where I force a definition of NULL into the g++296 compiler makes the error message go away and makes instances of
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
turn into
sqlasetdata(2,0,1,sql_setdlist,0,0L);
but it scares me because I have no idea what sqlasetdata is supposed to do with that argument. In V6.1, the same code generates
sqlasetd(2,0,1,sql_setdlist,0L);
It might be that the above shown "EXEC SQL INCLUDE SQLCA" already solves your problem. If not, then you should provide some sort if directive to the DB2 precompiler in such a way that NULL will be resolved (or that <stdlib.h> is included again).
Trouble is, the NULL s are inserted _after_ all macro expansion is done by the pre-compiler. So it is too late.
That is, strictly spoken, not correct. Using the C++ precompiler in the way you are doing it causes the "#include" directives to be processed and after that, they are gone.
The way I am doing is right out of the V6.1 books (that I have only on
CD-ROM for V8.1) that have worked for years. I cannot find this in the
V8.1 stuff (though it may well be there: I am just not familiar with the
documentation which has been reorganized and I find it hard to find
things). In any case, I cannot compile the example programs they have
supplied because of the same problem.
And it _should be OK_ that they are gone. It the precompiler chooses to
add NULLs into the program, it better find a way to get them defined, as
it used to do in V6.1.
It seems to me that someone changed the precompiler to invoke sqlasetdata
in V8.1 instead of sqlasetd that was used in V6.1., and the change to the
precompiler was hastily done and no provision was made to get the NULL
expanded. All the precompiler needed to do was put out a 0 instead of a
NULL. There are no other macros in the *.C files produced. Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the file so that the subsequent pre-compile/compile phase can resolve the "NULL"s - that's what you already did.
This will not work any better than including a #include (file with NULL
defined in it), since that has all been expanded long since.
(b) Replace the macros before the db2 prep starts (see my explanation below)
I do not see how, other than in (C), to replace the macros since they are
not there in the code I write; they are introduced by the DB2 precompiler.
(c) write the "#include <stdlib.h> in such a way that it will NOT be expanded by the DB2 precompiler during the precompile phase done with gcc. This could be done so, I think:
source file: ----------------- INCLUDE <stdlib.h> -----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Why is that any better than
... -D'NULL=0' ...
that I already guessed? What I do not know, since I cannot find any
documentation for the
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
function is what the fifth argument is for. I do not know what the other
arguments are for either, but those are the same as V6.1 that works.
Note in the IBM sample programs, they have no -D in the command line for
the g++ compiler after the precompiler has run and the NULLs put in. Note that (C) only works as described if your precompiler is not working recursively.
I would call this a bug, but it cannot be as it implies that I am the first person to try to compile C++ with Embedded SQL, and I am not vain enough to believe that.
If you want to get this behavior changed, then you should contact IBM support and open a PMR. Here we can give you suggestions how to work around the issue...
I do not know if I want the behavior changed or not, though I think I do.
I would settle for having it documented that you must have a -D'NULL=0" in
the command to the compile step. I have since built all libraries and most
client programs, and they all work. So I infer defining NULL to be 0 is
correct.
It is gratifying that V8.1.5 on this machine is so very fast. Partly,
because the hardware is so fast, partly because with RHEL 3 ES I can run
DMS instead of SMS mode, partly because I have four hard drive spindles
and can organize things better than with SMS on two spindles. A 10-hour
job (major part of the initial populating of the database now takes 57
minutes 43 seconds.Either way, I wouldn't use the compiler's precompiler because it garbles all the line numbers (at the latest after the DB2 prep was ran) and debugging this stuff will be a mess because the debugger has the incorrect line information and just shows the wrong things when you step through the code. Are you implying I should write my own precompiler to convert C++ with embedded SQL into the transmografied code ultimately delivered to the g++ compiler? I cannot believe you are serious. I would need to know the API interface for these functions and I cannot find them documented anywhere.
What APIs do you mean? I don't quite follow you there.
The functions that really get invoked to get SQL done. Below, the ones
called sqlastrt, sqlaaloc, sqlasetdata, sqlacall, and sqlastop, as well as
the definition of the structure built up in qla_setdata_list sql_setdlist.
Now, of course, I should never need to know any of this, but I do need to
know it if I can intelligently pick a value for the NULL that I should not
have to define myself.
When you write embedded SQL in a C++ (or a C, I believe) program, it looks
like this:
EXEC SQL BEGIN DECLARE SECTION;
char db_name[DB_NAME_SIZE+1];
EXEC SQL END DECLARE SECTION;
This is just so that, in this case, db_name can be used as a variable
inside embedded SQL code later in a function. Like this:
EXEC SQL DISCONNECT :db_name;
The colon warns the precompiler that db_name is a variable inside a C++
program and not a literal field name in a tuple.
Now the rest of the program may have #define and #include in it (highly
likely, of course).
When building such a program, the first thing that happens is that the C++
preprocessor is invoked to expand all the #include, #define, #ifdef, and
so on. This must be done so that the C++ precompiler that converts the
Embedded SQL need not include the C++ preprocessor functionality inside
itself. And the preprocessing cannot be deferred because then the
precompiler would not know what code is included and what code is not, nor
would it know the size of arrays, and a lot else. A consequence of this,
however, is that all C++ preprocessing is done, so all source text related
to it is removed. When the C++ preprocessor is complete, there is a .i
file that is equivalent to the .sqC file I originally wrote, but with all
the preprocessing done.
The second thing that happens is that the SQL Precompiler runs and it
replaces all the Embedded SQL stuff (the stuff related to the EXEC SQL
lines) in the .i file with equivalent code to produce a .C file. So the
EXEC SQL DISCONNECT :db_name;
line is replaced by:
/*
EXEC SQL DISCONNECT :db_name;
*/
{
#line 4433 "dbBase.i"
sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
#line 4433 "dbBase.i"
sqlaaloc(2,1,2,0L);
{
struct sqla_setdata_list sql_setdlist[1];
#line 4433 "dbBase.i"
sql_setdlist[0].sqltype = 460; sql_setdlist[0].sqllen = 41;
#line 4433 "dbBase.i"
sql_setdlist[0].sqldata = (void*)db_name;
#line 4433 "dbBase.i"
sql_setdlist[0].sqlind = 0L;
#line 4433 "dbBase.i"
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
}
#line 4433 "dbBase.i"
sqlacall((unsigned short)40,23,2,0,0L);
#line 4433 "dbBase.i"
sqlastop(0L);
}
The third thing that happens is that the g++ compiler is called to compile
the .C file into a .o file. And it is here that the problem exists, since
there are _no_ C++ preprocessor statements in the .C file. The SQL
precompiler should not have put the NULLs in there, since there is no
mechanism to get them expanded. The script I use parses a given header file (that has to adhere to some restrictions), finds all "#define" directives and their replacement, and then it goes through the .SQX files, replaces the macros with their values and writes the results to a .SQC file which is then given to "db2 prep" and no further PRECOMPILE option is used. The advantage to get the correct line numbers in the debug output of the compiled file was the most important factor in using that approach. The script is just 100 lines long.
But db2 prep removes all the macros and replaces them with their values.
And then IT IS TOO LATE because the precompiler sticks NULLs into the file
and the final g++ step cannot expand them!
--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 07:35:00 up 12 days, 8:18, 5 users, load average: 4.10, 4.15, 4.07
Jean-David Beyer wrote: Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the file so that the subsequent pre-compile/compile phase can resolve the "NULL"s - that's what you already did. This will not work any better than including a #include (file with NULL defined in it), since that has all been expanded long since.
I meant that this macro is inserted into the file by the precompiler used in
the PRECOMPILE option. (b) Replace the macros before the db2 prep starts (see my explanation below)
I do not see how, other than in (C), to replace the macros since they are not there in the code I write; they are introduced by the DB2 precompiler.
I was referring to your macros that you used in the host variables. If you
replace them before the "db2 prep" is done, then you don't need the
PRECOMPILE option in the first place and the whole issue vanishes. (c) write the "#include <stdlib.h> in such a way that it will NOT be expanded by the DB2 precompiler during the precompile phase done with gcc. This could be done so, I think:
source file: ----------------- INCLUDE <stdlib.h> -----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Why is that any better than
... -D'NULL=0' ...
that I already guessed?
Your "NULL=0" (I would rather use -DNULL="((void *)0)" ) is the option (A) I
outlined above.
What I do not know, since I cannot find any documentation for the
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
function is what the fifth argument is for. I do not know what the other arguments are for either, but those are the same as V6.1 that works.
That is an internal function and you do not need to worry about it. Hence,
it is not documented. You should never be in the situation to call the
function yourself. What APIs do you mean? I don't quite follow you there.
The functions that really get invoked to get SQL done. Below, the ones called sqlastrt, sqlaaloc, sqlasetdata, sqlacall, and sqlastop, as well as the definition of the structure built up in qla_setdata_list sql_setdlist. Now, of course, I should never need to know any of this, but I do need to know it if I can intelligently pick a value for the NULL that I should not have to define myself.
NULL is a null pointer, and it is even defined by the C standard (if I
remember correctly) as "(void *)0". So there is not much more you need to
know about it, is there?
When you write embedded SQL in a C++ (or a C, I believe) program, it looks like this:
EXEC SQL BEGIN DECLARE SECTION; char db_name[DB_NAME_SIZE+1]; EXEC SQL END DECLARE SECTION;
This is just so that, in this case, db_name can be used as a variable inside embedded SQL code later in a function. Like this:
EXEC SQL DISCONNECT :db_name;
The colon warns the precompiler that db_name is a variable inside a C++ program and not a literal field name in a tuple.
Now the rest of the program may have #define and #include in it (highly likely, of course).
When building such a program, the first thing that happens is that the C++ preprocessor is invoked to expand all the #include, #define, #ifdef, and so on.
[...] The second thing that happens is that the SQL Precompiler runs and it replaces all the Embedded SQL stuff (the stuff related to the EXEC SQL lines) in the .i file with equivalent code to produce a .C file. So the
[...] The third thing that happens is that the g++ compiler is called to compile the .C file into a .o file.
That depends on your specific build process. For your approach, the
description is correct. In my cases, I do use the Perl script to replace
only a certain, well-defined set of macros and I do not the full C/C++
preprocessing. So the resulting file is C including preprocesser
directives. (Note that your third step includes a C preprocessing - it is
just that there is nothing left to do.) The script I use parses a given header file (that has to adhere to some restrictions), finds all "#define" directives and their replacement, and then it goes through the .SQX files, replaces the macros with their values and writes the results to a .SQC file which is then given to "db2 prep" and no further PRECOMPILE option is used. The advantage to get the correct line numbers in the debug output of the compiled file was the most important factor in using that approach. The script is just 100 lines long. But db2 prep removes all the macros and replaces them with their values. And then IT IS TOO LATE because the precompiler sticks NULLs into the file and the final g++ step cannot expand them!
I think there is a misunderstanding. In my approach, I have:
(1) replace some macros but do not do a full C/C++ preprocessing step; the
#include directives remain in the .sqc file (along with other macros)!
(2) run db2 prep to convert the SQL statements to C function calls
(3) compile the .c file (involving the actual C/C++ preprocessing step) and
compile everything to an .o file.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena
Jean-David Beyer wrote: Here are the options I see:
(a) Make sure that a macro "#define NULL ((void *)0)" is inserted into the file so that the subsequent pre-compile/compile phase can resolve the "NULL"s - that's what you already did. This will not work any better than including a #include (file with NULL defined in it), since that has all been expanded long since.
I meant that this macro is inserted into the file by the precompiler used in
the PRECOMPILE option. (b) Replace the macros before the db2 prep starts (see my explanation below)
I do not see how, other than in (C), to replace the macros since they are not there in the code I write; they are introduced by the DB2 precompiler.
I was referring to your macros that you used in the host variables. If you
replace them before the "db2 prep" is done, then you don't need the
PRECOMPILE option in the first place and the whole issue vanishes. (c) write the "#include <stdlib.h> in such a way that it will NOT be expanded by the DB2 precompiler during the precompile phase done with gcc. This could be done so, I think:
source file: ----------------- INCLUDE <stdlib.h> -----------------
db2 prep ... PRECOMPILE "g++296... -DINCLUDE="#include" ..."
Why is that any better than
... -D'NULL=0' ...
that I already guessed?
Your "NULL=0" (I would rather use -DNULL="((void *)0)" ) is the option (A) I
outlined above.
What I do not know, since I cannot find any documentation for the
sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
function is what the fifth argument is for. I do not know what the other arguments are for either, but those are the same as V6.1 that works.
That is an internal function and you do not need to worry about it. Hence,
it is not documented. You should never be in the situation to call the
function yourself. What APIs do you mean? I don't quite follow you there.
The functions that really get invoked to get SQL done. Below, the ones called sqlastrt, sqlaaloc, sqlasetdata, sqlacall, and sqlastop, as well as the definition of the structure built up in qla_setdata_list sql_setdlist. Now, of course, I should never need to know any of this, but I do need to know it if I can intelligently pick a value for the NULL that I should not have to define myself.
NULL is a null pointer, and it is even defined by the C standard (if I
remember correctly) as "(void *)0". So there is not much more you need to
know about it, is there?
When you write embedded SQL in a C++ (or a C, I believe) program, it looks like this:
EXEC SQL BEGIN DECLARE SECTION; char db_name[DB_NAME_SIZE+1]; EXEC SQL END DECLARE SECTION;
This is just so that, in this case, db_name can be used as a variable inside embedded SQL code later in a function. Like this:
EXEC SQL DISCONNECT :db_name;
The colon warns the precompiler that db_name is a variable inside a C++ program and not a literal field name in a tuple.
Now the rest of the program may have #define and #include in it (highly likely, of course).
When building such a program, the first thing that happens is that the C++ preprocessor is invoked to expand all the #include, #define, #ifdef, and so on.
[...] The second thing that happens is that the SQL Precompiler runs and it replaces all the Embedded SQL stuff (the stuff related to the EXEC SQL lines) in the .i file with equivalent code to produce a .C file. So the
[...] The third thing that happens is that the g++ compiler is called to compile the .C file into a .o file.
That depends on your specific build process. For your approach, the
description is correct. In my cases, I do use the Perl script to replace
only a certain, well-defined set of macros and I do not the full C/C++
preprocessing. So the resulting file is C including preprocesser
directives. (Note that your third step includes a C preprocessing - it is
just that there is nothing left to do.) The script I use parses a given header file (that has to adhere to some restrictions), finds all "#define" directives and their replacement, and then it goes through the .SQX files, replaces the macros with their values and writes the results to a .SQC file which is then given to "db2 prep" and no further PRECOMPILE option is used. The advantage to get the correct line numbers in the debug output of the compiled file was the most important factor in using that approach. The script is just 100 lines long. But db2 prep removes all the macros and replaces them with their values. And then IT IS TOO LATE because the precompiler sticks NULLs into the file and the final g++ step cannot expand them!
I think there is a misunderstanding. In my approach, I have:
(1) replace some macros but do not do a full C/C++ preprocessing step; the
#include directives remain in the .sqc file (along with other macros)!
(2) run db2 prep to convert the SQL statements to C function calls
(3) compile the .c file (involving the actual C/C++ preprocessing step) and
compile everything to an .o file.
--
Knut Stolze
Information Integration
IBM Germany / University of Jena This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: jrefactors |
last post by:
If the C programs have UNIX system calls such as fork(), alarm(),
etc.., we should call it UNIX programs, not traditional C programs?
We couldn't...
|
by: Darryl W. DeLao Jr |
last post by:
Im currently on red hat 7.3 running postgres. Everything is running fine.
Obviously, Im going to have to upgrade to RHEL 3 in order to receive...
|
by: Rob Mayo |
last post by:
I have a bunch of XSD files in my assembly as embedded content that are read out via reflection and streams. My app creates the XML on the fly, and I...
|
by: Jean-David Beyer |
last post by:
I have some programs running on Red Hat Linux 7.3 working with IBM DB2
V6.1 (with all the FixPacks) on my old machine.
I have just installed IBM...
|
by: Mark Denardo |
last post by:
I have a DLL that I created that contains a reference to an image file on my
hard drive and when I go to use that DLL in another program it...
|
by: Christopher Taylor |
last post by:
Has anyone been able to get python 2.4 to compile properly for x86_64 RHEL?
Respectfully,
Christopher Taylor
|
by: prakash.mirji |
last post by:
Hello,
I am trying to compile C++ code which uses rogue wave 9.0 classes on
RHEL
4.0. I use gnu g++ compiler to compile the code.
Compiler is...
|
by: John Murtari |
last post by:
Folks,
Trying to build php 4.4.6 and apache 1.3.37 on RHEL 4.
Each of them builds and installs okay, but when we start
apache we get:
Syntax...
|
by: mark.bergman |
last post by:
I am porting from Digital Unix to Linux (RHEL 4), and am seeing a
difference in the return value of glob().
Given a non-existant directory...
|
by: better678 |
last post by:
Question:
Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct?
Answer:
Java is an object-oriented...
|
by: teenabhardwaj |
last post by:
How would one discover a valid source for learning news, comfort, and help for engineering designs? Covering through piles of books takes a lot of...
|
by: CD Tom |
last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
|
by: jalbright99669 |
last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
|
by: Matthew3360 |
last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function.
Here is my code.
...
|
by: Matthew3360 |
last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
|
by: WisdomUfot |
last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
| |