[comp.sys.amiga.tech] __chip keyword is evil

w-edwinh@microsoft.UUCP (Edwin Hoogerbeets) (12/21/89)

dirks@phao.eng.ohio-state.edu (William R.Dirks) writes:
% The following is quoted from the Lattice Amiga Compiler User's Guide
% page G51 without permission.  (I hope they don't get mad at me. ;) )
% 
%   "The chip, far, huge, and near keywords are extensions to the ANSI
%   standard.  The standard requires that each keyword extensions [sic]
%   be preceded by a double underscore, such as __near.  The Lattice 
%   compiler accepts the extended keywords in this form as well as in
%   the more natural form without the double underscores."
% 
% I guess "__chip" is ANSI, but "chip" breaks the rules.

Well, ANSI specifies that identifier names beginning with a double
underscore are not within the defined name space of C. This means that
if you should want to add an *extension* to the language, use the double
underscore method. The double underscore identifiers simply do not
violate ANSI.

It does NOT specify that __chip, __far, __huge or __near are reserved
keywords. If I were writing an ANSI Unix compiler, I would not have to 
support these.

This lack of specification means that they are not portable. 

I don't know if anyone would want to port code that needs chip memory to
a Unix box, but I'm quite sure that the same code might be "Manxified."

If Manx does not support __chip, but has a pragma instead, I'll be
happy.  (Any comments from those beta testers out there?)

martin@enuxha.eas.asu.edu (Ross D. Martin) writes:
% I don't see what you have against __chip.  

It is a pollution of the C language. 

C was designed to be a small language, and as such, it embodies the
"small is beautiful" philosophy quite well. Adding [non-portable] 
keywords to the language should not be done lightly, especially with
keywords like __chip, which do not have any semantic effect on the
code.

This is part of the reason Dennis Ritchie vetoed the "noalias" keyword.

% It is portable.  Just #define
% it to something harmless to do a port.  I believe you can #define something
% to a null string, can't you?  If not, there are several do-little modifiers
% out there that should work ok.  Perhaps #define __chip static?

This is not a good solution. It would be nice to be able to write code
for the Amiga, to be compiled with either of the ANSI compliant compilers
[soon for Manx 8-)]... with NO changes necessary to "port" between them.

% Pragmas involve more typing to get less clear, clean code.  Not a good idea
% in my book.

Pragmas take more typing? A quicksort takes more typing than a nice little
bubblesort, but that is no reason to use the bubblesort all the time.
Programmer convenience should not override more important issues (IMHO)
like portability, efficiency, or esthetics. And especially
maintainability.

As for clean and clear code how about:

char array[10];      

as opposed to

__chip char array[10];

Which is more clear and/or clean?  I'd say the first example.  

As another example of keywords growing wild:

peter@cbmvax.commodore.com (Peter Cherna) writes:
[good discussion of amiga shared libraries deleted - Thanks Peter!]
% char * __saveds __asm LIB_foo(register __d0 int i, register __a0 long *lptr)
% 
% The __saveds instructs Lattice to set up your data area (off A4) when
% anybody calls your function.  The __asm keyword states that you intend
% to specify which registers receive which parameters, as shown above.

__saveds? __asm? __d0? __a0?

Please don't tell me these are clear. Peter even had to tell us what all
these keywords were for! The function declaration is rather obsured.

Are there not pragmas for these, either?

w-stephm@microsoft.UUCP (Stephan Mueller) writes:
% On a more philosophical level, the __chip stuff has nothing to do
% with any data structure or any algorithm.  It is a code generation
% detail, and so, doesn't belong in the body of a C program which is
% supposed to be a high-level description of the program.

Yes! Good point.

% Now, assuming I've convinced you we should be using #pragma, what should
% the syntax of such a #pragma be?
% 
% Proposal :
%   #pragma chip (identifier1 [, identifier2 ...])

Sounds about right. 

How about it, Doug and John? (Actually, I don't know why I'm arguing
this point, since I don't own Lattice... I guess the argument is more 
on philosophical grounds.)

Followups directed to comp.sys.amiga.tech.

Edwin

bader+@andrew.cmu.edu (Miles Bader) (12/21/89)

I was under the impression that #pragma directives as defined by ANSI were
NOT allowed to be used for anything that changed the meaning of the program.
I.e., it has to work the same if the compiler ignores all #pragmas (if
perhaps less quickly, etc).

None of the lattice extensions (__chip, __asm, etc), seem to fit that
definition, so it would seem that you couldn't legally use #pragma to
implement them.  If something needs to be in chip memory, you can't just not
put it there!

Note that the lattice system call hack #pragmas ARE legal, since if you
ignore them, the program just ends up using the library stub instead--
slower, but with the same result.

-Miles

mwm@raven.pa.dec.com (Mike (With friends like these, who needs hallucinations) Meyer) (12/22/89)

I'm rather surprised - Edwin usually does better.

>> This lack of specification means that they are not portable. 
>> 
>> I don't know if anyone would want to port code that needs chip memory to
>> a Unix box, but I'm quite sure that the same code might be "Manxified."
>> 
>> If Manx does not support __chip, but has a pragma instead, I'll be
>> happy.  (Any comments from those beta testers out there?)

Let's see - you have code with a __chip keyword in it, and you compile
it. The code will give you an error and fail to compile. You run an
editor on it and change the keyword to whatever is appropriate.

Now, assume the keyword is a pragma. If you're lucky, either the
compiler will give you an error, or it'll give you a warning and
you'll notice it. In either case, you run an editor and fix the
problem. If you're not lucky, you'll try running the compiled program
without noticing that something failed, and get garbage results. You
now get to enter the debug cycle. This is supposed to be an
improvement?

>> % I don't see what you have against __chip.  
>>
>> It is a pollution of the C language. 
>> C was designed to be a small language, and as such, it embodies the
>> "small is beautiful" philosophy quite well. 

This should be compared to to the "pragma" construct, which allows for
doing pretty much arbitrary things to the language, and have an
arbitrary structure. Of course, they aren't part of the _language_
proper, so you can ignore them. But doing so could make debugging code
that depends on them that much harder.

>> % It is portable.  Just #define
>> % it to something harmless to do a port.  I believe you can #define something
>> % to a null string, can't you?  If not, there are several do-little modifiers
>> % out there that should work ok.  Perhaps #define __chip static?

>> This is not a good solution.

Could you explain why:

#if defined(LATTICE)
#define CHIP	__chip
#elif defined(MANX)
#define CHIP	<whatever>
#else
#define CHIP	Error_No_Chip
#endif

is so much worse than:

#if defined(LATTICE)
#pragam <whatever>
#elif defined(MANX)
#pragma chip <list>
#endif

>> It would be nice to be able to write code
>> for the Amiga, to be compiled with either of the ANSI compliant compilers
>> [soon for Manx 8-)]... with NO changes necessary to "port" between them.

Methinks you're dreaming. But, assuming that Manx actually gets
something that looks ANSIish out the door, you'll be able to do that
with the exising compilers - except, of course, for having to have
different makefile (or whatever you want to call them) for the two
systems. Both compilers allow you to compile a file such that
everything in it lands in chip memory. So the code file doesn't have
anything in it indicating that it's in chip memory; it's all in the
makefiles.

As an aside, I consider this solution intermediate between the #pragma
that lists objects to be put in chip and a chip keyword. The reason is
locality of reference. A chip keyword requires that the information
that this object is going to be in chip memory be associated with the
object (you could implement it so this wasn't required; not clear that
that's a good idea). The makefile approach means you can find all such
information in one place, even though it isn't local. The chip pragam
to make things local means you can make make such information local,
but makes doing so hard - and requires that you check all include
files to see if one of makes this object chip.

If you really want to use pragmas, I'd suggest:

#pragma chip

which puts the next defined object in chip memory. This gives back the
locality of information property of keyword.

>> __saveds? __asm? __d0? __a0?
>> 
>> Please don't tell me these are clear. Peter even had to tell us what all
>> these keywords were for! The function declaration is rather obsured.
>> 
>> Are there not pragmas for these, either?

Nope. Lattice doesn't believe in using pragmas for changing the
semantics of the code. Of course, you can get the same effect without
using any of those keywords by combining the correct compiler flags
with an understanding of how it allocates arguments to registers. 6.0
is going to make all of this much, much easier.

BTW, how would you specify pragmas to cause the code to compile with
the arguments as specified?

>> w-stephm@microsoft.UUCP (Stephan Mueller) writes:
>> % On a more philosophical level, the __chip stuff has nothing to do
>> % with any data structure or any algorithm.  It is a code generation
>> % detail, and so, doesn't belong in the body of a C program which is
>> % supposed to be a high-level description of the program.
>> 
>> Yes! Good point.

This comment applies to _pragmas_ - of any kind - as well. You
shouldn't use them in code that you want to be portable.  They should
be used to control things other than the semantics of the program, and
don't beling in the body of a C program.

I agree that __chip & etc. are ugly. However, pragmas are worse. They
shouldn't change the semantics of the program - which you're trying to
make them do. From a programming standpoint, they allow for text far
removed from code to cause that code to break, which is a bad thing.
It's part of the reason Dennis Ritchie vetoed the "noalias" keyword.

	<mike
--
I went down to the hiring fair,				Mike Meyer
For to sell my labor.					mwm@berkeley.edu
I noticed a maid in the very next row,			ucbvax!mwm
I hoped she'd be my neighbor.				mwm@ucbjade.BITNET

walker@sas.UUCP (Doug Walker) (12/23/89)

In article <10011@microsoft.UUCP> w-edwinh@microsoft.UUCP (Edwin Hoogerbeets) writes:
>dirks@phao.eng.ohio-state.edu (William R.Dirks) writes:
>% It is portable.  Just #define
>% it to something harmless to do a port.  I believe you can #define something
>% to a null string, can't you?  If not, there are several do-little modifiers
>% out there that should work ok.  Perhaps #define __chip static?
>
>This is not a good solution. It would be nice to be able to write code
>for the Amiga, to be compiled with either of the ANSI compliant compilers
>[soon for Manx 8-)]... with NO changes necessary to "port" between them.

You are more likely to be able to port with no changes by using the
keyword method than the #pragma method.  If you choose a name for a #pragma 
that another compiler implementation has chosen, you have an instant problem.
However, you can easily put a header in some include file like

#ifdef LATTICE
#define CHIP __chip
#else
#define CHIP
#endif

This only relies on no other vendors' compilers defining the symbol LATTICE.
The #pragma relies on each different #pragma syntax being unique among all
vendors.  This is ALREADY not the case with a couple of vendors in the 
MS-DOS marketplace.


>As for clean and clear code how about:
>
>char array[10];      
>
>as opposed to
>
>__chip char array[10];
>
>Which is more clear and/or clean?  I'd say the first example.  

I'd say the SECOND one is more clear.  Because if you use the #pragma way,
you have to correlate the declaration of the variable and the declaration
of the #pragma, which might be in another file somewhere.  Tell me which is
clearer the first time you mismatch the variable name with the #pragma name
in some header file or at the top of your .c file.  As to 'clean', seeing
the __chip doesn't really bother me, maybe that's just personal preference.

>As another example of keywords growing wild:
>
>% char * __saveds __asm LIB_foo(register __d0 int i, register __a0 long *lptr)
>
>__saveds? __asm? __d0? __a0?
>
>Please don't tell me these are clear. Peter even had to tell us what all
>these keywords were for! The function declaration is rather obsured.

So nobody would have to tell you what the #pragma definitions were for?
There is a LOT of additional information going on here.  Without the 
additional keywords, you are declaring a function that takes an integer and
a pointer to a long and returns a pointer to char.  WITH the definition,
you are declaring a function that preserves A4, takes an integer parameter
in register d0 and a pointer to a long parameter in register a0 and returns
a pointer to char.  Just look at the English description, and come up with
a more concise way of doing this.  Any #pragma construct to declare this
kind of information would also be wordy, and at least as hard to read.

>w-stephm@microsoft.UUCP (Stephan Mueller) writes:
>% On a more philosophical level, the __chip stuff has nothing to do
>% with any data structure or any algorithm.  It is a code generation
>% detail, and so, doesn't belong in the body of a C program which is
>% supposed to be a high-level description of the program.
>
>Yes! Good point.

No.  __chip is an attribute of the object being declared.  You tell the
compiler to put things in global data with the 'static' keyword; You tell
it the data is read-only with 'const';  you tell it it should not be
optimized with 'volatile';  you tell it to put it in CHIP memory with 
'__chip'.  I do not believe it is appropriate to put this information in
a preprocessor directive, which may be widely seperated from the definition
of the object it pertains to.

>How about it, Doug and John? (Actually, I don't know why I'm arguing
>this point, since I don't own Lattice... I guess the argument is more 
>on philosophical grounds.)

There is no way the __chip keyword will be removed - that would break
too much code, plus there is a large contingent that considers it useful.
If there is enough demand, we could implement #pragmas to duplicate the
results of #chip, but it would be at the cost of development time that,
in my opinion, could be better spent elsewhere.


  *****
=*|_o_o|\\=====Doug Walker, Software Distiller=======================
 *|. o.| ||
  | o  |//     "READY!   FIRE!   AIM!   (Software under development!)
  ======
usenet: ...mcnc!rti!sas!walker   plink: dwalker  bix: djwalker