» Sign in
  
Jump to HP Home Jump to Product & Services Jump to Support & Drivers Jump to Solutions Jump to How to buy
» Contact HP
 » Advanced Search
Jump to HP Home

Coding practices for compatibility

Developer & Solution Partner Program (DSPP)


A site for HP Partners

 »  DSPP home

Benefits & Services
 »  Marketing & Sales
 »  Technical
 »  Collaboration

Resources & Downloads
 »  Technologies & Tools
 »  HP Products
 »  HP Solutions
 »  Software downloads

 »  Specialized programs

 »  Events
 »  Newsletters

Partner information
 »  Find a partner
 »  Find a partner solution

Shortcuts for
 »  Independent software vendors
 »  Integrators & Consultants

About DSPP
 »  Why join?
 »  Membership benefits

 »  Latest updates

 »  Contact us

 »  Site map

» Overview
» Undocumented usage
» Platform specific
» Header files
» Compile/link
» Usage of APIs
» Error handling
» Data types
» Documentation

Overview

This document describes coding practices that can impact the compatibility of an application. Well-behaved applications conform to the following list of guidelines. If an application violates any of these guidelines, it may render the application non-portable and future compatibility may be compromised. Here are some coding practices that must be followed to maintain compatibility from release-to-release.

Undocumented usage

Documentation may include HP man pages and product documentation.

  • The application does not use undocumented interfaces.
  • The application does not depend on undocumented behaviors.
  • The application does not read /dev/kmem directly, as it is an undocumented internal interface whose internal contents may change from release-to-release. Use pstat() instead.

Platform specific

  • The application design/code is not based on internal knowledge or undocumented behavior of the platform architecture or system configuration.
  • The application does not read or write directly to HP-UX system files, but accesses this information via supported APIs. For example, an application should use getpwent() and setpwent() to read/write password file entries.
  • The application does not hardcode information that is available via header files or configuration APIs. For example, the application should not define a constant for the maximum value for an object of type unsigned int; instead, include the limits.h header file and use the macro INT_MAX. System configuration information can be obtained by calling APIs such as confstr(), getconf, [f]pathconf(), sysconf().
  • The application obeys and does not attempt to subvert the runtime architecture and procedure calling conventions. For example, the application passes parameters in standard ways and does not write to reserved fields in the frame marker.
  • The application does not directly manipulate the stack or backing store and avoids non-standard use of setjmp()/longjmp() and user thread code.

Header files

  • The application includes all of the appropriate header files as indicated in the man pages.
  • The application does not include undocumented header files or use undocumented sections of header files.
  • The application does not copy the contents of system header files into source code. If the application needs to replicate system structures, copy only the required fields, one field at a time.

Compile/link

  • The application that was compiled/linked on a given HP-UX release, is not deployed on a previous older release. Backward compatibility is NOT supported; only forward compatibility is supported. The reason is that there is a processor-dependent component of the binary. For example, if you compile a PA2.0 binary on 11.x, you cannot execute it on a 10.10 PA1 .x system as there are additional instructions on PA2.0. Additionally, the API set is different on 10.20 and 10.10. For example, if you compile a PA1.1 binary on 11.x, you cannot execute it on PA1.1 10.x.
  • The application should avoid being linked with shared libraries that have dependencies on archive HP-UX system libraries. Shared versions of libraries (especially HP-UX system libraries) should be used where they exist.

    Linking with both shared and archive libraries needs careful attention as described below to avoid possible unresolved symbols, hidden definitions, and duplicate definitions that may cause an application to abort or exhibit incorrect behavior at run time.

    When linking an application with a shared library which has dependencies on an archive library (more specifically, which has symbols that are resolved by an archived library), minor modifications to a shared library may require additional external references, which were not present at the time the application was linked. These additional external references can lead to the failures described above.

    This problem can be exacerbated when applications link with two libraries that have circular dependencies on symbols resolved in each other's libraries.

    To maximize compatibility, it is recommended that all symbols are resolved by shared libraries; however, if an application needs to use a library that exists only in archive form, it is important that other libraries containing dependencies on that archive library are also linked archive.

    An application that links with shared libraries with dependencies on archive libraries can be fixed as follows (there are many more fixes as well):

    • An application can be compiled with both shared libraries (or if an archive application is needed, both archive libraries)
    • The 10.20 libxyz.sl can version in 11.x
    In order to prepare your software for Itanium and other IPF systems, it is recommended to use all shared libraries:
    • To avoid binding in architecture dependencies into applications
    • Defect fixes are picked up automatically by the application when the shared library is patched, the difference in performance between shared and archive will decrease as new architectures are optimized for shared performance.

      System archive libraries are not available on HP-UX 11i Version 1.5 on Itanium platforms. For detailed descriptions and examples, please see the HP-UX Linker and Libraries User's Guide.

  • The application does not explicitly use the C compile option -lc.
  • The application does not contain code based on platform-specific compiler features. An example is inline assembly code.
    • Applications: Applications do not need to include -lc on the C compile line. The C compiler driver automatically includes the C library during the link phase. When the application link phase is performed by explicitly invoking ld, -lc should be last argument on the command line.
    • Shared Libraries: A shared library can be built by explicitly specifying the list of libraries on which it depends.

      If a shared library has been built with -lc on its ld command line on HP-UX 11.x, then it has an explicit dependency on libc.2. If an attempt is made to use this library in an application, which was built on a prior release and was linked with libc.1, then the application will be implicitly linked with both libc.1 and libc.2.

      For example, shared libraries built with the -lc option of ld on HP-UX 11.x can only be used exclusively with applications built on HP-UX 11.x. Shared libraries built with the -lc option of ld on HP-UX 10.20 can only be used exclusively with applications built on HP-UX 10.20.

      Recommended action for impacted libraries:

      1. Remove -lc from the ld line in HP-UX 11.x
      2. If removal of this dependency is not possible, then the impacted libraries should be versioned
  • The application does not use shl_load()/dlopen() to dynamically load a link file as opposed to a real file. Using shl_load()/dlopen() to load shared libraries not owned by your application (i.e. system libraries - libc) is particularly dangerous as links change over time and could eventually point to the wrong version of the library. If you must do this despite HP's recommendations, you need to check the status (compatibility, versioning, links, ...) of the shared libraries each release.
    • The library may have been a real file in a previous release, but may now be a link to the latest version of the library in a newer release, which may not work with the affected application.
    • The new library may have new incompatible behavior or may have obsoleted APIs.
    • If archive libraries are used by the application, the new library may depend on new symbols not resolvable in the affected application.
    • Applications that use shl_load()/dlopen() need to re-examine the status of the libraries that they load EVERY release to look for changes that could break the application. It is not recommended to use shl_load()/dlopen() to load libraries not owned by your product as the libraries can change without your knowledge.

      The application that uses shl_load()/dlopen() to dynamically load shared libraries at run time does not use a library name with an .sl extension if a numerical extension of a library exists. The .sl extension is associated with a symbolic link which is inherently variable across releases and runtime environments. An application should dynamically load libraries using the name containing a numerical extension; the value of that extension should be the same as the value that is pointed to by the corresponding .sl symbolic link that is installed in the development environment being used for the application. In addition, note that IPF platforms use the suffix .so for shared libraries.

      For example, to dynamically load lib_ISV which has both .1 and .2 versions of the library, an application should use the following explicit .2 numerical extension and not use lib_ISV.sl in the parameter list. (This practice is recommended only for dynamic loading with shl_load().)

         GOOD: h = shl_load("lib_ISV.2", BIND_DEFERRED, 0);   BAD:  h = shl_load("lib_ISV.sl", BIND_DEFERRED, 0);

Usage of APIs

  • The application does not use interfaces that have been documented as non-portable across releases. Here is a list of some APIs that should be avoided:
    • Context APIs (i.e. sigcontext(), ...) Context APIs are not recommended due to possible compatibility problems from release-to-release, because context APIs are very architecture-specific. The context APIs expose the internal architecture to the application, such that the application may not be compatible with all releases.

      If you must use context APIs, be aware of the following:

      Do not copy the context yourself. It is not contiguous. The context may have pointers that may point back to the original context rather than in the copied context; hence, it will be broken. The size of the context will vary in length from release-to-release.

    • nlist() Use of nlist() beyond checking for the existence of symbols will reduce binary and source compatibility in the application. Great care must also be taken in handling the error case if the symbol is not available. Note that nlist() is not available on IPF platforms.
    • pstat() 32-bit applications that will be deployed on 64-bit HP-UX platforms must use the pstat() wrappers turned on with -D_PSTAT64 in order to function correctly and remain compatible on the 64-bit HP-UX OS. See the pstat() section in the release notes for more details.
    • ptrace/ttrace() The function signature of the API will maintain source compatibility from release-to-release. Much of the functionality of ptrace() is highly dependent on the underlying hardware. An application that uses this system call should not be expected to be supportable across architectures or implementations. Note that ptrace() is not available on IPF platforms.
    • [sig]setjmp()/longjmp() The contents of the jmp_buf buffer are architecture and compilation environment specific. Thus, objects built using these functions may not be supported across architectures.
    • sigstack()/sigspace() There is not enough information provided in sigstack() to deal completely with stack sizes, directions, and multi-threading from release-to-release. sigstack() and sigspace() system calls should not be used for systems desiring future compatibility for the above reasons and there is already a better interface provided - sigaltstack().
    • uname(1) - uname -m Code that uses uname(1) to obtain the model string information should be changed to use getconf(1)/confstr(). The uname(1) command does not return a unique machine identification string on IPF platforms. uname(1) is restricted to eight characters for the model. The V-class machine has more than eight characters for the model. If the model string is longer than eight characters uname(1) will truncate the model string to eight characters. It is therefore recommended that the model(1) command be used to obtain the model string. Note that IPF platforms return a string beginning with ia64, while all PA platforms return a string beginning with 9000/.
  • The application does not use APIs that are obsolete or marked for obsolescence.
  • The application should avoid usage of APIs deprecated (marked for future obsolescence).
  • The application should use industry standard APIs over similar HP-proprietary solutions, as these may change to adhere to standards.

Error handling

  • The application handles the C language case labeled default when dealing with errno values or return values in order to handle future functional enhancements with new errno or return value cases. Examples of such APIs include: getconf, getcontext(), sysconf(), sysinfo(), uname, ...
  • The application uses signal handlers when using signals.

Data types

  • The application uses the appropriate data types as indicated in the documentation consistently throughout the application. For example, if the difftime() documentation states that the first parameter is a time_t, that parameter and all interactions with that parameter should be of type time_t.
  • The application does not make assumptions about undocumented relationships or sizes of data types. Header files are not considered documentation. For example, the application does not assume that the following pairs are the same size: long/int, time_t/int, ssize_t/long.
  • The application does not perform expression evaluation, assignments, bit shifts, data promotion between data objects of varying types/sizes.

Documentation

The application is not in violation of the information specified in the man pages, white papers, Release Notes, or other product documentation.








Printable version

Privacy statement Using this site means you accept its terms Trademark acknowledgment Contact us
HP Confidential © 2009 Hewlett-Packard Development Company, L.P.