I have this preprocessor directive:
#define INDEXES_PER_SECTOR BYTES_PER_SECTOR / 4
where BYTES_PER_SECTOR is declared in another header file as:
#define BYTES_PER_SECTOR 64
I have this simple math equation that I wrote where after executing I get an assertion error as the value assigned to iTotalSingleIndexes is incorrect.
int iTotalSingleIndexes = (iDataBlocks - 29) / INDEXES_PER_SECTOR;
Now I believe this to be because of the preprocessor directive INDEXES_PER_SECTOR. Upon executing my equation iDataBlocks is 285 which is correct. I have confirmed this with gdb. The problem is that the value that gets assigned to iTotalSingleIndexes is 1 when it ought to be 16. I really have no idea why this is happening.
When I do something like:
int iIndexesInASector = INDEXES_PER_SECTOR;
int iTotalSingleIndexes = (iDataBlocks - 29) / iIndexesInASector;
the correct value gets assigned to iTotalSingleIndexes.
On other notes I use preprocessor directives in other equations and they work just fine so I am even more puzzled.
Any help would be much appreciated.
The preprocessor simply performs token replacement - it doesn't evaluate expressions. So your line:
int iTotalSingleIndexes = (iDataBlocks - 29) / INDEXES_PER_SECTOR;
expands to this sequence of tokens:
int iTotalSingleIndexes = ( iDataBlocks - 29 ) / 64 / 4 ;
...which, due to the associativity of the / operator, is then parsed by the compiler as:
int iTotalSingleIndexes = ((iDataBlocks - 29) / 64) / 4;
...which results in the value of 1. As leppie says, you want:
#define INDEXES_PER_SECTOR (BYTES_PER_SECTOR / 4)
This makes INDEXES_PER_SECTOR expand to a complete subexpression.
#define INDEXES_PER_SECTOR (BYTES_PER_SECTOR / 4)
Both of the given answers so far are correct,so accept one of them, but I thought I should expand on what they are saying
Number 1 rule of preprocessor macros.
If a macro expands to an expression, always enclose the expansion in parentheses
Number 2 rule of preprocessor macros
Always enclose macro arguments in parentheses where they are used in the expansion
For example, consider the macro below
#define X_PLUS_4(X) X + 4
foo = 1;
y = 3 * X_PLUS_4(foo + 2) * 4; // naively expect y to be 84
the second line expands to
y = 3 * foo + 2 + 4 * 4; // y is 13
which is probably not what you want
Applying the rules
#define X_PLUS_4(X) ((X) + 4)
The use above then becomes
y = 3 * ((foo + 2) + 4) * 4;
If you want to accomplish preprocessing-time operations with the preprocessor, you can use the Boost preprocessing library. However, you should REALLY be using const data for this.
const int BytesPerSector = 64;
const int IndexesPerSector = BytesPerSector / 4;
The preprocessor should be reserved for when you have absolutely no other choice. Performing arithmetic at compile-time is easily done with const ints.
Related
int y = 89;
int foo = (y / 10.0 - y / 10) * 10;
int bar = (89 / 10.0 - 89 / 10) * 10;
cout << foo << ' ' << bar << '\n';
The above code is intended to get the last digit of an integer y, the strange thing is that foo is 8 and bar is 9, why this happens? What's the difference between the two versions of expressions?
The C++ standard permits an implementation to evaluate floating-point expressions with more precision than is required by the nominal format. For example, float expressions may be evaluated as if they were double or more, and double expressions may be evaluated as if they were long double. This extra precision can cause differences in evaluation, especially where discontinuous functions (such as conversion to int) are used.
For example, given y = 89, y / 10.0 - y / 10 would be .9 in real-number arithmetic, but it is 0.9000000000000003552713678800500929355621337890625 in double (IEEE-754 binary64) arithmetic and 0.89999999999999999965305530480463858111761510372161865234375 in long double (Intel’s 80-bit format) arithmetic, and then multiplying by 10 and converting to int produces 9 or 8, respectively.
With optimization disabled, the compiler may be evaluating the expression with y at run-time and the expression with 89 during compilation, and it may be using different precisions for them. With optimization, the compiler is likely to recognize y is effectively a constant 89 in the first expression and evaluate both expressions during compilation, use the same method for both.
The C++ standard requires that cast and assignment operations convert to the nominal type, so one test to see if this is happening is to insert casts:
int foo = (double) ((double) (y / 10.0) - y / 10) * 10;
int bar = (double) ((double) (89 / 10.0) - 89 / 10) * 10;
If this results in foo and bar being identical, that supports the hypothesis. Your compiler may have switches to control how floating-point expressions are evaluated.
Another test is to include <cfloat> and print the value of FLT_EVAL_METHOD. If it is 0, the implementation claims to evaluate floating-point operations in their nominal type, and this behavior should not occur. If it is 1 or 2, the implementation claims to use double or long double to evaluate double expressions, respectively, and this behavior should again not occur, since both expressions will be evaluated the same way. If it is −1, the implementation is not making these claims, and the behavior may occur.
To get the last digit of a non-negative integer, use y % 10.
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 5 years ago.
I know that #define has the following syntax: #define SYMBOL string
If I write, for example
#define ALPHA 2-1
#define BETA ALPHA*2
then ALPHA = 1 but BETA = 0.(why ?)
But if i write something like this
#define ALPHA (2-1)
#define BETA ALPHA*2
then ALPHA = 1 and BETA = 2.
Can someone explain me what's the difference between those two ?
Pre-processor macros created using #define are textual substitutions.
The two examples are not equivalent. The first sets BETA to 2-1*2. The second sets BETA to (2-1)*2. It is not correct to claim that ALPHA == 1 as you do, because ALPHA is not a number - it is a free man! it's just a sequence of characters.
When parsed as C or C++, those two expressions are different (the first is the same as 2 - (1*2)).
We can show the difference, by printing the string expansion of BETA as well as evaluating it as an expression:
#ifdef PARENS
#define ALPHA (2-1)
#else
#define ALPHA 2-1
#endif
#define BETA ALPHA*2
#define str(x) str2(x)
#define str2(x) #x
#include <stdio.h>
int main()
{
printf("%s = %d\n", str(BETA), BETA);
return 0;
}
Compile the above with and without PARENS defined to see the difference:
(2-1)*2 = 2
2-1*2 = 0
The consequence of this is that when using #define to create macros that expand to expressions, it's generally a good idea to use many more parentheses than you would normally need, as you don't know the context in which your values will be expanded. For example:
#define ALPHA (2-1)
#define BETA ((ALPHA)*2)
Macro (#define ...) are only text replacement.
With this version:
#define ALPHA 2-1
#define BETA ALPHA*2
The preprocessor replace BETA by ALPHA*2 then replace ALPHA by 2-1. When the macro expansion is over, BETA is replaced by 2-1*2 which is (due to operator precedence) equal to 2-(1*2)=0
When you add the parenthesis around the "value of ALPHA" (ALPHA doesn’t really have a value since macro are just text replacement), you change the order of evaluation of the operation. Now BETA is replaced by (2-1)*2 which is equal to 2.
Order of operations. The first example become 2-1*2, which equals 2-2.
The second example, on the other hand, expands to (2-1)*2, which evaluates to 1*2.
In the first example:
#define ALPHA 2-1
#define BETA ALPHA*2
alpha is substituted directly for whatever value you gave it (in this case, 2-1).
This leads to BETA expanding into (becoming) 2-1*2, which evaluates to 0, as described above.
In the second example:
#define ALPHA (2-1)
#define BETA ALPHA*2
Alpha (within the definition of BETA) expands into the value it was set to(2-1), which then causes BETA to expand into (2-1)*2 whenever it is used.
In case you're having trouble with order of opeartions, you can always use the acronym PEMDAS to help you (Parenthesis Exponent Multiplication Division Addition Subtraction), which can itself be remembered as "Please Excuse My Dear Aunt Sally". The first operations in the acronym must always be done before the later operations in the acronym (except for multiplication and division (in which you just go from left to right in the equation, since they are considered to have an equal priority, and addition and subtraction (same scenario as multiplication and division).
macros in c/c++ are just text substitutions, not functions. So the macro is there just to replace a macro name in the program text with its contents before the compiler event tries to analyze the code. So in the first case the compiler will see this:
BETA ==> ALPHA * 2 ==> 2 - 1 * 2 ==> compiler ==> 0
printf("beta=%d\n", BETA); ==> printf("beta=%d\n", 2 - 1 * 2);
In the second
BETA ==> ALPHA * 2 ==> (2 - 1) * 2 ==> compiler ==> 2
printf("beta=%d\n", BETA); ==> printf("beta=%d\n", (2 - 1) * 2);
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 6 years ago.
Why this code give to me value "4" instead of "0"?
#define PLUGIN_PPQ 96
#define MIDIENGINE_SCORE_LENGTH PLUGIN_PPQ * 4
int main ()
{
int mCurrentPatternPulse = 97;
int patternBar = (int)floor(mCurrentPatternPulse / MIDIENGINE_SCORE_LENGTH);
cout << "value: " << patternBar << " (" << MIDIENGINE_SCORE_LENGTH << ")";
}
97/384 (with/without floor) should give to me 0.
But it seems it divides by 96 instead of 384? Even if I print MIDIENGINE_SCORE_LENGTH is 384...
If you unpick the macro, then you get
floor(mCurrentPatternPulse / PLUGIN_PPQ * 4);
Since / and * have the same precedence, evaluation is from left to right, so the expression is equivalent to
floor((mCurrentPatternPulse / PLUGIN_PPQ) * 4)
Note that (mCurrentPatternPulse / PLUGIN_PPQ) is performed in integer arithmetic, so any remainder is discarded prior to the multiplication.
Imagine it being a "string-replace" and not a math operation.
So MIDIENGINE_SCORE_LENGTHis not 384 but 96 *4
so your code looks like:
floor(mCurrentPatternPulse / 96 *4 );
and the mCurrentPatternPulse / 96 will be evaluated first.
Just add some brackets:
floor(mCurrentPatternPulse / ( MIDIENGINE_SCORE_LENGTH ) );
Edit:
Or even better put them in the define directly:
#define MIDIENGINE_SCORE_LENGTH ( PLUGIN_PPQ * 4 )
#defines are just text substitution. You need to look up operator precedence.
I am working on a micro-controller and I want to implement a simple average filter on the resulted values to filter out noise (or to be honest to not let values dance on LCD!).
The ADC result is inserted into memory by DMA. I have (just for sake of ease of debugging) an array with size 8. To make life even easier I have wrote some defines to make my code editable with minimum effort:
#define FP_ID_POT_0 0 //identifier for POT_0
#define FP_ID_POT_1 1 //identifier for POT_1
#define FP_ANALOGS_BUFFER_SIZE 8 //buffer size for filtering ADC vals
#define FP_ANALOGS_COUNT 2 // we have now 2 analog axis
#define FP_FILTER_ELEMENT_COUNT FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT
//means that the DMA buffer will have 4 results for each ADC
So, the buffer has size of 8 and its type is uint32_t. And I am reading 2 ADC channels. in the buffer I will have 4 result for Channel A and 4 result for Channel B (in a circular manner). A simple dump of this array is like:
INDEX 0 1 2 3 4 5 6 7
CHNL A B A B A B A B
VALUE 4017 62 4032 67 4035 64 4029 63
It means that the DMA puts results for ChA and ChB always in a fixed place.
Now to calculate the average for each channel I have the function below:
uint32_t filter_pots(uint8_t which) {
uint32_t sum = 0;
uint8_t i = which;
for( ; i < FP_ANALOGS_BUFFER_SIZE; i += FP_ANALOGS_COUNT) {
sum += adc_vals[i];
}
return sum / (uint32_t)FP_FILTER_ELEMENT_COUNT;
}
If I want to use the function for chA I will pass 0 as argument to the funtion. If I want chB I pass 1...and if I happen to have chC I will pass 2 and so on. This way I can initiate the for-loop to point to the element that I need.
The problem is, at the last step when I want to return the result, I do not get the correct value. The function returns 1007 when used for chA and 16 when used for chB. I am pretty sure that the sum is calculated OK (I can see it in debugger). The problem, I beleive, is in the division by a value defined using #define. Even casting it to uint32_t does not help. The sum is being calculated OK, but I can no see what type or value FP_FILTER_ELEMENT_COUNT has been assigned to by compiler. Mybe its an overflow problem of dividing uint32 by uint8?
#define FP_FILTER_ELEMENT_COUNT FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT
//means FP_FILTER_ELEMENT_COUNT will be 8 / 2 which results in 4
What causes this behaviour and if there is no way that #define would work in my case, what other options I have?
The compiler is IAR Embedded Workbench. Platform is STM32F103
For fewer surprises, always put parenthesis around your macro definitions
#define FP_FILTER_ELEMENT_COUNT (FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT)
This prevents oddball operator precedence issues and other unexpected syntax and logic errors from cropping up. In this case, you're returning sum/8/2 (i.e. sum/16) when you want to return sum/4.
Parentheses will help, as #Russ said, but an even better solution is to use constants:
static const int FP_ID_POT_0 = 0; //identifier for POT_0
static const int FP_ID_POT_1 = 1; //identifier for POT_1
static const int FP_ANALOGS_BUFFER_SIZE = 8; //buffer size for filtering ADC vals
static const int FP_ANALOGS_COUNT = 2; // we have now 2 analog axis
static const int FP_FILTER_ELEMENT_COUNT = FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT;
In C++, all of these are compile-time integral constant expressions, and can be used as array bounds, case labels, template arguments, etc. But unlike macros, they respect namespaces, are type-safe, and act like real values, not text substitution.
int temp1,temp2,temp3;
temp1 = 199;
temp2 = 200;
temp3 = 199%temp2;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 199 as expected.
#define WIDTH 100
#define BUFFERWIDTH 200
int temp1,temp2,temp3;
temp1 = 199;
temp2 = BUFFERWIDTH;
temp3 = 199%BUFFERWIDTH;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 199 as expected.
#define WIDTH 100
#define BUFFERWIDTH 2*WIDTH
int temp1,temp2,temp3;
temp1 = 199;
temp2 = BUFFERWIDTH;
temp3 = 199%BUFFERWIDTH;
CString txt;
txt.Format(_T("temp3 = %d"),temp3);
AfxMessageBox(txt);
Output is 100...
Just wondering what is causing this :)
Read up about operator precedence, and note that you are saying 199 % 2 * 100.
.
.
.
or should I say, (199 % 2) * 100...
This is a classic problem with the preprocessor. The issue is that when you write
#define BUFFERWIDTH 2*WIDTH
temp3 = 199%BUFFERWIDTH;
The preprocessor expands this out to
#define BUFFERWIDTH 2*WIDTH
temp3 = 199 % 2 * WIDTH;
Notice that this is interpreted as
temp3 = (199 % 2) * WIDTH;
instead of the intended
temp3 = 199 % (2 * WIDTH);
To fix this, you have multiple options. First, you could parenthesize your definition of BUFFERWIDTH like this:
#define BUFFERWIDTH (2*WIDTH)
temp3 = 199%BUFFERWIDTH;
Now, this expands out to
temp3 = 199 % (2 * WIDTH);
as expected. However, a better option would be to use const to define your constants:
const int BUFFERWIDTH = 2 * WIDTH;
temp3 = 199%BUFFERWIDTH;
This is now interpreted correctly, because constants are understood by the compiler rather than the preprocessor.
More generally, I strongly urge you not to use #define to define constants. #define is essentially a search-and-replace mechanism over the source code that has no semantic or syntactic understanding of what it replaces. It doesn't play well with operator precedence, and so you can easily run into bugs like this. const, on the other hand, is understood by the compiler to define a constant, and so expressions will be evaluated correctly when operator precedence comes into play.
Hope this helps!
One of the most common pitfalls when using MACROS is not realizing that MACROS are code replacement units. So, your code:
#define BUFFERWIDTH 2*WIDTH
// ...
temp3 = 199%BUFFERWIDTH;
After preprocessing converts to:
temp3 = 199%2*100;
If you apply operator precedence, you get the number you showed.
In the last case,
temp3 = 199%BUFFERWIDTH;
becomes
temp3 = 199%2*WIDTH
which is
temp3 = 199%2*100
so
temp3 = (199%2) * 100
which means
temp3 = 100.
Rewrite it:
#define BUFFERWIDTH (2*WIDTH)
In your last example, 199%BUFFERWIDTH expands to 199 % 2 * 100 which evaluates to 100.
The preprocessor transforms this to 199*2%200.
Since * has a higher precedence than %, this is parsed as (199 * 2) % 200.
This is one of the many reasons where non-trivial #DEFINEs are evil.
In this particular case, you can fix it with parentheses:
#define BUFFERWIDTH (2*WIDTH)
You fallen into the Operator Precedence Macro Trap:
temp3 = 199%BUFFERWIDTH;
Becomes:
temp3 = 199%2*WIDTH;
Which becomes:
temp3 = 199%2*100;
Since % and * have equal precedence they are evaluated left to right and you get temp3 = 1*100;
This line:
temp3 = 199%BUFFERWIDTH;
resolves to
temp3 = 199%2*WIDTH;
which is not what you want. Enclose 2*WIDTH in parentheses, and you get the desired result:
#define BUFFERWIDTH (2*WIDTH)
Whilst macros as considered evil, but there are instances where they cannot be avoided at all, and ease if programming a lot. All macros should be fully parenthesized no matter how small:
#define BUFFERWIDTH ( 2 * (WIDTH) )
Which would adapt any changes you make to WIDTH later:
#define WITDH (10+12*55)