Is a C++ Preprocessor Identical to a C Preprocessor

Is a C++ preprocessor identical to a C preprocessor?

The C++03 preprocessor is (at least intended to be) similar to the C preprocessor before C99. Although the wording and paragraph numbers are slightly different, the only technical differences I'm aware of between the two are that the C++ preprocessor handles digraphs (two-letter alternative tokens) and universal character names, which are not present in C.

As of C99, the C preprocessor added some new capabilities (e.g., variadic macros) that do not exist in the current version of C++. I don't remember for sure, but don't believe that digraphs were added.

I believe C++0x will bring the two in line again (at least that's the intent). Again, the paragraph numbers and wording won't be identical, but I believe the intent is that they should work the same (other than retaining the differences mentioned above).

understanding a C Preprocessor Macro's output vs a line code

This expression

z2=x2+++y2;

is parsed by the compiler like

z2 = x2++ + y2;

From the C Standard (6.4 Lexical elements)

4 If the input stream has been parsed into preprocessing tokens up to
a given character, the next preprocessing token is the longest
sequence of characters that could constitute a preprocessing token.

So these tokens +++ are parsed like ++ and +.
The expression with the macro

z1=AD(x1,++y1);

is parsed by the compiler like

z1 = x1 + ++y1;

The compiler already formed these sets of tokens x1 and ++y1 due to the comma between the tokens.

So these two statements are different.

How do you test if two #defines are the same with the C preprocessor

You cannot compare the preprocessor macros as strings. One possibility would be to put the hardware port address (e.g., via another macro in the platform-specific headers) into the #defines and then compare the addresses.

However, the easiest way might be to do the comparison of addresses in actual code, e.g.:

if (&FOO_PORT == &BAR_PORT) {
// populate callbacks with handle_foo_bar_func
} else {
// populate callbacks with handle_foo_func and handle_bar_func
}

While not done in pre-processor, the compiler may be able to optimise away the unused branch since the hardware addresses are likely compile-time constants.

Is it safe to run the C preprocessor several times on the same source?

In general, preprocessing via cpp is not guaranteed to be idempotent (a noop after the first run). A simple counterexample:

#define X #define Y z
X
Y

The first invocation will yield:

 #define Y z
Y

The second one:

z

Having said that, valid C code shouldn't be doing something like that (because the output wouldn't be valid input for next stages of the compiler).

Moreover, depending on what you are trying to do, cpp has options like -fpreprocessed that may help.

Implementing a C preprocessor

I found a useful discussion in the document mcpp-summary at http://mcpp.sourceforge.net/

What's the equivalent of a C preprocessor-like #define for an array length?

Use const to fulfill your need:

const BUFFER: usize = 512;

However, this is not preprocessor: as underscore_d's comment says, the usage of preprocessor is a pretty archaic mechanism. It has been replaced in Rust with:

  • const in case of literal value;
  • macros, to generate code.

You can understand the Rust's const keyword as "evaluated at compile-time". The (maybe) incoming functions evaluated at compile-time will be marked as const also.

Furthermore, even in C, using the preprocessor to create a compile-time constant is not the best practice.



Related Topics



Leave a reply



Submit