开发者

Wrong value generated from math equation using a preprocessor directive

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 iTotalSingle开发者_StackOverflowIndexes 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜