Stylistic questions on UNIX C coding.

J

James Harris

I agree that that's a sore spot. But in complex conditions I often like to
align the logical operators w/ the if statement.

    if (sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3
    &&  sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3
    &&  needs_processing(color)) {
        compute_volume(length, width, height);
        compute_something_else(price, weight);
    }

Along with 8 space aligned indentation, it's not that bad.

Or, because the condition should be made clear how about setting it
off as follows.

if (
sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3 &&
sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3 &&
needs_processing(color)
) {
compute_volume(length, width, height);
compute_something_else(price, weight);
}

I generally indent continuation lines half as much as the indent for a
block of code. In this case there are four spaces prior to the guarded
block of code and hence two spaces prior to each of the continuation
lines.

I can't recall seeing a recommendation for continuation lines
anywhere. I've just used this from my early programming days. It's
clear and consistent but I expect there are better schemes I've never
come across.

James
 
J

James Harris

Given the amount of contradictory advise I'm getting in this
thread I am beginning to wonder why myself. :)

I know you wrote this with a smiley and you are right there's been a
lot of differing advice but just as general observations:

1. the differences of opinion have been informative in their own right
and also served to highlight what preferences there are, and
2. some areas of consensus have come up.

All-in-all a useful discussion. Someone even managed to insert a word
none of us had ever heard of, bedizenry. (I think it was this thread.)
When I checked even Google only showed nine web hits and that's
including duplicates. Nice one, whoever that was. :)


James
 
K

Keith Thompson

Stephen Sprunk said:
That's a problem with _mixing tabs and spaces_, which is Evil(tm).

If you use a tab character (inserted by pressing the tab key) for each
level of indentation, each programmer can set the tab stops in his
editor however he wants and it will look correct for everyone.

Only if everyone who ever modifies the code consistently uses tabs,
and only tabs, for indentation.

I really don't want to have to set the tabstops in my editor (and
in every other piece of software and/or hardware I might use to
look at the code, either on my own screen or on someone else's)
to the appropriate value for the particular file I'm looking at to
make it legible.

I might commonly examine a source file using any of vim, emacs, less,
cat (if it's very short), or one or more Windows-specific editors, or
I might print it, probably after using enscript to generate Postscript
output. I'm also likely to use diff, among other things, to process
the source file as input. I know how to set the tabstop width for
some of those, but certainly not all of them.
 
S

Stefan Ram

Poster Matt said:
Is CamelCase acceptable?

If you write code for your own enjoyment, you can do it anyway
that pleases you.

If you write code in school or a company, the teacher or lead
programmer will answer this.

If you ask me whether I like camel case in this case: No.
2. My personal variable and function naming style is camel
case, with variable names beginning with a lower case char
and function names not. Is that acceptable, if not what is?
Variables: int numFiles = 0;
Functions: int CountNumFilesInDir(char* path);

Are you aware that in C90, only the first 6 characters are
required to be significant in external identifiers? Thus,

int fcount( char const * const directory )

In C99,

int numberoffilesindir( char const * const path );

or

int number_of_files_in_dir( char const * const path );

. I do not use verbal phrase for the names of functions
whose main task is to return a value, so no »count«.
EG. I like: char* firstName; and not so much: char *firstName;

I agree, but the risk is that »char* a, b;« might look
misleading to some beginners. So, I believe I might often
use »char * a;«.
EG. #define ErrorDirNotFound "The directory was not found."

I am not aware of the advantages of using a macro here at all.

Consistent handling of run-time errors is the most difficult
part of programming. To prepare your program for
internationalization, you might also use something like:

puts
( get_country_specific_message_text
( "The directory was not found." ))
There are so many style guides out there, most of them say contradictory things
at one point or another. What do the pros do?

They ask their boss / lead programmer to tell them what
style to use. If they are a boss / lead programmer
themselves, then they already should know.
Finally, before someone points this out... I know if I'm coding for myself, and
not following somebody else's stylistic requirements, I can do whatever I want.
However I'd like my code to be 'acceptable looking' to the wider UNIX C community.

In this case, use code from authoritative sources as a
template / role model:

- programming examples in the Kernighan/Ritchie book
- programming examples in the ISO standard for C
- source code for the kernel and tools of your
operating system

I do not expect to see much camel case there.
 
S

Stefan Ram

if (condition) {
is preferred over
if (condition)
{
Makes it much more likely that a properly written function will fit on a single
page/screen.

Not if you keep writing after the »{« as I do.

Why?

I want my code to express the structure.

Which structure?

The structure of the if statement, in this case.

What is the structure of an if statement?

According to ISO/IEC 9899:1999 (E)

selection-statement:
if ( expression ) statement

So, there is a head

if ( expression )

and a body

statement

Thus,

if( expression ) /* head */
{ exam(); ple(); } /* body */

The separation between head and body in the deep structure
beautifully alignes with the separation between the first
and the second line in the visible surface structure. Thus,
the surface structure exposes the deep structure in a
not-misleading way. (Which to me is the generalized meaning
of »structured programming«: expressing as much of the deep
structure as possible already in the surface structure,
which makes the code more readable.)

I do not see how this takes more lines than

if( expression ) {
exam(); ple(); }

or even

if( expression ) {
exam(); ple();
}

Moreover, why would anyone sane in his mind compose a line
of the head of a structure /and the first character of its
body/ with the rest of the body following in another line?

As a comparision, in writing, we have headings and text body:

The Creation

In the beginning God created the heaven and the earth.

Now, why would I write the heading /and the first word of
its body/ on a line, as in the following example?

The Creation In

the beginning God created the heaven and the earth.

If you put that »In« on the same line as your heading you'll
just look like a fool in front of your friends and colleagues.
 
C

Casper H.S. Dik

Then, it's not always black and white.
Consider the case where a condition does not fit on a single line:
if (sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3 &&
sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3 &&
needs_processing(color)) {
compute_volume(length, width, height);
compute_something_else(price, weight);
}

if (sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3 &&
sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3 &&
needs_processing(color))
{
compute_volume(length, width, height);
compute_something_else(price, weight);
}
In the first case, it is hard to see where the condition ends
and where the body starts. In the second case it's obvious.
Don't you think that the opening brace on its own line here improves
the readability?

I call a strawman; a proper c-style will not allow the first form;
e.g., at Sun our style requires this form:

if (sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3 &&
sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3 &&
needs_processing(color)) {
compute_volume(length, width, height);
compute_something_else(price, weight);
}


It's clear what the condition is and where the body starts.

Things I absolutely hate in some c-styles are:


if(condition)


"if" is a not a *function* it shouldn't look like one.

cstyles which require additional parantheses

if ((sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3) &&
(sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3) &&


Some C code looks like as if it is written with a leaking fountain pen
on smudged and crumpled paper.

Casper
 
C

Casper H.S. Dik

Kelsey Bjarnason said:
The One True Tabstop Width is 8.
[/QUOTE]
Three, actually. Okay, 8, if you're stuck using output devices from the
1960's which didn't allow user-defined tab spaces, but for how many
people is this true anymore?

You don't quite understand why a ne True Tabstop Width is 8?

It is because *other* *people* want to look at your code.

If you file contains real tabstops they better make sure that the file
looks right when displayed with a standard terminal.
Now imagine if they were using spaces. This guy uses two, the next guy
uses three, the third guy uses 4, the fourth guy uses 5, some other guy
uses 8.
With tabs, at least just by setting your tab stops, you can get a degree
of consistency. Have fun sorting out the nightmare of inconsistency
spaces lead to.

No, because you make the file non-portable, unless you save with
spaces and not with tabstops.

Casper
 
S

Stefan Ram

Consider the case where a condition does not fit on a single line:
if (sscanf(input_buffer, "%d %d %d", &length, &width, &height) == 3 &&
sscanf(other_buffer, "%d %d %d", &color, &price, &weight) == 3 &&
needs_processing(color)) {
compute_volume(length, width, height);
compute_something_else(price, weight);
}

I use the same rules for parentheses as for square brackets
and curly braces and thus, format this as follows.

if
( sscanf( input_buffer, "%d %d %d", &length, &width, &height )== 3 &&
sscanf( other_buffer, "%d %d %d", &color, &price, &weight )== 3 &&
needs_processing( color ))
{ compute_volume( length, width, height );
compute_something_else( price, weight ); }

One Way to Format Parentheses

There are several different ways to format texts with braces
and parentheses. One of them is being described here.

Indentation within Braces

An indentation of just one space often is too small to be seen
clearly, because the natural width and form of characters
often varies by an amount that is not very much smaller than a
space. Therefore, the indentation should amount to at least
two positions. In order not to waste horizontal spaces, an
indentation of exactly two positions is chosen. This means,
that the left position of the next level is two larger than
the position of the directly enclosing level.

Indentation by two positions within a block

{ ++x;
++x; }
^ ^
0 2

Bad: A small indentation by one position is not always visible
clearly

{++x;
++x; }

Good: The indentation by two positions is visible clearly

{ ++x;
++x; }

Bad: A large indentation by more than two positions wastes
horizontal space with no additional benefit

{ ++x;
++x; }

Spaces within braces

In mathematics, there are often no spaces at the inner side of
parentheses or braces in expressions, but spaces are used
indeed at the inner side of braces in set notation, when the
braces contain a description (not when they contain a list).

Spaces in set notation

{ x | x > 2 }

This style is adopted here: One space is written at the inner
side of braces.

Spaces at the inner side of parentheses within a block

{ ++x; }

This style is consistent with the indentation by two
positions, because only using this style, corresponding parts
of two lines have the same position.

Bad: No space after the first brace, the two statements are
misaligned

{++x;
++x; }

Good: One space after the first brace, the two statements are
properly aligned

{ ++x;
++x; }

Bad: Two spaces after the first brace, the two statements are
misaligned

{ ++x;
++x; }

There are some exceptions to this rule: No spaces are used
within empty braces "{}" and between two or more closing
braces of the same direction "}}", except, when the first one
of them is part of an empty pair "{} }" (an empty pair of
braces if treated like a single non-braces character).

Unified rules for all Brackets

For simplicity and uniformity, the rules from above apply to
all kinds of brackets, including parentheses, braces (curly
brackets), square brackets, and angle brackets.

Spaces within parentheses and square brackets

{ y = f( x )+ g() + a[ 2 ]; }

Binary operators are sorrounded by a space, but the space is
omitted, when there already is a space on the other side of a
sequence of brackets directly beside the operator: By this rule,
" )+" is written instead of " ) +".

Representation of the Syntactical Structure

A method declaration in Java consists of a head and a body.
The following representation shows this structure:

Good formatting according to the structure

void alpha() // head
{ beta(); } // body

The following formatting is misleading, because the line break
does not match the structural break:

Bad line break within the body

void alpha() { // head and the beginning of the body
beta(); } // the rest of the body

This formatting also would make no sense for blocks within
blocks. So it is often not used for such blocks. Therefore
even the adopters of this style can not use it uniformly.

Opening Braces Look Like "bullets"

There is a well known style to publish lists in typography
using bullets sticking out on the left, looking like this:

Common list representation with bullets in typography

o This is the first point
of this list, it is written
here just as an example.

o Here is another entry

o This is another example given
just as an example to show
an example

The braces of the beginnings of blocks stand out on the left
just the same, when the formatting being described here is
used, so they look quite naturally as beginning-of-a-block
markers, when one is used to the typographical list notation:

Left braces look like bullets to mark blocks

{ printf(); printf();
printf(); printf(); printf();
printf(); printf(); }

{ printf(); printf(); }

{ printf(); printf(); printf();
printf(); printf();
printf(); }

Neutrality

Someone wrote this C code:

while( fgets( eingabe, sizeof eingabe, stdin ))
if( sscanf( eingabe, "%d", &wert )!= 1 )
fprintf( stderr, "Please enter a number!\n" );
else
summe += wert;

It amazes me that I can add braces by my style conventions
(not changing the meaning of the code)
without the need to change the position of any character of
the given code or need to change the overall number of lines:

The code from above plus braces

while( fgets( eingabe, sizeof eingabe, stdin ))
{ if( sscanf( eingabe, "%d", &wert )!= 1 )
{ fprintf( stderr, "Please enter a number!\n" ); }
else
{ summe += wert; }}

Insofar, my bracing style might be considered non-obtrusive.

Lines per Contents

Lines containing only a single brace waste vertical space, so
less contents fits on the same screen space. Therefore, I usually
avoid them, but sometimes I do use them, when this helps to
increase readability. I also might temporarily use them when editing
a section of code. Of course, they would help programmers paid or
being judged by the lines-of-code productivity.
 
S

Stefan Ram

if
( sscanf( input_buffer, "%d %d %d", &length, &width, &height )== 3 &&
sscanf( other_buffer, "%d %d %d", &color, &price, &weight )== 3 &&
needs_processing( color ))
{ compute_volume( length, width, height );
compute_something_else( price, weight ); }

^
'---- What I like about this is:

This is an if statement with two variable constituents:
an expression and a statement.

This is the macrostructure.

The major questions one encounters when reading are:

- What a kind of entity is this at all?

And then, having learned that it is an if statement:

- Where is its expression?

- Where is its statement?

And it are exactly the answers to these three questions
that are each marked with a character in the leftmost column.

So the type of the entity and its two constituents
clearly stand out graphically (visually). Albeit in a
manner not too obtrusive and not wasting lines.

Now we can compare this with:

Here the start and end of the statement are marked in the
leftmost column. This is also not bad, but the important
separation between the expression and the statement of the
if is »hidden« in the »center« of this character structure.
 
N

Nick Keighley

(e-mail address removed) (Ike Naar) writes:
Things I absolutely hate in some c-styles are:

        if(condition)

"if" is a not a *function* it shouldn't look like one.

I write it like this

if (condition)
some_func (x);

and 'if' still doesn't look like a function to me
 
N

Nick Keighley

Windows Notepad users are stuck with 8. Windows Wordpad users seem to
be stuck with 6. These are not earlier than the 1980s.

Come to think of it, apart from those two programs what do Windows
users use to enter and edit source code?

the IDE, ConText, emacs, Word
 
N

Nick Keighley

It's a character, often ASCII 9, which tells your editor to indent (or,
on removal, unindent) by whatever number of columns is required to bring
things in line with the next (previous) tab stop.

so your layout is tab-stop dependent

Contrast that to hitting delete on a line which uses spaces instead of
tabs.  All this does is mess up the formatting, as the editor is almost
certain to treat a space as a _space_, as it should, not as a tab, which
it _shouldn't_, because the character involved is not a tab, but a space.

get a better editor

Then, of course, there's inserting.  Hit space.  See how many columns the
line indents.  One, isn't it?

but if I hit 'tab' my editor inserts four spaces. Or rather enough
spaces to make it a multiple of four or to line up with the preceeding
line
 Why is that?  Oh, yes, because spaces
aren't tabs, and editors won't treat them as tabs.  Tabs are tabs, and
editors treat them that way.

mine doesn't
AFAIK, even Emacs and vi can cope with tabs.  I've yet to meet _any_
editor which, when you delete a space, correctly determines that you
really meant to delete four spaces, and removes that many,

ConTEXT (on Windows)
or, when you
hit the spacebar, correctly figures out that you actually meant a tab,
not a space, and thus inserts 4 (or is it 3?  8?  5?) spaces.

but TAB does that for me

well I'd argue you aren't using TABs in your source text
 
N

Nick Keighley

Kelsey Bjarnason said:
It's a character, often ASCII 9, which tells your editor to indent (or,
on removal, unindent) by whatever number of columns is required to bring
things in line with the next (previous) tab stop.

Something tells me Tim might have know that.


Contrast that to hitting delete on a line which uses spaces instead of
tabs.  All this does is mess up the formatting, as the editor is almost
certain to treat a space as a _space_, as it should, not as a tab, which
it _shouldn't_, because the character involved is not a tab, but a
space.

Not with any half competent editor.


Then, of course, there's inserting.  Hit space.  See how many columns the
line indents.  One, isn't it?  Why is that?  Oh, yes, because spaces
aren't tabs, and editors won't treat them as tabs.  Tabs are tabs, and
editors treat them that way.

And often treat spaces as tabs too. press left or right or delete on y
white space area and it deletes to a tap stop.


AFAIK, even Emacs and vi can cope with tabs.  I've yet to meet _any_

Even? Emacs is probably the most advanced editor out there. And vi one
of the most popular programmers editor.
editor which, when you delete a space, correctly determines that you
really meant to delete four spaces, and removes that many, or, when you
hit the spacebar, correctly figures out that you actually meant a tab,
not a space, and thus inserts 4 (or is it 3?  8?  5?) spaces.

They don't if you're half competent and configure it properly.


Because spaces, for purposes of indentation, are defective by design,
and

What total bullshit. Most people use spaces for indentation.
editors are generally built in such a manner as to use the right thing
for the right job.  Spaces between words, etc, tabs for indentation.

Totally and utterly wrong. Its rare to find tabs used anymore. Most
editors are LSEs (language sensitive editors) and indent automatically
based on a configured language layout.

For once, I agree with one of your posts!
 
J

Jonathan de Boyne Pollard

If you file contains real tabstops they better make sure that the file
looks right when displayed with a standard terminal.
"Standard terminal"s, eh? Where in IEEE 1003.1:2004 does it specify how
many spaces a terminal in TAB3 mode actually expands to? Where does it
specify what the default tabstops are when one hasn't run the tabs command?
 
R

Rainer Weikusat

I use the same rules for parentheses as for square brackets
and curly braces and thus, format this as follows.

if
( sscanf( input_buffer, "%d %d %d", &length, &width, &height )== 3 &&
sscanf( other_buffer, "%d %d %d", &color, &price, &weight )== 3 &&
needs_processing( color ))
{ compute_volume( length, width, height );
compute_something_else( price, weight ); }

This must have been invented by someone who never changes the first
and last lines of a block and who never appends lines to blocks :->.
 
I

Ian Collins

Casper said:
Things I absolutely hate in some c-styles are:


if(condition)


"if" is a not a *function* it shouldn't look like one.

Almost as bad a styles that require parentheses on return; "return" is
not a *function* it shouldn't look like one!
 
N

Nick

Ian Collins said:
Almost as bad a styles that require parentheses on return; "return" is
not a *function* it shouldn't look like one!

There's something fundamentally wrong with the contrast between these
two programs as a result of that:

#include <stdlib.h>

int main(void) {
return EXIT_FAILURE;
}

-----
#include <stdlib.h>

int main(void) {
exit(EXIT_FAILURE);
}
 

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
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top