Operating System - OpenVMS
1827458 Members
5642 Online
109965 Solutions
New Discussion

Compaq-C v6.5 and the behavior of #pragma extern_model comon_block byte

 
Glenn Wolf
Advisor

Compaq-C v6.5 and the behavior of #pragma extern_model comon_block byte

I have a mixed Fortran/C application that shares data through Fortran common blocks. I recently moved the development of this code from a system with OpenVMS 7.3-1 and Compaq C V6.2, to an OpenVMS 7.3.1 system with Compaq C V6.5. Under 6.2, setting the external model for the common blocks using "#pragma extern_model common_block byte" created a psect that matches the size of the Fortran common block. Under Compaq C V6.5, the psect is generated with a length extended to the next longword boundary. Thus I get the following diagnostic from the linker:
%LINK-E-NOIMGFIL, image file not created
%LINK-E-SHRPSCLNG, Psect SSPLIS_LOTINFOCOM has length of 6244648
in module TPSTATSLOTINFOSRV file ROOT:[PROJECTS.TPSTATS.TPC]TPCLIB.OLB;1
which exceeds length of 6244645 in shareable image DISK3:[PROMDEV05.PDB]LOTINF505.EXE;2
The declaration of the extern in C looks like:
#pragma extern_model save
#pragma extern_model common_block byte
extern Ssp_Lis_LotInfoCom_Struct SSPLIS_LOTINFOCOM; /* LotInfoCom global section */
#pragma extern_model restore

I have tried using the /psect_model=multilanguage switch as well to no effect.

Did the behavior of the #pragma extern_model common_block byte directive change between 6.2 and 6.5? How can I get these psects to match size-wise (other than padding the Fortran version)?

Thanks;

Glenn
3 REPLIES 3
John Gillings
Honored Contributor

Re: Compaq-C v6.5 and the behavior of #pragma extern_model comon_block byte

Glenn,

Most likely guess is the structures you're declaring in the psect are being aligned by the C compiler, with some fields being padded. Presumably the FORTRAN compiler isn't doing the same alignments and the PSECTs are ending up different sizes.

Get yourself a listing of both the FORTRAN and C structure declarations and make sure all the fields match up. If there are no other external dependencies, adjust one or other language so that all the fields are naturally aligned and match up correctly. If you have to conform to an existing layout, then play with C pragmas to make them fit correctly.

Perhaps:

#pragma __member_alignment _save
#pragma __nomember_alignment

/* declaration of the structure here...*/

#pragma __member_alignment __restore

A crucible of informative mistakes
Glenn Wolf
Advisor

Re: Compaq-C v6.5 and the behavior of #pragma extern_model comon_block byte

John:

Thanks for your help. These things I have already done, and the Compaq-C compiler V6.2 correctly sized the psect to match the Fortran common block size. The definition of the struct Ssp_Lis_LotInfoCom_Struct is bracketed with
#pragma member_alignment save
#pragma nomember_alignment

and

#pragma member_alignment restore

When I compile under Compaq-C V6.5, I get the %LINK-E-SHRPSCLNG diganostic. I used to get this under V6.2, until I added the #pragma extern_model common_block byte. That seems to be ineffective under 6.5.

If I build the code without linking it to the Fortran global section, it links correctly, and doing a printf("%d", sizeof(SSP_LIS_LOTINFOCOM)); yields the value 6244645, which is how long the Fortran declaration of the common block is (per the linker). So it looks like Compaq C V6.5 is padding out the psect to the next quadword (maybe octaword??) boundary.

Thanks;

Glenn
John Gillings
Honored Contributor

Re: Compaq-C v6.5 and the behavior of #pragma extern_model comon_block byte

Glenn,

A bit of research... this looks like a regression. The problem is that some languages (like BASIC, MACRO32 and FORTRAN) do their own PSECT layouts, resulting in exact size for the common block. Other languages let the GEM backend do it, resulting in a rounding up to the next octaword boundary. The C qualifier /PSECT_MODEL=MULTILANGUAGE and FORTRAN /ALIGN=COMMON=MULTILANGUAGE were supposed to fix that. Is your FORTRAN compiled with COMMON=MULTI?

If you have a case where it doesn't work, please package up the declarations into a simple reproducer and submit them to your local customer support centre (but first make sure you've tried it with the latest version of all compilers involved).

In the mean time, there's a fairly simple way to make sure the images are compatible. Create yourself a tiny C module that contains just the PSECT declaration and link that module with your FORTRAN shareable image. That way, no matter what the C compiler chooses to do, the PSECTs should be compatible. Since there's no executable code, it shouldn't affect anything else.
A crucible of informative mistakes