Here are 2 snippets of code, one is a macro and one is a function. They seem to do the same thing but after running them it seems that they exhibit different behavior and I don't know why. Could anyone help me please? Thanks!
#define ROL(a, offset) ((((Lane)a) << ((offset) % LANE_BIT_SIZE)) ^ (((Lane)a) >> (LANE_BIT_SIZE-((offset) % LANE_BIT_SIZE))))
Lane rotateLeft(Lane lane, int rotateCount)
{
return ((Lane)lane << (rotateCount % LANE_BIT_SIZE)) ^ ((Lane)lane >> (LANE_BIT_SIZE - (rotateCount % LANE_BIT_SIZE))) ;
}
Note: the Lane type is just an unsigned int and LANE_BIT_SIZE is a number representing the size of Lane in terms of No. of bits.
Think of using a macro as substituting the body of the macro into the place you're using it.
As an example, suppose you were to define a macro: #define quadruple(a) ((a) * (a) * (a) * (a))
... then you were to use that macro like so:
int main(void) {
int x = 1;
printf("%d\n", quadruple(x++));
}
What would you expect to happen here? Substituting the macro into the code results in:
int main(void) {
int x = 1;
printf("%d\n", ((x++) * (x++) * (x++) * (x++)));
}
As it turns out, this code uses undefined behaviour because it modifies x multiple times in the same expression. That's no good! Do you suppose this could account for your difference in behaviour?
one is macro and other one is function, the simple understanding gives difference in the way it will be called.
As in case of function CONTEXT SWITCHING will be there, you code flow will be changed to the calling function and will return eventually so there will be very small delay in execution when compared to MACRO.
other than that there should not be any other difference.
Please try by declaring the function as inline function then both should be same.
Lane may be promoted to a type with more bits, e.g. when it's an unsigned char or unsigned short, or when it is used in a larger assignment with mixed types. The <<operation will then shift the higher bits into the additional bits of the larger type.
With the function call these bits will be just cut off, because it returns a Lane, while the macro gives you the full result of the promoted type, including the additional bits - beside the other problems of macros, like multiple evaluations of the arguments.
Here are 2 snippets of code, one is a macro and one is a function.
They seem to do the same thing but after running them it seems that
they exhibit different behavior and I don't know why.
No they are doing the same thing.
ROL(a, offset); //does a*(2^offset)
rotateLeft(Lane lane, int rotateCount); //does lane*(2^rotateCount)
The only difference is that ROL is implemented through a macro , and rotateLeft() is a function.
Differences between Macros and functions
Macros are executed in the preprocessing stage of the compiler ,
whereas function executes , when it is called at runtime execution.
As a result Macros execute faster than functions , but when called
multiple times , the macro text is substitutes same code redundantly, and they end up consuming more "code" memory than an implementation using functions.
Unlike a function , there is no Type Enforcement in a macro.
Related
I have a strange behavior of a small piece of C code.
I want to store the result of a boolean expression in a variable but it seems not to work.
Following the code:
#define rtCP_Constant_Value_fklq (uint8_t) 1 //Simulink const
#define rtCP_Constant_Value (uint8_t) 0 //Simulink const
uint16_t rtb_tobit;
volatile unsigned char rtb_y;
uint8_t asr_ena_=14;
rtb_tobit = (1 << rtCP_Constant_Value_fklq);
uint8_t temp = ((uint8_t)rtb_tobit) & asr_ena_;
rtb_y = (temp !=(rtCP_Constant_Value));
I have tested this snippet of code with two compilers, Renesas SH 9_4_1 and gcc-arm non-eabi in an Nucleo eval board.
In both of them the variable rtb_y is always zero.
The debugger shows that the expression (temp !=(rtCP_Constant_Value)) is true but I cannot understand why, the variable rtb_y is always equal to zero.
Could someone explain me why? Is this strange behaviour because of C standards, which I used?
It is a really bad idea to use macros in the way you are using them. You need to be very careful, generally, to use parenthesis in the right places. Also you should not include the ; in the macro. For example, this is better:
#define rtCP_Constant_Value_fklq ((uint8_t) 1) //Simulink const
However, it is not really possible to offer any more help for your question than this, because your example will not compile, due to the inclusion of the ;. If you update the question with code that compiles, it may be possible to help further.
I need to write a macro that would count bits in odd positions (in ANSI C). For example, in 1010 the count of such bits is 2 while in 0101 the count is 0.
This is the macro I came up with:
#include <stdio.h>
#define BIT_IN_BYTE 8
#define size(x,t) { \
int i, sum = 0; \
for(i = 0; x; x >>= 1) { \
if( (x & 1) && (i % 2) != 0) { \
sum++; \
} \
i++; \
} \
t = sum; \
} \
int main() {
int b = 44444, result;
size(b, result);
printf("count = %d\n", result);
return 0;
}
I have 2 questions really: whether I could've written the macro in a way that it wouldn't need two arguments in its signature and more importantly if there's a relatively simple way to extend the macro onto float and double types.
As in the comments to your question, using a macro here really is not good practice. You should really use a function instead - inline or otherwise.
Since you're apparently forced to use a macro in your case for reasons outside of your control, here are some relevant points to your example:
You can use sizeof to get the number of bytes in whatever type you pass in your x parameter. This will potentially allow you to generalize the macros to different types (you mention float and double) that have different sizes.
Since the macro does not do type checking, if you have something that works for int in a generic way - probably using bit-wise operations - you'll have a fighting chance of making it work for other types. I again note, however, that the lack of type safety is a reason to avoid macros in many cases.
As noted in a comment on your question, your current approach destroys the value in whatever you pass as parameter x. That's likely undesired and unnecessary.
You would only be able to avoid passing the second parameter if you can rewrite this such that is evaluates to a number. I'm not motivated to figure out exactly how to do that for this contrived example or if it is actually possible.
I'm quite confusing about this:
#define prod(x,y) x*y
The following function call prints 11 in the console:
printf("%d",prod(1+2,3+4));
But when I use prod(x,y) as a function returning x*y, it returns 21.
Why the results are different? I thought #define should give prod(x,y) = x*y.
Operator precedence is biting you.
With
#define prod(x,y) x*y
the line
printf("%d",prod(1+2,3+4));
gets expanded to
printf("%d",1+2*3+4);
Note that * has higher precedence than +, so this is evaluated as 1 + (2 * 3) + 4 or 11.
Solution:
Surrround the parameters with parenthesis in your #define:
#define prod(x,y) ((x)*(y))
The line will now be expanded to:
printf("%d",((1+2)*(3+4)));
The purpose of the extra set of parenthesis around the entire expression is to make the expression work as you want when used in conjunction with an operator where evaluation order matters.
prod(4,3)/prod(1,2)) gets expanded to ((4)*(3))/((1)*(2)) or 6. Without the outer parenthesis the expansion would be (4)*(3)/(1)*(2) or 24.
According to your macro, prod(1+2,3+4) is expanded to 1+2*3+4 which equals to 11. Use parens to fix it:
#define prod(x, y) ((x)*(y))
With your definition of
#define prod(x,y) x*y
The line
printf("%d",prod(1+2,3+4));
becomes
printf("%d",1+2*3+4);
which will evaluate to
printf("%d",1+6+4);
yielding
11
A function evaluates things differently. With the function
int prod(int x, int y) { return x*y; }
the call
printf("%d",prod(1+2,3+4));
will have to collapse (evaluate) the parameters before they can be passed. This is because C is "pass by value" in it's parameter handling style. Even pointers, which are technically references are turned into values representing the reference and those values are passed. So the call reduces to
printf("%d",prod(3,7));
which inside the function becomes
return 3*7;
or
return 21
There's a valueable lesson here. Macros don't understand the language. They are just text substitutions, and they will not honor types, operator precedence, or any other language element you've taken the time to learn. Basically the macro language is a different-than-C language, and a much more primitive one than C.
I am newbie to C and trying to understand the MACRO expansion logic in C.
I wonder why the first approach is not working but second works as expected.
First approach
#include <stdio.h>
#define square(x) x*x
int main()
{
int x = 36/square(6); // Expended as 36/6*6
printf("%d", x);
return 0;
}
// Output: 36
Second approach
#include <stdio.h>
#define square(x) x*x
int main()
{
int x = square(6)/36; // Expended as 6*6/36
printf("%d", x);
return 0;
}
// Output: 1
Could someone explain me the difference ?
square(6)/36
expands to
6*6/36
which is equivalent to
(6*6)/36
and obviously equals 1.
Even though this is apparently for understanding macros and you may be aware of that, one suggestion:
macros involving operators should be surrounded by parantheses!
First expansion
36/6*6
Using the rules of precedence and left to right http://en.cppreference.com/w/c/language/operator_precedence works it out as
36/6 * 6 -> (36 / 6) * 6 -> 6 * 6 -> 36
Second expansion
6*6/36 -> (6 * 6)/36 -> 36 / 36 -> 1
Using the precedence/left to right rules above.
Sorry for the link - Did not want the cutter. Multiplication has higher precedence than division
Your macro should be defined as
#define square(x) ((x)*(x))
It is necessary to enclose the x's in parenthesis to prevent any surprises about operator precedence. The outer parenthesis are for the same reason.
Please note that this macro even as corrected above will not work if the parameter is a self-modifying expression. So you may want to consider putting it in all-uppercase or something to alert the user of the macro that it will not behave equivalently to a function call.
The reason your expansion of 36/square(6) does not work as you expect is because of its expansion.
36/square(6)
36/6*6
6*6 <-- 36/6 evaluated
36 <-- 6*6 evaluated
The corrected macro would be expanded thus
36/((6)*(6))
36/(36)
1
Which is the answer you would expect. Also note that 5+1 would also work as an argument because of the inner parenthesis but y++ would not behave as you would expect if reading the macro as a function, hence the reason I recommend naming it SQUARE to alert the user that this is a macro not a function.
Macros only behave as functions if each of their parameters appears exactly once and the syntax is otherwise like an expression (i.e. no {}'s). Also the user cannot pass a pointer to a macro as they can to a function.
Your question is a good illustration of the kind of problem that arise with macros:
36/square(6) expands to 36/6*6, which is parsed according to the C grammar as
(36 / 6) * 6
evaluating to 36.
If you had defined the macro as
#define square(x) ((x)*(x))
Both expressions would be equivalent and evaluate to 1.
Yet there is still a problem with this macro:
square(i++) expands as ((i++) * (i++)).
Evaluating i++ twice in the same expression is undefined behavior.
In C++, in some contexts, parentheses might change the meaning of the enclosed expression (for the given context). For example, decltype(expr) and decltype((expr)) often yeld different types:
int x;
decltype(x) a=x; // type int; a initialized with a copy of x
decltype((x)) b=x;//type int&; b is a reference to x; extra parentheses matter!
But what about C?
Enclosing macro parameters into parentheses is a common practice in C, can that produce some unexpected side effects?
[edit ]More precisely, if the parentheses are redundant for grouping, may they change program meaning?
I consider only expressions (not other syntactic elements such types, functions parameters lists, etc).
I believe the answer is "No".
I'm not aware of any cases where adding an extra pair of unnecessary parentheses, as in ((blah)), would change the meaning. As you say, this is critical for most macro definitions.
However, there are various cases where explicit grouping can causes changes not related to the rules of maths. I'm not referring to (1+2)*3; that's just math. I mean something where the compiler ends up producing a different, but equivalent, code sequence that is more, or perhaps less, efficient.
For example, consider this function;
float fourth_power (float n) {
return n*n*n*n;
}
It can perform differently to this function:
float fourth_power (float n) {
return (n*n)*(n*n);
}
In pure maths the results should be the same, but in reality with finite sized float values, you can get a different numerical answer, but that's not what I'm talking about here.
The change I'm talking about is that the second form runs faster. If you know you're only using smallish numbers (where the limits of float are not an issue) then you might like to code it the second way for a speed boost.
In fact, GCC will make this transformation if you use -ffast-math, I think, but ordinarily the compiler will play it safe.
This is one example that probably applies to all compilers (because it has to do with numerical accuracy), but there are many examples where apparently arbitrary grouping decisions can take a particular compiler down a different internal decision path, and can have interesting, and measurable differences in performance, code size, etc.
Perhaps you mean something like this:
#define SIMPLE_USELESS_MACRO(X) (X)
int int_ = 2;
long int long_int_ = 2L;
double double_ = 3.14;
double result = long_int_ + SIMPLE_USELESS_MACRO(int_ + double_);
if I'm right, in case when parentheses are around x the conversion sequence is following:
(assuming there is no compiler optimalization)
1) int -> double
2) long int -> double
in case there are no parentheses the conversion sequence is:
1) int -> long int
2) long int -> double
I'm not sure about time of above conversions, but probably the integer->float conversion takes more time (assuming there are no hardware unit responsible for this).
This is just a suggestion, if I'm wrong sorry.
something like this?
#define ODD( n ) n % 2
int a = 2;
bool n1 = ODD( a + 1 ); // a + 2 % 2
bool n2 = ODD( (a+1) ); // (a + 2) % 2
n1 true (!=0)
n2 false (==0)