Thread: c preprocessor functions

  1. #1
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95

    c preprocessor functions

    I am working on converting the shift functionality implemented below into a macro


    Code:
    #include <stdio.h>
    unsigned int shift (unsigned int value, int n)
    {
      if ( n > 0 )
          value <<= n;
      else
          value >>= -n;
      return value;
    }
    int main (void)
    {
      unsigned int w1 = 01777777u, w2 = 0444u;
      unsigned int shift (unsigned int value, int n);
      printf ("%o\t%o\n", shift (w1, 5), w1 << 5);
      printf("Here is w1 %o\tHere is w1 left shifted by 1 %o\n", w1, w1 << 1);
      printf ("Right Shift %o\t%o\n", shift (w1, -6), w1 >> 6);
      printf ("\n above line was a right shift of w1:%o by 6", w1);
      printf ("\n%o\t%o\n", shift (w2, 0), w2 >> 0);
      printf ("%o\n", shift (shift (w1, -3), 3));
      return 0;
    }
    I came up with this....

    Code:
    #include <stdio.h>
    #define  nsign(v,n)  ((n) > (0) ?  (v << n) : (v >> n))
    int main (int argc, char **argv)
    {
    int w1 = 01777777u;
    nsign(w1,-5);
    printf("%o\n", w1);
    }
    Which seems to work for positive values of n, but does not seem to work for negative values of n.

    How can I improve this? I have looked quite a bit. I read the preprocessor chapter of the book I follow, and a document on C preprocessor for GCC version 2 ( I know it is old, it was the only pdf on the subject I could find ) I also read parts of the GCC documentation. The examples all seem to be similar. I was looking for an example, which had a simple function and its equivalent macro. I also looked into the c library; went through a number of , perhaps half of the .c source files in hope of one macro implementation with if statements and etc. Stackoverflow has a number of very elaborate macros. But they seem to be snippets with the expectation that reader would add the rest I guess. Perhaps after reading all the content, I can understand and implement one them now but they are not exactly what I need. I did try to use what I can from them, but I run into error messages. I wanted to make sure I am not making this overly complex, and ask you for the ideal preprocessor documentation.


    So 1- Could you tell me what is the appropriate term I need to search under to find the best documentation on the C preprocess 2- Is what I am doing, the ideal way to go about implementing the shift function, and if not, how can I improve it please? Do I need to implement a compound statement?
    Thanks
    Last edited by zolfaghar; 06-16-2016 at 11:49 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    What benefit do you hope to get from this, apart from confusing yourself?

    If you say "performance", that's 1980's advice. The idea is redundant nowadays, as most compilers will inline short functions for you.


    Your macro doesn't negate n in the negative case.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Quote Originally Posted by Salem View Post
    What benefit do you hope to get from this, apart from confusing yourself?

    If you say "performance", that's 1980's advice. The idea is redundant nowadays, as most compilers will inline short functions for you.


    Your macro doesn't negate n in the negative case.
    Got it. Ok so just try to make sure I understand some of the stuff, but don't get bogged down with details. Thanks.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    You need to negate the final n.
    You need to give it a better name.
    You need to put parens around every use of an argument, and parens around the whole thing (which you did).

    And the thing still won't really work properly since it evaluates n more than once (see code below). Real function calls evaluate their inputs only once, and small functions will be inlined when optimized so there's no advantages and definite disadvantages to using a macro for this operation.
    Code:
    #include <stdio.h>
    
    #define shift(v,n) ((n) >= 0 ? (v) << (n) : (v) >> -(n))
    
    int main(void) {
        unsigned v = 1;
        printf("%u\n", shift(v,        10));
        printf("%u\n", shift(v + v,    10));
        printf("%u\n", shift(v << 10, -10));
        printf("%u\n", shift(v,        3 + 7));
    
        int n = 9;
        // Here we expect 1024 but we get 2048!
        printf("%u\n", shift(v, ++n));
        // This is because a macro is not really a function
        // but just textual substitution, yielding:
        n = 9;
        printf("%u\n", ((++n) >= 0 ? (v) << (++n) : (v) >> -(++n)));
    
        return 0;
    }

  5. #5
    Registered User zolfaghar's Avatar
    Join Date
    Mar 2016
    Posts
    95
    Quote Originally Posted by algorism View Post
    You need to negate the final n.
    You need to give it a better name.
    You need to put parens around every use of an argument, and parens around the whole thing (which you did).

    And the thing still won't really work properly since it evaluates n more than once (see code below). Real function calls evaluate their inputs only once, and small functions will be inlined when optimized so there's no advantages and definite disadvantages to using a macro for this operation.
    Code:
    #include <stdio.h>
    
    #define shift(v,n) ((n) >= 0 ? (v) << (n) : (v) >> -(n))
    
    int main(void) {
        unsigned v = 1;
        printf("%u\n", shift(v,        10));
        printf("%u\n", shift(v + v,    10));
        printf("%u\n", shift(v << 10, -10));
        printf("%u\n", shift(v,        3 + 7));
    
        int n = 9;
        // Here we expect 1024 but we get 2048!
        printf("%u\n", shift(v, ++n));
        // This is because a macro is not really a function
        // but just textual substitution, yielding:
        n = 9;
        printf("%u\n", ((++n) >= 0 ? (v) << (++n) : (v) >> -(++n)));
    
        return 0;
    }
    Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. preprocessor
    By Saurabh Mehta in forum C Programming
    Replies: 2
    Last Post: 03-11-2013, 11:53 PM
  2. Preprocessor ?
    By ZK57 in forum C Programming
    Replies: 2
    Last Post: 03-09-2013, 06:09 PM
  3. Functions to replace the preprocessor with #defines
    By Quor in forum C++ Programming
    Replies: 6
    Last Post: 11-03-2010, 03:45 AM
  4. preprocessor
    By pin2 in forum C Programming
    Replies: 5
    Last Post: 12-24-2009, 12:55 AM
  5. Preprocessor Functions
    By mart_man00 in forum C Programming
    Replies: 2
    Last Post: 01-09-2003, 09:58 PM

Tags for this Thread