Stylistic questions on UNIX C coding.

E

Ersek, Laszlo

Keith Thompson said:
Would you even consider writing '7 == x' rather than 'x == 7'
if C's equality and comparison operators were more distinct?

For example, consider a hypothetical C-like language in which the
equality operator is spelled "=" and the assignment operator is
"<-", and "==" is a syntax error. (Yes, that would quietly break
"x<-1"; let's ignore that.)

In such a language, would you ever write "if (7 = x)" in preference
to "if (x = 7)"? If so, why?

No, I would not have picked up the "7 == x" style in that case.

For example, Pascal has := for assignment and = for equality (IIRC :)). Even
in C, I started out with "x == 7". I was occasionally bitten by
"if (x = 7)" typos. Not very frequently, and most of the time caught by
compiler warnings. However, on some forum somebody brought up "7 == x"
explicitly, and after giving the idea my unrelenting attention :) for a
minute or two, I liked it so much that I trained myself to it.

Cheers,
lacos
 
S

Stefan Ram

Ben Bacarisse said:
How do you feel about i[array][j] and j[i[array]] (or, indeed,
j[array] to get the full set)?


Of all those, »j[i[array]]« stands out as more consistent,
since »i[array][j]« and »j[array]« seems to mix both »styles«.
 
S

Stefan Ram

Tim Streater said:
What about maintenance? Someone later will look at that and waste half a
day trying to see if there's some reason it's written that way.

That would be in favor of such a construct as it indicates
that it would help to find the incompetent code reviewers.
 
S

Seebs

That would be in favor of such a construct as it indicates
that it would help to find the incompetent code reviewers.

I wouldn't spend half a day on it, but I'd at the very least check the
rest of the code to see whether it used the same idiom.

Code reviewers who don't check out deviation from idioms are not being
careful enough, IMHO. It may be there's a good reason for it, but the most
common reasons I've seen are:

1. The person writing the code is not very familiar with standard idioms,
and may also make common mistakes that those idioms are designed to prevent.
2. The code DOES follow the idiom, and I misread it the first time.

-s
 
E

Ersek, Laszlo

What about maintenance? Someone later will look at that and waste half a
day trying to see if there's some reason it's written that way.

You are right.

In a pro setting, I'll participate when the coding style is set, and
then I'll follow it. If no coding style is set at all, I'll have my
share of the guerilla development. I may hint at the necessity of a
coding style, but I won't fight for it, because I hate politics, and
some co-workers always take it as an attack on their authority. I help
with creating guidelines the best I can when I'm asked, but I'm no
enforcer.

In a hobbyist setting, like I've been coding C recently, I don't care.
(The word being "hobby", not "unpaid job". (Hobby doesn't imply low
quality (hopefully!), just that I'm my boss and my customer.)) I don't
code for users and I work alone. I code for myself and am happy if
others benefit too. (... Though it seems they can prod me into more
work.)

Cheers,
lacos
 
S

Seebs

No, he isn't. :) Anyone who wastes half a day on understanding 7==x is
not the kind of person you want maintaining C code in the first place.

Not "understanding 7==x". Figuring out whether it's been done that way for
a particular reason. And while "half a day" may be a bit much, I've certainly
seen fairly experienced coders lose an hour or more to something that was
written in a way that suggested a deeper meaning or intent when it was, in
fact, merely idiosyncratic.

If someone wrote:
for (i = 0; max > i; ++i)
I'd at least want to investigate briefly whether there was some non-obvious
reason for which the comparison was written backwards. If I couldn't find
one, I'd check every comparison in the code (and a lot of other stuff) more
carefully, for much the same reason that I check code more carefully if
there's trivial misspellings in the comments.

Sometimes, the effort's wasted, but so far, my experience has been that it's
right more often than it's wrong.

-s
 
S

Seebs

If it takes him more than a quarter of a second to recognise that the
writer put the constant on the left to allow even the dumbest of
compilers to alert the programmer in case he missed one of the =s (given
that this technique is hardly a trade secret), then he's not the kind of
person you want maintaining C code in the first place.

I disagree. I wouldn't trust someone who made that assumption without
checking it -- at least, say, verifying that the same author did that
consistently.

I've heard of that convention, and that argument for it, but I've never seen
it actually solve a problem -- I don't think I've used a compiler in either
of the last two decades that couldn't catch such errors in other ways. So if
I see code written that way, I check it out to see whether that's what's up.
That takes a lot more than a quarter second -- and if only one test in a file
is written that way, I'm not going to assume it was someone using that
convention, because if they did, all the other tests would be the same.
You say it's "backwards", and okay, obviously I believe that you see it
that way. I /don't/ see it that way. <shrug>

That's fine -- but since the vast majority of code writes those relations in
a consistent way, exceptions ought to be looked at.

Cases where something is done in an unusual way are often either errors
or signs of something funky up with the code.

-s
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
Keith Thompson said:
Tim Rentsch wrote:
Anand Hariharan wrote:
<snip>
Haven't seen anyone point this out:

Rather than -

#define MAXNUMFILES 1024

- prefer -

const int MaxNumFiles = 1024;


That way your preprocessor won't do as much damage.
Fine in C99, I think, but an issue in C90 if he's using it to define
an array size.
It's a problem in C99 too, if the array is defined at file scope or it
has internal linkage. There are other reasons why it's not a great
idea in C99. They stem from the fact that MaxNumFiles is not
permitted as part of a constant expression. [snip elaboration]

Minor clarification -- MaxNumFiles is _permitted_ as part of a constant
expression, albeit an implementation-specific constant expression;
it just isn't _required_ to be a portable constant expression.

What? You could say just about any nonsense is permitted as part of
an implementation-specific expression.

That doesn't alter that fact that in C90 or C99, MaxNumFiles is not
permitted as part of a constant expression.

I think Tim is referring to C99 6.6p10:

An implementation may accept other forms of constant expressions.

Quite so.
(I just noticed that this doesn't use the term
"implementation-defined" implying, I think, that an implementation
can accept other forms of constant expressions but isn't required
to document them.)

My belief is that such forms of constant expressions still count
as language extensions. If they are they must be documented,
because extensions are required to be documented.

Then the only purpose of 6.6p10 is to permit implementations *not* to
issue diagnostics on the use of "other forms of constant expressions".
For example:

const int x = 42;
switch (...) {
case x:
...

Normally "case x:" is a constraint violation, but if the
implementation accepts it under 6.6p10, no diagnostic is required.
Plausible, but I'm not 100% convinced either that this is what the
standard says or that it's a good idea. For one thing, the lack
of a diagnostic would make it more difficult to write portable code.

Just three words: quality of implementation.

I'm not sure mine does. Another reasonable interpretation of 6.6p10
is that it permits implementations to support other forms of constants;
for example:

const int x = 0b10_1010;
/* 0b denotes binary, underscores are ignored */

This is obviously a syntax error, requiring a diagnostic, for an
implementation that doesn't support it. Can an implementation not
emit a diagnostic and point to 6.6p10 to justify it? Or must it
issue a diagnostic and make it an extension under 4p6?

A diagnostic must be issued. 6.6p10 doesn't give licence to
avoid giving a diagnostic, only to declare that something is
a constant expression. It's because an expression is a constant
expression that the various CE constraints are satisfied (and
so don't need diagnostics issued for them); but that doesn't
remove the obligation to satisfy other constraints as well.

I'd be happy to accept the committee's intent here if I knew what
it was.

So if you were sure that the intention was to allow other
forms of constant expressions without having to give a
diagnostic you'd be happy with that, even though you're
not sure it's a good idea? Or were you talking just about
the specific question of new kinds of constants?

Personally, I'd prefer to drop the permission in 6.6p10 and allow
other forms of constant expression, like any other extension, under
4p6. A conforming implementation would have to issue a diagnostic
for anything that would be a constraint violation or syntax error
without the extension. If you don't want the diagnostic, invoke
the compiler in a not-quite-conforming mode.

I think that's a bad idea, because I always want to invoke my
compilers in conforming modes (I essentially always use -pedantic,
for example). If I'm forced to use a non-conforming mode, who know
what other kinds of non-conformance might be introduced? I would
rather have my compiler always be conforming, and have the option
for getting warnings or errors on use of implementation-specific
forms of constant expression. 6.6p10 lets implementations do that.
 
T

Tim Rentsch

Tim Streater said:
I didn't use any such structured language before then. Well, that's
not quite true. We had Algol, Snobol, Lisp and perhaps some others on
my post-grad CS course in the late 60s, but I went to CERN after that
where everything was, perforce, FORTRAN.

So you're saying you've really only ever tried this one
bracing style? That you haven't tried out any others
even just to get a sense of what they might be like?
 
E

Ersek, Laszlo

On 5 Mar 2010 23:29:45 +0100


1) The "Even in C" is in one some way related to "For example,
Pascal..." ?


I guess I did some fairly bad editing with the above :)


1. The question was if people liking "7 == x" would stick to it if the
language had an assignment operator that couldn't easily be mixed up
with testing for equality.

2. No, I would not stick to it then. For example, in Pascal, where the
assignment operator ":=" resembles the mathematical "let ... be" (define
.... as) act and is intuitively different from testing for equality, and
also where you can't put an assignment into a controlling expression
anyway, I never felt the need to write 7 == x (or rather, in Pascal, 7 =
x). Pascal is an example for the kind of language Keith specified in 1.
(You snipped the original question so I write this from memory.)

3. Even in C, where I later found "7 == x" useful, it was not part of my
original style.


Thus: Pascal -- no motivation, C -- even though I discovered my
incentive later, the idea was not obvious and didn't match my initial
way of writing ==. The word "even" refers to the fact that Pascal bears
no such incentive for me, while C does.


(Perhaps it's even more confusing now, sorry.)

2) The fact you "liked it so much" has something to do with Pascal?

No, it has not.


Cheers,
lacos
 
D

Default User

I probably experimented and tried a few things, but I really don't
remember now, its 35 years ago. I vaguely recall changing it slightly
once I started using C in about 1983.

This is commonly called "Whitesmith's Style". It was my preferred style
when I was starting out, and happened to be the style chosen for the
first Common Coding Standard I worked under (mid 90s). That pleased me
and pissed off the OTBS guys.

Most of my formal programming since that period has been C++, and the
company standards specify:

if (cond)
{
dostuff();
}

Style.

Nowdays, even when I do C in prototype code or whatever, I stick to
that style. In fact, I basically follow the C++ CCS expect for a few
small points, like not putting a trailing _ at the end of struct
members. I figure most people reviewing it will be used to the C++
style and it will be less confusing, even though strictly speaking
prototype code doesn't have to follow any particular standard (yet).



Brian
 
N

Nick Keighley

For example, Pascal has := for assignment and = for equality (IIRC :)). Even
in C, I started out with "x == 7".  I was occasionally bitten by
"if (x = 7)" typos.  

I even went though the occaisional
x == 3;

somehow AutoPilot (the not very bright bit of the brain that handles
the routine stuff like getting to work and writing code) had come up
with the rule "in C we double up '=' symbols"
 
N

Nick Keighley

On 05/03/2010 16:04, Richard Heathfield wrote:


But Richard, you have to read the code in order to interpret it mentally
and decide whether it's correct or not, or how to amend it. I gave up on
Forth, Lisp, and regexps for just this reason.

I guess by "read" you mean subvocalise. I can read Lisp without
difficulty and regexps rather slowly. Never seriously tried Forth.

I'm pretty sure I subvocalise because I've acquired some odd
pronounciations for words that had been in my reading vocabulary
longer than my spoken vocabulary. I think the subroutine that assigns
sounds to unfamiliar words is fast but stupid.
 
N

Nick Keighley

Actually, I'm not exactly talking about English.  I'm talking about the
underlying cognitive structures English (and every other language) maps to.

ah! A disciple of Chompsky.I didn't know it had been proven beyond
doubt that such a Deep Structure existed
So far as I know, regardless of language, humans distinguish between the
topic and the comment (thanks to another poster for providing the
terminology).


Not a big deal, but oddly, somewhat related -- it's the kind of mistake that
shows up as a side-effect of added complexity.  If you add enough parentheses
to an expression, people will start mismatching them or putting them in the
wrong places because they can't track them automatically anymore, or because
the automatic tracking fails.

to write lisp you pretty well have to have support from your editor. I
seem to nest stuff deeper than most people- maybe this is something
computer programmers tend to do but lisp easily busts my internal
stack.
For me, swapping the "natural" order of a comparison (I expect the "topic"
to be first) is one extra layer, similar to an indirection, extra set of
parentheses, or whatever.  I don't know how common that is, but I'm pretty
sure it's not going to change in the forseeable future.

I'll suffer the pain of an extra translation stage if I think it buys
me much. In this case I'd rather have the test the "right" way round.
 
R

Rainer Weikusat

[...]
To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}


And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?
 
B

Ben Bacarisse

Rainer Weikusat said:
[...]
To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}


And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?


Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.
 
R

Rainer Weikusat

Ben Bacarisse said:
Rainer Weikusat said:
[...]
To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}


And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?


Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again. Also, the condition is known to be
true so checking it before the first execution of the loop body is a
pointless exercise. A sensible way to express this in C would be

do array[--i]; while (i);

This is politically incorrect for various reasons not the least one of
which is that people are often proud of having written code
thoughtlessly, presumably, because this demonstrate that it is below
their dignity to care for something as miniscule as that, and which
one will end up generating better code depends on the compiler and how
it was used. Eg, I have reason to suspect that at least some versions
of gcc transformate all loops to the 'condition in front of it'-form
(I don't know the English term for this, the German one would be
'abweisende Schleife') before they are feed to the various weird loop
optimizers intended to turn thoughtlessly written FORTRAN into
sensible machine code. But as R. Pike aptly observed in

http://www.lysator.liu.se/c/pikestyle.html

A program is a sort of publication. It's meant to be read by
the programmer, another programmer (perhaps yourself a few
days, weeks or years later), and lastly a machine. The
machine doesn't care how pretty the program is - if the
program compiles, the machine's happy - but people do, and
they should.

and the major problem is actually not that the machine has to deal
with the crud but that some day, some other human will need to decode
the text in order to understand the algorithm which will effectively
be performed by the program and the larger the amount of "compiler
knows what I mean" expressions in there is, the more complicated
becomes this task. Especially since people tend to confuse their
intentions everytime, not just in isolated examples. One useless
calculation isn't a big problem. Thousands of lines of code filled
with expressions which appear to do all kinds of useless operations
are a major obstacle because it is not possible to distinguish
the 'production' and the 'pollution' parts of the code without
understanding its purpose first.
 
B

Ben Bacarisse

Rainer Weikusat said:
Ben Bacarisse said:
Rainer Weikusat said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?


Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.


What do you mean by "oversteps"? The code above works correctly when
N is zero and it executes the body exactly N times as it should.
Also, the condition is known to be
true so checking it before the first execution of the loop body is a
pointless exercise.

The condition can't be know to be true. It may be false at the start.
A sensible way to express this in C would be

do array[--i]; while (i);

This is politically incorrect

I think this is technically incorrect because it does not handle the
case where N == 0.

<snip>
 
R

Rainer Weikusat

Ben Bacarisse said:
Rainer Weikusat said:
Ben Bacarisse said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?

Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.


What do you mean by "oversteps"?


Don't try to play 'stupid' with me. You understood me quite well, have
'surprisingly' completely ignored my text in order to construct a
straw man and are a live demonstration of the exact type of behaviour
I criticized. And very rightfully, sine I have to read quite lot of
code I didn't write myself and I claim to know something about the
problems the people who enjoy creating 'bunte Getueme' actually
fabricate.
 

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

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top