By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,301 Members | 1,412 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,301 IT Pros & Developers. It's quick & easy.

C isn't for timid souls !

P: n/a
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:

* No computations in control statements!
* No increment ++ and no decrement -- operators!
* No assignments in expressions!
* No comma operator!
* No question-mark operator!
* Don't use char for numbers!
* Don't expect rules of mathematics!
* Don't lookup precedence rules, use parentheses!


Or perhaps timidness is not the problem.

Jun 14 '06 #1
Share this Question
Share on Google+
24 Replies


P: n/a
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:

* No computations in control statements!
Like say

if (options & flags) { ... }
* No increment ++ and no decrement -- operators!
Why?
* No assignments in expressions!
Um ...
* No comma operator!
I can see places where it's good to avoid comma but there are places
where it is useful, e.g.

for (x = TOP, y = BOTTOM; y < x; y++, x--) { ... }
* No question-mark operator!
Lame.
* Don't use char for numbers!
characters ARE INTEGERS!!!
* Don't expect rules of mathematics!
No, just understand data type promotion rules.
* Don't lookup precedence rules, use parentheses!

Then you wouldn't know about the rules for shifts, logical and binary
operators, etc...
Or perhaps timidness is not the problem.


Stupid?

Where did you get the list?

Basically you're saying because you don't understand C that others
should avoid it's most basic offerings because you may get confused by
it.

Avoiding the "?" operator for instance... is just like saying "using
goto is always stupid".

Tom

Jun 14 '06 #2

P: n/a
<to********@gmail.com> wrote in message
news:11**********************@u72g2000cwu.googlegr oups.com...
sp****@gmail.com wrote:
First I want to present a list of hints to programmers who occasionally need to program in C: ((..ommitted..))


Where did you get the list?

The first line of the document at the link says "This paper was presented at
the G.U.I.D.E.&SHARE Europe Joint Conference (10-13 October 1994, Vienna,
Austria)." The list itself appears in the summary section.
Basically you're saying because you don't understand C that others
should avoid it's most basic offerings because you may get confused
by it.


Well no, actually he (or the author of the bit) is saying that if YOU only
occasionally need to use C then YOU should avoid these features. I expect
because limiting yourself thus will reduce the differences between whatever you
usually program and C. From the article it appears the common minimum is PL/I.
Basically it (the article) is a frag on C, in general, and specifically as
compared with PL/I.

- Bill
Jun 14 '06 #3

P: n/a

to********@gmail.com wrote:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:

* No computations in control statements!
Like say

if (options & flags) { ... }
* No increment ++ and no decrement -- operators!
Why?
* No assignments in expressions!
Um ...
* No comma operator!
I can see places where it's good to avoid comma but there are places
where it is useful, e.g.

for (x = TOP, y = BOTTOM; y < x; y++, x--) { ... }
* No question-mark operator!
Lame.
* Don't use char for numbers!
characters ARE INTEGERS!!!
* Don't expect rules of mathematics!
No, just understand data type promotion rules.
* Don't lookup precedence rules, use parentheses!

Then you wouldn't know about the rules for shifts, logical and binary
operators, etc...
Or perhaps timidness is not the problem.


Stupid?

Where did you get the list?


Errrm , I provided a link. Does it not appear on your newsreader ?
Basically you're saying because you don't understand C that others
should avoid it's most basic offerings because you may get confused by
it.


It's not me who's saying it. I was half bewildered half amused by it
and
was curious to see other peoples' reactions to it.

Spiros Bousbouras

Jun 14 '06 #4

P: n/a
to********@gmail.com writes:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/) [snip]
> * Don't use char for numbers!


characters ARE INTEGERS!!!


Sure, but it seldom makes sense to use type char for numeric
computations. int tends to be more efficient; it may be tempting to
save space by using a char, but it's seldom worth it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 14 '06 #5

P: n/a

Keith Thompson wrote:
to********@gmail.com writes:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/) [snip] > * Don't use char for numbers!


characters ARE INTEGERS!!!


Sure, but it seldom makes sense to use type char for numeric
computations. int tends to be more efficient; it may be tempting to
save space by using a char, but it's seldom worth it.

I think that using char for numbers is not a very good idea.
It is better to use either "signed char" or "unsigned char", depending
on whether you want a singed or unsigned integer type.
char may be signed or unsigned, depending on your compiler.

Jun 14 '06 #6

P: n/a
SuperKoko wrote:
Keith Thompson wrote:
to********@gmail.com writes:
> sp****@gmail.com wrote:
>> Here's some advice about how to programme in C:
>> (From
>> http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)

[snip]
>> > * Don't use char for numbers!
>
> characters ARE INTEGERS!!!


Sure, but it seldom makes sense to use type char for numeric
computations. int tends to be more efficient; it may be tempting to
save space by using a char, but it's seldom worth it.

I think that using char for numbers is not a very good idea.
It is better to use either "signed char" or "unsigned char", depending
on whether you want a singed or unsigned integer type.
char may be signed or unsigned, depending on your compiler.


If the values of interest are in the range 0..127, then plain char will
do, will it not?

Also note that while the space savings for char vs int are small, they're
not so small for struct { char vs int x, y, w, h, q; } and even less small for
char[] vs int[].

--
Chris "charred or singed, at your whim" Dollin
"People are part of the design. It's dangerous to forget that." /Star Cops/

Jun 14 '06 #7

P: n/a
Keith Thompson wrote:
characters ARE INTEGERS!!!


Sure, but it seldom makes sense to use type char for numeric
computations. int tends to be more efficient; it may be tempting to
save space by using a char, but it's seldom worth it.


Crypto.

Tom

Jun 14 '06 #8

P: n/a
Chris Dollin wrote:
If the values of interest are in the range 0..127, then plain char will
do, will it not?
Computations on chars on some platforms is a bit complex. On amd64 at
least there are byte/word/dword/qword operations for all of the GPRs
but on others like the ARM series you'd have to mask the register
before doing things like right shifts...
Also note that while the space savings for char vs int are small, they're
not so small for struct { char vs int x, y, w, h, q; } and even less small for
char[] vs int[].


Structures are normally padded so your struct example is valid but less
meaningful, the array is good though. Cryptography often makes use of
arrays of various sorts from input/output buffers to lookup tables and
whatever else.

SHA-512 for instance takes 128 bytes as input and compresses it to a
512-bit internal state [eight 64-bit words]. If you had to store the
input as "unsigned" you'd be taking [usually] 4x the space. Crossing
more cache lines then you want, etc, etc. It's also wasteful since the
data could be on the stack.

In general though, if you need an integer type "int" is better to use.
For most platforms it is the "most efficient" size to deal with. So
something like

char x;
for (x = 0; x < 10; x++) { printf("Hello world\n"); }

Is probably not a good use for a char type.

Tom

Jun 14 '06 #9

P: n/a
to********@gmail.com wrote:
Chris Dollin wrote:
If the values of interest are in the range 0..127, then plain char will
do, will it not?


Computations on chars on some platforms is a bit complex. On amd64 at
least there are byte/word/dword/qword operations for all of the GPRs
but on others like the ARM series you'd have to mask the register
before doing things like right shifts...


The ARM has byte load/store instructions.

--
Chris "ex-RISCOS user" Dollin
"Reaching out for mirrors hidden in the web." - Renaissance, /Running Hard/

Jun 14 '06 #10

P: n/a
Chris Dollin wrote:
The ARM has byte load/store instructions.


ok ...

unsigned char array[10], byte;

byte = array[0];
byte = byte + 1;
array[0] = byte >> 1;

What ARM code does that turn into?

LDR r0,#0[r1] ; assume r1 has array alread
ADDI r0, r0, #1, LSR #1
ANDI r0, r0, #255
STR r0,#0[r1]

You could have the MSB be set which would be undesired [e.g. array[0]
== 255, then 1+255>>1 == 0x80].

[Yes, I realize LDR/STR are for 32-bit words, I forgot the mnemonics
for 8/16 bit words, you get the point though right?]

Tom

Jun 14 '06 #11

P: n/a
Keith Thompson <ks***@mib.org> wrote:
to********@gmail.com writes:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)[snip] > * Don't use char for numbers!


characters ARE INTEGERS!!!


Sure, but it seldom makes sense to use type char for numeric
computations. int tends to be more efficient; it may be tempting to
save space by using a char, but it's seldom worth it.


That is probably correct for code running on desktops / mainframes /
embedded systems with MMU & paging, etc.
Not so when your target is an embedded system with no virtual memory,
and your last code change makes the final image larger than the
available physical memory. (This happens only 99% of the time ...)
Jun 14 '06 #12

P: n/a
to********@gmail.com wrote:
Chris Dollin wrote:
LDR r0,#0[r1] ; assume r1 has array alread
ADDI r0, r0, #1, LSR #1
ANDI r0, r0, #255
STR r0,#0[r1]


That should be

ANDI r0,r0,#127

Obviously we want to mask the MSB ... hehehe.

Ok, I gotta get back to packing...

Tom

Jun 14 '06 #13

P: n/a
to********@gmail.com wrote:
Chris Dollin wrote:
The ARM has byte load/store instructions.
ok ...

unsigned char array[10], byte;

byte = array[0];
byte = byte + 1;
array[0] = byte >> 1;

What ARM code does that turn into?


Heavens, we're going off-topic now ...
LDR r0,#0[r1] ; assume r1 has array alread
ADDI r0, r0, #1, LSR #1
That doesn't look like an ARM instruction to me. If you
use a literal, you don't get to shift the result - the
shift bits are used to position the literal bits in the
literal operand. (Unless I'm out-of-date, of course.)

ldrb r0, [r1]
add r0, r0, #1
and r0, r0, #255
ANDI r0, r0, #255
STR r0,#0[r1]
mov r0, r0, lsr #1
strb r0, [r1]
You could have the MSB be set which would be undesired [e.g. array[0]
== 255, then 1+255>>1 == 0x80].


I had written:

....> If the values of interest are in the range 0..127, then plain char will
....> do, will it not?

You're worrying about (a) values outside that range (b) doing
arithmetic, not just storing numbers. I agree that if you're
/doing arithmetic/ that char isn't a good choice for working
values. But "don't use char for numbers" seems to be a rather
more general, and less well-founded, prohibition. I should
have been clearer what my objection was.

--
Chris "seeker" Dollin
"We did not have time to find out everything we wanted to know." /A Clash of Cymbals/

Jun 14 '06 #14

P: n/a
Chris Dollin wrote:
LDR r0,#0[r1] ; assume r1 has array alread
ADDI r0, r0, #1, LSR #1
That doesn't look like an ARM instruction to me. If you
use a literal, you don't get to shift the result - the
shift bits are used to position the literal bits in the
literal operand. (Unless I'm out-of-date, of course.)


Last I checked "add" and "add immediate" were two different
instructions were they not? Your assembler may just map the "add" with
an immediate to addi.
I had written:

...> If the values of interest are in the range 0..127, then plain char will
...> do, will it not?

You're worrying about (a) values outside that range (b) doing
arithmetic, not just storing numbers. I agree that if you're
/doing arithmetic/ that char isn't a good choice for working
values. But "don't use char for numbers" seems to be a rather
more general, and less well-founded, prohibition. I should
have been clearer what my objection was.


My point is if the char is something like an loop counter or whatever,
you're best to just use "int" as that would map to a 32-bit register
and not require the ANDs to clear the upper bits.

"char" should only really be used for strings and for arrays of "bytes"
[yeah I know the idea char == byte is taboo but go look at network
code...] for protocols.

Tom

Jun 14 '06 #15

P: n/a
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:
You make it sound like C programming is a terrible burden, and you hope
that no programmers ever /need/ to program in it.
* No computations in control statements! What? So
if (x == y - 5)
is illegal? What should that be replaced with?
* No increment ++ and no decrement -- operators! What should
while (y++ < x)
be replaced with?
* No assignments in expressions! So,
while ((c = fgetc(file)) != EOF)
is also forbidden? What clearer code should I replace that with?
* No comma operator! Lest I try
for (x = 0, y = 50; x < y; x++, y--)
How should I do that differently?
* No question-mark operator! Why not?
rv = (p == NULL) ? MEM_ERR : 0;
There's a very clean null pointer catcher which changes
the return value. Why can't I use that?
* Don't use char for numbers! But chars are integers. Why shouldn't I use them as 1-byte
numbers? What if I have a million numbers to store all of
which are less than 200? Should I use at least two million
bytes of memory to store it in an int? Or maybe I should
use a guaranteed 1 million bytes of memory (whatever a byte
might be in this compiler).
* Don't expect rules of mathematics! Last I checked, 26 + 27 = 53 (mod 2^TYPE_BITS), and every
single other expression I've tried works out as well. If you
can't understand modulo, maybe you shouldn't work with computers.
* Don't lookup precedence rules, use parentheses!

Gotcha.
z = ((((((x)++) * (4))) + (y)) + (15))
is much safer than
z = x++ * 4 + y + 15
(I couldn't remember if y + 15 would be evaluated as y + 1 and 5,
so I figured I'd just type (15) for clarity).
Hope I got the attributions right; I took a reply and cleared
out the reply part because my ISP lost the original message.

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 14 '06 #16

P: n/a
On 2006-06-14, Andrew Poelstra <ap*******@localhost.localdomain> wrote:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
> First I want to present a list of hints to programmers who occasionally need to program in C:
> [post snipped]


I read elsethread that you were equally shocked and amused as the rest
of us at that list, so my post shouldn't have been targeted at you. Oops.

Thought it seemed uncharacteristic of spibou to write something so stupid...

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 14 '06 #17

P: n/a
to********@gmail.com wrote:
Chris Dollin wrote:
> LDR r0,#0[r1] ; assume r1 has array alread
> ADDI r0, r0, #1, LSR #1


That doesn't look like an ARM instruction to me. If you
use a literal, you don't get to shift the result - the
shift bits are used to position the literal bits in the
literal operand. (Unless I'm out-of-date, of course.)


Last I checked "add" and "add immediate" were two different
instructions were they not?


That depends on what you mean by "different instruction".

There's an ADD instruction: Rd := Ra + B. B can be a shifted
register or a literal. You may choose to think of this as there
being two instructions

ADD: Rd := Ra + (Rb SOMESHIFT #amount)
ADDI: Rd := Ra + SOMELITERAL

However, what you /don't/ get is an instruction that allows you
to specify a literal /and/ a shift, which is what you had above.

(Unless, as I say, I've missed out on some update.)

The SOMELITERAL is an eight-bit value rotated according to a 4-bit
field (value * 2) - ie, there is a shift component, but it's just
used to specify the literal value.

--
Chris "mostly ARMless" Dollin
"Reaching out for mirrors hidden in the web." - Renaissance, /Running Hard/

Jun 14 '06 #18

P: n/a
sp****@gmail.com wrote:
* No question-mark operator!
Anyone who would call it the "question mark operator" is already
suspect...
* Don't lookup precedence rules, use parentheses!

Well and good when you're writing code, but if someone with a clue
reads it, or you read code written by someone with a clue, you will be
SOL. It's a much better idea to simply learn the precedence rules, or
find another language/job.
Or perhaps timidness is not the problem.


Indeed; I rather believe the original author must have been abused by
a C compiler as a child.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jun 14 '06 #19

P: n/a
to********@gmail.com writes:
[...]
"char" should only really be used for strings and for arrays of "bytes"
[yeah I know the idea char == byte is taboo but go look at network
code...] for protocols.


I don't know what you mean. The idea that char == byte is part of the
definition of "byte" in the C standard.

(Usually unsigned char is preferred for byte data.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 14 '06 #20

P: n/a
Keith Thompson wrote:
to********@gmail.com writes:
[...]
"char" should only really be used for strings and for arrays of "bytes"
[yeah I know the idea char == byte is taboo but go look at network
code...] for protocols.


I don't know what you mean. The idea that char == byte is part of the
definition of "byte" in the C standard.


Possibly the char == octet taboo?

--
imalone
Jun 15 '06 #21

P: n/a

sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:

* No computations in control statements!
* No increment ++ and no decrement -- operators!
* No assignments in expressions!
* No comma operator!
* No question-mark operator!
* Don't use char for numbers!
* Don't expect rules of mathematics!
* Don't lookup precedence rules, use parentheses!


Or perhaps timidness is not the problem.


Well, I'm going to stick my neck out and say that this list looks quite
a good idea, at least in parts.

The context seems to be that someone who doesn't know much C (and who
isn't intending learning much more) has to, or wants to, write a C
program for some reason. It would seem prudent to assume that the
program might be maintained by either the same programmer or someone
else who knows little C.
* No computations in control statements!
While experienced programmers find lines such as:

while ((c = fgetc(file)) != EOF)

a neat way of doing things (it's from Andrew Poelstra's post) it does
look confusing and in my view might be best avoided for a beginner or
inexperienced maintainer.
* No increment ++ and no decrement -- operators!
Now this makes perfect sense. How many times have people posted
perfectly plausible code to clc, saying "why doesn't this work?", and
the answer has been a lack of sequence points. It's possibly the most
frequently asked question here, despite it being in the FAQ.

And what leaps to mind first when you hear the question "Will this
macro work properly?"?

You don't need to use ++ or -- - and if you don't know exactly what
you're doing they are best avoided.
* Don't expect rules of mathematics!


Another popular snag is finding that floating point numbers don't have
exactly the values you were expecting - often revealing itself when a
comparision unexpectedly returns false. You need to be aware of such
things.

The other items on the list also refer to things that could either
cause your program not to work properly, or to make it difficult to
read and understand. So in the context of advice to occasional C
programmers, it seem to all make sense.

Just my tuppenceworth...
Paul.

Jun 15 '06 #22

P: n/a
gw****@aol.com wrote:
sp****@gmail.com wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)

The context seems to be that someone who doesn't know much C (and who
isn't intending learning much more) has to, or wants to, write a C
program for some reason. It would seem prudent to assume that the
program might be maintained by either the same programmer or someone
else who knows little C.
* No computations in control statements!
While experienced programmers find lines such as:

while ((c = fgetc(file)) != EOF)

a neat way of doing things (it's from Andrew Poelstra's post) it does
look confusing and in my view might be best avoided for a beginner or
inexperienced maintainer.

TBH this has one more, more serious, problem for someone unfamiliar
with the language, that c should be of type int.
* No increment ++ and no decrement -- operators!
Now this makes perfect sense. How many times have people posted
perfectly plausible code to clc, saying "why doesn't this work?", and
the answer has been a lack of sequence points. It's possibly the most
frequently asked question here, despite it being in the FAQ.


Well, I think the most idiomatic use of these things is the
for(ii=0; ii<SOME_NUMBER; ii++) { } and friends. The people
who ask the question here seem to have an obsession with the
bizarre rather than simply trying to get by in the language.
Your conclusion:
if you don't know exactly what you're doing they are best avoided.
is sound.
* Don't expect rules of mathematics!


Another popular snag is finding that floating point numbers don't have
exactly the values you were expecting - often revealing itself when a
comparision unexpectedly returns false. You need to be aware of such
things.


This isn't a C issue though, and there's no simple rule you can
apply to deal with it.
* Do expect rules of mathematics! (but with finite precision, integer
maths, type promotion and C operator precedence)

--
imalone
Jun 15 '06 #23

P: n/a
to********@gmail.com wrote:
In general though, if you need an integer type "int" is better to use.
For most platforms it is the "most efficient" size to deal with. So
something like

char x;
for (x = 0; x < 10; x++) { printf("Hello world\n"); }

Is probably not a good use for a char type.


For 8 bit processors, unsigned char gives much more efficient operation
when only 8 bits are needed. With C99 you can specify (u)int_fast8_t
for the fastest type for your platform, but, with the near exception of
gcc for the Atmel AVRs, C99 compilers don't exist for these processors.

--
Thad
Jun 16 '06 #24

P: n/a
sp****@gmail.com wrote:
Here's some advice about how to programme in C: (From
http://www.uni-muenster.de/ZIV/Mitar.../PL1andC.html/)
First I want to present a list of hints to programmers who occasionally need to program in C:

* No computations in control statements!
* No increment ++ and no decrement -- operators!
* No assignments in expressions!
* No comma operator!
* No question-mark operator!
* Don't use char for numbers!
* Don't expect rules of mathematics!
* Don't lookup precedence rules, use parentheses!


Or perhaps timidness is not the problem.


Well, no. If using PL/I makes you use that many exclamation marks, I'm
glad I use a sane language instead.

Richard
Jun 16 '06 #25

This discussion thread is closed

Replies have been disabled for this discussion.