Skip to main content
GameDev.net gamedev.net
🔒 Locked

Macro problem (C++, VC6)

Started by AshleysBrain Sep 7, 2006 at 10:11 AM 11 replies 1.9k views
Original Post
AshleysBrain
AshleysBrain
I'm using a macro defined as such:

#define PROPERTY_EDIT(theVar, theLabel, theDesc) if (bInit)
	{
		CPropItem item;
		item.Type = 0;
		item.Label = theLabel ;
		item.Description = theDesc ;
		Items.push_back(item);
	} 
	else 
	{
		if (SLabel == theLabel )
		{
			eData-> theVar = szValue;
		} 
	}

Edit: I've got backslashes to escape the end of each line there, but it seems to mangle the formatting Then I use it like so:
PROPERTY_EDIT(m_Text, "bob", "Description");
However I get the following errors pointing to that line:
error C2065: 'm_Text' : undeclared identifier
error C2501: 'PROPERTY_EDIT' : missing storage-class or type specifiers
error C2078: too many initializers
error C2440: 'initializing' : cannot convert from 'char [12]' to 'int'
Weirdest is why the hell is it converting the "Description" string to an integer?? If I paste the code of what I'd expect it to expand to, this compiles fine without any problems:
	if (bInit)
	{
		CPropItem item;
		item.Type = 0;
		item.Label = "bob";
		item.Description = "Descriptive text";
		Items.push_back(item);
	}
	else
	{
		if (SLabel == "bob")
		{
			eData->m_Text = szValue;
		} 
	}


I cannot figure this one out, can someone show me whats wrong? Cheers
Construct (Free open-source game creator)
F1N1TY
F1N1TY
Got the books open, I'm working through it... bare with me...

EDIT: I'm still looking through it. Looks fine to me at the moment, checking a few more possibilites. However, this is an excerpt from "Practical C++":

WHEN TO USE MACROS

Macros can be useful for eliminating tedious, repetitive typing, and they are very important in C programming, but they have much less usefulness in C++ programming. Because macros reorganize source code text before the compiler sees it, they can cause problems that aren't readily apparent. In short, it's good to know how to create and use a macro, but don't use one unless you thinkn you have to.
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
Svenjamin
Svenjamin
I'm not sure why this isn't working for you off the top of my head, but may I suggest that use write a function for this instead of trying to make it into a macro? I believe that would be better in this situation. (unless you have a specific reason for not wanting to use a function)
F1N1TY
F1N1TY
I am going to have to agree with Svenjamin, a function to execute this code would definitely be more efficient here. I can't figure out what is wrong with the code, and I'm sure it's some very wierd problem. Make sure that when expanding macros on multiple lines, each backslash is followed by a hard return, and that there is no backslash on the last line in the macro (i.e)

EDIT: I see what you mean about the backslash problems... ah well, I think you get the point.

Lastly, try surrounding the entire macro in curly braces (i.e. { if(bInit) ... }})

That may work, other than that, I'd really suggest a function instead.
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
F1N1TY
F1N1TY
I have VS2005 in which I could compile it, however, I don't have the definitions of the classes that are used, or the code preceeding and following this code. How large is the source at the moment?

EDIT: I'll see if I can't create an empty class with similar names and try that.
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
F1N1TY
F1N1TY
Nah, I'm going to need the source, atleast the definitions of CPropItem, Items, eData, etc... all the stuff contained in the sample. However, running that code alone, all I'm getting are "Undeclared Identifiers", which means the macro may be working fine under VS2005
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
Conner McCloud
Conner McCloud
There are two separate issues here: one, you're using VC6, and two, you're using macros. Fix the former first, it'll be easier, and may make fixing the latter unneccessary.

CM
F1N1TY
F1N1TY
Do you have the definition, or know the include file for CString?
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
F1N1TY
F1N1TY
Make sure your "TEST SET OF MACROS" is after the #defines, also remove the backslash at the end of the last define.

This, for me, got rid of the errors that showed up, that were similar to yours (i got a bunch more because I didn't have CString and stuff. Tell me if that fixes it, or if you even have it in that order.

EDIT: Added the MFC functions to my code, now have CString running, a few more errors to sort out, and it should be working.

[Edited by - F1N1TY on September 7, 2006 12:21:42 PM]
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
F1N1TY
F1N1TY
Definitely make sure this code:

BEGIN_PROPERTY_TABLE();PROPERTY_EDIT(m_Text, "A", "B");END_PROPERTY_TABLE();


Comes AFTER the macro definitions (#define). That's the only reason it generates those errors for me.

Also, there's no need for the paranthesis after BEGIN_PROPERTY_TABLE and END_PROPERTY_TABLE if it doesn't take paramaters, and it's just a macro. See if this fixes your problem, I hope it does.
"I'd rather know one thing, no matter how ordinary, than discourse endlessly on great issues." -- Galileo
NotAYakk
NotAYakk
KISS: Keep It Simple, Stupid

How to write macros that won't drive you batty 101.

1> If you can, do it in a function.
Change PROPERTY_EDIT to be a one-line macro that calls a function, passing in parameters.

Now compilation errors in the code will make sense, and you can even debug without doing it in disassembly!

2> Baby steps
Start with a simple macro that has a similar structure, and does something simple like "hello world".

Work your way up one step at a time by making your macro code a touch more complex at each stage. Use source control to check in your code whenever you make it do something new, so you can compare and roll back your mistakes.

...

#2 you'll have to do yourself. #1 I can do for you:
template<typename T, typename U, typename ItemsType>inline void DoPropertyEdit(  bool bInit,  char const* theLabel,  char const* theDesc,  T* theVar,  U szValue,  ItemsType& Items){	if (bInit) {		CPropItem item;		item.Type = 0;		item.Label = theLabel ;		item.Description = theDesc ;		Items.push_back(item);	} else {		if (SLabel == theLabel )		{			*theVar = szValue;		} 	}}


Now we change PROPERTY_EDIT:
#define PROPERTY_EDIT(theVar, theLabel, theDesc) \   DoPropertyEdit(bInit, theLabel, theDesc, &(eData->theVar), szValue, Items);

(note I inserted a space after the slash in the above macro -- you'll have to fix that if you copy/paste).

This minimizes the amount of complex code that happens within your macro. Debugging macros (both compile-time failure and run-time failure) is a bitch, so don't do it.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.