Strange behaviour of macros C/C++
Macros are (relatively simple) textual substitutions.
Use parentheses in your definitions (both to enclose the macro itself and the macro arguments):
#define PI (atan(1) * 4)
#define radians(deg) ((deg) * PI / 180)
#define degrees(rad) ((rad) * 180 / PI)
Strange macro behaviour
Your macro does not properly parenthesize the arguments in the expansion:
#define idx(__n__, __i__, __j__) __j__ + __n__*(__i__)
Should be:
#define idx(n, i, j) ((j) + (n) * (i))
Unless you really mean something crazy.
This is a bug, but not one causing your problem. Try fixing the printf
format for double
to %f
instead of %lf
. Also make verify the types of j
and n
, A
, epsilon
and norm
are consistent with the printf
formats.
Strange behavior of #define
Preprocessor is just doing simple "find & replace", so this code:
printf("%d",d*d);
changes to
printf("%d",10+10*10+10);
which is 10+100+10 = 120
That's why it's so important to add parens in defines:
#define d (10+10)
Function-like macros and strange behavior
The compiler replaces the macros with exactly what you pass in, verbatim. So you end up with
int a = 5, b = 0;
f((++a) > (b) ? (++a) : (b));
f((++a) > (b+10) ? (++a) : (b+10));
Strange behavior of Macro-expansion
In one case you have + ++
and in the other case you have ++ +
. + ++
and ++ +
are different streams of tokens. Macro pasting doesn't change tokenization because it's tokens that are pasted.
If you punch your program into a C pre-processor, you'll get this out for that line:
int result = a/d/e*b+ ++c%d;
Notice that the preprocessor had to insert a space because one is mandatory between a +
token and a ++
token.
Debug Macro strange behaviour
You are explicitly defining DEBUG in your source file
#define DEBUG
Remove that line so that you are not overriding any definition from your build environment.
strange result on macro expansion
Pass it the -E option (Ex: gcc -E a.c
). This will output preprocessed source code.
int main()
{
printf("The value of A is %d\n", - -5);
return 0;
}
So it will introduce a space between -
and -5
hence it will be not considered as an decrement operator --
, so printf
will print 5.
GCC Documentation On Token Spacing provides the Information on Why There is an Extra Space Produced:
First, consider an issue that only concerns the stand-alone preprocessor: there needs to be a guarantee that re-reading its preprocessed output results in an identical token stream. Without taking special measures, this might not be the case because of macro substitution. For example:
#define PLUS +
#define EMPTY
#define f(x) =x=
+PLUS -EMPTY- PLUS+ f(=)
==> + + - - + + = = =
not
==> ++ -- ++ ===
One solution would be to simply insert a space between all adjacent tokens. However, we would like to keep space insertion to a minimum, both for aesthetic reasons and because it causes problems for people who still try to abuse the preprocessor for things like Fortran source and Makefiles.
For now, just notice that when tokens are added (or removed, as shown by the EMPTY example) from the original lexed token stream, we need to check for accidental token pasting. We call this paste avoidance. Token addition and removal can only occur because of macro expansion, but accidental pasting can occur in many places: both before and after each macro replacement, each argument replacement, and additionally each token created by the
#
and##
operators.
Related Topics
How to Print Stack Trace for Caught Exceptions in C++ & Code Injection in C++
Const to Non-Const Conversion in C++
Cmake with Include and Source Paths - Basic Setup
How to Increment an Iterator by 2
How to Use a Boost Condition Variable to Wait for a Thread to Complete Processing
Why Is There No Base Class in C++
Calling Constructors in C++ Without New
Is There a Readable Implementation of the Stl
Calculating Execution Time in C++
Rodrigues into Eulerangles and Vice Versa
Which Is Faster:If (Bool) or If(Int)
What Does Iterator->Second Mean
What's the Deal with Boost.Asio and File I/O