[comp.lang.ada] "limitations" of conditional compilation

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (12/11/89)

From emery@MBUNIX.MITRE.ORG (Emery):
> Armin points out that it is perfectly legal to do conditional
> compilation of statements based on some (constant) boolean value. [...]
> Where this approach fails, though, is in non-statements such as type
> declarations.  It would be nice to have support for this:
> 	type foo_bar is record
>           x : integer;
> #ifdef VAX
> 	    y : float_64;
> #elsif IBM_PC_WITH_8087    [...]
> 
> Using these ("constant type") variant records would probably make the
> program harder to read, because it wouldn't be clear to the maintainer
> if this was a variant record object (or subtype) based on some 'real
> variant) or based on some conditional compilation feature.  

   Amazingly enough, the standard SYSTEM package provides precisely
   the constant that we need to do this... it's SYSTEM.SYSTEM_NAME.

   Now are you REALLY contending that any competent maintainer is 
   going to fail to understand the following?

     type foo_bar (MACHINE : SYSTEM.NAME := SYSTEM.SYSTEM_NAME) is record
        X : Integer;
        case MACHINE is
           when VAX => Y : Float_64; 
           when IBM_PC_WITH_8087 => Y : IEEE_Float;
        end case;
     end record;

   The floating-point type definitions are taken from your example,
   despite the fact that they do not conform to the standard protocol
   for the naming of any additional compiler-supplied floating-point 
   subtypes (Short_Float, Long_Float, Long_Long_Float, etc.).  

   
   Bill Wolfe, wtwolfe@hubcap.clemson.edu
 

keith@sunpix.UUCP ( Sun Visualization Products) (12/13/89)

In article <7398@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>From emery@MBUNIX.MITRE.ORG (Emery):
>>  It would be nice to have support for this:
>> 	type foo_bar is record
>>           x : integer;
>> #ifdef VAX
>> 	    y : float_64;
>> #elsif IBM_PC_WITH_8087    [...]
>   Amazingly enough, the standard SYSTEM package provides precisely
>     type foo_bar (MACHINE : SYSTEM.NAME := SYSTEM.SYSTEM_NAME) is record
>        X : Integer;
>        case MACHINE is
>           when VAX => Y : Float_64; 
>           when IBM_PC_WITH_8087 => Y : IEEE_Float;
>        end case;
>     end record;

I no longer work in an Ada shop, so I don't have a compiler or my
old copy of the interpretations to help double-check
my reading of the LRM, but according to 3.7 (3)
"The identifiers of all components of a record type must be distinct."
I interpret this to mean that the above record is illegal.

However, even if my interpretation is incorrect, I still feel that
some form of conditional compilation above and beyond "IF FALSE" is
advantageous.  At my last job, we were implementing and maintaining
an Ada compiler (written in Ada) targeted to several machines.  As
much as possible, target dependencies were localized to packages and
tables.  However, there were still occasions when a target dependent
section was best handled in a file of primarily target independent
code.   These cases did not always neatly fit into the IF TARGET=X
code scenario.  We used a preprocessor to handle these cases.  However,
if such a preprocessor were standard to Ada, then the source could
have fit better into the 'normal' Ada development environment.

defaria@hpcladb.HP.COM (Andy DeFaria) (12/14/89)

>> Furthermore, there are many reasons besides host machine name for
>> doing separate compilation.  One that comes immediately to mind occurs
>> when a specific feature is present or absent from the version of the
>> operating system generated for a given machine.  I've seen this rather
>> frequently in Unix.
>
>   Appropriately handled in the package which provides the binding to
>   the operating system involved.  OS bindings must also be standardized,
>   and this is taking place; e.g., the IEEE 1003.5 Ada binding to Posix.
>    

I'm developing such a binding as we speak.  One problem that I have, and
haven't been able to workaround, is that of different representation clauses.
This OS binding is designed to be portable to multiple architectures.  The
data alignment of the different machines are different so I need to:

         Machine 1                                Machine 2
----------------------------------   ----------------------------------------
for RECORD_1 use                     for RECORD_1 use
   record                               record
      FIELD_1 at 0 range 0 .. 15;          FIELD_1 at 0 range 0 .. 15;
      FIELD_2 at 2 range 0 .. 15;          FIELD_2 at 4 range 0 .. 15;
      ...                                  ...
   end record;                          end record;

As you can see Machine 2 need to be aligned at the 4 byte boundary.  Since the
interface code I am going to is C (Unix system calls) I'm stuck the these
record layouts and alignments.  I have thought using some sort of constant to
determine where the next alignment would be but it would make the coding of
the for clause exceeding difficult.  

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (12/15/89)

From article <920015@hpcladb.HP.COM>, by defaria@hpcladb.HP.COM (Andy DeFaria):
> I'm developing such a binding as we speak.  One problem that I have, and
> haven't been able to workaround, is that of different representation clauses.
> This OS binding is designed to be portable to multiple architectures.  The
> data alignment of the different machines are different so I need to:
> 
%          Machine 1                                Machine 2
% ----------------------------------   ----------------------------------------
% for RECORD_1 use                     for RECORD_1 use
%    record                               record
%       FIELD_1 at 0 range 0 .. 15;          FIELD_1 at 0 range 0 .. 15;
%       FIELD_2 at 2 range 0 .. 15;          FIELD_2 at 4 range 0 .. 15;
%       ...                                  ...
%    end record;                          end record;
> 
> As you can see Machine 2 need to be aligned at the 4 byte boundary.  Since the
> interface code I am going to is C (Unix system calls) I'm stuck the these
> record layouts and alignments.  I have thought using some sort of constant to
> determine where the next alignment would be but it would make the coding of
> the for clause exceeding difficult.  

   Hmmm... how about:

      ALIGNMENT_LENGTH : constant := 2;   -- or 4, or whatever...

      for RECORD_1 use
         record
            FIELD_1 at 0 * ALIGNMENT_LENGTH range 0..15;
            FIELD_2 at 1 * ALIGNMENT_LENGTH range 0..15;
            ...
         end record;

   The general form of the "at" expression seems to qualify as a
   static_simple_expression (by 4.9.7 & 4.4.2, plus a similar 
   example is given in 13.4.9), and the coding of the for clause 
   would seem to be relatively straightforward.


   Bill Wolfe, wtwolfe@hubcap.clemson.edu
 

defaria@hpcladb.HP.COM (Andy DeFaria) (12/16/89)

>   Hmmm... how about:
>
>      ALIGNMENT_LENGTH : constant := 2;   -- or 4, or whatever...
>
>      for RECORD_1 use
>         record
>            FIELD_1 at 0 * ALIGNMENT_LENGTH range 0..15;
>            FIELD_2 at 1 * ALIGNMENT_LENGTH range 0..15;
>            ...
>         end record;
>
>   The general form of the "at" expression seems to qualify as a
>   static_simple_expression (by 4.9.7 & 4.4.2, plus a similar 
>   example is given in 13.4.9), and the coding of the for clause 
>   would seem to be relatively straightforward.

It's the old "who came first? the chicken or the egg" syndrone.  How do you
define ALIGNMENT_LENGTH?  Its 2 on some machines and 4 on others.