Click here to Skip to main content
16,004,727 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
i wish to simplify a whole block of code, into a series of macro statements, but i'm unsure of how to make a macro actually include a curly bracket. I have class called entity and a member function called GetParams, but i want to make a macro that begins the function so that following macros can be written afterward within the function. for example:

C++
#define DATA_LAYOUT_START(type) {  void type::GetParams(ifstream & in){  }
#define DATA_LAYOUT_END()   {  }  }

and then I'd make a bunch of macros for each type of parameter so that it would look something like this.


C++
DATA_LAYOUT_START(Entity);
   DEFINE_FLOAT(m_floatExample);
   DEFINE_STRING(m_stringExample);
   DEFINE_INT(m_intExample);
   //... and whatever other variables i need for that specific class.
DATA_LAYOUT_END()


so my question is, is it possible to have the macro replace itself, literally, with a curly bracket to start the function?

EDIT: Thanks for the rapid response, the actual function for each class should look something like this in the end.
C++
void type::GetParams(ifstream & in) {
    in >> m_floatExample;
    in.getline(m_stringExample, 100, ' ');
    in >> m_intExample;
    // ... etc, except those variables are different for each class.
}

the main reason i want to use a macro here, is so there is no tempation to change the functions around. GetParams is a function inherited from a base class, and changing the parameters or return could really mess things up.
Posted
Updated 4-Nov-11 6:18am
v2

It would help me if you provided a piece of code that you would like to have as the final code, and possibly mark it as bold so I can give more specific help.

In general, you can do just about anything with the pre-processor, a different issue is whether you should or not.

If you wanted to declare a the function proto-type of your function as a MACRO you can do this:

(edit: Fixed MACRO definition below, originally a copy-paste mistake where both macros were defined as DATA_LAYOUT_START)
DATA_LAYOUT_START(type) void type::GetParams(ifstream& in) {
DATA_LAYOUT_END() }


if you want your macro to expand to multiple lines, end the last character on the line that should be continued with \
The macro will end at the first line that does not have the continuation character.
ex:

DATA_LAYOUT_START(type) {\
                          static int count = 0;\
                          count++;


MFC and ATL use Macro tables quite often. For a nice example Lookup BEGIN_MSG_MAP in atlwin.h. This function implements the windows procedure for an ATL window with a MACRO table definition.
 
Share this answer
 
v2
Also, macros are just "compile time helpers", think of them as "mildly smart typists" Whatever you put in after the macro name is considered text. In your example, you immedately start with a curley brace as if you think that's part of the define syntax. It is not, the curley brace will be included in every expansion of the macro.

As Paul said, there is a continuation character (\) to make macros expand to multiple lines. The only thing that terminates a macro definition is a line without a continuation, there is no "end curley brace".

The Windows/MFC BEGIN_MESSAGE_MAP/END_MESSAGE_MAP macros do a similar thing, having a being and end wrapper around some other macro code. You might want to look at how those macros are written. They are in afxwin.h (pasted below) Ignoring just how the message map works, the syntax for these wrapper macros should be helpful in writing yours.

#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
	PTM_WARNING_DISABLE \
	const AFX_MSGMAP* theClass::GetMessageMap() const \
		{ return GetThisMessageMap(); } \
	const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
	{ \
		typedef theClass ThisClass;						   \
		typedef baseClass TheBaseClass;					   \
		static const AFX_MSGMAP_ENTRY _messageEntries[] =  \
		{
#define END_MESSAGE_MAP() \
		{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
	}; \
		static const AFX_MSGMAP messageMap = \
		{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
		return &messageMap; \
	}								  \
 
Share this answer
 
Macro is evil. Don't do that. It's usually possible to simplify code using language abstractions, not macro.

—SA
 
Share this answer
 
Comments
Chuck O'Toole 4-Nov-11 15:39pm    
Wearing your "architectural purity hat" I see :) Macros are only evil in the hands of evil people. In the hands of children, they are mildly dangerous, like matches :)
Sergey Alexandrovich Kryukov 4-Nov-11 19:57pm    
I basically agree; however, not using macros is a reasonable rule of thumb, a zero approximation of what to do.
--SA
Philippe Mori 4-Nov-11 19:56pm    
Well effectively, I try to avoid them as much as possible but sometimes they allows some interesting tricks.
Sergey Alexandrovich Kryukov 4-Nov-11 19:58pm    
This is my point, too, not absolute 100% prohibition.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900