473,489 Members | 2,492 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

I cannot compile embedded SQL in C++ programs with RHEL 3 ES.

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

Nov 12 '05 #1
10 4416
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
Nov 12 '05 #2
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
Nov 12 '05 #3
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

Nov 12 '05 #4
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

Nov 12 '05 #5
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
Nov 12 '05 #6
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
Nov 12 '05 #7
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

Nov 12 '05 #8
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

Nov 12 '05 #9
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
Nov 12 '05 #10
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
Nov 12 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
3398
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 compile the programs with system calls using VC++...
26
3005
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 updates, etc. Does anyone know of any problems with...
9
2915
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 want to validate it using the schema files...
0
582
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 DB2 V8.1 on this (new) machine running Red Hat...
5
9977
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 complains that it can't find it. (I'm using a relative...
1
1598
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
1
7149
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 not able to match the right type of parameters to...
3
4114
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 error on line 238 of...
8
2354
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 "/tmp/a", and the following line of code: result =...
0
7108
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6967
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7142
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7352
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5445
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3078
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3071
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1383
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
618
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.