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 #define
s 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
What Is the Meaning and Usage of _Stdcall
Is There a Linq Library for C++
How to Get Rid of the _Imp_ Prefix in the Linker in Vc++
Building a 32-Bit Float Out of Its 4 Composite Bytes
Dll Redirection Using Manifests
Compile the Python Interpreter Statically
Nested Templates with Dependent Scope
What Is Uint_Fast32_T and Why Should It Be Used Instead of the Regular Int and Uint32_T
How Does the Standard Library Implement Std::Swap
How to Implement 2D Vector Array
How to Initialize a Static Const Member in C++
Waitpid Equivalent with Timeout
C++ Std::Vector VS Array in the Real World
How to Use MACro Argument as String Literal
Why Don't the C or C++ Standards Explicitly Define Char as Signed or Unsigned