[comp.lang.ada] conditional compilation

haug%vax.runit.unit.uninett@TOR.NTA.NO (Steinar Haug) (06/13/88)

Hi,

I'm developing programs for both DEC VAX (VAX/VMS Ada compiler) and
SUN-3 (Alsys Ada compiler). I need to use some form of conditional
compilation. The Alsys compiler has the BEGIN_COMPILE/END_COMPILE
pragmas to control the compilation but I have not found any similar
mechanism for the VAX/VMS compiler. Can anybody out in Adaland tell
me how to do conditional compilation with the VAX/VMS compiler?

The LRM contains a reference [10.6] to conditional compilation but
it seems rather cryptic and it is not obvious to me how I could use
it in practice.

Steinar Haug             ! ARPA:        haug%vax.runit.unit.uninett@tor.nta.no 
Database Research Group  !   or:        steinar@tor.nta.no                     
Computing Research Center! EAN(X.400):  haug@vax.runit.unit.uninett            
 University of Trondheim ! BITNET/EARN: haug@norunit                           
7034 Trondheim, NORWAY   ! VMS Mail:    psi%02422530001003::12423              
                         !       or:    psi%0242211000114::z_haug_s            

rds@moss.ATT.COM (06/17/88)

On the issue of conditional compilations in Ada...

Our Ada requirements would be well suited by a conditional compilation
but our application must be portable. My interpretation of LRM 10.6(2)
is since the compiler omits code not referenced the programmer can
omit code by conditionally (not) referencing it and setting static
conditions for evaluation at compile time. 

If this is, in fact, what the LRM intends to say it is an insufficient
method for conditional compilation. Consider the following scenario:

Package A is generic with a generic type parameter. Package B is generic
with the same generic parameter. A particular system requires only
package A and another system requires both A & B. 

B's compilation requires the existance of an instantiated version of A.

It is important that the customer with system A who does not need package B
not get package B and not neccesarily know of the existance of package B.

An appropriate solution (in a C environment) is to conditionally
include the code for package B with package A at compilation time.

The LRM does not require the implementation of an include like feature.

Is there an accepted practice for "including" files in the Ada world?

Richard DeSimine
AT&T Bell Laboratories
(201) 386-2059

rjs@moss.ATT.COM (06/17/88)

In article <909*haug@vax.runit.unit.uninett>
haug%vax.runit.unit.uninett@TOR.NTA.NO (Steinar Haug) asks:
>I'm developing programs for both DEC VAX (VAX/VMS Ada compiler) and
>SUN-3 (Alsys Ada compiler). I need to use some form of conditional
>compilation.
>
>The LRM contains a reference [10.6] to conditional compilation but
>it seems rather cryptic and it is not obvious to me how I could use
>it in practice.
>
This seems to be the type of mechansim that 10.6 is referring to:

-- At the beginning of your source, or in a separate package that you
-- include in any module that needs to conditionally compile based on
-- the target, make the following declarations.

type MACHINE_NAME is (VAX, SUN3);
TARGET : constant MACHINE_NAME := VAX;  -- Change this line to compile
                                          -- for a different target


-- Then wherever you need to conditionally compile code based on the 
-- target machine, use the following:

case TARGET is
  when VAX =>
	-- VAX specific code goes here.
  when SUN3 =>
	-- SUN-3 specific code goes here.
end case;


Of course this solution assumes that you can put all your conditional
stuff in a case statement.  The compiler is allowed to not generate any
of the code for the obviously FALSE case.
Good Luck.

	Robert Snyder
	{ihnp4|clyde}!moss!rjs
	(201) 386-4467
The above statements are my own thoughts and observations and are not
intended to represent my employer's position on the subject(s).

jb@rti.UUCP (Jeff Bartlett) (06/22/88)

In article <28254@clyde.ATT.COM>, rds@moss.ATT.COM writes:
> 
> If this is, in fact, what the LRM intends to say it is an insufficient
> method for conditional compilation. Consider the following scenario:
> 
> Package A is generic with a generic type parameter. Package B is generic
> with the same generic parameter. A particular system requires only
> package A and another system requires both A & B. 
> 
> B's compilation requires the existance of an instantiated version of A.

1. if the customer is to do this instantiation of A then they must receive
   the source for B.

> It is important that the customer with system A who does not need package B
> not get package B and not neccesarily know of the existance of package B.

2. This implies that there are no packages in the minimal system that depend
	on B
     ==> no shipped executables need package B.
     ==> package B is supplied to customer in source or in a shipped
         compilation library

> An appropriate solution (in a C environment) is to conditionally
> include the code for package B with package A at compilation time.
 
The C source would have:
	#ifdef EXTRA_FEATURES
	#include "package_b.c"
	#endif

- the existance of package B should not be revealed in limited systems.
- the C source would reveal the existance of package B
- C is appropiate solution.
==> the customers do not get the source.

for the limited system:
    - if it is in a shipped compilation library compile everything
      and delete the interface and body for package B from the library

    - not supplied B in source form (for the case of user instantiated A and
      '#include "package_b.c"' is acceptable ).

    - these are separately compilable units.  Just don't compile the
      file containing package B.

Any bad assumptions or flaws in logic?

Are the any tests in the Ada compiler validation suite that checks that
compilation unit Y does not depend on the interface of B in the compilation
library?

    with B;
    procedure Y is
       K : B.TYPE1;  -- unref'd, may be removed
    begin
	if FALSE then
	    B.ROUTINE1;
	    K := 5;
	end if;
    end Y;

DecAda V1.5 has the library dependancy but no code or stack space was generated.

LRM 10.1.1.6 states that the 'with' will cause a library dependancy.  Should
the optimizer be allowed to revoke it or does a 'with' imply an explict
elaboration of package B regardless of the fact that there are no references
to B in procedure Y.

Of course this isn't allowed

   procedure Y is
   begin
      if FALSE then
	 declare
	    with B;
	    K : B.TYPE1;  -- unref'd, may be removed
	 begin
	    B.ROUTINE1;
	    K := 5;
	 end;
      end if;
   end Y;

if it were then the compiler could safely assume that the elaboration of B
was not needed.
     
> Richard DeSimine
> AT&T Bell Laboratories
> (201) 386-2059

Jeff Bartlett
Center for Digital Systems Research
Research Triangle Institute
jb@rti.rti.org		...mcnc!rti!jb

arny@wayback.UUCP (Arny B. Engelson) (06/23/88)

In article <28254@clyde.ATT.COM>, rds@moss.ATT.COM writes:
> 
> On the issue of conditional compilations in Ada...
> 
> Our Ada requirements would be well suited by a conditional compilation
> but our application must be portable. My interpretation of LRM 10.6(2)
> is since the compiler omits code not referenced the programmer can
> omit code by conditionally (not) referencing it and setting static
> conditions for evaluation at compile time. 
 
LRM 10.6 is insufficient for conditional compilation because it is not
REQUIRED that an implementation check for code that will never be executed
and eliminate the corresponding object code.  It (the LRM) only says that
it is permissible to do this as part of optimization.  Some compilers may
do it, some may not, and some may do it only if (the equivalent of)
/optimize is used.

This is an (optional) optimization step, not a standardized way of
providing conditional compilation.  Personally, I think the "pragma"
solution for conditional compilation works well, and would like to see
it standardized and provided with all implementations.  Comments?

  - Arny Engelson

djs@actnyc.UUCP (Dave Seward) (06/28/88)

In article <1369@wayback.UUCP> arny@wayback.UUCP (Arny B. Engelson) writes:
>In article <28254@clyde.ATT.COM>, rds@moss.ATT.COM writes:
>> On the issue of conditional compilations in Ada...
>[...]
>This is an (optional) optimization step, not a standardized way of
>providing conditional compilation.  Personally, I think the "pragma"
>solution for conditional compilation works well, and would like to see
>it standardized and provided with all implementations.  Comments?

I don't like the pragma approach as it is very hard to specify it within
the bounds of pragma legality. RM 2.8(8) says "An implementation is not
allowed to define pragmas whose presence or absence infuences the legality
of the text outside such pragmas." This means that conditional compilation
pragmas could not be used to select one of multiple possible declarations,
as, without the pragmas, the program would be seen to have multiple,
conflicting declarations of the same identifier.

Additionally, a significant conditional compilation facility requires a
meta-language of its own for definition and evaluation of conditions upon
which to include text into a compilation or not. This would probably be
force fit into existing Ada rules for declarations and expressions, or
would stick out like a sore thumb.

I am in favor of a distinct facility in the programming environment, like
a preprocessor, for doing file inclusion, conditional compilation, and
the like. Go ahead and standardize it, but don't force it into the Ada
compiler. A compiler should compile the text you feed into it. Defining
that text is a job for other tools.

Dave Seward
uunet!actnyc!djs

brucej@hcx9.SSD.HARRIS.COM (06/29/88)

djs@actnyc.UUCP states several objections to embedding conditional
compliation within an Ada compiler:

> I don't like the pragma approach as it is very hard to specify it within
> the bounds of pragma legality.  [RM references & explanation deleted]

> Additionally, a significant conditional compilation facility requires a
> meta-language of its own for definition and evaluation of conditions upon
> which to include text into a compilation or not. [more deletions]

> I am in favor of a distinct facility in the programming environment, like
> a preprocessor, for doing file inclusion, conditional compilation, and
> the like. Go ahead and standardize it, but don't force it into the Ada
> compiler. 

Here at Harris, we discovered a need for conditional compilation when
we first attempted to rehost and retarget the toolset we ship with our
Ada compiler.  Our approach was to create a preprocessor to perform 
that conditional compilation, and to implement code in the compiler
to automatically invoke the preprocessor as needed.  Ada source files
have a `.a' suffix,  while files in need of preprocessing have a `.pp'
suffix.  If the compiler's input file ends in `.pp' it first invokes
the preprocessor ("a.pp <foo.pp >foo.a"), and then compiles the `.a' file.

Preprocessing as a separate pass is cheap and efficient.  Invoking an
expensive global optimizer to perform this function is overkill.  Besides,
the optimizer has more than enough to do anyways.

While it would be presumptuous of me to propose that Harris' preprocessor
syntax be standardized,  I can at least point out the preprocessor's great 
value in allowing us to use a common set of source code for our Ada toolset 
for all of our different host/target combinations.  We found a.pp so useful
that we released it as part of our toolset.

----------
Bruce Jones 
brucej@hcx1.harris.com
Harris Computers, Fort Lauderdale, FL

emery@MBUNIX.MITRE.ORG (Emery) (12/12/89)

Bill Wolfe writes:
>   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;

I contend that any competent compiler will REJECT this code for (at
least) two reasons:
	1.  There is no guarantee that an arbitrary compiler will have
either of the two enumeration values "VAX" or "IBM_PC_WITH_8087" in
the type SYSTEM.NAME.  Furthermore, the declaration is ILLEGAL if the
(enumeration type) SYSTEM.NAME has additional values besides the two
mentioned (although the addition of "when others => null;" would at
least fix this problem.) 
	2.  Even if these two exist, the program is still semantically
ILLEGAL, as you would have two components both named Y, which is not
permitted. 

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.

L.T.F.L.
				dave emery
				emery@aries.mitre.org

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

From emery@MBUNIX.MITRE.ORG (Emery):
>>   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;
> 
> 	1.  There is no guarantee that an arbitrary compiler will have
> either of the two enumeration values "VAX" or "IBM_PC_WITH_8087" in
> the type SYSTEM.NAME.   [...]

   The point is that the construction would be easily understood
   by a hypothetical maintainer.  There is a need to standardize
   the set of SYSTEM.NAMEs on each pass of the validation cycle, 
   but a similar problem would arise with the proposed conditional
   compilation mechanism.  If one environment had IBM_PC_WITH_8087
   and another expressed the same hardware as IBM_PC_8087_CPU, the 
   lack of name standardization would be similarly troublesome.

   Once this standardization (required in either case) is accomplished,
   the problem is solved.  There is no need for conditional compilation.

> 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.
    
   Conditional compilation would introduce an entirely new mechanism;
   such a move must be justified in terms of benefits which cannot
   reasonably be obtained using existing mechanisms.  The situations 
   cited thus far do not appear to satisfy this requirement.  


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

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

In article <7403@hubcap.clemson.edu> billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu writes:
>    
>   Conditional compilation would introduce an entirely new mechanism;
>   such a move must be justified in terms of benefits which cannot
>   reasonably be obtained using existing mechanisms.  The situations 
>   cited thus far do not appear to satisfy this requirement.  

As of this  reply to dave emery, you still haven't dealt with the fact 
(brought out by dave and myself) that your proposed construct (using 
a component named Y twice) is illegal.   
 
I generally respect your views, but in this case, I think the fact 
of the matter is that people are already using preprocessors.  Standardizing 
to some syntax would simply make it easier to integrate the true source code 
with smart editors, debuggers, etc.