[comp.lang.c] "far" type specifiar

turner@sdti.UUCP (Prescott K. Turner) (06/18/88)

In article <6347@cup.portal.com> Paul_L_Schauble@cup.portal.com writes:
>Here's another request. I just had a go around with 'far' in Microsoft C.
>Could one of the wizards please post a description of how const, volatile,
>&c work in declarations?

The first confusing thing about Microsoft C's keywords near, far, etc. is the
terminology with which they are documented.  "Far" used in "far int" means
the int data object is allocated to far storage.  But when used in
"far pointer" it does NOT mean that the pointer data object is allocated to
far storage, it means that the object POINTED TO can be allocated to far
storage.  So to be clear, I prefer to say "pointer to far data" or
"far-allocated pointer" and avoid "far pointer" which has an ambiguous
tendency.

Microsoft C's syntax is not so bad as to share this ambiguity.  Its problem
is that the syntax for C++'s "const" type specifier works differently than
"far", and that ANSI incorporated "const".  "Const" tends to group to the
left, while "far" is grouped with things to its right.  Since Microsoft C is
staying compatible with earlier releases while adopting ANS extensions,
users will have to keep in mind both ways of using type specifiers.

My examples will use "far" and "const".  "Near" and "huge" work as "far".
"Volatile" works as "const".

Microsoft C rules:
   1. Given a declaration of some data object x, replacing x with
      (far x) declares that x is allocated in "far" storage.
   2. Given a declaration where "*" is used to indicate a pointer
      type, replacing "*" with "far *" indicates that the object
      pointed to may be allocated in "far" storage.
ANS C rules:
   1. Given a declaration where "*" is used to indicate a pointer
      type, replacing "*" with "* const" indicates that the pointer
      itself is unmodifiable.
   2. (Take a deep breath.)  Given a declaration of the form
            declaration-specifiers declarator;
      the declaration specifiers indicate some base type.
      The object declared either has that type, is a pointer
      to that type, an array of that type, or some such thing.
      Then adding "const" to the list of declaration specifiers
      says respectively that the object is unmodifiable, the
      object pointed to is unmodifiable, the array elements are
      unmodifiable, or some such thing.  For example, given
            int (*p)[3];
      declaring a pointer to an array of 3 integers, both
            int const (*p)[3];
            const int (*p)[3];
      declare a pointer to an array of 3 unmodifiable integers.

Examples:

Microsoft C pointer to far-allocated data:
      int far * p;
      int (far * p);    /* int far (* p);    is a syntax error */
ANS C pointer to unmodifiable data:
      int const * p;
      int const (* p);  /* int (const * p);  is a syntax error */
Microsoft C far-allocated pointer to ordinary data:
      int * far p;
      int (* far p);
      int * (far p);    /* int * far (p);    is a syntax error */
ANS C unmodifiable pointer to ordinary data:
      int * const p;
      int (* const p);
      int * const (p);  /* int * (const p);  is a syntax error */

It's not easy for Microsoft C to support both of these kinds of type
specifiers in combination.  Actually, there is a bug in the ANS support,
since Microsoft C indicates a syntax error for
      int (* const (* p));
which in ANS C declares a pointer to an unmodifiable pointer to an int.
--
Prescott K. Turner, Jr.
Software Development Technologies, Inc.
375 Dutton Rd., Sudbury, MA 01776 USA        (617) 443-5779
UUCP:genrad!mrst!sdti!turner