Preprocessor commands and whitespace

J

Juha Nieminen

I tried to decipher from the C++ standard draft where whitespaces are
or aren't allowed in preprocessor commands, but I found the standard
text rather cryptic on this subject. So I have two questions:

1) Is it allowed to have whitespace at the beginning of the line,
before the # symbol?

2) Is it allowed to have whitespace between the # symbol and the
keyword that follows it?

gcc seems to accept both, but it wouldn't be the first time gcc is a
bit lax about implementing the letter of the standard...
 
I

Ian Collins

Juha said:
I tried to decipher from the C++ standard draft where whitespaces are
or aren't allowed in preprocessor commands, but I found the standard
text rather cryptic on this subject. So I have two questions:

1) Is it allowed to have whitespace at the beginning of the line,
before the # symbol?
Yes.

2) Is it allowed to have whitespace between the # symbol and the
keyword that follows it?

Yes.
 
N

Neelesh

  I tried to decipher from the C++ standard draft where whitespaces are
or aren't allowed in preprocessor commands, but I found the standard
text rather cryptic on this subject. So I have two questions:

  1) Is it allowed to have whitespace at the beginning of the line,
before the # symbol?

Yes, 16.1:
A preprocessing directive consists of a sequence of preprocessing
tokens. The first token in the sequence is a # preprocessing token
that is either the first character in the source file (optionally
after white space containing no newline characters) or that follows
white space containing at least one newline character
  2) Is it allowed to have whitespace between the # symbol and the
keyword that follows it?

Yes, 16.2
The only whitespace characters that shall appear between preprocessing
tokens within a preprocessing
directive (from just after the introducing # preprocessing token
through just before the terminating newline character) are space and
horizontaltab
 
J

Jerry Coffin

I tried to decipher from the C++ standard draft where whitespaces are
or aren't allowed in preprocessor commands, but I found the standard
text rather cryptic on this subject. So I have two questions:

1) Is it allowed to have whitespace at the beginning of the line,
before the # symbol?

2) Is it allowed to have whitespace between the # symbol and the
keyword that follows it?

gcc seems to accept both, but it wouldn't be the first time gcc is a
bit lax about implementing the letter of the standard...

Whitespace is allowed both places, with a few minor (but mostly obvious)
restrictions, such as that the whitespace between the '#' and the rest
of the directive can't include a new-line.

Keep in mind, however, that pre-standard preprocessors often did NOT
allow white space before the '#', so if you ever write code that has to
work on really old compilers, it's something to avoid.
 
J

James Kanze

[...]
Keep in mind, however, that pre-standard preprocessors often
did NOT allow white space before the '#', so if you ever write
code that has to work on really old compilers, it's something
to avoid.

That's probably "some pre-standard preprocessors", not
necessarily all. And keep in mind that the standard we're
talking about here is C90, so we're talking about very, very old
compilers. And that before the standardization, there really
wasn't any standard pre-processor---there were two or three
major variants, with radically different ways of concatenating
tokens or stringizing (when they could stringize at all). So
that any pre-processor dependent code written for those
compilers probably won't compile with a modern compiler.

Of course, if we're talking about C++... Any C++ compiler
dating before C90 won't support templates, or exceptions, or
probably not even nested classes. Not to mention being horribly
buggy. So you have a lot more than just white space before the
# in preprocessor directives to worry about.

On the other hand, because of the history, it's very much a
tradition to put the # in column 1, and that's where most
readers expect it.
 
J

Jerry Coffin

[...]
Keep in mind, however, that pre-standard preprocessors often
did NOT allow white space before the '#', so if you ever write
code that has to work on really old compilers, it's something
to avoid.

That's probably "some pre-standard preprocessors", not
necessarily all.

Right -- that's what I meant by "often". At least TTBOMK, a given
preprocessor either always allowed or always prohibited the extra white
space, but not all allowed it.
 
J

Juha Nieminen

James said:
On the other hand, because of the history, it's very much a
tradition to put the # in column 1, and that's where most
readers expect it.

From a stylistic point of view, which one of these would be the best?

// Style 1:
some_indented_code_here();
#ifdef SOMETHING
a_very_indented_line();
#endif
more_code_here()


// Style 2:
some_indented_code_here();
# ifdef SOMETHING
a_very_indented_line();
# endif
more_code_here()



// Style 3:
some_indented_code_here();
#ifdef SOMETHING
a_very_indented_line();
#endif
more_code_here()


Or none of the above?
 
J

Jerry Coffin

[ ... indentation of preprocessor directives ]
From a stylistic point of view, which one of these would be the best?

At least to me, indentation of preprocessor directives is entirely
separate from indentation of normal code. Then again, I don't think
there's often a reason to mix the two at all. Mostly, I use #ifdef's to
control inclusion of headers:

#ifdef X
#include "XYZ stuff"

#ifdef Y
#include "YZ stuff"
#ifdef Z
#include "Z stuff"
#endif
#endif
#else
#include "general stuff"
#endif

Makes sense, but indentation of the actual code is entirely separate. If
you're mixing preprocessor directives with normal code much like you
showed in your post, I'd advise reading "#ifdef considered harmful":

ftp://gatekeeper.dec.com/pub/news/c/doc/usenix92.ps.Z
 
J

James Kanze

From a stylistic point of view, which one of these would be the best?
// Style 1:
some_indented_code_here();
#ifdef SOMETHING
a_very_indented_line();
#endif
more_code_here()
// Style 2:
some_indented_code_here();
# ifdef SOMETHING
a_very_indented_line();
# endif
more_code_here()
// Style 3:
some_indented_code_here();
#ifdef SOMETHING
a_very_indented_line();
#endif
more_code_here()
Or none of the above?

None of the above. The only use of #ifdef I allow is for header
guards. Of course, conditional compilation within a function
body is simply too horrible to contemplate. The issue of
indenting tends to arise with nested conditions:

/* This is the obsolete POSIX.1-1988 name for the same constant.
*/
# if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
# ifndef CLK_TCK
# define CLK_TCK CLOCKS_PER_SEC
# endif
# endif

(from time.h under Linux). I'd avoid such cases as well,
whenever possible, but if necessary, something like the above
seems to be about the best compromize to me.
 
J

Juha Nieminen

James said:
None of the above. The only use of #ifdef I allow is for header
guards.

Then I assume you strongly oppose things like the _GLIBCXX_DEBUG
precompiler constant supported by gcc which, if defined, turns on
boundary and other sanity checks for all STL containers, for debugging
purposes (at the cost of efficiency, naturally).

If that's so, then we just have to agree to disagree.
 

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

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top