Macro Miscalculation

Sep 2, 2010 at 12:01am
So I'm working on a library and I'm writing a lot of cryptographic classes, such as SHA1. I'm using this code for bit rotation:
1
2
3
4
5
6
7
8
9
#ifndef XSPEEDOPT
// Makes external functions
static uint rotater(uint val, int shift) { return ((uint)val >> shift) | ((uint)val << (32 - shift)); }
static uint rotatel(uint val, int shift) { return ((uint)val << shift) | ((uint)val >> (32 - shift)); }
#else
// Inlines a math only function
#define rotater(val, shift) (uint)((uint)val >> shift) | ((uint)val << (32 - shift))
#define rotatel(val, shift) (uint)((uint)val << shift) | ((uint)val >> (32 - shift))
#endif 


XSPEEDOPT is defined if I feel like optimizing speed (like inlining etc). When I do that, the macro does not work 0.o The output hash of, such as a SHA1, is invalid, but if I use the actual functions, it works... lolwut?
Last edited on Sep 2, 2010 at 12:05am
Sep 2, 2010 at 12:10am
What on earth makes you think a macro would be faster than an inlined function?
Ditch the macro - worrying about why it doesn't work is a waste of time.
Sep 2, 2010 at 12:12am
To my understanding, a macro inlines that function

I'm working on a cross platform library so i want to use a macro on math functions that want to be inlined otherwise i would have done that
Sep 2, 2010 at 12:15am
a macro inlines that function


inlined functions also inline the function, but they don't destroy the global namespace in the process.

Avoid macros wherever possible.

Just use the nice inline keyword:

1
2
static inline uint rotater(uint val, int shift) { return ((uint)val >> shift) | ((uint)val << (32 - shift)); }
static inline uint rotatel(uint val, int shift) { return ((uint)val << shift) | ((uint)val >> (32 - shift)); }
Sep 2, 2010 at 12:15am
A macro is no faster. In fact, it can be slower since it *forces* the compiler to inline the function, even if it would slow down the program. Just use an the inline keyword and let the compiler do the hard work for you.
Sep 2, 2010 at 12:18am
I'm working on a cross platform project... windows only can do inlining... so I would like to do a macro where i can cause that can be interpreted on other platforms

And I disabled inline checks, i have it inline everywhere i choose to
Sep 2, 2010 at 12:21am
windows only can do inlining


Where did you hear that? That's not true at all.

And I disabled inline checks, i have it inline everywhere i choose to


So you think you know more about what the compiler is doing than the compiler, then, eh? ;P
Sep 2, 2010 at 12:26am
I've read it at a few places but if that's the case then ok, I will use inline but I just wanna know why a macro wouldn't work anyways D:
Sep 2, 2010 at 12:50am
Probably because you're compounding statements when you pass them, causing the macro to expand in a way you didn't expect (yet another reason why they're evil)

1
2
3
4
5
6
7
8
9
10
11
12
13
#define TEST(a,b) a*b

int main()
{
  int foo = 3;

  int test = TEST(3,foo+4);   // you expect test to be 21, right?

  cout << test;  // SURPRISE, it's 13!

  // TEST(3,foo+4) gets expanded to 3*foo+4 which evaluates as (3*foo)+4
  //  not as 3*(foo+4) as you'd expect
}
Sep 2, 2010 at 1:13am
@disch
Nope that's not it...
Sep 2, 2010 at 2:34am
Nope that's not it...

So does that mean you already put an extra pair of braces around the entire term, plus around each occurrence of val?
Last edited on Sep 2, 2010 at 2:38am
Sep 10, 2010 at 12:30pm
Nothing wrong.
Topic archived. No new replies allowed.