Code: Select all
ITS $ cc /version
VSI C V7.4-001 on OpenVMS IA64 V8.4-2L3
ITS $ cxx /version
VSI C++ V7.4-006 on OpenVMS IA64 V8.4-2L3
"VSI C++ V7.4-006 Release Notes for OpenVMS Integrity servers"
(SYS$HELP:CXX.RELEASE_NOTES) includes an example program intended to
show how "To use the LIB$INITIALIZE feature explicitly in either
C or C++". A (very) slightly edited version of that example is included
below as "lix.c". The comments therein say:
/* Compile with either C or C++ on Alpha or I64, link and run.
** The output is:
** In some_init_function.
** In some_other_init_function.
** In main.
*/
CC is happy enough:
its $ cc lix.c /obj = lix_cc
its $ link lix_cc
its $ run lix_cc
In some_init_function.
In some_other_init_function.
In main.
CXX complains, but the executable seems to work:
its $ cxx lix.c /obj = lix_cxx
extern void (* const unused_global_variable_2[])() =
.....................^
%CXX-W-ALIGNNOTSTD, Alignment specifed for extern model is less than the
alignment required for a global variable of this size under the
Itanium Software Conventions. Access to this variable may cause
alignment faults.
at line number 30 in file ITS$DKA0:[SMS.VSI.lix]lix.c;7
its $ cxxlink lix_cxx
%ILINK-W-COMPWARN, compilation warnings
module: LIX
file: ITS$DKA0:[SMS.VSI.lix]lix_cxx.OBJ;1
its $ run lix_cxx
In some_init_function.
In some_other_init_function.
In main.
"seems to work" is the critical phrase here.
So far as I know, the only good reason to expend the effort to use
LIB$INITIALIZE instead of just invoking an initialization function in
main() is to get DECC$ARGV_PARSE_STYLE set in time to be effective.
Sadly, it looks as if no one actually tried this with this example code.
When I modified the example program to do this one useful task, I was
disappointed. (Also confused, frustrated, exasperated, and a few other
things in turn.) In "lix2.c", I expanded "some_init_function()" to use
the usual decc$feature_set_value() (et al.) functions to set
DECC$ARGV_PARSE_STYLE:
its $ show proc /pars
[...]
Parse Style: Extended
its $ cc lix2.c /obj = lix2_cc
its $ link lix2_cc
its $ mcr sys$disk:[]lix2_cc UPPERlower
In some_init_function.
FEAT: >DECC$ARGV_PARSE_STYLE<
Feature init init state = -1, value = 0.
Feature new init state = 2, value = 1.
In some_other_init_function.
In main.
argv[ 1]: >upperlower<
The new code clearly gets executed, but, just as clearly, it has no
effect on the way argv[] is handled. There was no difference using CXX,
except for the warnings:
its $ cxx lix2.c /obj = lix2_cxx
extern void (* const unused_global_variable_2[])() =
.....................^
%CXX-W-ALIGNNOTSTD, Alignment specifed for extern model is less than the
alignment required for a global variable of this size under the
Itanium Software Conventions. Access to this variable may cause
alignment faults.
at line number 34 in file ITS$DKA0:[SMS.VSI.lix]lix2.c;8
its $ cxxlink lix2_cxx
%ILINK-W-COMPWARN, compilation warnings
module: LIX2
file: ITS$DKA0:[SMS.VSI.lix]lix2_cxx.OBJ;1
its $ mcr sys$disk:[]lix2_cxx UPPERlower
In some_init_function.
FEAT: >DECC$ARGV_PARSE_STYLE<
Feature init init state = -1, value = 0.
Feature new init state = 2, value = 1.
In some_other_init_function.
In main.
argv[ 1]: >upperlower<
Defining the logical name before running the program _does_ work, of
course:
ITS $ define /user_mode DECC$ARGV_PARSE_STYLE 1
ITS $ mcr sys$disk:[]lix2_cxx.exe UPPERlower
In some_init_function.
FEAT: >DECC$ARGV_PARSE_STYLE<
Feature init init state = 1, value = 1.
Feature new init state = 2, value = 1.
In some_other_init_function.
In main.
argv[ 1]: >UPPERlower<
After extensive bumbling, I found that disabling some of the printf()
diagnostics in some_init_function() (in "lix3.c") was helpful:
its $ cc lix3.c /obj = lix3_cc
its $ link lix3_cc
its $ mcr sys$disk:[]lix3_cc UPPERlower
Feature new init state = 2, value = 1.
Leaving some_init_function.
In some_other_init_function.
In main.
argv[ 1]: >UPPERlower<
Enabling them restores the bad behavior:
its $ cc lix3.c /obj = lix3d_cc /def = DIAG=1
its $ link lix3d_cc
its $ mcr sys$disk:[]lix3d_cc UPPERlower
In some_init_function.
FEAT: >DECC$ARGV_PARSE_STYLE<
Feature init init state = -1, value = 0.
Feature new init state = 2, value = 1.
Leaving some_init_function.
In some_other_init_function.
In main.
argv[ 1]: >upperlower<
A naive user might guess that doing I/O using printf() _before_
setting DECC$ARGV_PARSE_STYLE causes some CRTL initialization to occur
which closes the door on any possibility of getting
DECC$ARGV_PARSE_STYLE set in time to be effective. If so, then that
might be a fact worthy of documentation.
Another disappointment is that this change appears to be insufficient
to wring the desired result from CXX:
its $ cxx lix3.c /obj = lix3_cxx
extern void (* const unused_global_variable_2[])() =
.....................^
%CXX-W-ALIGNNOTSTD, Alignment specifed for extern model is less than the
alignment required for a global variable of this size under the
Itanium Software Conventions. Access to this variable may cause
alignment faults.
at line number 34 in file ITS$DKA0:[SMS.VSI.lix]lix3.c;5
its $ cxxlink lix3_cxx
%ILINK-W-COMPWARN, compilation warnings
module: LIX3
file: ITS$DKA0:[SMS.VSI.lix]lix3_cxx.OBJ;1
its $ mcr sys$disk:[]lix3_cxx UPPERlower
Feature new init state = 2, value = 1.
Leaving some_init_function.
In some_other_init_function.
In main.
argv[ 1]: >upperlower<
So:
1. The LIB$INITIALIZE example program in the CXX release notes has
some problems:
A. CXX warnings.
B. Excessive diagnostic I/O (I'd guess) which nicely reveals the
program activity, but renders it useless in the one case where
it's truly valuable.
C. It failed to show me how to get DECC$ARGV_PARSE_STYLE set in
time to be effective in a C++ program. (Which is how I got
started on this ordeal in the first place.)
Helpful (tested) advice would be appreciated.
My example programs should be attached.