C++, declaring an array with define; What is happening? (Easy and quick) - c++

Im trying to learn some c++, and I bumped into this code:
static const unsigned char t_CountBits13[8192] = {
#define B2(n) n, n+1, n+1, n+2
#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
#define B8(n) B6(n), B6(n+1), B6(n+1), B6(n+2)
#define B10(n) B8(n), B8(n+1), B8(n+1), B8(n+2)
#define B12(n) B10(n), B10(n+1), B10(n+1), B10(n+2)
B12(0), B12(1)
};
I think this is pretty weird !
Question 1: Is this the same as:
#define B2(n) n, n+1, n+1, n+2
#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
#define B8(n) B6(n), B6(n+1), B6(n+1), B6(n+2)
#define B10(n) B8(n), B8(n+1), B8(n+1), B8(n+2)
#define B12(n) B10(n), B10(n+1), B10(n+1), B10(n+2)
static const unsigned char t_CountBits13[8192] = {B12(0), B12(1)};
Question 2:
#define B2(n) n, n+1, n+1, n+2
Am I right to think that a C++ function can only return one value ? Because it seems like you define a function here that returns multiple (like lua for example)
Kind regards!

Answer 1: The array will be initialized with the same value. The preprocessed result will look a bit different with regards to white space, so textually it isn't the same, but the result of compilation should be identical.
Answer 2: As mentioned in the comments, these are not C++ functions, but are macros interpreted by the C pre-processor. These result in text expansion prior to the compiler interpreting it. The expansion in your example is too large to show here (2 * 4^6 = 8192 elements is a lot). I'll reduce it for an example.
Original source code:
static const unsigned char data[] = {
#define B2(n) n, n+1
#define B4(n) B2(n), B2(n+1)
B4(1), B4(2)
};
output of preprocessor (for example, as output by gcc -E tst.c:
# 1 "tst.c"
# 1 "<command-line"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line" 2
# 1 "tst.c"
static const unsigned char data[] = {
1, 1 +1, 1 +1, 1 +1 +1, 2, 2 +1, 2 +1, 2 +1 +1
};
Note the blank lines where the preprocessing directives were. Also note that the values are not the result of the arithmetic, but the text expansion. This is the code the compiler will actually interpret. Also note that the expansions are recursive through the #define macros defined above.
The lines starting with # are additional information from the preprocessor and includes things like defines from the command line and file information. It's fairly bland in the example, but if you were to have a #include <somefile.h> you'd see its contents, and the contents of the files it includes (recursively), as well as some # lines indicating the real line numbers of those locations (often used by the compiler for displaying warning and error messages, since by the time it gets it the line that used to be your line 5 might now be line 2592, but you'd expect the warning to indicate line 5).
Looking at the output of the preprocessor can be quite helpful debugging weird errors. When the message from the compiler just doesn't make sense, it can be an errant #define replacing text you didn't expect. For example, you might have the following code
int limit(int x) {
if (x > LIMIT) {
return LIMIT;
}
return x;
}
The compiler might say error: expected identifier or '(' before numeric constant on the line int limit(int x) {
If you look at the preprocessed output you might find
int 5(int x) {
and realize that the following line made it into your code (either original source file or from an included file)
#define limit 5
Note how limit is lower case, and we tried naming a function that, but the preprocessor replaced it with the 5. The #define should probably have been LIMIT (all uppercase)
This has been a bit of a long answer, but I hope illustrates the text-replacement nature of #defines and some hints at finding the intermediary representations of your own code.
Note: The actual output of your preprocessor depends on your toolchain. The information above holds for the GNU Compiler Collection. Some toolchains don't actually separate the pre-processor phase from the compilation phase, but simply behave as though they do, which is allowed by the language.

Related

Prevent Simple Macro Substitution

How does one prevent simple macro substitution?
e.g.
#define number 0x10
int number = 0x5;
I know this can be done for function-style macros, like min and max, by surrounding the macro with parentheses (thus, separating it from the adjacent parentheses that would've been used for the args):
#define max(...)
void (max)();
My current method is to push the macro value, undefine it, use it, then pop the original value.
You can't prevent macro substitution.
That's one of the reasons why macros are usually all caps:
#define NUMBER 0x10
int number = 0x5; // no problem here.
Even this can be done of course:
int number = NUMBER; // even this can be done of course
I would advise using const variables when you want to define constants instead of using macros. And to avoid name collisions maybe just add some prefix or suffix to the name or capitalize the name.
In c++ you can even use constexpr.
There is no standard way for this but you can do the following:
#define number 0x10
#pragma push_macro("number")
#undef number
int number = 0x5;
#pragma pop_macro("number")
The #undef directive undefines a constant or preprocessor macro defined previously using #define.
Refer: https://www.cprogramming.com/reference/preprocessor/undef.html

Macro expansion in context of arithmetic expression?

I saw this below code in an website.
I could not able to understsnd how the result is coming as 11, instead of 25 or 13.
Why I am thinking 25 because SQ(5) 5*5
or 13 because
SQ(2) = 4;
SQ(3) = 9;
may be final result will be 13 (9 + 4)
But surprised to see result as 11.
How the result is coming as 11?
using namespace std;
#define SQ(a) (a*a)
int main()
{
int ans = SQ(2 + 3);
cout << ans << endl;
system("pause");
}
The preprocessor does a simple text substitution on the source code. It knows nothing about the underlying language or its rules.
In your example, SQ(2 + 3) expands to (2 + 3*2 + 3), which evaluates to 11.
A more robust way to define SQ is:
#define SQ(a) ((a)*(a))
Now, SQ(2 + 3) would expand to ((2 + 3)*(2 + 3)), giving 25.
Even though this definition is an improvement, it is still not bullet-proof. If SQ() were applied to an expression with side effects, this could have undesired consequences. For example:
If f() is a function that prints something to the console and returns an int, SQ(f()) would result in the output being printed twice.
If i is an int variable, SQ(i++) results in undefined behaviour.
For further examples of difficulties with macros, see Macro Pitfalls.
For these reasons it is generally preferable to use functions rather than macros.
#define expansions kick in before the compiler sees the source code. That is why they are called pre-processor directives, the processor here is the compiler that translates C to machine readable code.
So, this is what the macro pre-processor is passing on to the compiler:
SQ(2 + 3) is expanded as (2 + 3*2 + 3)
So, this is really 2 + 6 + 3 = 11.
How can you make it do what you expect?
Enforce the order of evaluation. Use (), either in the macro definition or in the macro call.
OR
Write a simple function that does the job
The C preprocessor does textual substitution before the compiler interprets expressions and C syntax in general. Consequently, running the C preprocessor on this code converts:
SQ(2 + 3)
into:
2 + 3*2 + 3
which simplifies to:
2 + 6 + 3
which is 11.
#define preprocesor
Syntax :
# define identifier replacement
When the preprocessor encounters this directive, it replaces any occurrence of identifier in the rest of the code by replacement.
This replacement can be an expression, a statement, a block or simply anything.
The preprocessor does not understand C, it simply replaces any occurrence of identifier by replacement.
# define can work also with parameters to define function macros:
# define SQ(a) (a*a)
will replace any occurance of SQ(a) with a*a at compile time.
Hence,
SQ(2+3) will be replaces by 2+3*2+3
The computation is performed after the replacement is done.
hence answer 2+3*2+3=11
For your implementation, the value will expand to 2+3 * 2+3 which will result into 2+6+3=11.
You should define it as:
#define SQ(x) ({typeof(x) y=x; y*y;})
Tested on gcc, for inputs like
constants,
variable,
constant+const
const+variable
variable++ / ++variable
function call, containing printf.
Note: typeof is GNU addition to standard C. May not be available in some compilers.
It's just a replacement before compilation
so you should try this out :
#define SQ(a) ((a)*(a))
In your case , SQ(2 + 3) is equivalent to (2+3*2+3) which is 11.
But correcting it to as I wrote above, it will be like, ((2+3)*(2+3)) which is 5*5 = 25 that's the answer you want.

How to expand this macro properly?

When I define this macro:
#define SQR(x) x*x
Let's say this expression:
SQR(a+b)
This expression will be replaced by the macro and looks like:
a+b*a+b
But, if I put a ++ operator before the expression:
++SQR(a+b)
What the expression looks like now? Is this ++ placed befor every part of SQR paramete? Like this:
++a+b*++a+b
Here I give a simple program:
#define SQR(x) x*x
int a, k = 3;
a = SQR(k+1) // 7
a = ++SQR(k+1) //9
When defining macros, you basically always want to put the macro parameters in parens to prevent the kind of weird behaviour in your first example, and put the result in parens so it can be safely used without side-effects. Using
#define SQR(x) ((x)*(x))
makes SQR(a+b) expand to ((a+b)*(a+b)) which would be mathematically correct (unlike a+b*a+b, which is equal to ab+a+b).
Putting things before or after a macro won't enter the macro. So ++SQR(x) becomes ++x*x in your example.
Note the following:
int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
// since preincrement will affect the value of a before it is read.
You're seeing the ++SQR(a+b) appear to increment by 2 since the preincrement kicks in before a i read either time, i.e. a increments, then is used twice and so the result is 2 higher than expected.
NOTE As #JonathanLeffler points out, the latter call invokes undefined behaviour; the evaluation is not guaranteed to happen left-to-right. It might produce different results on different compilers/OSes, and thus should never be relied on.
For C++ the right way to define this macro is to not use a macro, but instead use:
template<typename T> static T SQR( T a ) { return a*a; }
This will get right some horrible cases that the macro gets wrong:
For example:
SQR(++a);
with the function form ++a will be evaluated once. In the macro form you get undefined behaviour as you modify and read a value multiple times between sequence points (at least for C++)
A macro definition just replaces the code,hence it is generally preferable to put into parenthesis otherwise the code may replaced in a way you don't want.
Hence if you define it as :
#define SQR(x) ((x)*(x))
then
++SQR(a+b) = ++((a+b)*(a+b))
In your example, ++SQR(a+b) should be expanded as ++a+b*a+b.
So, if a == 3 and b == 1 you will get the answer 9 if the compiler evaluates it from left to right.
But your statement ++SQR(3+1) is not correct because it will be expanded as ++3+1*3+1 where ++3 is invalid.
In your preprocessor it evaluates to ++a+b*a+b. The right way is put brackets around each term and around the whole thing, like:
#define SQR(x) ((x)*(x))

C++ - Macro defines directive

At: http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/
It mentions a directive called "Macro defines". What do we mean when we say "Macro"?
Thanks.
A macro is a preprocessor directive that defines a name that is to be replaced (or removed) by the preprocessor right before compilation.
Example:
#define MY_MACRO1 somevalue
#define MY_MACRO2
#define SUM(a, b) (a + b)
then if anywhere in the code (except in the string literals) there is a mention of MY_MACRO1 or MY_MACRO2 the preprocessor replaces this with whatever comes after the name in the #define line.
There can also be macros with parameters (like the SUM). In that case the preprocessor recognizes the arguments, example:
int x = 1, y = 2;
int z = SUM(x, y);
preprocessor replaces like this:
int x = 1, y = 2;
int z = (x + y);
only after this replacement the compiler gets to compile the resulting code.
A macro is a code fragment that gets substituted into your program by the preprocessor (before compilation proper begins). This may be a function-like block, or it may be a constant value.
A warning when using a function-like macro. Consider the following code:
#define foo(x) x*x
If you call foo(3), it will become (and be compiled as) 3*3 (=9). If, instead, you call foo(2+3), it will become 2+3*2+3, (=2+6+3=11), which is not what you want. Also, since the code is substituted in place, foo(bar++) becomes bar++ * bar++, incrementing bar twice.
Macros are powerful tools, but it can be easy to shoot yourself in the foot while trying to do something fancy with them.
"Macro defines" merely indicate how they are specified (with #define directives), while "Macro" is the function or expression that is defined.
There is little difference between them aside from semantics, however.

C++ throwing compilation error on sizeof() comparison in preprocessor #if

I have this which does not compile with the error "fatal error C1017: invalid integer constant expression" from visual studio. How would I do this?
template <class B>
A *Create()
{
#if sizeof(B) > sizeof(A)
#error sizeof(B) > sizeof(A)!
#endif
...
}
The preprocessor does not understand sizeof() (or data types, or identifiers, or templates, or class definitions, and it would need to understand all of those things to implement sizeof).
What you're looking for is a static assertion (enforced by the compiler, which does understand all of these things). I use Boost.StaticAssert for this:
template <class B>
A *Create()
{
BOOST_STATIC_ASSERT(sizeof(B) <= sizeof(A));
...
}
Preprocessor expressions are evaluated before the compiler starts compilation. sizeof() is only evaluated by the compiler.
You can't do this with preprocessor. Preprocessor directives cannot operate with such language-level elements as sizeof. Moreover, even if they could, it still wouldn't work, since preprocessor directives are eliminated from the code very early, they can't be expected to work as part of template code instantiated later (which is what you seem to be trying to achieve).
The proper way to go about it is to use some form of static assertion
template <class B>
A *Create()
{
STATIC_ASSERT(sizeof(B) <= sizeof(A));
...
}
There are quite a few implementations of static assertions out there. Do a search and choose one that looks best to you.
sizeof() cannot be used in a preprocessor directive.
The preprocessor runs before the compiler (at least logically it does) and has no knowledge of user defined types (and not necessarily much knowledge about intrinsic types - the preprocessor's int size could be different than the compiler targets.
Anyway, to do what you want, you should use a STATIC_ASSERT(). See the following answer:
Ways to ASSERT expressions at build time in C
With a STATIC_ASSERT() you'll be able to do this:
template <class B>
A *Create()
{
STATIC_ASSERT( sizeof(A) >= sizeof( B));
return 0;
}
This cannot be accomplished with pre-processor . The pre-processor executes in a pass prior to the compiler -- therefore the sizes of NodeB and Node have not yet been computed at the time #if is evaluated.
You could accomplish something similar using template-programming techniques. An excellent book on the subject is Modern C++ Design: Generic Programming and Design Patterns Applied, by Andrei Alexandrescu.
Here is an example from a web page which creates a template IF statement.
From that example, you could use:
IF< sizeof(NodeB)<sizeof(Node), non_existing_type, int>::RET i;
which either declares a variable of type int or of type non_existing_type. Assuming the non-existing type lives up to its name should the template IF condition evaluate as true, a compiler error will result. You can rename i something descriptive.
Using this would be "rolling your own" static assert, of which many are already available. I suggest you use one of those after playing around with building one yourself.
If you are interested in a compile time assert that will work for both C and C++, here is one I developed:
#define CONCAT2(x, y) x ## y
#define CONCAT(x, y) CONCAT2(x, y)
#define COMPILE_ASSERT(expr, name) \
struct CONCAT(name, __LINE__) { char CONCAT(name, __LINE__) [ (expr) ? 1 : -1 ]; }
#define CT_ASSERT(expr) COMPILE_ASSERT(expr, ct_assert_)
The to how this works is that the size of the array is negative (which is illegal) when the expression is false. By further wrapping that in a structure definition, this does not create anything at runtime.
This has already been explained, but allow me to elaborate on why the preprocessor can not compute the size of a structure. Aside from the fact that this is too much to ask of a simple preprocessor, there are also compiler flags that affect the way the structure is laid out.
struct X {
short a;
long b;
};
this structure might be 6 bytes or 8 bytes long, depending on whether the compiler was told to 32-bit align the "b" field, for performance reasons. There's no way the preprocessor could have that information.
Using MSVC, this code compiles for me:
const int cPointerSize = sizeof(void*);
const int cFourBytes = 4;`
#if (cPointerSize == cFourBytes)
...
however this (which should work identically) does not:
#if ( sizeof(void*) == 4 )
...
i see many people say that sizeof cannot be used in a pre-processor directive,
however that can't be the whole story because i regularly use the following macro:
#define STATICARRAYSIZE(a) (sizeof(a)/sizeof(*a))
for example:
#include <stdio.h>
#define STATICARRAYSIZE(a) (sizeof(a)/sizeof(*a))
int main(int argc, char*argv[])
{
unsigned char chars[] = "hello world!";
double dubls[] = {1, 2, 3, 4, 5};
printf("chars num bytes: %ld, num elements: %ld.\n" , sizeof(chars), STATICARRAYSIZE(chars));
printf("dubls num bytes: %ld, num elements: %ld.\n" , sizeof(dubls), STATICARRAYSIZE(dubls));
}
yields:
orion$ ./a.out
chars num bytes: 13, num elements: 13.
dubls num bytes: 40, num elements: 5.
however
i, too, cannot get sizeof() to compile in a #if statement under gcc 4.2.1.
eg, this doesn't compile:
#if (sizeof(int) == 2)
#error uh oh
#endif
any insight would be appreciated.