Stylistic questions on UNIX C coding.

K

Keith Thompson

Vladimir Jovic said:
Keith said:
if ( pointer1 != NULL &&
pointer1->field7 == 0x152 )
{
return;
}
[...]

Yes, you missed the point. I prefer this way :

if ( NULL != pointer1 &&
0x152 == pointer1->field7 )
{
return;
}

Can save you some debugging time :)

Oh, I see. I noticed the use of "=!" for "!=" and "=" for "==", but
assumed there were unintentional typos.

``pointer1 =! NULL'', of course, parses as ``pointer1 = !NULL''.
``!NULL'' evaluates to 1, and assigning an int value (other than a
null pointer constant) to a pointer object requires a diagnostic.

But yes, I'm familiar with the convention of putting the constant
expression on the left hand side of a comparison operator, and with
all the arguments in favor of it. Personally, I find it ugly.
No offense.
 
C

Casper H.S. Dik

Keith Thompson said:
``pointer1 =! NULL'', of course, parses as ``pointer1 = !NULL''.
``!NULL'' evaluates to 1, and assigning an int value (other than a
null pointer constant) to a pointer object requires a diagnostic.

And for other types the compiler or lint will also create a
diagnostic.

(4) warning: assignment operator "=" found where "==" was expected
(4) warning: constant operand to op: "!"
But yes, I'm familiar with the convention of putting the constant
expression on the left hand side of a comparison operator, and with
all the arguments in favor of it. Personally, I find it ugly.
No offense.

Same here.

Casper
 
R

Rainer Weikusat

John Gordon said:
No, it does actually do something: it will throw a compile error if you
mistype == as =.

To demonstrate, imagine that you intended to type this:

if (x == 7)

But you mistakenly typed this:

if (x = 7)

This is legal code but will not behave in the way you intended.

It is a bad idea to try to solve social problems with technical
means. The problem behind this is that = in C is a so-called 'false
cognate' for people who are intimately familiar with mathematics, that
is, a term in a foreign language which 'looks' very similar to a
loosely related term in one's mother tongue, but with a (subtly)
different meaning. This means that such people will likely confuse =
and == in C intuitively and have a hard time spotting such an error
since the text 'looks right' according to the set of conventions they
are so used to that they no longer actively think about them.

But this really only means that average people well-versed in
mathematics shouldn't attempt to code in C because they will likely
make basic errors other people wouldn't.
 
S

Seebs

No, it does actually do something: it will throw a compile error if you
mistype == as =.

But gcc gives a warning for it, anyway. And "x == 7" is much more readable
than "7 == x".

At least, for English speakers it is. I don't know; maybe there are languages
in which saying "if x is equal to y" implies that x is the constant and y
is the variable.

-s
 
J

Jonathan de Boyne Pollard

But this really only means that average people well-versed in
mathematics shouldn't attempt to code in C because they will likely
make basic errors other people wouldn't.
I'm sure that they'll be delighted to hear that it's their fault for
being mathematicians, and not the C language's fault.
 
J

Jonathan de Boyne Pollard

English is meant to be read left to right, and is how I prefer to read
code, not the Yoda style '7 == x'.
Then the C and C++ declaration syntaxes, which are read spiral-fashion
(per David Anderson, 1994-05-06), are not for you, grasshopper.
 
J

Jonathan de Boyne Pollard

And "x == 7" is much more readable than "7 == x".

At least, for English speakers it is. I don't know; maybe there are
languages in which saying "if x is equal to y" implies that x is the
constant and y is the variable.
Nonsense. This is nothing to do with speaking English. There are
plenty of examples of English prose that use that ordering, from the
King James Bible through handbooks on baseball to Richard Dawkins. You
only find the ordering natural in C for purely circular reasons: It's
natural to (most) C programmers because that's how most C language code
that they have read is written. (And it's written that way because
"It's natural.") Nothing more, and nothing as a result of the English
language.
 
D

David Given

On 03/03/10 21:42, Ersek, Laszlo wrote:
[...]
Very nice. Thank you for releasing it as free software.

Thank you very much!
I can also see that WordGrinder is in Debian, starting with lenny, and
that you are its maintainer. Hats off!

It's not also as up to date as it should be --- occasionally upstream
forgets to tell me a new version has been released. Once my mentor
actually had to remind me to repackage it. (I should go find upstream
and give him a good talking-to...)
 
C

Chip Eastham

I'm sure that they'll be delighted to hear that it's their fault for
being mathematicians, and not the C language's fault.

We mathematicians claim as a birth right
to make the same basic errors in all
programming languages!

--c
 
N

Nick

Tim Streater said:
Rubbish. You don't say "if that chicken is an animal then I'll eat
it", you say "If that animal is a chicken then I'll eat it".

If wrong you are, my hat I will eat.
 
I

Ike Naar

But it makes the code much more difficult to read.

You're not testing that NULL now has a different value or that
0x152 has a different value.

The != operator is symmetric, ``NULL != pointer'' and ``pointer != NULL''
mean exactly the same thing, and both expressions are easy to read.

You are not testing if the left operand now has a different value,
you are testing if the left and the right operand have different values.
 
I

Ike Naar

I congratulate you : it has everything that sucks in pseudo styling.

1) unnecessary waste of vertical screen usage

Who cares; use your scroll button.
2) horrible "Non english" comparisons.

It's also "non chinese" and "non swahili". It's C, and in C the order
of the operands of the == and != operators is irrelevant.
You don't read arithmetic expressions like you read a work of literature.
When discussing vars in computing it is normal to discuss the variables
b name.

You dont say "if pi is larger than p".You say "if p is larger than
pi".

No. The two statements do not have the same meaning.
I think you mean "if pi is larger than p" vs. "if p is less than pi".
If you have trouble understanding ``pi > p'' then perhaps you shouldn't
be programming.
You're style is nothing more than fancy for fancy's sake IMO.

Of course; so is your style (and so is mine).
 
I

Ike Naar

It is a bad idea to try to solve social problems with technical
means. The problem behind this is that = in C is a so-called 'false
cognate' for people who are intimately familiar with mathematics, that
is, a term in a foreign language which 'looks' very similar to a
loosely related term in one's mother tongue, but with a (subtly)
different meaning. This means that such people will likely confuse =
and == in C intuitively and have a hard time spotting such an error
since the text 'looks right' according to the set of conventions they
are so used to that they no longer actively think about them.

But this really only means that average people well-versed in
mathematics shouldn't attempt to code in C because they will likely
make basic errors other people wouldn't.

Using ``='' for something other than equality was, in my opinion, the
most unfortunate design decision in the design of C.

We should be glad that the language designers left it at that, and did not
use ``+'' for ``or'', and ``++'' for addition ;-)
 
J

James Harris

Or, more Yoda-esque: If wrong you are, eat my hat I will.
Yes, Master Yoda :)

Reminds me of a phrase from, I think, Watership Down (the book, not
the animation): It's lost you are is it? Where was that from? Not the
far reaches of the Empire but deepest Wales. Maybe the force is strong
there also....

James
 
T

Tim Rentsch

Ian Collins said:
Tim said:
Ben Bacarisse said:
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.

Yes, such things are explicitly allowed as implementation-specific
forms of constant expressions, in both C90 (s 6.4) and C99 (6.6p10).
 
S

Seebs

We mathematicians claim as a birth right
to make the same basic errors in all
programming languages!

I'm not sure which ending fits better:

.... bringing a whole new meaning to the phrase "without loss of generality".
.... thus reducing everything to a class of problems already solved.

-s
 
S

Seebs

It's also "non chinese" and "non swahili". It's C, and in C the order
of the operands of the == and != operators is irrelevant.

To the compiler, yes. To the reader, no.
You don't read arithmetic expressions like you read a work of literature.

You sort of do, actually.

In general, while everyone knows that addition is commutative, people will
tend (slightly) to see "x + 3" as "basically x, but with 3 more", and "3 + x"
as "basically 3, but with x more". The lefthand operand has primacy, and
this *does* matter.

It's the same reason that:
the man was eaten by the bear
and
the bear ate the man
are not the same statement, even though they have the same information
in them if you ignore connotations. One is telling you about the bear's
diet; one is telling you about what happened to a man.

So even if it's the same for the compiler, if you write:
if (x != y)
the reader assumes that x is the value which is in question, not y. Maybe
the reader is wrong, but the assumption is sufficiently deeply wired in
most brains that there is no point trying to outsmart the reader. The reader
will pick up the connotation with very high reliability, *even if it's wrong*.
Thus, your best bet when writing code so that humans can read it reliably
remains to honor the convention even though there's no reason in C itself to
do so.

It's like indentation. We don't indent in C because the compiler cares, but
because it helps readers understand. Bad indentation can result in readers
misunderstanding code, because they trust the indentation to be a cue.
Similarly, reversing the order of the comparands in an equality or inequality
comparison, even though in theory it changes nothing semantically, can cause
readers to misunderstand code.

I write for humans, not compilers. Compilers aren't subject to assumptions,
or to difficulty keeping track of the code.

-s
 
K

Keith Thompson

Tim Streater said:
Rubbish. You don't say "if that chicken is an animal then I'll eat
it", you say "If that animal is a chicken then I'll eat it".

The word "is" isn't an equality operator in that context; it's more
like a set membership operator. In fact, I think that most uses of
"is" in English mean something other than equality.

I suggest that in cases where "is" is used to denote equality,
usage is more symmetric than you might think. "My brother is Fred
Thompson" and "Fred Thompson is my brother" seem equally clear to me
(and equally false, since that's not my brother's name).

If that (a specific creature) animal (more specific information to
help identify the creature) is a chicken (is a member of the set
of chickens) then I'll eat it. Swapping "chicken" and "animal"
changes the meaning of the sentence. By contrast, "x == 7" and
"7 == x" have exactly the same meaning in C; the only question is
which one more clearly expresses that meaning.

As I've said, I agree that "x == 7" is clearer. More precisely,
I can state authoritatively that it's clearer *to me*. If others
state that both forms are equally clear *to them*, I have no reason
to doubt it.

And someone who finds "x == 7" and "7 == x" equally clear is probably
thinking about it more clearly than I'm able to, and possibly having
trouble figuring out what my problem is. (I'm not entirely sure
about that myself.)
 
E

Ersek, Laszlo

But gcc gives a warning for it, anyway. And "x == 7" is much more readable
than "7 == x".

At least, for English speakers it is. I don't know; maybe there are languages
in which saying "if x is equal to y" implies that x is the constant and y
is the variable.

I've found the following phrases in Wiktionary:

http://en.wiktionary.org/wiki/equal

"Two plus two equals four."
"A and B are equal"
"A is equal to B"
"A is equal with B"

In Hungarian, forms 1 and 3 don't exist, but forms 2 and 4 are used with
the exact same structure. And yet I don't have any difficulty writing

7 == x

and thinking, "7 is equal with x". Equality is symmetric. It took some
self-education (let's not be inquisitive about the why), but it was so
effective that now I frown on

x == 7


.... I updated the function below to its current form two days ago;
you'll love to hate it:


static void
bailout(void)
{
sigset_t tmp_set;

if (pthread_equal(pthread_self(), main_thread)) {
if (0 != opathn) {
(void)unlink(opathn);
}

if (0 == sigemptyset(&tmp_set) && 0 == sigaddset(&tmp_set, SIGPIPE)
&& 0 == sigaddset(&tmp_set, SIGXFSZ)) {
(void)pthread_sigmask(SIG_UNBLOCK, &tmp_set, 0);
}
}
else {
if (0 == sigemptyset(&tmp_set) && 0 == sigpending(&tmp_set)) {
int chk;

chk = sigismember(&tmp_set, SIGPIPE);
if (0 == chk || (1 == chk && 0 == kill(pid, SIGPIPE))) {
chk = sigismember(&tmp_set, SIGXFSZ);
if ((0 == chk || (1 == chk && 0 == kill(pid, SIGXFSZ)))
&& 0 == kill(pid, SIGUSR1)) {
pthread_exit(0);
}
}
}
}

_exit(EX_FAIL);
}


(If called from the main thread, it removes the output file, if any.
Then it tries to unblock any pending SIGPIPE or SIGXFSZ. If it succeeds
(it should) and there is in fact any such signal pending for the whole
process or specifically for the main thread, such that its action is not
SIG_IGN (but SIG_DFL), then the process dies with one of those signals.
If unblocking fails (for whatever reason -- it shouldn't), or no such
signal was pending, or all relevant actions were SIG_IGN (yes, a signal
may remain pending even though its action is SIG_IGN), then the process
exits with status 1. (Unless a sub-thread encounters an EPIPE/EFBIG and
raises a SIGPIPE or SIGXFSZ, see below, to the process level, just
between unblocking and exiting, which is fine.)

If called from any sub-thread, if any of the following fails, the entire
process is terminated with exit status 1 as a last resort. Each
sub-thread has SIGPIPE and SIGXFSZ blocked. If any such signal is
pending on the thread, the thread forwards it to the process level, so
that it will become deliverable to the main thread. If any such signal
is already pending on the whole process, then the thread regenerates it
for the whole process -- an idempotent operation. Then the thread wakes
the main thread -- which is waiting for asynchronously generated signals
anyway like SIGINT and SIGTERM -- with a SIGUSR1 error notification, and
finally, the sub-thread terminates.

sigismember() can theoretically return -1, that's why 1 == chk is
checked after 0 == chk proves false.

tmp_set must be emptied before it can be passed to sigpending().)

Cheers,
lacos
 

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,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top