From: Jonathan Kirwan
Subject: Re: To C or not to C
References: <email@example.com> <firstname.lastname@example.org> <email@example.com> <firstname.lastname@example.org>
X-Newsreader: Forte Agent 1.92/32.572
NNTP-Posting-Date: Sun, 05 Jan 2003 20:56:05 GMT
Organization: AT&T Broadband
Date: Sun, 05 Jan 2003 20:56:05 GMT
On Sun, 5 Jan 2003 13:31:29 +0100, "Frank Bemelman"
>"Jonathan Kirwan" schreef in bericht
>> On Sun, 5 Jan 2003 01:42:26 +0100, "Frank Bemelman"
>> >Okay, I'll keep scratching my head in the meantime ;)
>> For example, rather than:
>> #define MAXBUF (128)
>> in a .H file, I might instead use:
>> const MAXBUF = 128;
>> in a .C configuration file which I could then compile into an
>> .OBJ or .O. The linker would have access to this symbolic value
>> and would link it appropriately with any extern references to
>> it, substituting the values at link time.
>> Without this mechanism, the C compiler must recompile each and
>> every .C file which includes the .H, rather than recompiling
>> only the configuration constants file and then linking. For
>> large projects, this can be kind of nice.
>Okay, but this more a convenience issue.
One can always say such things about language features. Using
COBOL vs C might be summarized as just a "convenience issue."
But it's a missing semantic, just the same.
>> But there are other values to this. For example, being able to
>> specify absolute addresses for memory mapped peripheral
>> registers and so on. Some of the embedded C compilers actually
>> provide pre-compiled .OBJ or .O files which include these
>> predefined symbolics in them for convenience and provide
>> appropriate .H files for inclusion. But it isn't possible to
>> produce those .OBJ files (or .LIB) without the assembler being
>> involved. C just doesn't have a syntax to specify the semantics
>> for it.
>Well, some C compilers offer extensions allowing you to write
>BYTE lcd_command @ 0xC000;
>... but I'm the first to admit I had to write a small ASM module
>to take care of such things. But I don't call that writing in
Yes, I've seen such extensions also in the Quadravox compiler
for the MSP430, as well. Microchip's C18 compiler, for example,
does not provide such a mechanism. So one must rely on their
library files to provide them in the object code or use assembly
to produce your own.
The point is, the semantic is missing.
>> Generating equal times in the 'then' and 'else' clauses of an
>> 'if'. I recently encountered a situation, in doing bus
>> arbitration between a variable number of asynchronous devices
>> sharing it, where the timing of each address bit during the
>> arbitration phase (much like the APIC bus on the Intel P II
>> cpus) depended on some constant factors PLUS two times the
>> variability in the bit timing. Since this was an active low,
>> high impedance high type of line sharing, the microcontroller
>> had to use two different mechanisms for driving a '0' and a '1'.
>> This meant that I couldn't just mask the bit and drive it to the
>> latch. I had to use an 'if' statement and do different things
>> depending on whether the bit was a 0 or 1. However, if the
>> 'then' and 'else' clauses had different timing, I'd have to
>> double that variability and add it into the total bit time and
>> this could greatly slow down the resolution process.
>This is a speed issue. You want maximum speed, or control over
No. You may have missed the point. The *variability* is
important. Faster or slower isn't the only part of it. The
difference in execution time between the two parts must also be
doubled and used as part of the overall time. And this isn't
the only such example, just one of a whole class or problems
>> C simply doesn't provide a syntax to allow the programmer to
>> specify to the compiler that this is a desired outcome. Not
>> even nice #pragma's for this, for example. No amount of
>> screwing around with the C code would help here. It's plain and
>> simple, not in the C card deck.
>That's true. OTH if I needed to balance a 'then-else' I'd may
>try if the compiler understood NOP(); or else I might try
>something like dummy++;
In assembly, that's what I do. But optimizers in the compiler,
or the next version of the compiler which changes them, causes a
great source of maintenence head-aches. In assembly, on
processors with predictable execution times, of course, it's
easy to do and only needs doing once.
>> Co-routines. It would take a while to properly elaborate this
>> one. A quick example in pig-C might get the point across more
>> quickly, though:
>> the case of the Primes() call, for example, the full set of
>> primes do not need to be passed back nor fully computed before a
>> yield takes place. There is no equivalent in C. But this is
>> actually quite easy in assembly (and some other higher level
>Lost you here completely, sorry ;)
Sorry about that. I worried that I'd lose some people there.
Life, I guess.
>> Assembly is quite a bit more flexible than C. The difficulty is
>> that one needs to have a broader set of mental models in order
>> to take advantage of that flexibility.
>Well, I lack that broader set of mental models. Your examples are
>good, and obviously you are using 'assembly' at an entiry different
>level than (I assume) most are doing. I my case I'm often more
>concentrating on the application itself, not some deep buried gearbox.
>I have the impression that you are more involved with the very
>complicated gearboxes ;)
There are times where you cannot avoid getting into that level
of detail. Luckily, most of the time people can.
I like development environments which permit separate
compilation of modules, including assembly modules. That way, I
can choose to use assembly, C, or a combination.
Coroutines and processes actually simplify the application code
and lend greatly to its readability and maintenence. To add
them to C requires at least a little assembly, unless you buy
someone else's library where they did the work.
>> Anyway, I just wanted to point out that those limiting their C
>> vs assembly arguments to "speed" or "space", being unable to see
>> any other reasons, are in fact myopic and color blind in their
>> views. There is a bigger, more colorful world out there, most
>> especially in embedded work. And C vs assembly for embedded use
>> doesn't just boil down to speed and space and development time.
>> I admit it often does so, but not always. And it's the times
>> when it doesn't boil down that way, that things are really more
>ASM is harder to write, and when used at a higher level I fear
>that it does not result in the best possible application, or
>perhaps a rather spartanic application. 'Embedded' suggests a
>small area, but in fact it is a very wide area with many different
>diciplines. Trying to deny that is a form of colorblindness too ;)
Not denying it at all. Embedded is everything from networked
PCs equipped with ADC cards to a tiny music module on a
Christmas card, I suppose. Worlds apart, they can be.
What I'm saying is that any C-only or assembly-only view is
myopic, and that even narrowly couching the question into a C vs
assembly itself is myopic.
There is no one better solution. For a programmer, it's better
to always be growing in skills -- numerical methods, physics,
chemistry, optics, differential equations, finite group theory,
optimal filtering, signal processing -- as well as facility with
assembly, C, C++, BASIC, Forth, SNOBOL, Lisp, ADA, APL -- or
more deeply, compiler theory, operating systems and concurrent
programming, ... and on and on.
It never ends.