Stylistic questions on UNIX C coding.

A

Anand Hariharan

Hi,

I've a few questions concerning style when programming C on UNIX systems. I
don't want to look like an amateur. :)

1. Having been programming in higher level languages for the last 15 years, I'm
finding it hard to get used to DEFINES in all capitals. Is it really frowned on
not to do so? Is CamelCase acceptable?

EG. '#define MaxNumFiles 1024' not '#define MAXNUMFILES 1024'.

As see from the umpteen replies, you are not going to get one answer
when it comes to a style-related question.

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

Ersek, Laszlo

static const unsigned int MaxNumFiles = 1024;

[...]

This allows the compiler to use more strict type checking with the
constants, and signedness is explicit.

#define MAX_FILES 1024u
#define BUFSIZE ((size_t)4096)

(Yes, when I *use* MAX_FILES, I don't necessarily remember its type. But
in that situation the same applies to "MaxNumFiles": we have to look up
the definition.)

Signedness is equally explicit in

#define MAX_FILES 1024

as 1024 is ((int)1024) -- that macro definition is just ugly.

Cheers,
lacos
 
A

Anand Hariharan

Anand Hariharan wrote:








Fine in C99, I think, but an issue in C90 if he's using it to define an
array size.

Good point (and that's probably why no one mentioned it?). Even in
C99, it is not your good old array but a 'Variable' Length Array.

Does the standard have anything to say about VLAs being automatic
storage or free store, but cleans itself up when they go out of scope?
 
B

Ben Bacarisse

Richard Heathfield said:
Anand Hariharan wrote:


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. There are several slight
variations depending on what sort of constant expression is required
but I think the simplest things is to say that using the above will
confuse someone sometime and is therefore not usually considered good
style even in C99.
 
R

Rainer Weikusat

Keith Thompson said:
Rainer Weikusat said:
4. Does anyone care where the pointer * is? I prefer keeping to next
to the type, rather than next to the variable name.

EG. I like: char* firstName; and not so much: char *firstName;

C knows about three kinds of derived types, arrays

char a[];

Pointers to functions

char (*a)();

and pointers

char *a;

Array types, structure types, union types, function types, and pointer
types are all derived types (C99 6.2.5).

Exercise for the reader: Which of the six types defined above are
irrelevant for this statement about 'declaration of derived types'
because they belong to a different syntactical class than the three
examples? Which type is irrelevant because it cannot directly appear
in a variable declaration? Which other class of types should appear
instead because they can?
But it might be acceptable to special-case on some cases *with*
an understanding of the C type system. I prefer "char *a;" myself,
but there's a valid argument that "char* a;" makes it more obvious
that's meant (that a is of type char*).

A type 'char*' doesn't exist. A type named 'char' does, and assuming
that T names an existing type, an object can be declared as 'pointer
to a T' by using the syntax

T *o;

'Pointerness' is an attribute of the object, not of the type. This is
also consistent with the original intention behind this syntax, namely
that 'declaration should resemble use'.

[...]
Why not? Or are you just being rude?

They are bound to end up as quite useless quarrels between people
who desire to write "beautiful" code and people who desire to write
readable code.
 
K

Keith Thompson

I agree that MAXNUMFILES is harder to read than MaxNumFiles. The
solution is to write it as MAX_NUM_FILES.
Well, defines are macros, not constants, so I try to avoid them for this use.
With C99 and C++, one should probably use static const
<type> (where type a signed or unsigned integer of the appropriate width).
[...]

Even in C99, the name of a static const object cannot be used as a
constant expression. This:

static const int max = 42;
int arr[max];

is valid in C99, but only because arr is a VLA (though the compiler
might implement it exactly as if it were a non-VLA). But max can't be
used in other contexts that requires a constant expression, such as
case labels.

A common trick is to use enum:

enum { max = 42 };

This has the drawback that it can only be of type int.
 
K

Keith Thompson

Keith Thompson said:
His convention apparently is to use camelCase for variables and
PascalCase for functions. It's not necessarily a style I'd use, but
it's not obviously horrible (and it's more or less the style I use
at work).

On re-reading, I realize that sounds a bit odd. What I meant is that
it's not necessarily a style I'd use *voluntarily*, but I have no
problem using it if it's necessary to conform to the existing style of
the code I'm working on.
 
K

Keith Thompson

Rainer Weikusat said:
Keith Thompson said:
Rainer Weikusat said:
4. Does anyone care where the pointer * is? I prefer keeping to next
to the type, rather than next to the variable name.

EG. I like: char* firstName; and not so much: char *firstName;

C knows about three kinds of derived types, arrays

char a[];

Pointers to functions

char (*a)();

and pointers

char *a;

Array types, structure types, union types, function types, and pointer
types are all derived types (C99 6.2.5).

Exercise for the reader: Which of the six types defined above are
irrelevant for this statement about 'declaration of derived types'
because they belong to a different syntactical class than the three
examples? Which type is irrelevant because it cannot directly appear
in a variable declaration? Which other class of types should appear
instead because they can?

You said that "C knows about three kinds of derived types". In fact,
there are six. I was disputing the accuracy of your statement, not
its relevance.
A type 'char*' doesn't exist. A type named 'char' does, and assuming
that T names an existing type, an object can be declared as 'pointer
to a T' by using the syntax

T *o;

'Pointerness' is an attribute of the object, not of the type. This is
also consistent with the original intention behind this syntax, namely
that 'declaration should resemble use'.

Wrong. char* is a type. Specifically, it's a derived type and a
pointer type. See C99 6.2.5, particularly paragraph 20.

If char* is not a type, can you explain what exactly you mean when you
use the word "type"? Your usage appears to be inconsistent with the
usage in the C standard.

You might have a valid point in there somewhere, but your misuse of
terminology makes it difficult to discuss it.

(And for the record, I agree that "T *o;" is preferable to
"T* o;"; I just don't agree that it's a huge deal.)
[...]
Why not? Or are you just being rude?

They are bound to end up as quite useless quarrels between people
who desire to write "beautiful" code and people who desire to write
readable code.

Perhaps, but we've also seen some useful discussion in this thread,
particularly the point about the importance of conforming to whatever
coding standard is used for an existing project.
 
I

ImpalerCore

You need to fix your misprint.  Clearly you meant

If you *dont* put your  opening braces on
the same line as your conditional, you'll
just look like a fool in front of your
friends and colleagues.

                  - William Hughes

You both are wrong. It's best to mix the two styles, to get the best
of both worlds.

if ( conditional ) {
// line of code
} else {
// line of code
}

if ( conditional )
{
// multiple
// lines
// of
// code
}
else
{
// multiple
// lines
// of
// code
}

if ( conditional ) {
// line of code
}
else
{
// multiple
// lines
// of
// code
}

and yes this is actually my personal style :p
 
J

Jonathan de Boyne Pollard

Why not? Or are you just being rude?
Didn't you know? Source code style is a shameful secret, to be
practiced behind closed doors by consenting adults only.

I saw the subject of the first post in this thread, and immediately
thought that there's a quick way to get one of the largest threads in
the newsgroup.
 
I

Ian Collins

Scott said:
Indeed.

if (condition) {

is preferred over

if (condition)
{

By whom?
Makes it much more likely that a properly written function will fit on a single
page/screen.

If the extra lines required for an opening brace are an issue, the
function isn't properly written!
In 30 years of C programming, no employer or project has used the latter form.

I can honestly negate that line.
 
I

Ike Naar

if (condition) {

is preferred over

if (condition)
{

Makes it much more likely that a properly written function will fit on
a single page/screen.

And then there are people who write like this:

if (condition) {

do_something();
do_another_thing();
}
 
R

Rainer Temme

And then there are people who write like this:

if (condition) {

do_something();
do_another_thing();
}

or like this:
if (condition)
{
do_something();
do_another_thing();
}

or even like this:
if (condition) { do_something(); do_another_thing(); }

.... the world is a cruel place!
 
R

Richard Bos

BruceS said:
I would like to add that, as long as you're trying to use good style,
for God's sake don't use the wrong indentation style. If you put your
opening braces on the same line as your conditional, you'll just look
like a fool in front of your friends and colleagues.

Yeah. Those Kernighan and Ritchie guys knew jack shit about C.

Richard
 
R

Richard Bos

Seebs said:
No. Look into gettext() if you need to do this, or just put them in
literally.

gettext() is nice if you have it (it's POSIX, isn't it? Not ISO, anyway,
but common), but putting the messages in literally only works if you
don't reuse them. IME, _some_ error messages are used more than once, in
which case a #define is nice.

Richard
 
I

ImpalerCore

Hmmm...

if (condition) {    <-- one line

if (condition)      <-- one line
{                   <-- and another one, makes two lines

Does that really make a BIG difference?  

The only time it bugs me is when I have a single line of code for an
if and else statement.

if ( condition )
{
// line
}
else
{
// other line
}

I used to use this for a while. But I tried the other convention and
ended up liking it better. Again, this is for my personal stuff; if a
style is already in place in a project, I follow that standard.

I also don't leave out braces though for single lines since I've been
bitten by that in the past.

if ( condition )
// line

I always do this

if ( condition ) {
// line
}
 
S

Stefan Monnier

Indeed.
if (condition) {
is preferred over
if (condition)
{
Makes it much more likely that a properly written function will fit on
a single page/screen.
In 30 years of C programming, no employer or project has used the
latter form.

The standard GNU style (i.e. recommended for GNU projects) is to use

if (condition)
{
blabla
}

so Emacs uses this style. I personnally prefer the single-line form (my
windows never have enough lines), so I hacked up some .emacs thingy that
makes the two-line form display as the one-line form.


Stefan
 
M

Malcolm McLean

Yeah. Those Kernighan and Ritchie guys knew jack shit about C.
As CS Lewis said, the first pot, which would prove its maker a genius
if it were the first pot ever made, would prove him a dunce if it came
after many millenia of pot-making.
 
A

Anand Hariharan

   if (condition) {

is preferred over

   if (condition)
   {

Makes it much more likely that a properly written function will fit on a single
page/screen.

In 30 years of C programming, no employer or project has used the latter form.

scott


You've gotten some strong reactions to your not-seen-in-30-years
comment above.

FWIW I use the latter form myself. However, one good reason I got
from an ex-colleague for using the first style was that if you are
scrolling upward in source code, and get to the closing brace of a
block, using the keyboard shortcut in your editor for jumping to the
matching brace will get you to see the if (or while or for)
condition. Otherwise, it will only scroll upward to a point where the
opening brace is shown as the first line, and one has to go up one
line more. To me, this is not a big inconvenience.

- Anand
 
S

Seebs

In fairness to Scott, I think he just intended to describe his personal
experience. In my own experience, Allman style (i.e. the latter of the
two styles quoted above) is almost universal. I can't actually call to
mind a single project where 1TBS was used - but there must have been at
least one; my memory isn't what it... um... ah!... was.

The two that come to mind are Linux and NetBSD. :)

-s
 

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,233
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top