HP C/HP-UX Programmer's Guide HP 3000 MPE/iX Computer Systems Edition 6 Manufacturing Part Number: 92434-90009 E0696 U.S.A.
Notice The information contained in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability or fitness for a particular purpose. Hewlett-Packard shall not be liable for errors contained herein or for direct, indirect, special, incidental or consequential damages in connection with the furnishing or use of this material.
Introduction to HP C 11 Storage and Alignment Comparisons 13 Calling Other Languages 43 Optimizing HP C Programs 59 Programming for Portability 121 Migrating C Programs to HP-UX 159 Using C Programming Tools 165 9
10
Preface The HP C Programmer's Guide contains a detailed discussion of selected C topics for the HP 9000 Series 700/800 computer systems. This manual is intended for experienced programmers who are familiar with HP systems, data processing concepts, and the C programming language. The manual does not discuss every feature of C. For more information, refer to the manual HP C/HP-UX Reference Manual. This manual is organized as follows: Chapter 1 , “Introduction to HP C,” Introduces HP C.
Printing History First Edition, Nov 1986 Second Edition, Nov 1987, MPE/XL: 31506A.00.02 HP-UX: 92453-01A.00.09 Update 1, Oct 1988, MPE/XL: 31506A.01.21 HP-UX: 92453-01A.03.04 Third Edition, August 1992, MPE/iX: 31506A.04.01 HP-UX: 92453-01A.09.17 Fourth Edition, January 1994, MPE/iX: 31506A.04.01 HP-UX: 92453-01A.09.61 Fifth Edition, June 1996, HP C/HP-UX A.10.
Introduction to HP C 1 Introduction to HP C HP C is Hewlett-Packard's version of the C programming language that is implemented on the HP 9000 Series 700/800 computers and the HP 3000 Series 900 computers. This manual discusses the HP 9000 Series 700/800 product. HP C is highly compatible with the C compiler implemented on the HP 9000 Series 300/400 and CCS/C, Corporate Computer Systems C compiler for the HP 3000. Some system and hardware-specific differences do exist.
Introduction to HP C HP C Online Help HP C Online Help Online help for HP C is available for HP 9000 Series 700 and 800 users. The online help uses the HP VUE help facility. The VUE help can be accessed from an X Windows display device. Several methods of invoking the HP C online help are listed below.
Storage and Alignment Comparisons 2 Storage and Alignment Comparisons This chapter focuses on the different ways that internal data storage is allocated on various platforms and discusses the HP_ALIGN pragma which you can use to overcome these differences. The storage and alignment rules of HP C on the HP 9000 Series 700/800 are compared with those of other systems. (Note that the storage and alignment rules on the HP 3000 Series 900 are the same as those on the HP 9000 Series 700/800.
Storage and Alignment Comparisons Data Type Size and Alignments Data Type Size and Alignments This section discusses storage sizes and alignment modes for the HP 9000 and HP Apollo systems as well as the VAX/VMS C, CCS/1000, and CCS/C 3000. In all, there are a total of seven possible alignment modes which can be grouped into five categories as described in Table on page 14. Table 2-1.
Storage and Alignment Comparisons Data Type Size and Alignments See the section titled "The HP_ALIGN Pragma" in this chapter for a detailed description of this pragma. The NATURAL alignment mode should be used whenever possible. This mode enables data to be shared among the greatest number of HP-UX and Domain (HP Apollo) systems.
Storage and Alignment Comparisons Alignment Rules Alignment Rules This discussion of alignment rules divides them into sections on scalar types, arrays, structures and unions, bit-fields, and typedefs. Alignment of Scalar Types Scalar types are integral types, floating types, and pointer types. Alignment of scalar types that are not part of a structure, union, or typedef declaration are not affected by the alignment mode. Therefore, they are aligned the same way in all alignment modes. Table 2-2.
Storage and Alignment Comparisons Alignment Rules is a member of a structure or union. An array that is a member of a structure or union is aligned according to the rules for structure or union member alignment (see the section "Alignment of Structures and Unions" below for more information.
Storage and Alignment Comparisons Alignment Rules Table 2-3. Aligning Structure or Union Members Data Type Size (bytes) HPUX_WORD DOMAIN_WORD HPUX_NATURAL DOMAIN_NATUR AL HPUX_ NATURAL_S 500 NATURAL long long 8 2 8 4 8 pointer 4 2 4 4 4 long pointer 8 2 4 4 4 float 4 2 4 4 4 double 8 2 8 4 8 long double 16 2 8 4 8 arrays Follows alignment of array type inside a structure or union. struct, union NOTE Follows alignment of its most restricted member.
Storage and Alignment Comparisons Alignment Rules in Figure 2-1. on page 19 Figure 2-1. Example of HPUX_WORD/DOMAIN_WORD Alignment for Structures HPUX_NATURAL/DOMAIN_NATURAL Alignments For HPUX_NATURAL and DOMAIN_NATURAL alignments, the alignment of structure and union types is the same as the strictest alignment of any member. Therefore, they may be aligned on 1-, 2-, 4-, or 8-byte boundaries. Padding is performed as necessary so that the size of the object is a multiple of the alignment size.
Storage and Alignment Comparisons Alignment Rules alignment modes, padding is done to a multiple of the alignment size. For example, the following code: struct { char c; double d; } s1; compiled with the +m option produces: Identifier s1 c d Class - ext def member member Type Address struct char double 0x0 @ 0x0 0x4 @ 0x0 The entire structure is 4-byte aligned, with a resulting size of 12 bytes.
Storage and Alignment Comparisons Alignment Rules Figure 2-3. Example of NOPADDING Alignment for Structure s1 Note that if a member of a structure or union has been declared previously under a different alignment mode, it will retain its original alignment which may not be byte alignment. The NOPADDING alignment will not override the alignment of the member, so there may be some padding done within the structure, and the structure may be greater than byte aligned.
Storage and Alignment Comparisons Alignment Rules d e member member char char 0x7 @ 0x0 0x8 @ 0x0 The size of the structure is 12 bytes, with 4-byte alignment as illustrated in Figure 2-4. on page 22. Figure 2-4. Example of HPUX_NATURAL/HPUX_NATURAL_S500 Alignment for Structure foo Since b (being an int type) does not cross any word boundaries, a and b are adjacent. c starts on the next word because it would cross a word boundary if it started right after b.
Storage and Alignment Comparisons Alignment Rules of padding between c and i, even with NOPADDING alignment mode (see Figure 2-5. on page 23.) Figure 2-5. Example of NATURAL Alignment for Structure bar HPUX_WORD Alignments For HPUX_WORD alignments: • Alignment for char and short bit-fields is identical to that of HPUX_NATURAL. • Alignment for any other bit-fields (int, long long, enum, for example) is identical to DOMAIN bit-field alignment.
Storage and Alignment Comparisons Alignment Rules Figure 2-6. Example of Structures basic_str and enum_str Notice that char_bit follows the HPUX_NATURAL alignment scheme, but char_enum_bit follows the DOMAIN_WORD alignment scheme, even though the length of their bit-field types are equivalent. Alignment of Typedefs Alignment for typedefs is slightly different than alignment for structures. Within a structure, the member itself is affected by the alignment mode.
Storage and Alignment Comparisons Alignment Rules In the first typedef, my_ptr will be a 4-byte aligned pointer to a 2-byte aligned int. The second typedef will create another type for my_ptr which is now 2-byte aligned, since my_double_ptr is derived from my_ptr. So my_double_ptr is a 4-byte aligned pointer to a 2-byte aligned pointer which points to a 2-byte aligned int. Similar declarations inside a structure will not have the same resulting alignment.
Storage and Alignment Comparisons The HP_ALIGN Pragma The HP_ALIGN Pragma The HP_ALIGN pragma controls data storage allocation and alignment of structures, unions, and type definitions, using typedefs. It enables you to control the alignment mode when allocating storage space for data. It is especially important when used to control the allocation of binary data that is transmitted among machines having different hardware architectures.
Storage and Alignment Comparisons The HP_ALIGN Pragma Using the HP_ALIGN Pragma The HP_ALIGN pragma allows you to control data storage allocation and alignment of structures, unions, and typedefs. NOTE The basic scalar types, array types, enumeration types, and pointer types are not affected by the HP_ALIGN pragma. The pragma only affects struct or union types and typedefs - No other types are affected by specifying the HP_ALIGN pragma.
Storage and Alignment Comparisons The HP_ALIGN Pragma typedef int int32; void routine (int *x); int main() { int *ok; int32 *bad; routine(ok); routine(bad); /* warning */ } Compiling this with -Aa -c will give two warnings: warning 604: Pointers are not assignment-compatible. warning 563: Argument #1 is not the correct type. These warnings occur because the actual pointer value of bad may not be as strictly aligned as the pointer type routine expects.
Storage and Alignment Comparisons The HP_ALIGN Pragma c foo c auto auto member member i char struct st char int SP-48 SP-44 0x0 @ 0x0 0x4 @ 0x0 The resulting size of foo is 8 bytes, with 4-byte alignment.
Storage and Alignment Comparisons The HP_ALIGN Pragma . . . } } This code is not written safely. Although struct s is declared under NOPADDING alignment mode, it has 2-byte alignment due to the typedef for ushort. However, a pointer to struct s can be assigned an address that can point to anywhere in the char array (including odd addresses). If the function get_index always returns an even number, you will not run into any problems, because it will always be 2-byte aligned.
Storage and Alignment Comparisons The HP_ALIGN Pragma char bus_color; }; #pragma HP_ALIGN POP Variables declared of type struct string_1, are aligned according to the HPUX_WORD alignment mode. Variables declared of type struct car, are aligned according to the HPUX_NATURAL alignment mode. Variables declared of type struct bus are aligned according to HPUX_WORD.
Storage and Alignment Comparisons The HP_ALIGN Pragma typedef int non_native_int; #pragma HP_ALIGN POP main () { int i; non_native_int *p = non_native_rec.b; i = *p; } An alternative to using the HP_ALIGN pragma and typedefs to control non-natively aligned pointers is to use the +ubytes compiler option of HP C/HP-UX. The +ubytes forces all pointer dereferences to assume that data is aligned on 8-bit, 16-bit, or 32-bit addresses. The value of bytes can be 1 (8-bit), 2 (16-bit), or 4 (32-bit).
Storage and Alignment Comparisons Aligning Structures Between Architectures Aligning Structures Between Architectures Differences in data type alignment can cause problems when porting code or data between systems that have different alignment schemes.
Storage and Alignment Comparisons Aligning Structures Between Architectures Figure 2-7. Comparison of HPUX_WORD and HPUX_NATURAL Byte Alignments In the HPUX_WORD alignment mode, six bytes are written to myfile. The integer field2 begins on the third byte. In the HPUX_NATURAL alignment mode, eight bytes are written to myfile. The integer field2 begins on the fifth byte.
Storage and Alignment Comparisons Aligning Structures Between Architectures shown above the variable names. Shaded cells indicate padding bytes. Figure 2-9. Storage with HP C on the HP 9000 Series 700/800 and HP 3000 Series 900 The struct q is aligned on an 8-byte boundary because the most restrictive data type within the structure is the double u. Table on page 36 shows the padding for the example code fragment: Table 2-4.
Storage and Alignment Comparisons Aligning Structures Between Architectures Table 2-4. Padding on HP 9000 Series 700/800 and HP 3000 Series 900 Padding Location Reason for Padding a+17 Aligns the short z on a 2-byte boundary. a+25 Fills out the structure to a 2-byte boundary. a+26 through a+31 Aligns the double u on an 8-byte boundary. The bit-field s begins immediately after the previous item at a+41. Two bits of padding is necessary to align the next byte properly.
Storage and Alignment Comparisons Aligning Structures Between Architectures Figure 2-10. Storage with HP C on the HP 9000 Series 300/400 Figure on page 38 shows the padding for the example code fragment: Table 2-5. Padding on the HP 9000 Series 300/400 Padding Location Reason For Padding a+1 Within structures align short on a 2-byte boundary. a+5 Aligns the short z on a 2-byte boundary. a+14 Structures within structures are aligned on a 2-byte boundary.
Storage and Alignment Comparisons Aligning Structures Between Architectures Cross-Reference> are aligned in memory when using CCS/C on the HP 1000 or HP 3000: Figure 2-11. Storage with CCS/C NOTE All data types and structures are 2-byte aligned when using CCS/C on the HP 1000 or HP 3000. Table on page 39 shows the padding for the example code fragment: Table 2-6. Padding with CCS/C Padding Location Reason for Padding a+1 Aligns the structure on a 2-byte boundary.
Storage and Alignment Comparisons Aligning Structures Between Architectures Table 2-6. Padding with CCS/C Padding Location Reason for Padding a+25 Fills out the structure to a 2-byte boundary and aligns the double u on a 2-byte boundary. a+37 Pads a to a 2-byte boundary. VAX/VMS C The differences between HP C and VAX/VMS C are: • In HP C Series 700/800, the double type is 8-byte aligned; in VAX/VMS C, the double type is 4-byte aligned. • In HP C, bit-fields are packed from left to right.
Storage and Alignment Comparisons Aligning Structures Between Architectures Figure 2-12. Storage on VAX/VMS C Table on page 41 shows the padding for the example code fragment: Table 2-7. Padding on VAX/VMS C Padding Location Reason for Padding a+1 The most restrictive type of any struct x member is short; therefore, struct x is 2-byte aligned. a+5 Aligns the short z on a 2-byte boundary. a+13 Fills out the struct x to a 2-byte boundary. a+17 Needed for alignment of the short z.
Calling Other Languages 3 Calling Other Languages This chapter describes how to call routines written in other HP languages from HP C programs. Invoking routines or accessing data defined or declared in another programming language from HP C can be tricky. Here are some common problems: • Mismatched data types for parameters and return values. • Different language storage layouts for aggregates (arrays, records, variants, structures, unions, equivalences, and commons).
Calling Other Languages Comparing HP C and HP Pascal Comparing HP C and HP Pascal Table on page 44 summarizes the differences in storage allocation between HP C and HP Pascal. The footnote numbers refer to notes located in a section immediately following the table. Table 3-1. HP C versus HP Pascal Storage Allocation HP C Type HP C Description char, signed char 1 byte, byte aligned unsigned char 1 byte, byte aligned char 1 byte, byte aligned; Subrange: 0 ..
Calling Other Languages Comparing HP C and HP Pascal Table 3-1. HP C versus HP Pascal Storage Allocation HP C Type HP C Description Correspondin g HP Pascal Type HP Pascal Description long enum 4 bytes, 4-byte aligned integer 4 bytes, 4-byte aligned, subrange: -2,147,483,648..2,147,483,647 array [n] of type Size is number of elements times element size. Align according to element type. ARRAY [0 .. n-1] OF type (See Note 3) Size is the number of elements times element size.
Calling Other Languages Comparing HP C and HP Pascal Table 3-1.
Calling Other Languages Comparing HP C and HP Pascal • 2 bytes, if between 257 and 65536 elements. • 4 bytes, otherwise. If the default enumeration specifier is modified with a char or short type specifier, 1 or 2 bytes of storage are allocated. See Table 3-1 for a description of the sized enumerated types. This is important if the items are packed.
Calling Other Languages Comparing HP C and HP Pascal 9. A union corresponds directly to an untagged HP Pascal variant record.
Calling Other Languages Comparing HP C and HP Pascal b5 : -16 .. 15; b6 : -32 .. 31; b7 : -64 .. 63; END; 11.Unsigned bit-fields map onto HP Pascal packed record fields whose types are the appropriate subranges. For example, the HP C structure: typedef struct { unsigned int b1 unsigned int b2 unsigned int b3 unsigned int b4 unsigned int b5 unsigned int b6 unsigned int b7 } BITS; : : : : : : : 1; 2; 3; 4; 5; 6; 7; corresponds to this untagged HP Pascal record: TYPE BITS = PACKED RECORD b1 : 0 ..
Calling Other Languages Comparing HP C and HP Pascal unsigned int b9 : 1; } SET_10; SET_10 s; Also, the following operation in HP Pascal: s := s + [9]; has the following corresponding HP C code: s.b9 = 1; 15.HP C and HP Pascal file types and I/O operations do not correspond. Passing Parameters Between HP C and HP Pascal This section describes additional information on parameter passing. 1. All HP C parameters are passed by value except arrays and functions, which are always passed as pointers.
Calling Other Languages Comparing HP C and HP Pascal ret_val := 0; for i := 1 to len - 1 do begin if ( a[i] <> ’a’ ) then ret_val := 1; a[i] := ’z’; if ( b[i] <> ’b’ ) then ret_val := 256; b[i] := ’y’; end; for i := 1 to strlen (c) do begin if ( c[i] <> ’c’ ) then ret_val := 65536; c[i] := ’x’; end; for i := 1 to strlen (d) do begin if ( d[i] <> ’d’ ) then ret_val := maxint; d[i] := ’w’; end; pass_char_arrays := ret_val; end; function pass_a_string (var a: string) : integer; var i : integer; ret_val : integ
Calling Other Languages Comparing HP C and HP Pascal /* a Pascal routine */ extern int pass_char_arrays (/* pac10, var pac10, string_10, var string[10] */); main(void) { static struct string_10 a, b, c, d; int ret_val; strcpy (a.chars, "aaaaaaaaa"); strcpy (b.chars, "bbbbbbbbb"); strcpy (c.chars, "ccccccccc"); c.cur_len = strlen (c.chars); strcpy (d.chars, "ddddddddd"); d.cur_len = 5; ret_val = pass_char_arrays (a.chars, b.chars, &c, &d); printf ("a: %s\n", a.
Calling Other Languages Comparing HP C and HP Pascal 4. In non-ANSI mode, HP C promotes most float (32-bit) arguments to double (64-bit). Therefore, all arithmetic using objects defined as float is actually using double code. Float code is only used when the float objects are stored. In ANSI mode where function prototypes have been declared with a float parameter, no automatic promotion is performed. If the prototype is within the current scope, floats will not be automatically promoted.
Calling Other Languages Comparing HP C and HP FORTRAN 77 Comparing HP C and HP FORTRAN 77 Table on page 55 shows the differences in storage allocation between HP C and HP FORTRAN 77. The notes the table refers to are located after the table in the section called "Notes on HP C and HP FORTRAN 77." Table 3-2.
Calling Other Languages Comparing HP C and HP FORTRAN 77 Table 3-2. HP C versus HP FORTRAN 77 Storage HP C Type HP C Description HP FORTRAN 77 Type string (char *) CHARACTER*n (See Note 3) char array CHARACTER*1 array (See Notes 4 &5) (See Note 5) Hollerith array HP FORTRAN 77 Description arrays Size is number of elements times element size. Aligned according to element type. (See Note 4) Size is number of elements times element size. Aligned according to element type.
Calling Other Languages Comparing HP C and HP FORTRAN 77 3. HP FORTRAN 77 passes strings as parameters using string descriptors corresponding to the following HP C declarations: char *char_string; int len; /* points to string */ /* length of string */ 4. HP C stores arrays in row-major order, whereas HP FORTRAN 77 stores arrays in column-major order. The lower bound for HP C is always zero; for HP FORTRAN 77, the default lower bound is 1. 5.
Calling Other Languages Comparing HP C and HP FORTRAN 77 chapter. Passing string variables of any length must be done by: building and passing a two-parameter descriptor (defined in Note 3 above), initializing the string appropriately, and by passing two arguments. The two arguments are the pointer to the characters and the value of the length word.
Calling Other Languages Comparing Structured Data Type Declarations Comparing Structured Data Type Declarations This section shows how to declare a nested structure in HP C, HP Pascal, and HP FORTRAN 77. HP C Nested Structure struct x { char y [3]; short z; char w [5]; }; struct q { char n; struct x v [2]; double u; char t; } a; struct u{ union { int x; char y[4]; } uval; }; HP Pascal Nested Structure TYPE x = RECORD y : PACKED ARRAY [1 .. 3] OF CHAR; z : SHORTINT; w : PACKED ARRAY [1 ..
Calling Other Languages Comparing Structured Data Type Declarations structure /x/ character*3 y integer*2 z character*5 w end structure structure /q/ character n record /x/ v(2) real*8 u character t end structure structure /u/ union map integer*4 x end map map character*4 y end map end union end structure Chapter 3 59
Calling Other Languages Comparing Structured Data Type Declarations 60 Chapter 3
Optimizing HP C Programs 4 Optimizing HP C Programs This chapter discusses the following: • When and how to use the optimizer. • The four levels of optimization. • Profile-based optimization. The HP C optimizer transforms programs so machine resources are used more efficiently. The optimizer can dramatically improve application run-time speed. HP C performs only minimal optimizations unless you specify otherwise. You activate additional optimizations using HP C command line options.
Optimizing HP C Programs Summary of Major Optimization Levels Summary of Major Optimization Levels The HP C major optimization options are summarized in Table on page 60. Table 4-1. HP C Major Optimization Options Option Description Benefits +O0 (default) Constant folding and simple register assignment. Compiles fastest. +O1 Level 0 optimizations plus instruction scheduling and optimizations that can be performed on small sections of code. Produces faster programs than level 0.
Optimizing HP C Programs Supporting Optimization Options Supporting Optimization Options Table on page 61 shows optimization options that support the core optimization levels. These optimizations are performed only when specifically invoked. They are available at all optimization levels. Table 4-2. Other Supporting Optimizations Option Description Benefits +ESfic Replaces millicode calls with inline code. Run-time code is faster because fast indirect calls are used instead of millicode calls.
Optimizing HP C Programs Enabling Basic Optimization Enabling Basic Optimization To enable basic optimizations, use the -O option (equivalent to +O2), as follows: cc -O sourcefile.c Basic optimizations do not change the behavior of ANSI C standard-conforming code. They improve run-time execution time but only increase compile time and link time by a moderate amount.
Optimizing HP C Programs Enabling Different Levels of Optimization Enabling Different Levels of Optimization There may be times when you want more or less optimization than what is provided with the basic -O option. Level 1 Optimization To enable level 1 optimization, use the +O1 option, as follows: cc +O1 sourcefile.c Level 1 optimization compiles quickly, but still provides some run-time speedup. Level 2 Optimization To enable level 2 optimization, use the +O2 option, as follows: cc +O2 sourcefile.
Optimizing HP C Programs Changing the Aggressiveness of Optimizations Changing the Aggressiveness of Optimizations At each level of optimization, you can control the aggressiveness of the optimizations performed. Use the +Oconservative option at optimization level 2, 3, or 4 if you are not sure if your code conforms to standards. This option provides more safety.
Optimizing HP C Programs Removing Compilation Time Limits When Optimizing Aggressive optimizations are new optimizations or are optimizations that can change the behavior of programs.
Optimizing HP C Programs Specifying Maximum Optimization cc +O4 +Osize sourcefile.c Most optimizations improve execution speed and decrease executable code size. A few optimizations significantly increase code size to gain execution speed. The +Osize option disables these code-expanding optimizations. Use this option if you have limited main memory, swap space, or disk space. Specifying Maximum Optimization To get maximum optimization, use: cc +Oall Performs maximum optimization.
Optimizing HP C Programs Summary of Optimization Parameters Summary of Optimization Parameters The HP C optimization parameters are summarized in Table on page 67. Table 4-3. HP C Optimization Parameters Option What It Does Level of Opt +O[no]aggressive The +O[no]aggressive option enables optimizations that can result in significant performance improvement, but that can change a program's behavior.
Optimizing HP C Programs Profile-Based Optimization Table 4-3. HP C Optimization Parameters Option What It Does Level of Opt +O[no]size The +Osize option suppresses optimizations that significantly increase code size. The +Onosize option does not prevent optimizations that can increase code size. The default is +Onosize. 2, 3, 4 a. See and the following section for details about advanced optimization options.
Optimizing HP C Programs Profile-Based Optimization Collecting Data for Profiling To collect execution profile statistics, run your instrumented program with representative data as follows: sample.exe < input.file1 Collect execution profile data. sample.exe < input.file2 This step creates and logs the profile statistics to a file, by default called flow.data.
Optimizing HP C Programs Profile-Based Optimization %cc -o sample.exe +I +03 sample.o %sample.exe < input.file1 %mv flow.data /users/profile/prog.data %cc -o sample.exe +df /users/profiles/prog.data +P +03 sample.o Maintaining Instrumented and Optimized Program Files You can maintain both instrumented and optimized versions of a program. You might keep an instrumented version of the program on hand for development use, and several optimized versions on hand for performance testing and program distribution.
Optimizing HP C Programs Controlling Specific Optimizer Features scheduling, note that instruction scheduling occurs at link time. Therefore, the system on which you link, rather than compile, determines the implementation of instruction scheduling. For more information on profile-based optimization, see the HP-UX Linker and Libraries Online User Guide.
Optimizing HP C Programs Controlling Specific Optimizer Features Table 4-4. HP C Advanced Optimization Options Option Option +O[no]whole_program_mode +O[no]dataprefetch Optimization level(s): 2, 3, 4 Default: +Onodataprefetch When +Odataprefetch is enabled, the optimizer will insert instructions within innermost loops to explicitly prefetch data from memory into the data cache.
Optimizing HP C Programs Controlling Specific Optimizer Features +O[no]fastaccess Optimization level(s): 0, 1, 2, 3, 4 Default: +Onofastaccess at optimization levels 0, 1, 2 and 3, +Ofastaccess at optimization level 4 The +Ofastaccess option optimizes for fast access to global data items. Use +Ofastaccess to improve execution speed at the expense of longer compile times.
Optimizing HP C Programs Controlling Specific Optimizer Features +O[no]initcheck Optimization level(s): 2, 3, 4 Default: unspecified The initialization checking feature of the optimizer has three possible states: on, off, or unspecified. When on (+Oinitcheck), the optimizer initializes to zero any local, scalar, non-static variables that are uninitialized with respect to at least one path leading to a use of the variable.
Optimizing HP C Programs Controlling Specific Optimizer Features • n > 100 More aggressive inlining. The optimizer is less restricted by compilation time and code size when searching for eligible routines to inline. • n = 1 Only inline if it reduces code size. The +Onolimit and +Osize options also affect inlining. Specifying the +Onolimit option has the same effect as specifying +Oinline_budget=200. The +Osize option has the same effect as +Oinline_budget=1.
Optimizing HP C Programs Controlling Specific Optimizer Features The +O[no]loop_transform option enables [disables] transformation of eligible loops for improved cache performance. The most important transformation is the reordering of nested loops to make the inner loop unit stride, resulting in fewer cache misses. +Onoloop_transform may be a helpful option if you experience any problem while using +Oparallel.
Optimizing HP C Programs Controlling Specific Optimizer Features Parallelization is incompatible with the prof tool, so the -p option is disabled by +Oparallel. Parallelization is compatible with gprof. Special *crt0.o startup files are required for programs compiled for a parallel environment. The parallel runtime library, libmp.a, must be linked in. For additional information, see the section "Parallel Execution" at the end of this chapter.
Optimizing HP C Programs Controlling Specific Optimizer Features When +Onoprocelim is specified, procedures that are not referenced by the application are not eliminated from the output executable file. The default is +Onoprocelim at levels 0-3, and +Oprocelim at level 4. If the +Oall option is enabled, the +Oprocelim option is enabled.
Optimizing HP C Programs Controlling Specific Optimizer Features The optimizer generally spills all global data from registers to memory before any modification to global variables or any loads through pointers. However, you can instruct the optimizer on how data types interact so that it can generate more efficient code. If you have the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 int *p; float *q; int a,b,c; float d,e,f; foo() { for (i=1;i<10;i) { d=e *p=..
Optimizing HP C Programs Controlling Specific Optimizer Features Dynamic cast is allowed with +Optrs_strongly_typed or +Optrs_ansi. A pointer dereference is called dynamic cast if a cast is applied on the pointer to a different type. In the example below, type-inferred aliasing is applied on P generally, not just to the particular dereference. Type-aliasing will be applied to any other dereferences of P.
Optimizing HP C Programs Controlling Specific Optimizer Features int *p; p=b; foo() For more information about type aliasing see the section "Aliasing Options" at the end of this chapter. +O[no]regionsched Optimization level(s): 2, 3, 4 Default: +Onoregionsched Applies aggressive scheduling techniques to move instructions across branches. This option is incompatible with the linker -z option. If used with -z, it may cause a SIGSEGV error at run-time.
Optimizing HP C Programs Controlling Specific Optimizer Features with a pointer to private memory may run incorrectly if this optimization is enabled. Use +Osignedpointers to improve application run-time speed. +O[no]static_prediction Optimization level(s): 0, 1, 2, 3, 4 Default: +Onostatic_prediction +Ostatic_prediction turns on static branch prediction for PA-RISC 2.0 targets. PA-RISC 2.
Optimizing HP C Programs Controlling Specific Optimizer Features +O[no]volatile Optimization level(s): 1, 2, 3, 4 Default: +Onovolatile The +Ovolatile option implies that memory references to global variables cannot be removed during optimization. The +Onovolatile option implies that all globals are not of volatile class. This means that references to global variables can be removed during optimization. The +Ovolatile option replaces the obsolete +OV option.
Optimizing HP C Programs Using Advanced Optimization Options Using Advanced Optimization Options Several advanced optimization options can be specified on the same command line. For example, the following command line specifies aggressive level 3 optimizations with unrestricted compile time, disables software pipelining, and disables moving conditional floating-point instructions out of a loop: cc +O3 +Oaggressive +Onolimit +Onomoveflops +Onopipeline \ sourcefile.
Optimizing HP C Programs Level 1 Optimization Modules Level 1 Optimization Modules The level 1 optimization modules are: • Branch optimization. • Dead code elimination. • Faster register allocation. • Instruction scheduler. • Peephole optimization. The examples in this section are shown at the source code level wherever possible. Transformations that cannot be shown at the source level are shown in assembly language.
Optimizing HP C Programs Level 1 Optimization Modules becomes: if(!a) { goto L1; } statement 1 statement 2 L1: Dead Code Elimination The dead code elimination module removes unreachable code that is never executed. For example, the code: if(0) { a = 1; } else { a = 2; becomes: a = 2; Faster Register Allocation The faster register allocation module, used with unoptimized code, analyzes register use faster than the coloring register allocator (a level 2 module).
Optimizing HP C Programs Level 1 Optimization Modules LDW LDI ADDI -52(0,sp),r1 10,r19 3,r1,r31 ;use of r1 is now separated from load Table 4-5. Descriptions of Assembly Language Instructions Instruction Description LDW offset(sr, base), target Loads a word from memory into register target. ADDI const, reg, target Adds the constant const to the contents of register reg and puts the result in register target. LDI const, target Loads the constant const into register target.
Optimizing HP C Programs Level 2 Optimization Modules Level 2 Optimization Modules Level 2 performs optimizations within each procedure. At level 2, the optimizer performs all optimizations performed at the prior level, with the following additions: • FMAC synthesis. • Coloring register allocation. • Induction variable elimination and strength reduction. • Local and global common subexpression elimination. • Advanced constant folding and propagation.
Optimizing HP C Programs Level 2 Optimization Modules becomes: LDI LDO LDO 2,r25 5(r25),r26 10(r26),r31 Induction Variables and Strength Reduction The induction variables and strength reduction module removes expressions that are linear functions of a loop counter and replaces each of them with a variable that contains the value of the function. Variables of the same linear function are computed only once.
Optimizing HP C Programs Level 2 Optimization Modules A = 10; B = 15; C = 60; Loop Invariant Code Motion The loop invariant code motion module recognizes instructions inside a loop whose results do not change and moves them outside the loop. This ensures that the invariant code is only executed once.
Optimizing HP C Programs Level 2 Optimization Modules f(int x) { int a,b,c: a = 1; b = 2; c = x * b; return c; } becomes: f(int x) { int a,b,c; b = 2; c = x * b; return c; } Software Pipelining Software pipelining is a code transformation that optimizes program loops. It rearranges the order in which instructions are executed in a loop. It generates code that overlaps operations from different loop iterations.
Optimizing HP C Programs Level 2 Optimization Modules pseudo-code as follows: R1 = 0; Initialize array index. R2 = 4.0; Load constant value. R3 = Y[0]; Load first Y value. R4 = X[0]; Load first X value. R5 = R4 / R3; Perform division on first element:n = X[0] / Y[0]. do { Begin loop. R6 = R1; Save current array index. R1++; Increment array index. R7 = X[R1]; Load current X value. R8 = Y[R1]; Load current Y value. R9 = R5 + R2; Perform addition on prior row:X[i] = n + 4.0.
Optimizing HP C Programs Level 2 Optimization Modules X[R6] = R11 Save result of operations on current row. } while (R1 <= 100); End loop. R9 = R5 + R2; Perform addition on last row:X[i+2] = n + 4 X[R6] = R9; Save result of operations on last row. This transformation stores intermediate results of the division instructions in unique registers (noted as n and m). These registers are not referenced until several instructions after the division operations.
Optimizing HP C Programs Level 2 Optimization Modules The register is initialized outside the loop to the loop invariant portion of the virtual memory address expression and the register is incremented or decremented within the loop by the loop variant portion of the virtual memory address expression. On PA-RISC, the update of such a dedicated register can often be performed for "free" using the base-register modification capability of load and store instructions.
Optimizing HP C Programs Level 3 Optimizations Level 3 Optimizations Level 3 optimization includes level 2 optimizations, plus full optimization across all subprograms within a single file. Level 3 also inlines certain subprograms within the input file. Use +O3 to get level 3 optimization. Level 3 optimization produces faster run-time code than level 2 on code that frequently calls small functions within a file. Level 3 links faster than level 4.
Optimizing HP C Programs Level 3 Optimizations After inlining, the source file looks like this: main() { int xval,yval,gcdxy; /* statements before inlined version of gcd */ { int int1; int int2; int1 = xval; int2 = yval; { int inttemp; if ( ( int1 <= 0 ) || ( int2 <= 0 ) ) { gcdxy = ( 0 ); goto AA003; } do { if ( int1 < int2 ) { inttemp = int1; int1 = int2; int2 = inttemp; } int1 = int1 - int2; } while ( int1 > 0 ); gcdxy = ( int2 ); } } AA003 : ; /* statements after inlined version of gcd */ } 96 Chapte
Optimizing HP C Programs Level 4 Optimizations Level 4 Optimizations Level 4 performs optimizations across all files in a program. At level 4, all optimizations of the prior levels are performed. Two additional optimizations are performed: • Inlining across multiple source files. • Global and static variable optimization. Interprocedural global optimizations across all files within a program searches across function boundaries to produce better and faster code sequences.
Optimizing HP C Programs Guidelines for Using the Optimizer Guidelines for Using the Optimizer The following guidelines help you effectively use the optimizer and write efficient HP C programs. 1. Use register variables where needed. 2. Hash table sizes should be in powers of 2; field sizes of variables should also be in powers of 2. 3. Where possible, use local variables to help the optimizer promote variables to registers. 4.
Optimizing HP C Programs Optimizer Assumptions Optimizer Assumptions During optimization, the compiler gathers information about the use of variables and passes this information to the optimizer. The optimizer uses this information to ensure that every code transformation maintains the correctness of the program, at least to the extent that the original unoptimized program is correct.
Optimizing HP C Programs Optimizer Pragmas Optimizer Pragmas Pragmas give you the ability to: • Control compilation in finer detail than what is allowed by command line options. • Give information about the program to the compiler. Pragmas cannot cross line boundaries and the word pragma must be in lowercase letters. Optimizer pragmas may not appear inside a function.
Optimizing HP C Programs Optimizer Pragmas Table 4-6. Optimization Level Precedence Command-line Optimization Level #Pragma OPT_LEVEL Resulting OPT_LEVEL +O2 3 2 +O2 4 2 +O3 OFF 0 +O3 1 1 +03 2 2 +03 3 3 +03 4 3 +04 OFF 0 +04 1 1 +04 2 2 +04 3 3 +O4 4 4 The values of OPTIMIZE and OPT_LEVEL are summarized in Table on page 101. Table 4-7. Optimizer Control Pragmas Pragma Description #pragma OPTIMIZE ON Turns optimization on.
Optimizing HP C Programs Optimizer Pragmas For example, to specify inlining of the two subprograms checkstat and getinput, use: #pragma INLINE checkstat, getinput To specify that an infrequently called routine should not be inlined when compiling at optimization level 3 or 4, use: #pragma NOINLINE opendb See the related +O[no]inline optimization option.
Optimizing HP C Programs Optimizer Pragmas and return the pointer that malloc() or calloc() returns. For example, in the program below: struct_type *get_new_record(void) { struct_type *p; if ((p=malloc(sizeof(*p))) == NULL) { printf("get_new_record():out of memory\n"); abort(); } else { /* initialize the struct */ º return p; } the routine get_new_record falls under this category, and can be included in the ALLOCS_NEW_MEMORY pragma.
Optimizing HP C Programs Optimizer Pragmas Example 1 double *d; #pragma PTRS_STRONGLY_TYPED BEGIN int *i; float *f; #pragma PTRS_STRONGLY_TYPED END main(){ ........................ } In this example only two types, pointer-to-int and pointer-to-float will be assumed to be type-safe. Example 2 cc +Optrs_strongly_typed foo.c /*source for Ex.2 */ double *d; ... #pragma NOPTRS_STRONGLY_TYPED BEGIN int *i; float *f; #pragma NOPTRS_STRONGLY_TYPED END ... main(){ ...
Optimizing HP C Programs Aliasing Options Aliasing Options To be conservative, the optimizer assumes that a pointer can point to any object in the entire application. Instead, if the optimizer can be educated on the application's pointer usage, then the optimizer can generate more efficient code, due to the elimination of some false assumptions.
Optimizing HP C Programs Aliasing Options • Each field of a structure type is placed in a separate equivalent group which is distinct from the equivalent group of the field's base type. (The assumption here is that a pointer to int will not be assigned the address of a structure field whose type is int). The actual type name of a structure type is not considered significant in constructing equivalent groups (e.g.
Optimizing HP C Programs Parallel Execution Parallel Execution This section provides information on parallel execution. Transforming Eligible Loops for Parallel Execution (+Oparallel) The +Oparallel option causes the compiler to transform eligible loops for parallel execution on multiprocessor machines.
Optimizing HP C Programs Parallel Execution export MP_NUMBER_OF_THREADS=2 MP_HEAP_MBYTES For this release, parallel programs have a fixed amount of heap storage. If your parallel program allocates dynamic memory (or calls a program that does) and it runs out of memory, use the MP_HEAP_MBYTES environment variable to increase the size (in megabytes) of the data segment.
Optimizing HP C Programs Parallel Execution routine or to a user-defined routine with the same name as a system routine. If the call is to a system routine, the code inhibits parallel execution. NOTE If your program makes explicit use of threads, do not attempt to parallelize it. Parallel Execution and Shared Memory A program compiled with the +Oparallel option and executing on more than one processor mostly uses shared memory instead of the normal process data and stack segments.
Optimizing HP C Programs Parallel Execution Calling Routines with Side Effects The compiler will not parallelize any loop containing a call to a routine that has side effects.
Optimizing HP C Programs Parallel Execution data dependence in the inner loop only, allowing the outer loop to be parallelized. Consider the following: for (i=0; i<10; i++) for (j=1; j<100; j++) a[i][j] = a[i][j-1] + 1; The data dependence in this nested loop occurs in the inner [j] loop: Each row access of a[j,i] depends upon the preceding row [j-1] having been assigned in the previous iteration.
Optimizing HP C Programs Parallel Execution the HP-UX kernel's shmmax (shared memory maximum) configuration parameter if necessary. Warning Messages Warning: could not use requested number of processes. Using 1 process. (Parallel Library 311) The parallel runtime library could not start the requested number of processes for use in executing the program.
Programming for Portability 5 Programming for Portability The syntax of C is well defined as a result of the efforts of the ANSI X3J11 Technical Committee. The standard C function libraries are rich with features that isolate programs from operating system specific function calls. These factors make C programs highly portable between various combinations of hardware platforms and operating systems.
Programming for Portability Guidelines for Portability Guidelines for Portability This section lists some things you can do to make your HP C programs more portable. • Use the ANSI C compiler option whenever possible when writing new programs. HP C conforms to the standard when it is invoked with the -Aa option. The -w and +e options should not be used with the -Aa option, as these options will suppress warning messages and allow non-conforming extensions.
Programming for Portability Guidelines for Portability The main program fmult.c uses the #ifdef preprocessor command to include floatX.h by default. If the option -D IEEE_FLOAT is passed to the compiler, and subsequently the preprocessor, the program will use the IEEE representation for the structure float_rep rather than a machine-dependent representation. Partial contents of the file IEEE.h: #define FLT_MAX 3.
Programming for Portability Practices to Avoid Practices to Avoid To make a program portable, you need to minimize machine dependencies. The following are programming practices you should avoid to ensure portability: • Using dollar signs ($) in identifiers. • Using underscores (_) as the first character in an identifier. • Using sized enumerations. • Reliance on implicit expression evaluation order. • Making assumptions regarding storage allocation and layout.
Programming for Portability General Portability Considerations General Portability Considerations This section summarizes some of the general considerations to take into account when writing portable HP C programs. Some of the features listed here may be different on other implementations of C. Differences between Series 300/400 versus 700/800 implementations are also noted in this section.
Programming for Portability General Portability Considerations degradation will be significant, but if it only occurs in a few places in your program it shouldn't be a big concern. Whether you use alternative 2 or 3 above depends on your specific code. The +ubytes option costs significantly less per access than the handler, but it costs you on every access, whether your data is aligned or not, and it can make your code quite a bit bigger.
Programming for Portability General Portability Considerations Checking for Alignment Problems with lint If invoked with the -s option, the lint command generates warnings for C constructs that may cause portability and alignment problems between Series 300/400 and Series 700/800, and vice versa. Specifically, lint checks for these cases: • Internal padding of structures.
Programming for Portability General Portability Considerations Series 300/400 and Series 700/800 would look like this: struct S { char c1; char pad1,pad2,pad3; int i; char c2; char pad9,pad10,pad11, pad12,pad13,pad14, pad15; double d; }; /* /* /* /* /* /* /* /* byte 0 */ bytes 1 through 3 */ bytes 4 through 7 */ byte 8 */ bytes 9 */ through */ 15 */ bytes 16 through 23 */ Casting Pointer Types Before understanding how casting pointer types can cause portability problems, you must understand how Series 7
Programming for Portability General Portability Considerations As another example, if a program passes a casted pointer to a function that expects a parameter with stricter alignment, an alignment fault may occur.
Programming for Portability General Portability Considerations … #endif If this code is compiled on a Series 300/400 system, the first block is compiled; if compiled on Series 700, the second block is compiled; if compiled on either the Series 700 or the Series 800, the third block is compiled. You can use this feature to ensure that a program will compile properly on either Series 300/400 or 700/800.
Programming for Portability General Portability Considerations The char Data Type The char data type defaults to signed. If a char is assigned to an int, sign extension takes place. A char may be declared unsigned to override this default. The line: unsigned char ch; declares one byte of unsigned storage named ch. On some non-HP-UX systems, char variables are unsigned by default.
Programming for Portability General Portability Considerations such an expression against zero may not produce the object code you expect as the following example illustrates.
Programming for Portability General Portability Considerations unsigned int remainder:20; }; In this struct declaration, the assignment of data space for c must be aligned so it doesn't violate a byte boundary, which is the normal alignment of unsigned char. Consequently, two undeclared bits of padding are added by the compiler so that c is aligned on a byte boundary. sizeof(struct foo2) returns 6 (bytes) on Series 300/400, and 8 on Series 700/800.
Programming for Portability General Portability Considerations Structure Assignment The HP-UX C compilers support structure assignment, structure-valued functions, and structure parameters. The structs in a struct assignment s1=s2 must be declared to be the same struct type as in: struct s s1,s2; Structure assignment is in the ANSI standard. Prior to the ANSI standard, it was a BSD extension that some other vendors may not have implemented.
Programming for Portability General Portability Considerations f may be evaluated before or after g, but g(x) will always be multiplied by 5 before it is added to f(x). Since there is no C standard for order of evaluation of expressions, you should avoid relying on the order of evaluation when using functions with side effects or using function calls as actual parameters. You should use temporary variables if your program relies upon a certain order of evaluation.
Programming for Portability General Portability Considerations use during the compilation process. These files are normally invisible to you since they are created and removed automatically. If, however, your system is tightly constrained for file space these files, which are usually generated on /tmp or /usr/tmp, may exceed space requirements. By assigning another directory to the TMPDIR environment variable you can redirect these temporary files. See the cc manual page for details.
Programming for Portability Porting to ANSI Mode HP C Porting to ANSI Mode HP C This section describes porting non-ANSI mode HP C programs to ANSI C. Specifically, it discusses: • Compile line options. • ANSI C name spaces. • Differences that can lead to porting problems. ANSI Mode Compile Option (-Aa) To compile in ANSI C mode, use the -Aa compile time option.
Programming for Portability Porting to ANSI Mode HP C an initial value of 3.14: const float pi = 3.14; A const variable can be used like any other variable. For example: area = pi * (radius * radius); But attempting to assign a value to a const variable causes a compile error: pi = 3.1416; /* This causes an error. */ Only obvious attempts to modify const variables are detected. Assignments made using pointer references to const variables may not be detected by the compiler.
Programming for Portability Porting to ANSI Mode HP C struct s x; { /* Function body using the old method for declaring function parameter types */ } int new_way(struct s x) { /* Function body using the new method for declaring function parameter types */ } /* The functions "old_way" and "new_way" are both called later on in the program. */ old_way(1); /* This call compiles without complaint. */ new_way(1); /* This call gives an error.
Programming for Portability Porting to ANSI Mode HP C for declaring function parameter types */ extern double sqrt(double); /* The function "sqrt" is called later on in the program. */ sqrt(1); In this example, any value passed to sqrt is automatically converted to double. Compiling an existing program in ANSI mode yields some of these advantages because of the existence of prototypes in the standard header files.
Programming for Portability Porting to ANSI Mode HP C Function Prototype Considerations There are three things to consider when using function prototypes: • Type differences between actual and formal parameters. • Declarations of a structure in a prototype parameter. • Mixing of const and volatile qualifiers and function prototypes.
Programming for Portability Porting to ANSI Mode HP C different structures, both named stname. The stname referred by the declaration was created within prototype scope. This means it goes out of scope at the end of the declaration of func3. The declaration of stname on the line following func3 is a new instance of struct stname.
Programming for Portability Porting to ANSI Mode HP C Figure 5-4. These declarations show how successive levels of a type may be qualified. The declaration for actual0 has no qualifiers. The declaration of actual1 has only the top level qualified. The declarations of actual2 and actual3 have two and three levels qualified.
Programming for Portability Using Name Spaces in HP C and ANSI C Using Name Spaces in HP C and ANSI C The ANSI standard specifies exactly which names (for example, variable names, function names, type definition names) are reserved. The intention is to make it easier to port programs from one implementation to another without unexpected collisions in names.
Programming for Portability Using Name Spaces in HP C and ANSI C program using the defined libraries. Table 5-2. Selecting a Name Space in ANSI Mode When using the name space… Use command line option… or #define in source program Platform HP-UX -D_HPUX_SOURCE #define _HPUX_SOURCE HP-UX Only XOPEN -D_XOPEN_SOURCE #define _XOPEN_SOURCE HP-UX Only POSIX -D_POSIX_SOURCE #define _POSIX_SOURCE HP-UX ANSI C default default HP-UX In ANSI mode, the default is ANSI C name space.
Programming for Portability Silent Changes for ANSI C Silent Changes for ANSI C Non-ANSI mode HP C is different from ANSI mode HP C in ways that generally go unnoticed. On HP-UX, many of these silent differences can be found by running the lint(1) program. The following list provides some of these silent changes: • Trigraphs are new in ANSI C. A trigraph is a three character sequence that is replaced by a corresponding single character. For example, ??= is replaced by #.
Programming for Portability Silent Changes for ANSI C • Empty tag declarations in a block scope create a new struct instance in ANSI mode. The term block scope refers to identifiers declared inside a block or list of parameter declarations in a function definition that have meaning from their point of declaration to the end of the block. In the ANSI mode, it is possible to create recursive structures within an inner block.
Programming for Portability Porting between HP C and Domain/C Porting between HP C and Domain/C All HP-UX and Domain computers have ANSI C compilers. Strictly standard-compliant programs are highly portable between all these architectures. The following Domain/C extensions are not supported on HP-UX in compatibility mode and in most cases, are not supported in ANSI mode either: • Reference variables.
Programming for Portability Porting between HP C and Domain/C • Programs that rely on undefined behaviors, for instance, the order of expression evaluation and the application of unsequenced side-effects, will probably execute differently.
Programming for Portability Porting between HP C and VMS C Porting between HP C and VMS C The C language itself is easy to port from VMS to HP-UX for two main reasons: • There is a high degree of compatibility between HP C and other common industry implementations of C as well as within the HP-UX family. • The C language itself does not consider file manipulation or input/output to be part of the core language. These issues are handled via libraries.
Programming for Portability Porting between HP C and VMS C formats which are not compatible with VMS types but which are compatible with most other industry implementations of UNIX. • VMS C converts floats to doubles by padding the mantissa with 0s. HP-UX uses IEEE formats for floating-point data and therefore must do a conversion by means of floating-point hardware or by use of library functions. When doubles are converted to floats in VMS C, the mantissa is rounded toward zero, then truncated.
Programming for Portability Porting between HP C and VMS C Each character constant can contain up to four ASCII characters. If it contains fewer, as is the normal case, it is padded on the left by NULLs. However, only the low order byte is printed when the %c descriptor is used with printf. Multicharacter character constants are treated as an overflow condition on Series 300/400 if the numerical value exceeds 127 (the overflow is silent).
Programming for Portability Porting between HP C and VMS C _ _hpux and _ _unix on all systems • HP-UX preprocessors do not include white space in the replacement text of a macro. The VMS preprocessor does include the trailing white space. If your HP C program depends on the inclusion of the white space, you can place white space around the macro invocation. Compiler Environment • In VMS, files with a suffix of .C are assumed to be C source files, .OBJ suffixes imply object files, and .
Programming for Portability Calling Other Languages Calling Other Languages It is possible to call a routine written in another language from a C program, but you should have a good reason for doing so. Using more than one language in a program that you plan to port to another system will complicate the process. In any case, make sure that the program is thoroughly tested in any new environment.
Programming for Portability Calling Other Languages Table 5-5. C Interfacing Compatibility C HP-UX Pascal FORTRAN struct record (cannot always be done; C and Pascal use different packing algorithms) structure union record case of… union a. long double is available only in ANSI mode. Calling FORTRAN You can compile FORTRAN functions separately by putting the functions you want into a file and compiling it with the -c option to produce a .o file. Then, include the name of this .
Programming for Portability Calling Other Languages The C main program is compiled using cc -Aa x.c xx.o. Another area for potential problems is passing arrays to FORTRAN subprograms. An important difference between FORTRAN and C is that FORTRAN stores arrays in column-major order whereas C stores them in row-major order (like Pascal).
Programming for Portability Calling Other Languages It should be noted that a FORTRAN main should not be linked with cc. Calling Pascal Pascal gives you the choice of passing parameters by value or by reference (var parameters). C passes all parameters (other than arrays and structures) by value, but allows passing pointers to simulate pass by reference. If the Pascal function does not use var parameters, then you may pass values just as you would to a C function.
Programming for Portability Calling Other Languages The command line for compiling the C main program and linking the Pascal module is $ cc x.c pfunc.
Migrating C Programs to HP-UX 6 Migrating C Programs to HP-UX This chapter discusses issues to consider when migrating C language programs from VAX systems, HP 9000 Series 300/400, and HP 9000 Series 500 computers to HP 9000 Series 700/800 computers. The first section lists some steps you need to take to migrate an application program to an HP 9000 Series 700/800 computer.
Migrating C Programs to HP-UX Migrating an Application Migrating an Application Following are the general steps to migrate a C program from an HP-UX or UNIX system. 1. Test your program on the current system so you have a copy of the results. 2. Use the tar command (see the HP-UX Reference manual) with the cv options to transfer the source files you want to migrate to tape. 3. Use the tar command with the r option to transfer any associated data files to tape. 4.
Migrating C Programs to HP-UX Data Alignment data files should migrate to the HP 9000 Series 700/800 without change. Data Alignment The HP 9000 Series 700/800 is stricter than other machines with respect to data alignment. Misaligned data addresses cause bus errors when attempting to dereference them. Use the +w1 option when compiling to report occurrences of "Casting from loose to strict alignment.
Migrating C Programs to HP-UX Hexadecimal Escape Sequence space around the macro invocation. Hexadecimal Escape Sequence The HP 9000 Series 700/800 compiler allows character constants containing hexadecimal escape sequences. For example, can be expressed with the hexadecimal escape sequence . The HP 9000 Series 200, 300, and 500 do not allow hexadecimal escape sequences. Check your source files for any occurrences for \x, and verify that a hexadecimal escape sequence is intended.
Migrating C Programs to HP-UX Library Functions Library Functions The set of library routines available on HP-UX systems may differ from those available on BSD 4.2 systems. If you encounter an unresolved function after linking, refer to the HP-UX Reference Manual to see if there is an HP-UX function that does what you want it to do. If not, you will have to write one of your own. Floating-Point Format The VAX floating-point representation is different from that on HP 9000 computers.
Migrating C Programs to HP-UX Typedefs Typedefs The HP C compiler does not allow combining type specifiers with typedef names. For example: typedef long t; unsigned t var; Compilers derived from pcc accept this code, but HP C does not.
Using C Programming Tools 7 Using C Programming Tools This chapter contains a list and a description of the C tools. It also provides "how to use" information on lint and discusses HP specific features of lex and yacc. For more information on each of the HP C tools see the man pages or HP-UX Reference Vol. 1: Section 1. Another general source of information on lex and yacc is lex and yacc by John R. Levine, Tony Mason, and Doug Brown.
Using C Programming Tools Description of C Programming Tools Description of C Programming Tools Below is a brief description of each of the C tools. • cb is a C program beautifier. • cflow is a C flow graph generator. • cpp is the C language preprocessor. • ctags is a C programming tool that creates a tag file for ex(1) or vi(1) from the specified C, Pascal, and FORTRAN sources. • cxref is a C program cross-reference generator. • lex is a program generator for lexical analysis of text.
Using C Programming Tools HP Specific Features of lex and yacc HP Specific Features of lex and yacc The following native language support features have been added to the HP C lex and yacc tools: • LC_CTYPE and LC_MESSAGES environment variable support in lex - Determines the size of the characters and language in which messages are displayed while you use lex. • -m command line option for lex - Specifies that multibyte characters may be used anywhere single byte characters are allowed.
Using C Programming Tools Using lint Using lint The main purpose of lint is to supply the programmer with warning messages about problems with the source code's style, efficiency, portability, and consistency. The lint command can be used before compiling a program to check for syntax errors and after compiling a program to test for subtle errors such as type differences. Error messages and lint warnings are sent to standard error (stderr).
Using C Programming Tools Using lint The lint command accepts certain arguments, such as: -lm The lint library files are processed almost exactly like ordinary source files. The only difference is that functions that are defined on a library file but are not used on a source file do not result in messages. The lint command does not simulate a full library search algorithm and will print messages if the source files contain a redefinition of a library routine.
Using C Programming Tools Using lint detected. They have the following form: (line #) warning: message text Information about external functions and variables is collected and analyzed after lint has processed the source files. At that time, if a problem has been detected, it outputs a warning message with the form message text followed by a list of external names causing the message and the file where the problem occurred.
Using C Programming Tools Using lint followed by the function or variable name, the line number and file in which it was defined. The lint command also looks at the special case where one of the parameters of a function is not used.
Using C Programming Tools Using lint The lint command's detection of unreachable code is by no means exhaustive. Warning messages can be issued about valid code, and conversely lint may overlook code that cannot be reached. Programs that are generated by yacc or lex can have many unreachable break statements. Normally, each one causes a complaint from lint. The -b option can be used to force lint to ignore unreachable break statements.
Using C Programming Tools Using lint • character comparisons • pointer alignments (this is default on PA-RISC computers) • length of external variables • type casting Character representation varies on different machines. Characters may be implemented as signed values. As a result, certain comparisons with characters give different results on different machines. The expression c<0 where c is defined as type char, is always false if characters are unsigned values.
Using C Programming Tools Using lint int begin on a four-byte boundary. The following structure will be aligned differently on the two architectures: struct s { char c; long l; /* The offset equals 2 on MC680x0 computers */ }; /* and 4 on PA-RISC computers. */ In many cases the different alignment of structures does not affect the behavior of a program. However, problems can happen when raw structures are written to a file on one architecture and read back in on another.
Using C Programming Tools Using lint by sending the message: warning: precedence confusion possible: parenthesize! The lint command judges it bad style to redefine an outer block variable in an inner block. Variables with different meanings should normally have different names. If variables are redefined, the message sent is: warning: name redefinition hides earlier one The -h option suppresses lint diagnostics of strange constructions.