|  |  HP C HP CUser's Guide for OpenVMS Systems
 
 5.4.12 #pragma linkage Directive  (I64 ONLY)
The
#pragma linkage
 directive behaves much the same on I64 systems as it does on OpenVMS 
 Alpha systems, with some important differences.
 
On I64 systems, the
#pragma linkage
 directive has the following formats:
 
  
    | #pragma linkage linkage-name = (characteristics)
 #pragma linkage_ia64 linkage-name = (characteristics)
 |  
 5.4.12.1 #pragma linkage Format
On I64 systems, the
#pragma linkage
 format of this directive accepts Alpha register names and conventions 
 and automatically maps them, where possible, to specific I64 registers. 
 So whenever HP C for I64 encounters a
#pragma linkage
 directive, it attempts to map the Alpha registers specified in the 
 linkage to corresponding I64 registers, and emits a SHOWMAPLINKAGE 
 informational message showing the I64 specific form of the directive,
#pragma linkage_ia64
, with the I64 register names that replaced the Alpha register names. 
The SHOWMAPLINKAGE message is suppressed under the
#pragma nostandard
 directive, normally used within system header files.
 
Code compiled on I64 systems that deliberately relies on the register 
mapping performed by
#pragma linkage
 should either ignore the SHOWMAPLINKAGE informational, or disable it.
 5.4.12.1.1 Register Mapping
Table 5-2 shows the mapping that HP C applies to the Alpha integer 
register names used in
#pragma linkage
 directives when they are encountered on an I64 system. Note that the 
 six standard parameter registers on Alpha (R16-R21) are mapped to the 
 first six (of eight) standard parameter registers on I64 systems, which 
 happen to be stacked registers (see Section 5.4.12.2).  
 
  Table 5-2 Integer Register Mapping
  
    | Alpha -> | I64 |  | Alpha -> | I64 |  
    | R0 | R8 |  | R16 | R32
      1 |  
    | R1 | R9 |  | R17 | R33
      1 |  
    | R2 | R28 |  | R18 | R34
      1 |  
    | R3 | R3 |  | R19 | R35
      1 |  
    | R4 | R4 |  | R20 | R36
      1 |  
    | R5 | R5 |  | R21 | R37
      1 |  
    | R6 | R6 |  | R22 | R22 |  
    | R7 | R7 |  | R23 | R23 |  
    | R8 | R26 |  | R24 | R24 |  
    | R9 | R27 |  | R25 | R25 |  
    | R10 | R10 |  | R26 | no mapping |  
    | R11 | R11 |  | R27 | no mapping |  
    | R12 | R30 |  | R28 | no mapping |  
    | R13 | R31 |  | R29 | R29 |  
    | R14 | R20 |  | R30 | R12 |  
    | R15 | R21 |  | R31 | R0 |  1In parameters or result; else ignored
 
 
 
Table 5-3 shows the mapping that HP C applies to the Alpha 
floating-point register names used in
#pragma linkage
directives when they are encountered on an I64 system:  
 
  Table 5-3 Floating-Point Register Mapping
  
    | Alpha -> | I64 |  | Alpha -> | I64 |  
    | F0 | F8 |  | F16 | F8 |  
    | F1 | F9 |  | F17 | F9 |  
    | F2 | F2 |  | F18 | F10 |  
    | F3 | F3 |  | F19 | F11 |  
    | F4 | F4 |  | F20 | F12 |  
    | F5 | F5 |  | F21 | F13 |  
    | F6 | F16 |  | F22 | F22 |  
    | F7 | F17 |  | F23 | F23 |  
    | F8 | F18 |  | F24 | F24 |  
    | F9 | F19 |  | F25 | F25 |  
    | F10 | F6 |  | F26 | 26 |  
    | F11 | F7 |  | F27 | 27 |  
    | F12 | F20 |  | F28 | 28 |  
    | F13 | F21 |  | F29 | F29 |  
    | F14 | F14 |  | F30 | F30 |  
    | F15 | F15 |  |  |  |  5.4.12.1.2 Mapping Diagnostics
In some cases, the HP C compiler on Alpha systems silently ignores 
linkage registers if, for example, a standard parameter register like 
R16 is specified in a
preserved
 option. When you compile on an I64 system, this situation emits an 
 MAPREGIGNORED informational message, and the SHOWMAPLINKAGE output 
 might not be correct. If there is no valid mapping to I64 registers, 
 the NOMAPPOSSIBLE error message is output. There are two special 
 situations that can arise when floating-point registers are specified 
 in a linkage:
 
  Only IEEE-format values are passed in floating-point registers 
  under the OpenVMS Calling Standard for I64: VAX format values are 
  passed in integer registers. Therefore, a compilation that specifies 
  /FLOAT=D_FLOAT or /FLOAT=G_FLOAT produces an error for any linkage that 
  specifies floating-point registers. Note that this includes use in 
  options that do not involve passing values, such as the
preserved
 and
notused
 options.
  The mapping of floating-point registers is many-to-one in two cases:
  
    Alpha registers F0 and F16 both map to I64 register F8
    Alpha F1 and F17 both map to I64 register F9.
   A valid Alpha linkage may well specify uses for both F0 and F16, 
    and/or both F1 and F17. Such a linkage cannot be mapped on an I64 
    system. But because of the way this situation is detected, the 
    MULTILINKREG warning message that is produced can only identify the 
    second occurrence of an Alpha register that got mapped to the same I64 
    register as some previous Alpha register. The actual pair of Alpha 
    registers in the source is not identified, and so the message can be 
    confusing. For example, an option like
preserved(F1,F17)
 gets a MULTILINKREG diagnostic saying that F17 was specified more than 
 once.
 5.4.12.2 #pragma linkage_ia64 Format
The
#pragma linkage_ia64
 format requires register names to be specified in terms of an I64 
 system. The register names will never be mapped to a different 
 architecture. This form of the pragma always produces an error if 
 encountered on a different architecture.
 
For this format of the pragma, valid registers for the
preserved
,
nopreserve
,
notused
,
parameters
, and
result
options are:
 
  Integer registers R3 through R12 and R19 through R31
  Floating-point registers F2 through F31
 
Valid registers for the
parameters
 and
result
 are:
 
  Integer registers R3 through R12, and R19 through R31
  Integer registers R32 through R39 (according to the convention 
  described below)
  Floating-point registers F2 through F31
 
The
parameters
 and
result
options permit integer registers R32 through R39 to be specified 
according to the following convention: On IA64, the first eight integer 
input/output slots are allocated to stacked registers, and thus the 
calling routine refers to them using different names than the called 
routine. The convention for naming these registers in either the
parameters
or
result
 option of a
#pragma linkage_ia64
directive is always to use the hardware names as they would be used 
within the called routine: R32 through R39. The compiler 
automatically compensates for the fact that within the calling routine 
these same registers are designated using different hardware names.
 5.4.13 #pragma [no]member_alignment Directive
By default, HP C for OpenVMS VAX systems does not align 
structure members on natural boundaries; they are stored on byte 
boundaries (with the exception of bit-field members).
 
By default, HP C for OpenVMS Alpha systems does align 
structure members on natural boundaries.
 
The
#pragma member_alignment
 preprocessor directive can be used to force natural-boundary alignment 
 of structure members. The
#pragma nomember_alignment
 preprocessor directive restores byte-alignment of structure members.
 
This pragma has the following formats:
 
  
    | #pragma member_alignment
 #pragma member_alignment save
 #pragma member_alignment restore
 #pragma nomember_alignment [base_alignment]
 |  
 
When
#pragma member_alignment
 is used, the compiler aligns structure members on the next boundary 
 appropriate to the type of the member, rather than on the next byte. 
 For example, a
long
 variable is aligned on the next longword boundary; a
short
 variable is aligned on the next word boundary.
 
Consider the following example:
 
 
  
    | 
 
#pragma nomember_alignment 
 
struct x { 
           char c; 
           int b; 
           }; 
 
#pragma member_alignment 
 
struct y { 
          char c;       /*3 bytes of filler follow c */ 
          int b; 
          }; 
 
main () 
 
{ 
        printf( "The sizeof y is: %d\n", sizeof (struct y) ); 
        printf( "The sizeof x is: %d\n", sizeof (struct x) ); 
} 
 
 |  
When this example is executed, it shows the difference between
#pragma member_alignment
 and
#pragma nomember_alignment
.
 
Once used, the
member_alignment
 pragma remains in effect until the
nomember_alignment
 pragma is encountered; the reverse is also true.
 
The optional base_alignment parameter can be used to specify 
the base-alignment of the structure. Use one of the following keywords 
for the base_alignment:
 
  
byte
 (1 byte)
  
word
 (2 bytes)
  
longword
 (4 bytes)
  
quadword
 (8 bytes)
  
octaword
 (16 bytes)
 
The
#pragma member_alignment save
 and
#pragma member_alignment restore
 directives can be used to save the current state of the
member_alignment
 and to restore the previous state, respectively. This feature is 
 necessary for writing header files that require
member_alignment
 or
nomember_alignment
, or that require inclusion in a
member_alignment
 that is already set.
 5.4.14 #pragma message Directive
The
#pragma message
 directive controls the issuance of individual diagnostic messages or 
 groups of messages. Use of this pragma overrides any command-line 
 options that may affect the issuance of messages.
 
The
#pragma message
 directive has the following formats:
 
  
    | #pragma message option1 (message-list)
 #pragma message option2
 #pragma message (quoted-string)
 |  
 5.4.14.1 #pragma message option1
The parameter option1 must be one of the following keywords:
 
  
enable
---Enables issuance of the messages specified in the 
message-list
  
disable
---Disables issuance of the messages specified in the 
message-list
  
emit_once
---Emits the specified messages only once per compilation. Certain 
messages are emitted only the first time the compiler encounters the 
causal condition. When the compiler encounters the same condition later 
in the program, no message is emitted. Messages about the use of 
language extensions are an example of this kind of message. To emit one 
of these messages every time the causal condition is encountered, use 
the EMIT_ALWAYS option.
 Errors and Fatals are always emitted. You 
cannot set them to
emit_once
.
emit_always
---Emits the specified messages at every occurrence of the condition.
  
error
---Sets the severity of the specified messages to Error. Supplied 
Error messages and Fatal messages cannot be made less severe. 
(Exception: A message can be upgraded from Error to Fatal, then later 
downgraded to Error again, but it can never be downgraded from Error.)
 Warnings and Informationals can be made any severity.)
fatal
---Sets the severity of the specified messages to Fatal.
  
informational
---Sets the severity of the specified messages to Informational. Note 
that Fatal and Error messages cannot be made less severe.
  
warning
---Sets the severity of each message in the message-list to Warning. 
Note that Fatal and Error messages cannot be made less severe.
 
The message-list can be any one of the following:
 
  A single message identifier (within parentheses, or not). The 
  message identifier is the name following the severity at the start of a 
  line when a message is issued. For example, in the following message, 
  the message identifier is GLOBALEXT:
 
  
    | 
 
%CC-W-GLOBALEXT, a storage class of globaldef, globalref, or globalvalue 
is a language extension. 
 | The name of a single message group (within parentheses, or not). 
  Message-group names are:
  
    ALL---All the messages in the compiler
    ALIGNMENT---Messages about unusual or inefficient data alignment.
    C_TO_CXX---Messages reporting the use of C features that would be 
    invalid or have a different meaning if compiled by a C++ compiler.
    CDD---Messages about CDD (Common Data Dictionary) support.
    CHECK---Messages reporting code or practices that, although correct 
    and perhaps portable, are sometimes considered ill-advised because they 
    can be confusing or fragile to maintain. For example, assignment as the 
    test expression in an "if" statement. The check group gets defined 
    by enabling LEVEL5 messages.
DEFUNCT---Messages reporting the use of obsolete features: ones 
    that were commonly accepted by early C compilers but were subsequently 
    removed from the language.
    NEWC99---Messages reporting the use of the new C99 Standard 
    features.
    NOANSI---This is a deprecated message group. It is an obsolete 
    synonym for NOC89. Also see message groups NEWC99, NOC89, NOC99.
    NOC89---Messages reporting the use of non-C89 Standard features.
    NOC99---Messages reporting the use of non-C99 Standard features.
    OBSOLESCENT---Messages reporting the use of features that are valid 
    in Standard C, but which were identified in the standard as being 
    obsolescent and likely to be removed from the language in a future 
    version of the standard.
    OVERFLOW---Messages that report assignments and/or casts that can 
    cause overflow or other loss of data significance.
    PERFORMANCE---Messages reporting code that might result in poor 
    run-time performance.
    PORTABLE---Messages reporting the use of language extensions or 
    other constructs that might not be portable to other compilers or 
    platforms.
    PREPROCESSOR---Messages reporting questionable or non-portable use 
    of preprocessing constructs.
    QUESTCODE---Messages reporting questionable coding practices. 
    Similar to the CHECK group, but messages in this group are more likely 
    to indicate a programming error rather than just a non-robust style.
 
  | Note Enabling the QUESTCODE group provides lint-like checking.
 | RETURNCHECKS---Messages related to function return values.
    UNINIT---Messages related to using uninitialized variables.
    UNUSED---Messages reporting expressions, declarations, header 
    files, CDD records, static functions, and code paths that are not used. 
    Note, however, that unlike any other messages, these messages must 
    be enabled on the command line (/WARNINGS=ENABLE=UNUSED) to be 
    effective.
A single message-level name (within parentheses, or not). 
  Message-level names are:
 
    LEVEL1---Important messages. These are less important than the 
    level 0 core messages, because messages in this group are not displayed 
    if
#pragma nostandard
 is active.
    LEVEL2---Moderately important messages.
    LEVEL3---Less important messages. LEVEL3 is the default message 
    level for HP C for OpenVMS systems.
LEVEL4---Useful check/portable messages.
    LEVEL5---Not so useful check/portable messages.
    LEVEL6---Additional "noisy" messages.
   Be aware that there is a core of very important compiler messages 
    that are enabled by default, regardless of what you specify with 
    /WARNINGS or
#pragma message
. Referred to as message level 0, it includes all messages issued in 
header files, and comprises what is known as the nostandard group. All 
other message levels add additional messages to this core of enabled 
messages.
 You cannot modify level 0 (You cannot disable it, enable 
it, change its severity, or change its EMIT_ONCE characteristic). 
However, you can modify individual messages in level 0, provided such 
modification is allowed by the action. For example, you can disable a 
Warning or Informational in level 0, or you can change an error in 
level 0 to a Fatal, and so on. (See restrictions on modifying 
individual messages.)
 Enabling a level also enables all the 
messages in the levels lower than it. So enabling LEVEL3 messages also 
enables messages in LEVEL2 and LEVEL1.
 Disabling a level also 
disables all the messages in the levels higher than it. So disabling 
LEVEL4 messages also disables messages in LEVEL5 and LEVEL6.
A comma-separated list of message identifiers, group names, and 
  messages levels, freely mixed, enclosed in parentheses.
 5.4.14.2 #pragma message option2
The parameter option2 must be one of the following keywords:
 
  
save
---Saves the current state of which messages are enabled and disabled.
  
restore
---Restores the previous state of which messages are enabled and 
disabled.
 
The
save
 and
restore
 options are useful primarily within header files.
 
 
 |