4 Replies - 6556 Views - Last Post: 05 October 2011 - 05:01 AM Rate Topic: -----

#1 shwhjw   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-April 11

C++ Macro in an 'if' statement?

Posted 05 October 2011 - 04:23 AM

Hi all,

I'm having some trouble with a macro in C++. I am using C code as a reference so of course what I am trying to do may not be possible in C++. I'm using VS2010 to compile.

The example C code I am using as a reference has the macro:
#define IS_PRESSED(dev, button)		((dev->btns & button) == button)

This macro is used in an if statement in the format:
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A))
{}


Where WIIMOTE_BUTTON_A is a hex value. As you can see, this code allows any button to be checked, losing the need to have a function for each button.

I want to recreate this code in C++. Here's what I have so far:
#define BUTTON_PRESSED(wm,btn) (wm->remote.Button.btn() && !wm->lastButtonState.last_btn)

and called in the if statement:
if(BUTTON_PRESSED(wiimote,'A'))


The compiler doesn't like the call to 'BUTTON_PRESSED', saying it 'expected a member name'. I'm not sure if passing a char will work either, but that's not the main problem.

Everywhere I look I find pages telling me not to use macro functions in C++, but I can't find anywhere which will tell me what to use instead! Am I going to have to write out nearly identical functions for each button I want to check?

Thanks in advance, Simon.

Is This A Good Question/Topic? 0
  • +

Replies To: C++ Macro in an 'if' statement?

#2 Salem_c   User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2555
  • View blog
  • Posts: 4,739
  • Joined: 30-May 10

Re: C++ Macro in an 'if' statement?

Posted 05 October 2011 - 04:42 AM

> #define BUTTON_PRESSED(wm,btn) (wm->remote.Button.btn() && !wm->lastButtonState.last_btn)
So given
if(BUTTON_PRESSED(wiimote,'A'))

you see that wm will be replaced by wiimote
and btn will be replaced by 'A'.

Now expand it.
(wiimote->remote.Button.'A'() && !wiimote->lastButtonState.last_btn)
Can you see that Button.'A' makes no sense at all?
Was This Post Helpful? 1
  • +
  • -

#3 shwhjw   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-April 11

Re: C++ Macro in an 'if' statement?

Posted 05 October 2011 - 04:53 AM

Hmmm, just thought, maybe my idea of what a macro can do is wrong...

LastButtonState is a struct of booleans with names like Last_A, last_B etc. I want to use the button argument to replace a method name, and part of a variable name. Got me thinking, it's a preprocessor command so it might be possible, but in all likelyhood I am asking too much of the compiler!

Can anyone confirm this?

Yes Salem, you're right. For some reason I thought the compiler would complain as A would not be defined. Now the compiler says LastButtonState has no member last_btn. I guess I cannot replace half of the variable name with A ?

This post has been edited by shwhjw: 05 October 2011 - 04:53 AM

Was This Post Helpful? 0
  • +
  • -

#4 sepp2k   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2770
  • View blog
  • Posts: 4,429
  • Joined: 21-June 11

Re: C++ Macro in an 'if' statement?

Posted 05 October 2011 - 04:57 AM

First of all while it is considered bad style to use macros in C++, there is nothing in C++ that makes macros not work - there just usually are better alternatives (like inline functions or templates), though they don't seem to apply in this particular case.

Quote

I'm not sure if passing a char will work either, but that's not the main problem.


Actually I think that this is the main problem.

The reason that your code does not work isn't that you're using macros, but that your macro expands to something invalid. Namely it expands to (wm->remote.Button.'A'() && !wm->lastButtonState.last_btn), which is obviously invalid. If you use A without single quotes around it as the argument, you will get wm->remote.Button.A() && !wm->lastButtonState.last_btn) instead, which is better, but I'm guessing that you want last_A instead of last_btn. To get that you need to separate btn from last_ so that it appears as its own token and the preprocessor recognizes it as a macro parameter and substitutes it. Then you can paste the two token back together using ##. That would look like this:

#define BUTTON_PRESSED(wm,btn) (wm->remote.Button.btn() && !wm->lastButtonState.last_ ## btn)



Note that the same points would have applied in C, so this is not a C++ problem.

That being said the above solution is quite messy and probably very confusing for readers of your code, so you should consider whether there isn't a better way to design your program, which avoids having to do things like this.

This post has been edited by sepp2k: 05 October 2011 - 05:01 AM

Was This Post Helpful? 1
  • +
  • -

#5 shwhjw   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 30-April 11

Re: C++ Macro in an 'if' statement?

Posted 05 October 2011 - 05:01 AM

View Postsepp2k, on 05 October 2011 - 04:57 AM, said:

Then you can paste the two token back together using ##. That would look like this:

#define BUTTON_PRESSED(wm,btn) (wm->remote.Button.btn() && !wm->lastButtonState.last_ ## btn)



Nailed it. Thought it was possible! Thanks vm guys :D
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1