[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::languages

Title:Languages
Notice:Speaking In Tongues
Moderator:TLE::TOKLAS::FELDMAN
Created:Sat Jan 25 1986
Last Modified:Wed May 21 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:394
Total number of notes:2683

10.0. "Conditional Compilation, pro or " by KOALA::ROBINS () Mon Mar 26 1984 23:30

I'd like to solicit comments on conditional compilation as a programming/design
technique.  I personally dislike it, but many of the people I work with think
it's the best thing since sliced bread.  If you have any ideas on how I can 
convince them of the truth (that it is a sleazy technique for lazy people),
please help me.  If you want to try to convince me otherwise, well, try. I'm
more open minded than the previous sentence implies.

We use (could you guess?) KOALA.

sar
T.RTitleUserPersonal
Name
DateLines
10.1VAXUUM::DYERWed Mar 28 1984 15:246
	Conditional compilation is very nice when you're trying to write
portable code.  It's also useful for putting in debugging code that you
don't want to keep in, etc.
	On the other hand, I've seen some really gross stuff done with
it.  Used without proper documenting, it serves to make code unreadable.
		<_Jym_>
10.2SERPNT::ARONSONThu Mar 29 1984 09:2714
Conditional code is a practically a necessity when one is developing 2 or
more different systems that are similar enough to share 75%-95% of the
code.  An example is the devlopment practice of the P/OS group for the
hard disk PRO350 and the floppy based PRO325.  If it weren't for conditional
code, we would have to maintain 2 sets of source code.  In real $$$ terms,
that would mean at least another 175M disk, tracking bugs in 2 places,
writing redundant code, and having 2 systems so diverge, that it would be
impossible to merge them again.  Fortunately, we work on these systems
serially.  Hard disk, then floppy based system.  The development cycle
for the floppy based system is about 50% of the hard disk system.  What would
that cost DEC.  I would imagine the saving is considerable.  The time of
the developers and management, plus the shelf costs saved by getting the
system out the door quicker.  If used wisely, conditional code = $$$$.
10.3ELUDOM::ARSENAULTThu Mar 29 1984 11:2913
The Bliss compiler is itself written in Bliss.  The compiler runs on VAXEN and
10/20's, and produces code for 11's.  The vast majority of code is common.
Modules that do I/O and modules that generate code are system-specific and
do not have much, if any, conditional code.  The common code has a small
amount of conditional code.  

Working on a system with conditional code is a little more difficult than
working on a system without it.  However, it's a lot easier than maintaining
half a dozen separate copies of all the code.

Overall, it works out rather well.

mark
10.4REX::MINOWThu Apr 05 1984 11:5817
The DECtalk firmware contains many conditional code segments --
this allows us to run the same firmware on Vax/VMS (for debugging)
and the 68000 for production.  It also allows several of the larger
modules to contain stand-alone test packages which appear only
when the magic flag is set.

Usually, the conditionalization is done automatically -- the various
compilers predefine environment varialbles which are tested as needed.

Another issue is the need, in some places, to do conditional execution.
(not in DECtalk, however).  For example, the Decus C library must
test whether RSX-flavored code is running under vms/rsts/pos "emulation"
to set magic features correctly.

The alternative, as has been mentioned, is chaos.

Martin.
10.5BARTOK::BARABASHThu Apr 19 1984 15:5910
The Galileo skeleton parser uses conditional compilation to allow the user to
select the desired set of features.  For example, tracing routines, syntactic
error recovery, a tree builder, keyword abbreviation.  They're all there in the
code, and turning on the appropriate bit in the variant number causes the
feature to be compiled into the parser.  The VAX Galileo kit contains a command
procedure that helps the user select the right set of features, then submits a
batch job which does the compilations using the correct BLISS/VARIANT=nn
command.

-- Bill B.
10.6VLNVAX::RDFMon Apr 30 1984 13:4710
I agree with the "one copy of source" rational.  The best thing about this
is that you can not ignore machine specific optimizations, while still
keeping the code in one spot.  Granted you can have seperate BLISS library
files which have the same macro names implemented different ways, but often
it is important to see why you would issue a BLT on TOPS-20 vs a CH$MOVE
on a VAX.  In writing a portable product, making maintenance changes can be
easier if you can "see it all" as you work.

Rick
10.7TURTLE::GILBERTMon May 07 1984 04:1845
Besides the previously mentioned benefits....

Conditional code allows one to put and keep debug code in the sources.
This is certainly better than developing the debug code and throwing it
all away when the code is product-ized; and it can make the code easier
to maintain.  The debug code could be put in another module, but this
often requires that data structures internal to a module be exported to
the debug module.

Conditional code also allows new program features to be added and tested
before they are officially approved.  For example, VAX Sort/Merge allows
the users to define conditions using simple comparisons, ANDs and ORs,
but not NOTs (don't throw rocks at me - I fought hard just to get ANDs and
ORs to have their normal precedence); the code supporting NOTs is conditional
on the definition of a NOT keyword.  Some prototyped but incomplete code
is also conditionalized - this should simplify the next persons job.

Conditional code is useful for checking assumptions at compile-time.
Code that depends on a particular ordering of fields, for example, can
assert such, and issue a warning if the compile-time assertion fails.
Knowing that no code is produced helps justify a liberal use of an "assert"
macro.

Some expressions are more easily written (and read) with assertions.  For
example, asserting that the VMS block size equals the page size.

Internal format records in VAX Sort/Merge may contain some of the following:
an RFA, a length, the original record, converted keys, an input file number,
stable information, a format field, original keys, and a VFC field.  Constants
define the relative ordering of these fields; any code relying on the ordering
asserts its assumptions; in fact, these assertions were useful in producing the
ordering in the first place.  They also assure that any innocent changes will
be diagnosed at the place where the assertion fails (which is better than a
blanket "don't rearrange these fields" where they are defined).

Certain types of code can be effectively and consistently marked by prefixing
with, for example, "IF HACK_K_STRIP THEN ...", where HACK_K_STRIP is a literal
defined to be true.  This makes such code easy to find, while the alternative
of using only comments offers less guarantee of finding them all, and may
produce many false matches.

					- Gilbert

Please excuse the verbosity and inappropriateness of the above.  Should coding
style and maintainability be taboo in a notes file called HACKERS?
10.8ULTRA::HERBISONMon May 07 1984 15:2920
As mentioned in the previous replies, you can do these nifty things with
conditional code which mean that you can finish development before you
finish logging in and save DEC millions of dollars a day in the process
(excuse the slight exageration).  However, you can also use them for no
good reason and end up with a program that is both a TECO compiler and
a FORTRAN interpreter, has 99.5% of the code conditionalized and is
impossible to fix.

As with many other things you can give a person, I see no way to allow
all the benificial uses of conditional assembly and at the same time
prevent any harmful uses.

If you are trying to sell a system for any fool to use correctly,
avoid things which can cause bad problems if misused.  If you are
giving a system to a good programmer or someone who thinks he is
(I fall into one of those categories), give them things which can
be useful and tell them what good and bad uses are for the feature.
People who can program well should make good use of it and people
who can't should learn to stick to simpler things.
						B.J.
10.9VLNVAX::RDFWed May 09 1984 00:1715
All you have said are true.  BUT even with all the complexities you
can generate with conditional compilation, you can often present a clean
easy to use interface for a green programmer to maintain or enhance.  Quite
often you just get your hands dirty once with the macros, and deal with
an easy to maintain macro interface for years.   

I admit I tend to gag a bit though, when I want to find out what is
really going on and find a four page macro loaded with %DECLARED and %LTCE's
and the like.

Bottom line.   Systems programming languages are not made for any fool to
use correctly, they fall into the second category you mention.

Rick
10.10ALIEN::PETTENGILLFri May 18 1984 05:5131
I would broaden the question a little bit:

	Should a language support various lexical functions, such as
	macros, environment information (word size, precision, target
	machine), and conditionals?

I feel that the features are very important for any language, BLISS or FORTRAN
or KOALA.  I have at times have almost switched from FORTAN to MACO or BLISS
just so I could define some data easily rather than having to pains takingly
fit it into FORTRANs syntax.  For a quick and dirty parser, TPARSE is great
but try doing something similar in FORTRAN.

KOALA potentailly has an advantage (like ADA) because the compiler knows all
and in theory can rearrange and restructure for you.  In a sense you could
write a module that creates the tables from simple data and then the compiler
could figure out that this is one time initialization code and generate the
tables and leave out the code.  Or the compiler could make all the decisions
as to how the code should be different on the 8086 vs VAX vs VMS vs RSX vs
P/OS vs UNIX etc.

Or are really just looking for an excuse to say,

	"find n programmers for the n+1 hardware systems that you want
	to support but leave me alone.  I'll code for the user with the
	personal 20 MIPS 32MB VAX where I don't have to deal with cheap
	hardware.  All those other fools can figure out how to make my
	cost run on hardware that cheap people what to buy."

(Of course it could be a sonmewhat different line:  Hey the PDP-8 is the
only reasonable computer to implement word processing and business applications
on.  Besides, what other compiler (sic) outputs a banner that represents itself.)
10.11RAINBW::CRESSEYTue Jul 03 1984 17:4622
flame_setting := dull_roar {;}

re: "sleazy technique for lazy people".  Anybody who isn't lazy should
GET OUT of the automation industry!  The very best techniques there are
are precisely the ones that allow someone to acheive, with less EFFORT,
the same, or better RESULTS, than with some inferior technique.  Good
labor saving techniques are almost always the product of an interesting
blend of COMMITMENT (to results not effort), creativity, and LAZINESS!

With regard to the specific issue:  Languages that don't allow 
conditional compilation force program writers make up their minds
at writing time concerning some questions that would be better left to 
compile time, (but not better left to link time).  This is a disservice.

The manyana principle applies here:  Don't bind yourself too early.
      ^^
      ||
      ||
(feeble attempt to render     Regards,
 the Spanish letter "enye")     Dave Cressey

flame_setting := initial_flame_setting
10.12Koala::ROBINSTue Jul 03 1984 19:3044
My reply:

    1) It aids in portability.

        Koala is a high level language.  Any non-portable code is usually
        operating-system dependent.  The statements (subroutines) that are
        machine- or operating-system- specific can be placed in a module
        by themselves and exported from there.  In this way I have written
        a program which runs under VMS, RSX, POS, and MS-DOS (on a rainbow)
        without a single line of conditional code.  There is only ONE
        operating-system dependent module, and that contains file names.

    2) For developing two very similar systems, which share up to 95% of the
       code. (floppy and hard-disk systems)

        The same technique could work with hardware dependencies.

    3) You can keep test or debug code in the source.

        Any good compiler (and even a few bad ones) can perform a peephole
        optimization called (I think) 'constant propagation'.  If you surround
        all your test/debug code with an if statement of the form:

            IF debug_flag THEN
                debug_code_here ;
            END IF ;

        and define debug_flag as a boolean constant.  When debug_flag is TRUE,
        the code will be generated.  The extra IF shouldn't matter since you
        are debugging.  When you are finished debugging, you define debug_flag
        to be FALSE.  The compiler, if it performs constant propagation, will
        not generate object code that would never be executed.

    4) New features can be added and tested before they are approved.

        Same argument.  Replace debug_flag with new_feature_flag.


        Maybe what I really should have asked is, What can you do with
        conditional compilation that you can't do with the structuring
        techniques most modern high-level languages give you (like modules)?


sar
10.13ALIEN::PETTENGILLWed Jul 04 1984 15:0313
My experience with BLISS is that its flow analysis doesn't produce optimal
code in many cases if conditionals are implemented with compile time constants.
The semantics of the language restrict the code motion out of blocks so that
the blocks required to enclose the conditional code result in values being
materialized that might otherwise be used by inference.

While you might argue that this is a failing in the BLISS compiler, the BLISS
implementations have advocated this technique more than most other compilers
and yet haven't been able to eliminate the need for conditional compilation.
Until code optimization is so well advanced that every compiler incorporates
what is today state of the art, there will be a need for allowing the programmer
to provide additional information to the compiler about the structure of the
code.
10.14LATOUR::AMARTINWed Jul 04 1984 15:4312
Using IF's with constant conditions can only replace conditional compilation
when you want to eliminate pieces of code and data you can put inside of
a nested scope (block).  You can't leave out parts of a table being
initialized, or similar things.

Trying to chop up your program lexically by using control flow operations
is not the best way to go about the job.  It certainly isn't a very use
of your time in a language which does support conditional compilation.

I'll look for Brender's "Generation of Blisses" tech report from CMU
one of these days and see what it has to say about conditional compilation.
				/AHM
10.15MANANA::DICKSONMon Jul 09 1984 18:3411
You aren't supposed to use the expression-oriented IF for compile-time
tests in Bliss.  You are supposed to use the lexical-IF, %IF --- %FI.
It splices out lexeme streams before they are seen by the syntax
analyzer, so you are not restricted to whole expressions or blocks.

For example, if while debugging calls to FOO should have an extra
parameter of .X, then I can write

	FOO( .arg1, .arg2  %IF debugflag %THEN , .x %FI )

Likewise you can use it for parts of tables, etc.
10.16Koala::ROBINSMon Jul 09 1984 19:493
Would you call BLISS a high-level language?  I've never used it.

sar
10.17VLNVAX::RDFTue Jul 10 1984 09:539
Ive heard people describe BLISS as a "medium" level language.

One point I dont like about using expression oriented IFs is that if someone
is essentially doing conditional compilation, I'd like to explicitly know 
about it.  Having a seperate set of lexical operators for compile time stuff
makes things easier to read (at least for me), and I don't have to go hunting
through IF statements figuring out what are CTCE's and LTCE's , etc.

Rick
10.18VLNVAX::AMARTINTue Jul 10 1984 17:094
Do I recall hearing Bevin Brett bemoaning the lack of a good lexical
facility in Ada?  If so (or if not), would he like to say something
on the issue?
				/AHM/THX
10.19ORPHAN::BRETTTue Jul 10 1984 23:3745
In general, I think BLISS is really neat with its integrate lexical, syntactic,
and semantic processing.  

This is IMPOSSIBLE in Ada, because of such things as overloading resolution,
use clauses, etc.    

Instead I believe we should be using mechanical methods to generate the source
to feed into the compiler - doing it IN the compiler seems unnecessary and
a complication - after all we don't do links in the compiler!  Its just the
same but at the other end.

People ABUSE Bliss lexicals - the Ada compiler probably worse than most - and
all you really gain is slow compiles.  For example generating a translation
table using a recursive macro definition is POSSIBLE but EXPENSIVE.  When this
is used for BIG tables such as you get in compilers, the result is complex and
NOT easy to fix compile-time bugs in.

I think we would be better off using more powerful tools to generate such
tables.  For example, write a Pascal program and a Bliss macro that both
generate bliss source for a lower->upper case translation table.  Pascal is
a lot clearer.  

eg.
	program UPPERCASE(output);
	var C : CHARACTER;
	begin
	    for C := ' '..'~' do
		writeln(' [''', C:1, '''] = ', ...


/Bevin











Well, maybe that WAS a bad example,  or should I pretend all the above was
tongue in check?
10.20TURTLE::GILBERTFri Jul 13 1984 01:5214
Yes.

Certainly some things might be better done with code than with macros.
But macros cannot be so easily dispensed.

If the innards work, the external interface is clean and commented, and
there's no need for enhancements, then there's nothing wrong with using
macros when a different method would be more obvious.  It's the tool at
hand (although I'll be the first to agree that we need better tools).

Your note suggests a wish-list item for Bliss - initialization routines
which would do compile-time initialization of data structures.

					- Gilbert
10.21Vaxuum::DYERSun Jul 15 1984 23:5121
	I agree that the conditional compilation should be done explicitly,
rather than as a side-effect of optimization.  Three reasons:
	    o Good programming style.  It's better to know why
	      that IF is being done.
	    o Less work for the compiler.  If the conditional
	      compilation keywords say ignore it, it's just
	      ignored.
	    o Portability.  Maybe the compiler you have now
	      will do the right optimization, but you don't
	      want the code generated when you move on to a
	      new compiler.
	    o Make that four reasons:  Perhaps the code isn't
	      compilable with any other compiler.  For exam-
	      ple, VAX C uses keywords like "globalvalue."
	      No other C compiler will compile that, much less
	      start optimizing.
	I agree that a general-purpose macro preprocessor is a great thing
to have.  I use the C preprocessor with much more than C programs.  There's
also a general-purpose macro preprocessor called M4 that you get with Unix
that I'd love to get my hands on...
		<_Jym_>
10.22ELUDOM::ARSENAULTTue Oct 16 1984 15:106
One of the neat things about the Bliss lexical/macro facility is that it
is integrated in the language.  The best example of this is iterated macros.

If you want a general-purpose macro preprocessor, consider using SCAN.

mark
10.23LATOUR::AMARTINTue Oct 16 1984 16:0312
Actually, iterated macros are also an example of one of the worst designed
features in the language.  Instead of providing the facility to specify
for each iterative macro the separator, and starting and ending strings,
the facility grovels around to decide what context it is in to pick the
right default.  It certainly seems harder to implement, and it loses when
you want to define a macro which expands the same way whether it is an
input-actual-parameter or an output-actual-parameter in a routine-call.
The separator is "," for the former, but ";" for the latter.

Has anyone defined any useful iterative macros that are meant to be called
in more than one context?
				/AHM