#C Compilers: which one?
19 messages in this thread
It may be YOUR point, but since I started this thread on another point (which
is that inline asm in in all cases bad news), it has little to do with my
point, which you have yet to respond to in a way that shows inline asm to be a
useful (let's say necessary) tool. I say anything you can do with inline asm
you can do better (a LOT better) with a module in asm. Better being defined as
faster executing, more portable, and cleaner.
As for the compiler issue(s), I maintain that Lattice is the better compiler.
Code written in it will NOT have inline asm in it. Ever. For a very simple
reason – you can't do it. Code written in it may be made to conform to the ANSI
proposal, a good thing in my opinion. It also has a debugger, not a good thing,
but I can't change it, can I? A debugger is a crutch, I've believed that all
along and have seen nothing that makes me want to change that opinion. Now both
compilers have crutches. Phoo <shrug>. If Lattice were to add inline asm
tomorrow, they would STILL be the better compiler – ANSI conformant, faster,
smaller code, etc, etc. For that matter, you ever see the author of the Manx
compiler around here? Tobbes (the Lattice author) comes by now and then, and is
highly accessible. this is hardly a negative thing. Larry, should things turn
completely around and Manx become the compiler of choice in ALL respects…
inline asm would still be one of the filthyest, laziest, worthless,
qriddled-with-serious-consequences, just plain bad _style_ things you can write
into a C program.
And _that_ is the point of this thread, for me.
–Ben-
Ben,
I have, in another message, invited you to show me how you would code an
example function using some techique other than inline asm. Please feel free to
respond to that one with your C wisdom.
As for your arguments about which is the better compiler…
Code written in Manx may indeed have inline asm in it. You keep harping on
this, but it is not pertinent to the discussion. Lattice may have 'emit'
statements in it, which is a darn sight worse, since you would have to
effectively disassemble it before you could even hope to understand it. This,
in itself does not make a compiler bad. Inline asm capability does not make a
compiler bad. Though I still feel that there can be a need for inline asm, and
you don't, can we not agree that programs that needlessly use inline asm are
bad? Note that this says nothing about the compiler that produced the inline
stuff, whether it be machine code or asm.
Let me know when the ANSI proposal is a standard. If by that time, Manx has
not brought out an ANSI conformant compiler, and Lattice has fixed the bugs, I
might just agree with your evaluation.
As for faster/smaller, I have seen the gyrations you have to go through to
make Lattice code smaller and faster. manx does a decent job, at higher speed,
and by default. Each compiler has its strong points.
Perhaps you'd feel more comfortable if we spin off a separate thread on the
discussion of which is the better compiler?
-larry
I have responded to your message and indicated that the function you diagrammed
is ill-conceived. Even so, it is no indication that the assembly code is
required to be next to the c code, unless the only criteria is that the
function be written in c – which I won't buy.
As per the compiler discussion, I recommend Lattice – you go ahead and
recommend Manx, if that's your preference, or both, or neither, or individual
evaluation, or Modula.
or whatever.
Gyrations depend on the application… you know that.
I don't think that the compiler issue is one that needs any more debate from
me; because I don't feel that strongly about it. I prefer Lattice – I can help
people if they use Lattice; I can share code with them; and vice-versa; I won't
see any inline asm. And if I were to see emit stuff, rest assured they wouldn't
get the flames out till the next ice age!
But the odds of seeing emit are miniscule… it's major league hard to
generate, while #asm stuff is trivial to generate in comparison.
by the way – Lattice currently defaults to the same setup that Manx uses, re 16
bits and etc; I don't use the standard configuration since they made that
change, which was at 4.0 or thereabouts.
So you don't need gyrations at this point… not that it matters.
–Ben-
Ben,
Glad to hear lattice has seen the light. To my way of thinking, defaults
should produce the best code, in the quickest time. Note that this does not
mean the best code alone, if it requires extremely long compile times. ie. an
optimizer that takes a long time to run should not be the default mode.
Hmm… I could have sworn, from your messages, that you did feel strongly
about the choice of compilers. Personally, I think they are both fine, and are
'keeping each other honest'.
Anyway… one last kick at the inline asm…
Assume for a moment that the function I mentioned requires the asm. You say
that the entire function should be in asm, and one of the reasons you say that
is because of maintainability.
Now, I ask you, what is more easily maintainable? A non-trivial function
written entirely in asm, or a couple of lines of asm at the beginning and end
of the function? I would think that for a C programmer, a couple of lines
(along with a comment as to why it's there, would be far easier to handle than
say, 5 or 10 pages of pure assembly code.
-larry
I must be missing something here. You're talking about this one:
somefunc()
{
#asm
neded code goes here
#endasm
C code goes here
#asm
more needed code
#endasm
}
… yes? I don't follow what's going one here. You've a module which STARTS
with assembly code, ENDS with assembly code, and then has C source in the
middle? I agree with Ben: that's bad form. It really looks like it wants to
be an assembler module, but I can't tell because I don't know how big the
relative sizes of the three chunks are.
Anyway, if you're interested, the way I'd suggest handling it would be as
follows: if the C code is the majority of the bulk, do:
somefunc()
<continued>
<continuation>
{
asmfunc1()
C CODE GOES HERE
asmfunc2()
}
If the assembly is the bulk of the code and the C section is small, then just
write somefunc() in assembly and be done with it.
The only argument I can see for ILAC is "it avoids the setup time required to
call my time critical assembly routine". But that's not really an argument, I
don't THINK, since the proper approach would be to move the call point back to
before the time-critical section.
As I don't feel strongly about these points (see my comments to Ben, BTW), I'm
not going to get involved in the discussion to any great extent. But I AM
trying to understand all sides and what everyone is saying, and would
appreciate it if you can clarify for me what you're asking and why what I've
suggested isn't appropriate. It just seems like "the obvious way to do it" to
me, which must mean I'm missing SOMETHING….
Thanks for your time.
Rick
Rick,
What you are missing is that the code generated by the C part make certain
assumptions about register usage, and expect certain registers to contain, for
example, pointers to data hunks. The assembly is required because the routine
will be called from somewhere external to the program. Now if indeed you could
code it with the asm in two separate modules, and the C part in its own module,
that's fine, and my only argument for the necessity of inline asm will
disappear. ie. you could call the function(s) by calling the asm, which would
'fall through' to the C, and then to the other asm module.
I invited Ben to show me a better way, and his only comment was that it was
obvious that the module should be entirely coded in asm, for 'obvious' reasons.
-larry
Larry,
You could also code the beginning and end in asembly, and have your assembly
routine call a C function. If you need portable code, this is the way to do
it.
Dave @OTG
David,
Well, as far as I could tell, when I tried to do the example I had in mind
(beepit), I could not do that, since the extra junk in the C function clobbered
the setup. Putting the asm stuff into the C function did the trick.
I like your statement that starts 'if you want portable code…'. Frankly, I
don't, and have never wanted it badly enough to go one inch out of my way to
attain that goal. I really don't see the value of it in my situation.
-larry
Maybe you don't need portability. Portability is a design decision. I strive
to maintain portability so that I can pick the best compiler to work with, can
move my code to other systems, and in the event that my compiler vendor of
choice goes down the tubes.
Dave @OTG
Dave,
That's true. I don't need portability because after I have written a program,
I have a working version. If I need to port it to a different compiler, I would
see the port as a necessary part of the step. I have no wish to port to other
machines.
-larry
Ah, right now you don't foresee the need to port. But who knows – 5, 10 years
from now you might look back and say, "Gee. Wish I'd written that program in a
portable fashion so that it would run on C= new Superwhatever computer."
Programmers who write portably, are men of vision. 🙂
Dave @OTG
Dave,
I figure most things worth writing for the Amiga won't port to other machines
anyway, so when I switch to another machine, there will be a lot of rewriting
from scratch anyway.
-larry
> Programmers who write portably, are men of vision.
Ooooo, Dave, I bet the female programmers will get annoyed at that turn of
phrase. <Grin>
Geo
Geo,
No sexism intended.
Dave @OTG
<Looking over at Dave, nodding, and waiting for him to finish, then turning
back to Larry>
Right. If the problem is that you're coming in from the outside world
somewhere and your registers aren't right for C, but you have a big chunk of C
code to do, you'd set up the registers properly, then call the C function.
Same thing on exit: when you return, use the asm to straighten it back out. So
it'd look something like:
asmfunc()
{
do_register_setup
cfunc()
do_register_desetup
}
How does this look?
Question: where is this "somewhere external to the program" of which you speak?
Looking at it from a single-tasking aspect, the only thing you could be talking
about is calling a C fragment from another language. Since I'm pretty sure
that's not what you're doing, you must be talking about some sort of
multitasking thing; inter-process stuff, or interrupts, or something. I'm
curious about this. Could you give me an example, using the Amiga's
environment, where a C function would be called by, say, another C program
which is "somewhere external"?
Rick
Rick,
That looks exactly like I outlined it. Two chunkx of assembler around some C
code. (Unless you mean that the C func is external to the asm func).
For an example, see 'beepit', a little thing I wrote years ago to replace the
DisplayBeep() function, allowing an audible beep. The routine in question is
called from any code that calls DisplayBeep().
As far as I know, it the C func does not have the assembly wrapping, there
are some rather nasty assumptions made, and it is for this reason that the asm
stuff is inline.
I can think of a LOT of places that you would call a function externally.
Think interrupts and SetFunction.
-larry
I mean that the C function is just that: a function, not a piece of code which
exists inline with the assembly code.
Having just written an interrupt handler for the Amiga, and having written it
in assembly, I'm finding it difficult to conceive of a handler which would have
to be written in C. But you've given me the examples I asked for, and when I
have some time I'm going to sit down, study SetFunc and interrupts, and think
about what you and Ben have been discussing.
I'm going to bow out of this one now. Thanks for taking the time to bounce it
about with me!
Rick
Rick,
It isn't so much that the piece of code has to be written in C, but that if
the function is large enough, and easily understandable in C, then it is
probably desirable to code it in C. The particular example I had in mind
(beepit), used 30 lines of C code (not compacted, but spaced out for
readability), which translates into about 80 lines of asm code as generated by
the compiler, which is far less obvious in meaning than the C code, and would
be to anyone but an asm programmer even if written by a human.
In this case, the #asm consists of 2 lines whose meanings are quite obvious.
Let me know if you come up with anything. I spent an hour or so messing with
it again, without being able to recode it, and will try again.
-larry