Macro with run time argument-change giving wrong ans in cpp [duplicate] - c++

When is it is necessary to put the whole (right) expression of a define macro in parenthesis?
If I do something like
#define SUM(x, y) ((x)+(y))
I have to put the right expression into parenthesis, because "+" has a low precedence in C (and it wouldn't work if I would use it in the following context SUM(x, y) * 5U)
Are these parenthesis still required if I use an operator of the highest precedence e.g.
#define F foo()
or even
#define ACCESS(x, y) (x)->(y)
Does an expression exist that that would break the actual meaning as it would do for the SUM() example?)
For the precedence rules I used http://en.cppreference.com/w/c/language/operator_precedence

It's a good practice to use parenthesis to avoid some big blunders. Currently you might think that your operator is having high precedence but suppose you're making the header file of your code and give it to your friend who uses macro from that file with the function having even higher precedence so at that time it will be a great pain to debug the code. You can save this time as a programmer by putting parenthesis.

Some programmers using simple #defines will write
#define ZERO (0)
which is of no use other than complicating things.
Actually the macro is wysiwyg so with that in mind you can decide what parentheses are needed:
SUM(3,4) => ((3)+(4)) // parentheses around 3 and 4 are not necessary
RATIO(3+4,4+5) => ((3+4)/(4+5)) // probably necessary here due to operator precedence
Its not rocket science to figure this out, it's actually quite straightforward.

Related

What does C++ if-Statement with double parantheses do?

I have stumbled upon an if statement where the condition is actually an assignment and I don't really understand what it does. Now, I found a similar Question with extensive answers but I still don't quite understand, what my snippet does:
if ((x = !x))
/* some code */
The similar question I found is this one: https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs
One user states, that
((…)) double parentheses surround an arithmetic instruction, that is, a computation on integers, with a syntax resembling other programming languages. This syntax is mostly used for assignments and in conditionals. This only exists in ksh/bash/zsh, not in plain sh.
What does that mean? Is the value of x toggled now and nothing else happened? In what case does this condition return false?
It does the same thing as if(x = !x) does. However, because it is very easy to accidentally use = in place of ==, compilers will warn you when you're using an assignment inside of an if statement. That warning doesn't get displayed if the assignment expression is inside of a second set of parenthesis.
So that's the point of the extra parens: to tell the compiler/reader that the writer really meant to use assignment rather than equality testing.

Will bitshift and arithmetic operations be evaluated by the precompiler?

If I define the following in a C++98 program:
#define BITS_PER_FOO 2
#define BITS_PER_BAR 3
#define FOOBARS (1<<(BITS_PER_FOO*BITS_PER_BAR))
then will FOOBARS get evaluated as 64 by the precompiler? Or will a multiplication and bit-shift operation take place at each location that I use FOOBARS in the code?
No, since it's not the preprocessor's business. It does the usual replace thing, not constant folding.
However, any reasonable compiler will do constant folding, so you should not expect this to correspond to instructions being executed at runtime.
The precompiler just does text substitution - it's essentially copy & paste on steroids. This means that the expression you wrote for FOOBAR will be expanded in full at each replacement location.
Now, any decent compiler will evaluate that whole subexpression at compile time anyway. However, you can save it some work (and have some extra advantages, like having a clear type of your expression, clearer diagnostic, less surprises deriving from substitutions in the wrong places, and having an actual lvalue for your constants instead of expressions) by defining these values as actual constants, like:
const int bits_per_foo = 2;
const int bits_per_bar = 3;
const int foobars = 1<<(bits_per_foo*bits_per_bar);
A multiplication and bit-shift operation will take place at each location that you use FOOBARS.
See: #define Directive (C/C++)
#define forms a macro, meaning the identifier is replaced with everything in the token-string. In your case, the preprocessor replaces instances of FOOBARS with the expression (1<<(BITS_PER_FOO*BITS_PER_BAR))

Ampersand and square brackets priority

I see a lot of programmers using brackets around an expression, e.g. :
&(tab[i]) /* I use `&tab[i]`. */
I think it isn't necessary, because the [] operator has a greater priority than & operator. So, why do they use brackets ?
For sake of clarity. Not everyone has all the operator precedences memorized.
I'd say there are basically two reasons:
The programmer isn't sure about operator precedence and codes defensively
To make absolutely clear for every reader (who may not have the precendence memorized) what is going on
It is indeed not necessary because postfix operators always have higher precedence than unary operators.
The people that use parens in &(tab[i]) use them for the same reason they use it in the expression (8 * 5) / 2.
In a recent question, someone had to decypher code like --p---> x < 0. Just like your code, that code is unambiguous as per C++ parsing rules.
However, humans don't always remember all of these complex rules, so many programmers make it a habit to use parens in situations that might look not totally clear to others (or to themselves). It is documenting the real intention of the code.
This is a Good Thing To Do™
Because they find it clearer? Especially for something like this:
int *a[];
Is that a pointer to an array of ints or an array of pointers to int?

Processing conditional statements

I'm not looking for an implementation, just pseudo-code, or at least an algorithm to handle this effectively. I need to process statements like these:
(a) # if(a)
(a,b) # if(a || b)
(a+b) # if(a && b)
(a+b,c) # same as ((a+b),c) or if((a&&b) || c)
(a,b+c) # same as (a,(b|c)) or if(a || (b&&c))
So the + operator takes precedence over the , operator. (so my + is like mathematical multiplication with , being mathematical addition, but that is just confusing).
I think a recursive function would be best, so I can handle nested parentheses nice and easy by a recursive call. I'll also take care of error handling once the function returns, so no worries there. The problems I'm having:
I just don't know how to tackle the precedence thing. I could return true as soon as I see a , and the previous value was true. Otherwise, I'll rerun the same routine. A plus would effectively be a bool multiplication (ie true*true=true, true*false=false etc...).
Error detection: I've thought up several schemes to handle the input, but there are a lot of ugly bad things I want to detect and print an error to the user. None of the schemes I thought of handle errors in a unified (read: centralized) place in the code, which would be nice for maintainability and readability:
()
(,...
(+...
(a,,...
(a,+...
(a+,...
(a++...
Detecting these in my "routine" above should take care of bad input. Of course I'll check end-of-input each time I read a token.
Of course I'll have the problem of maybe having o read the full text file if there are unmatched parenthesis, but hey, people should avoid such tension.
EDIT: Ah, yes, I forgot the ! which should also be usable like the classic not operator:
(!a+b,c,!d)
Tiny update for those interested: I had an uninformed wild go at this, and wrote my own implementation from scratch. It may not be pretty enough for the die-hards, so hence this question on codereview.
The shunting-yard algorithm is easily implementable in a relatively short amount of code. It can be used to convert an infix expression like those in your examples into postfix expressions, and evaluation of a postfix expression is Easy-with-a-capital-E (you don't strictly need to complete the infix-to-postfix conversion; you can evaluate the postfix output of the shunting yard directly and just accumulate the result as you go along).
It handles operator precedence, parentheses, and both unary and binary operators (and with a little effort can be modified to handle infix ternary operators, like the conditional operator in many languages).
Write it in yacc (bison) it becomes trivial.
/* Yeacc Code */
%token IDENTIFIER
%token LITERAL
%%
Expression: OrExpression
OrExpression: AndExpression
| OrExpression ',' AndExpression
AndExpression: NotExpression
| AndExpression '+' NotExpression
NotExpression: PrimaryExpression
| '!' NotExpression
PrimaryExpression: Identifier
| Literal
| '(' Expression ')'
Literal: LITERAL
Identifier: IDENTIFIER
%%
There's probably a better (there's definitely a more concise) description of this, but I learned how to do this from this tutorial many years ago:
http://compilers.iecc.com/crenshaw/
It's a very easy read for non-programmers too (like me). You'll need only the first few chapters.

Comma operator in a conditional

I have read in a lot of places but I really can't understand the specified behavior in conditionals.
I understand that in assignments it evaluates the first operand, discards the result, then evaluates the second operand.
But for this code, what it supposed to do?
CPartFile* partfile = (CPartFile*)lParam;
ASSERT( partfile != NULL );
bool bDeleted = false;
if (partfile,bDeleted)
partfile->PerformFileCompleteEnd(wParam);
The partfile in the IF was an unnecessary argument, or it have any meaning?
In this case, it is an unnecessary expression, and can be deleted without changing the meaning of the code.
The comma operator performs the expression of the first item, discards the results, then evaluates the result as the last expression.
So partfile,bDeleted would evaulate whatever partfile would, discard that result, then evaluate and return bDeleted
It's useful if you need to evaluate something which has a side-effect (for example, calling a method). In this case, though, it's useless.
For more information, see Wikipedia: Comma operator
bool bDeleted = false;
if (partfile,bDeleted)
partfile->PerformFileCompleteEnd(wParam);
Here, the if statement evaluates partfile,bDeleted, but bDelete is always false, so the expression fails to run. The key question is "what's that all about?". The probable answer is that someone temporarily wanted to prevent the partfile->PerformFileCompleteEnd(wParam); statement from running, perhaps because it was causing some problem or they wanted to ensure later code reported errors properly if that step wasn't performed. So that they're remember how the code used to be, they left the old "if (partfile)" logic there, but added a hardcoded bDeleted variable to document that the partfile->Perform... logic had effectively been "deleted" from the program.
A better way to temporarily disable such code is probably...
#if 0
if (partfile)
partfile->PerformFileCompleteEnd(wParam);
#endif
...though sometimes I try to document the reasoning too...
#ifndef DONT_BYPASS_FILE_COMPLETE_PROCESSING_DURING_DEBUGGING
if (partfile)
partfile->PerformFileCompleteEnd(wParam);
#endif
...or...
if (partFile, !"FIXME remove this after debugging")
partfile->PerformFileCompleteEnd(wParam);
The best choice depends on your tool set and existing habits (e.g. some editors highlight "FIXME" and "TODO" in reverse video so it's hard to miss or grey out #if 0 blocks; you might have particular strings your source-control checkin warns about; preprocessor defines only in debug vs release builds can prevent accidental distribution etc.).
partfile is evaluated, then bDeleted is evaluated and used as the test. Since evaluation of partfile does not have any side effects, removing it from the conditional has no effect.
The comma operator is a rather obscure feature of C/C++. It should not be confused with the comma in initialising lists (ie: int x, int y; ) nor with function call parameter separation comma (ie: func(x, y) ).
The comma operator has one single purpose: to give the programmer a guaranteed order of evaluation of an expression. For almost every operator in C/C++, the order of evaluation of expressions is undefined. If I write
result = x + y;
where x and y are subexpressions, then either x or y can be evaluated first. I cannot know which, it's up to the compiler. If you however write
result = x, y;
the order of evaluation is guaranteed by the standard: left first.
Of course, the uses of this in real world applications are quite limited...