C isn't for timid souls !

S

spibou

Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/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.
 
T

tomstdenis


Like say

if (options & flags) { ... }

Um ...

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--) { ... }

characters ARE INTEGERS!!!

No, just understand data type promotion rules.

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
 
W

William J. Leary Jr.

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
 
S

spibou

Like say

if (options & flags) { ... }


Um ...


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--) { ... }


characters ARE INTEGERS!!!


No, just understand data type promotion rules.


Then you wouldn't know about the rules for shifts, logical and binary
operators, etc...


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
 
S

SuperKoko

Keith said:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/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.
 
C

Chris Dollin

SuperKoko said:
Keith said:
(e-mail address removed) wrote:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/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[].
 
T

tomstdenis

Keith said:
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
 
T

tomstdenis

Chris said:
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
 
C

Chris Dollin

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.
 
T

tomstdenis

Chris said:
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
 
R

Roberto Waltman

Keith Thompson said:
Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/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 ...)
 
T

tomstdenis

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
 
C

Chris Dollin

Chris said:
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.
 
T

tomstdenis

Chris said:
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
 
A

Andrew Poelstra

You make it sound like C programming is a terrible burden, and you hope
that no programmers ever /need/ to program in it.
What? So
if (x == y - 5)
is illegal? What should that be replaced with?
What should
while (y++ < x)
be replaced with?
So,
while ((c = fgetc(file)) != EOF)
is also forbidden? What clearer code should I replace that with?
Lest I try
for (x = 0, y = 50; x < y; x++, y--)
How should I do that differently?
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?
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).
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.
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.
 
A

Andrew Poelstra

Here's some advice about how to programme in C:
(From
http://www.uni-muenster.de/ZIV/Mitarbeiter/EberhardSturm/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...
 
C

Chris Dollin

Chris said:
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.
 
C

Christopher Benson-Manica

Anyone who would call it the "question mark operator" is already
suspect...

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.
 
K

Keith Thompson

"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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,973
Members
47,529
Latest member
JaclynShum

Latest Threads

Top