Annex E Portability Considerations


This section gathers together information about areas where this standard deliberately gives leeway to implementations. This leeway is intended to allow compliant implementations to make choices that provide better performance or add value in other ways. But this leeway inherently makes programs non-portable. This section describes the techniques that can be used to ensure that programs operate the same way independent of the particular implementation of the CLI.

Note that code may be portable even though the data is not, because of both size of integer type and direction of bytes in words. Read-write invariance holds, provided the read method corresponds to the write method (i.e., "write as int, read as int" works, but "write as string, read as int" might not).

E.1 Uncontrollable Behavior

The following aspects of program behavior are implementation-dependent. Many of these items will be familiar to programmers used to writing code designed for portability (for example, the fact that the CLI does not impose a minimum size for heap or stack).

  1. The heap and stack aren't required to have minimum sizes.

  2. Behavior [is] relative to asynchronous exceptions (see System.Thread.Abort).

  3. Globalization is not supported, so every implementation specifies its culture information, including such user-visible features as sort order for strings.

  4. Threads cannot be assumed to be either pre-emptively or non-pre-emptively scheduled. This decision is implementation-specific.

  5. Locating assemblies is an implementation-specific mechanism.

  6. Security policy is an implementation-specific mechanism.

  7. File names are implementation-specific.

  8. Timer resolution (granularity) is implementation-specific, although the unit is specified.

E.2 Language- and Compiler-Controllable Behavior

The following aspects of program behavior can be controlled through language design or careful generation of CIL by a language-specific compiler. The CLI provides all the support necessary to control the behavior, but the default is to allow implementation-specific optimizations.

  1. Unverifiable code can access arbitrary memory and cannot be guaranteed to be portable.

  2. Floating point compiler can force all intermediate values to known precision.

  3. Integer overflow compiler can force overflow checking.

  4. Native integer type need not be exposed, or can be exposed for opaque handles only, or can reliably recast with overflow check to known size values before use. Note that "free conversion" between native integer and fixed-size integer without overflow checks will not be portable.

  5. Deterministic initialization of types is portable, but "before first reference to static variable" is not. Language design either can force all initialization to be deterministic (cf. Java) or can restrict initialization to deterministic cases (i.e., simple static assignments).

E.3 Programmer-Controllable Behavior

The following aspects of program behavior can be controlled directly by the programmer.

  1. Code that is not thread-safe may operate differently even on a single implementation. In particular, the atomicity guarantees [that] around 64-bit must be adhered to, and testing on 64-bit implementations may not be sufficient to find all such problems. The key is never to use both normal read-write and interlocked access to the same 64-bit datum.

  2. [Be careful with] calls to unmanaged code or calls to non-standardized extensions to libraries.

  3. Do not depend on the relative order of finalization of objects.

  4. Do not use explicit layout of data.

  5. Do not rely on the relative order of exceptions within a single CIL instruction or a given library method call.



The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net