简体   繁体   中英

Using preprocessor statements for Macros in C

I am making a program that shifts values left or right depending on the value of the 2nd argument. If it is positive then it shifts left, else it shifts right. N is the number of times it shifts left or right. I am having trouble in implementation of my Macros.

#include <stdio.h>

#define SHIFT(value, n) 

#if (n) > 0
    (unsigned int value) <<= (int n);
#else 
    ( (unsigned int value)) >>= (int -n);



int main()
{
    printf("%d\n", SHIFT(1, 4));
} 

Currently I am getting a conditional directive error.

The C preprocessor doesn't really work the way you intend to use it. In particular, you cannot use other CPP directives (like #if , ...) in the expansion of a macro. Besides, since macro expansion is a static compile-time feature, this wouldn't help anyway, when the actual shift-values are only known at run-time:

int value_to_shift = read_some_integer_from_user();
int amount_to_shift_by = read_another_integer_from_user();
int shifted_value = SHIFT(value_to_shift, amount_to_shift_by);

If you don't mind the potential double-evaluation of macro arguments, go with the ternary operator:

#define SHIFT(value, n)   ( (n) < 0? ((value) >> (-n)) : ((value) << (n)) )

Note, that using <<= (and >>= ) as you do in the code is most likely not what you want, given, that you pass literal numbers as value arguments to your the SHIFT macro.

I would probably go for a tiny helper function here instead of a macro:

static int 
shift(int value, int nbits)
{
    return nbits < 0? (value >> -nbits) : (value << nbits);
}

Your #define isn't doing what you think it does. You need to continue the lines with \\ . And since n is known at runtime (assuming your case is just a simplification) you can use a regular function, and inline it if needed:

inline int shift(int value, int n) {
    if (n < 0) {
        return (unsigned int) value << n;
    }
    else {
         return (unsigned int) value << -n;
    }
}

You need to combine the lines with a \\ . you also missed thed #endif

Inplace macro:

#define SHIFT(value, n)        \
     value = ((n) > 0)  ?      \
             value << (n) :    \
             value >> -(n)

Return shifted value:

#define SHIFT(value, n)        \
     ( ((n) > 0)  ?            \
             (value) << (n) :  \
             (value) >> -(n) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM