Coding standards

C

Chris Croughton

As far as I am concerned, multiplicative has precedence over
additive which has precedence over logical will do. Anything
further should be explicitly indicated with the use of the all
purpose parentheses. The mere existence of further levels in C is
a fault IMNSHO. Yes, I know there are no precedence levels in C,
just Backus-Naur descriptions.

I've tried to write a precedence-based parser for C expressions. It's
all fine apart from the ternary operator, as far as I could determine
nothing makes that come out right (I tried all combinations of left and
right precedence, and none gave the right answer for a ? b ? c : d : e).
Which was annoying since I did not want to use a top-down BNF parser for
it. I eventually 'solved' it with a hack which did special things with
the ternary operator...

Chris C
 
C

Chris Croughton

I always wanted to write down a grammar that allows exactly those C
expressions that I find acceptable and disallows those that I don't like
(for example "a << b + c" - is it (a << b) + c or a << (b + c)? ) Never
found the time for it, but it shouldn't be too difficult.

The problem I find is that what I want the expression to do
'intuitively' depends on the context. The precedence I do find awkward
is the && and &, I often want to do something like:

if (flags & FLAG_1 && flags & FLAG_2)

meaning do the bit operations first, and dislike the extra parentheses I
have to put in to force that. As I recall in the rationale for C89
there was something about "we really wanted to change some of these but
it would break too much code".

Chris C
 
I

infobahn

Richard said:
Beg to differ. IsLeapYear(), obviously yes. IsPrinterReady(), yes. But I
could imagine HasTransferCompleted() to write the address of the next
completed data buffer through its argument, and return the number of
unprocessed complete data buffers.

Wow! I must be more thoughtful about function-naming in the future.
My idea of "obvious" is clearly not in line with other people's idea
of "obvious". I would have encapsulated the functionality you describe
using a function named something like WriteNextDataBufferAddress().
I am not sure that I'd necessarily get such a function to return
a number of unprocessed buffers; I think I'd prefer to return a
status code.
In all these cases, except perhaps
IsLeapYear() if I'm certain I'm not going to pass dates before 1572, I'd
certainly want to read the specs before using them no matter how obvious
they look.

It would be irresponsible to do otherwise, no matter what the
function is called.
No, he hasn't. He's demonstrated that muddle-headed programmers find
themselves encouraged to do so by whatever style they use, but that's
hardly surprising.

Correction accepted.
Oh? We shouldn't remember that * goes above +, and both above &&?

One eventually absorbs this information anyway, without particularly
having to go to the trouble of learning it. There is a difference
between knowing a tiny fraction of the precedence "rules" (there
aren't any, really - they just fall out of the grammar; but I know
you know that) and knowing the whole table, operator-perfect.
It's
not generally necessary to remember the details surrounding &, &&, = and
==,

Precisely my point.
but I'd certainly want any competent programmer to remember the
basics.

I would not judge the competence of a C programmer by his ability to
remember a couple of facts from p53. I might, however, judge his
incompetence from his inability to remember those same facts!

Off the top of my head, I can't remember which has higher precedence,
? : or =. If I can't, then I suspect that a good few other people
can't, either - so I'll use parentheses to clarify my meaning, rather
than look it up. That way, I save N + 1 lookups - one for me, and N
for those reading my code whose memory is as bad as mine.
 
I

infobahn

Keith said:
Actually, you can implement Boolean values with ints by writing zero
or non-zero to them, and by referring to them only in ways that work
the same way for any non-zero value. Treating 2 or -1 as "true" is
perfectly valid.

True enough, but I always prefer to be a little stricter about such
matters than is perhaps common amongst typical C programmers. A
failing of mine, no doubt.
 
B

Ben Pfaff

Chris Croughton said:
The problem I find is that what I want the expression to do
'intuitively' depends on the context. The precedence I do find awkward
is the && and &, I often want to do something like:

if (flags & FLAG_1 && flags & FLAG_2)

meaning do the bit operations first, and dislike the extra parentheses I
have to put in to force that.

The above is equivalent to
if ((flags & FLAG_1) && (flags & FLAG_2))
I don't know why you seem to think it isn't.
 
R

Richard Bos

CBFalconer said:
As far as I am concerned, multiplicative has precedence over
additive which has precedence over logical will do. Anything
further should be explicitly indicated with the use of the all
purpose parentheses.

You write

a = (b + (c[1]));

? Methinks you know more than you realise you know.

Richard
 
C

Chris Croughton

The above is equivalent to
if ((flags & FLAG_1) && (flags & FLAG_2))
I don't know why you seem to think it isn't.

Because I get the precedence wrong <g>. So, it seems, do a lot of
people (almost everywhere I've worked with a "coding style" has said to
put them in there). Wrong example, it's relational operators which are
the silly ones:

value & 0x1F == 3

evaluates the == first, which is silly because there is no time anyone
would sensibly want to apply a bit mask to the result of a boolean
operation, it's all the other way round.

Chris C
 
C

CBFalconer

Ben said:
The above is equivalent to
if ((flags & FLAG_1) && (flags & FLAG_2))
I don't know why you seem to think it isn't.

I don't think it is the "isn't" that bothers him, it's the
uncertainty, lacking the parentheses. I would always use your
version of the expression.
 
T

Tim Rentsch

Natt Serrasalmus said:
There are things that I like that I can give objective
reasons for liking. For instance, I don't like K&R brace style. I like for
the braces to be at the same indentation level so it's easy to see which
braces match which.

The reason given here doesn't qualify as objective IMO. I find it
just as easy to match braces in code using K&R bracing; easier,
in many cases.

Furthermore, the idea that ease of brace matching is the only factor
(for brace placement) that matters for code quality is itself
subjective. For some quality metrics, it is outright false.
 
R

Richard Bos

infobahn said:
Wow! I must be more thoughtful about function-naming in the future.
My idea of "obvious" is clearly not in line with other people's idea
of "obvious".

Let's put it this way: if pressed, I'd guess that that function did what
you intended it to do. If not pressed, though, I wouldn't assume unless
the context was entirely clear. I wouldn't recommend that you change the
function's name; I _would_ recommend that people using those or any
other function take care with their assumptions.
One eventually absorbs this information anyway, without particularly
having to go to the trouble of learning it. There is a difference
between knowing a tiny fraction of the precedence "rules" (there
aren't any, really - they just fall out of the grammar; but I know
you know that) and knowing the whole table, operator-perfect.

You'd be surprised at how much people do know. The most surprising ones
are the bitwise operators and the shifts; the precedence of the unary,
mathematical, equality and assignment operators is perfectly logical,
and so is that of the logical and ternary operators provided you don't
use them with the bitwise and shift ones.
I would not judge the competence of a C programmer by his ability to
remember a couple of facts from p53.

Well, no; most of us don't need to know about universal character names,
after all.

Richard
 
X

xarax

Tim Rentsch said:
The reason given here doesn't qualify as objective IMO. I find it
just as easy to match braces in code using K&R bracing; easier,
in many cases.

Furthermore, the idea that ease of brace matching is the only factor
(for brace placement) that matters for code quality is itself
subjective. For some quality metrics, it is outright false.

I also agree that block braces should be at the
same indentation level. I have two reasons that
work for me:

1. My eye-sight is degraded; braces at the end
of a line are easily missed. Placing braces at
the same indentation level on their own lines
are easier for me to identify.

2. My C debugger knows nothing about C semantics;
it uses GNU-style stabs debugging information,
which only has references to original source line
number. The stabs info doesn't have anything about
statements, just line numbers. So, if I want to
set breakpoints at the start or end of a block,
the simplest way to do that is to click on the
opening or closing brace. If that brace is on
its own line, then I get the breakpoint set
correctly. If the brace line has other stuff on
it, then the breakpoint is set incorrectly (from
my viewpoint).

if(fubar == gorko) { /* line [1] */
geezer(krabbers);} /* line [2] */

In the above example, setting a breakpoint at
the start of the block requires pointing at
line [2] rather than line [1] which has the
opening brace. There is no way to set a
breakpoint on the closing brace.

if(fubar == gorko) /* line [1] */
{ /* line [2] */
geezer(krabbers); /* line [3] */
} /* line [4] */

Now I can set breakpoints on any of the
four lines, and my poor eye-sight can
easily distinguish the indentation levels
and where the block begins and ends.

For those of you with superior eye-sight,
please remember that someday someone else
with lesser visual acuity may have to
maintain the code and use a debugger with
the above limitations.

Hopefully there are enough C beautifiers
out there that can re-arrange code into
whatever style that best fits your own
requirements.

2 cents worth. Your mileage may vary.

--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 
I

infobahn

Richard said:
You'd be surprised at how much people do know. The most surprising ones
are the bitwise operators and the shifts; the precedence of the unary,
mathematical, equality and assignment operators is perfectly logical,
and so is that of the logical and ternary operators provided you don't
use them with the bitwise and shift ones.

I presume that, by "ternary operator", you mean the conditional
operator. You have certainly pinpointed the operators which are
most in need of parenthesisation by the paranoid^Wcautious.
Well, no; most of us don't need to know about universal character names,
after all.

That's most amusing. I can't believe a man of your calibre doesn't
know the precedence table on p53 of "The C Programming Language",
2nd edition.
 
K

Keith Thompson

xarax said:
I also agree that block braces should be at the
same indentation level. I have two reasons that
work for me:

1. My eye-sight is degraded; braces at the end
of a line are easily missed. Placing braces at
the same indentation level on their own lines
are easier for me to identify. [snip]
if(fubar == gorko) { /* line [1] */
geezer(krabbers);} /* line [2] */

In the above example, setting a breakpoint at
the start of the block requires pointing at
line [2] rather than line [1] which has the
opening brace. There is no way to set a
breakpoint on the closing brace.

if(fubar == gorko) /* line [1] */
{ /* line [2] */
geezer(krabbers); /* line [3] */
} /* line [4] */

If you put *all* your braces at the ends of lines, of course you're
not going to be able to match them up easily. Here's how I'd write
it:

if (fubar == gorko) {
geezer(krabbers);
}

When I read this, I check that the indentation of the "}" matches the
indentation of the "if"; my only concern for the "{" is that there is
one.

I also use braces even for a single statement, as shown above (a habit
I picked up from Perl, which requires them).

I can't comment on the debugger issue you mentioned because I've never
run into it.
 
P

pete

Stephen said:
Except many operators in C are not ordinary mathematical symbols or may have
non-math meanings in certain contexts.


I agree, except I don't consider ? and : to be terminators --

K&R refers to only to ; as a statement terminator.
 
E

E. Robert Tisdale

pete said:
K&R refers to only to ; as a statement terminator.

Perhaps, but it isn't relevant.
The question mark, colon, comma and semicolon
are English punctuation marks first.
They are used as terminators in ordinary English.
The fact that they may be used to represent operators
in C programs should not matter.
I think that C programs are more readable
if they follow the same rules that are used
in ordinary [mathematical] typesetting.
 
D

Derrick Coetzee

Chris said:
After years of operating without any coding standards whatsoever, the
company that I recently started working for has decided that it might be a
good idea to have some. I'm involved in this initiative. [ . . . ]

Pleasing to see a helpful and sensible discussion here without a flurry of
vitriolic comments claiming it to be off-topic (perhaps it's just a matter
of the weekend or timezones).

Well, at least it *contains* C.
 
J

jdallen2000

Michael said:
Please provide proper attributions when you quote on Usenet.
For someone so concerned with imposing consistency, you're
observing rather poor netiquette.

Sorry. I often omit the attribution when the quote is
a paraphrased or consensus opinion, of limited relevance,
simply for context, or even in the interest of brevity.
Please note that readers who need the source can easily find
it, e.g. at Groups.Google. (Also posting at both Groups.Google
and Groups-Beta.Google seems to be broken these days. I
had to cut and paste to get the remark and attribution above.
Suggestions welcome, but be aware I post from Internet cafe.)

Also, to avoid disharmony, I often omit the attribution for a quoted
idea when I argue against the *idea*, but not against the ideator.

Speaking of harmony, let's please do avoid frivolous
objections or "straw-man" debates. I apologize for
any of my own comments which have been misunderstood --
My rhetoric gets a little too whimsical sometimes.


But if you *do* name the reference in an excerpt,
it is Netiquette to give quotee the benefit of his own
words. It is unreasonable to imply that jdallen2000
extrapolates a claim about the readability of
j } else {
to promote construction like
j char *s, *commap; int cnt;
j s = Begp; if (*s == '\0') return 0;
j for (cnt = 1; commap = index(s, ','); cnt++) {
j *commap = '\0'; plain_ups(s);
j s = commap + 1; while (*s == ' ') ++s;
j } plain_ups(s); return cnt;

I saw this sophomoric prank coming, and felt I had forestalled
it by posting the early rejoinder:
... with poor eyesight. (*Rarely*, I may even run statements
together on the same line, when the statements are
*very* similar, very short, and obviously coupled.)
Elsewhere:
Your (understanding of English is flawed).

Hunh? What's your point? Are you one of the guys that
writes, "i saw the lite"? You seem to be from the laissez-faire
school, but your arguments shed more heet than lite.
[True Style] was in very widespread use among the most elite C
programmers. ... proud to emulate the style of so many Masters.
Linus Torvalds also codes in True Style, so I don't think this
is just a Berkeley/Bell-Labs phenomenon.

Someone responded, and I paraphrase:
No, this list of True Style programmers is not particularly
more or less skilled than [some other groups].

Really? Are you guys comparing yourselves to Bill Joy?
Of all the code *you*'ve examined, pick those that exhibited
the most skill and name the programmers.
What style did they use?

The best C code I've examined has been Unix kernels, shells, etc.
I realize this is a biased sample, but it would be fun to hear
from others. If your nominee did *not* write in True Style,
can you honestly say he's as good a programmer as nominees
like Linus Torvalds, Dennis Ritchie, and some of the BSD and
Sun programmers? I've not examined much of Chris Torek's
code but he'd qualify: what style does he use?

I said:
Although defense counsel continues to recommend `indent'
they offered no rebuttal to this point:
Are we to conclude that the defendants are satisfied to use
only indent-approved spacing?

Still, no one has deigned to post a rebutter here.


Finally, I'll restore the spaces Google ate in the
code sample of the earlier post. Google seems to
be forcing short lines today, so you'll still have
to use a little imagination to see what the code
*really* looks like.
A year ago I mentioned a stylistic deviation I use, and one
of the defense attorneys in the present case responded:

Which of the following is more easily read?
Do be open-minded, setting aside any convention.

j My way:
j /*
j * Do a 3-D convolution.
j * Convolve in_sig with conv_k producing out_sig.
j * (Delivered code may be slightly different.)
j */
j for (x = in_sig->beg_x; x < in_sig->end_x;x++)
j for (y = in_sig->beg_y; y < in_sig->end_y;y++)
j for (z = in_sig->beg_z; z < in_sig->end_zz++) {
j val = 0;
j for (dx = conv_k->beg_x; dx < conv_k
end_x; dx++)
j for (dy = conv_k->beg_y; dy < conv_k->end_y; dy++)
j for (dz = conv_k->beg_z; dz < conv_k->end_z; dz++) {
j val += in_sig->dat[x+dx][y+dy][z+dz]
j * conv_k->dat[dx][dy][dz];
j }
j out_sig->dat[x][y][z] = val;
j }
j
... tends to hide the nesting [, but] FWIW, I *never*
omit the new-line before a for-body, even if it's the trivial
for-body (";"), so ... such for's will *always* be nested.

j
j
j "Approved" style:
j for (x = in_sig->beg_x; x < in_sig->end_x; x++)
j {
j for (y = in_sig->beg_y; y < in_sig->end_y; y++)
j {
j for (z = in_sig->beg_z; z < in_sig->end_z; z++)
j {
j val = 0;
j for (dx = conv_k->beg_x; dx < conv_k->end_x; dx++)
j {
j for (dy = conv_k->beg_y; dy < conv_k->end_y;
dy++)
j {
j for (dz = conv_k->beg_z; dz < conv_k->end_z;
dz++)
j {
j val += in_sig->dat[x+dx][y+dy][z+dz]
j * conv_k->dat[dx][dy][dz];
j }
j }
j }
j out_sig->dat[x][y][z] = val;
j }
j }
j }
j


Dearest regards, James Dow Allen (mail address: jamesdowallen at gmail)
j
j
 
C

Chris Croughton

Perhaps, but it isn't relevant.
The question mark, colon, comma and semicolon
are English punctuation marks first.

So is dot (period, full stop). If I were writing C programs using
English punctuation rules I would write:

x = a. b? fred. bill + joe: foo. bar;

(it is conventional typography to put two spaces after a terminator, but
that looks even sillier).

For that matter, ! is also a terminator in English, do you also write
(! a)? Do you put the terminator inside the quotation marks, as style
guides for English say you should? I thank the gods (particularly God
Ritchie asd God Kernighan) that I don't have to maintain your code...
They are used as terminators in ordinary English.

Which is irrelevant, I am writing C not English.
The fact that they may be used to represent operators
in C programs should not matter.
I think that C programs are more readable
if they follow the same rules that are used
in ordinary [mathematical] typesetting.

They don't mean the same thing (what do ? and : mean in mathematical
typesetting anyway?). Certainly = doesn't mean the same as it does in
mathematics (something which trips a lot of mathematics students when
learning programming). Nor does ^ have its conventional meaning of
exponentiation.

C is not English. C is not mathematics. Different languages -- even
Real World(tm) ones, have different conventions for typography. Live
with it...

Chris C
 
P

pete

Chris said:
So is dot (period, full stop). If I were writing C programs using
English punctuation rules I would write:

x = a. b? fred. bill + joe: foo. bar;

(it is conventional typography to put two
spaces after a terminator, but that looks even sillier).

For that matter, ! is also a terminator in English, do you also write
(! a)? Do you put the terminator inside the quotation marks, as style
guides for English say you should? I thank the gods (particularly God
Ritchie asd God Kernighan) that I don't have to maintain your code...


Which is irrelevant, I am writing C not English.

That's a tedious point to keep repeating to E. Robert Tisdale.
Thank you.
 
A

Arthur J. O'Dwyer

for (x = in_sig->beg_x; x < in_sig->end_x; x++)
for (y = in_sig->beg_y; y < in_sig->end_y; y++)
for (z = in_sig->beg_z; z < in_sig->end_z; z++) {
val = 0;
for (dx = conv_k->beg_x; dx < conv_k->end_x; dx++)
for (dy = conv_k->beg_y; dy < conv_k->end_y; dy++)
for (dz = conv_k->beg_z; dz < conv_k->end_z; dz++) {
val += in_sig->dat[x+dx][y+dy][z+dz]
* conv_k->dat[dx][dy][dz];
}
out_sig->dat[x][y][z] = val;
}
[snip]

Unfortunately, we can't tell what kind of indentation you're using,
since group.google.com decided leading blanks aren't significant (a
violation of their "Don't be evil" policy IMHO). I've complained to
them about this and received what appears to be a form letter in
response.

Keep it up. There are humanoids reading the mail, but they won't
pay attention to you unless you write early and often. (I'm currently
engaged in a one-man letter campaign against their @-sensitive email
munging, which kills TeX source code even worse than blank-munging
kills C source code, and doesn't make rec.games.roguelike.development
much fun, either.)

HTH,
-Arthur
 

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

Similar Threads


Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top