Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

C Macros in C++

Status
Not open for further replies.

RileyCat

Programmer
Apr 5, 2004
124
US
I have discovered the problem causing my

"Object reference not set to an instance of an object"

error.

It appears after debugging through the watch window and disassembler code that the C macros my code is calling is wiping out the memory of the object I send to the macro. So, when I come back from the macro, the object is no longer alive.

My question is this -- does anybody know about problems related to Mfc C++ and C Macros???

Thanks in advance!
 
Hard to say without seeing some code
But there is little reason for using macros in C++



--
 
You should use macros where they are useful: not in place of inline code or enums.
 
> And what is the macro?

This is an example in C
Code:
#define MAX_LIVES 9         /* constant-like macro */
#define LOSE_A_LIFE(x) x++  /* function-like macro */

int lives[MAX_LIVES];
int num_lives = 0;
LOSE_A_LIFE(num_lives);

In C++, you can do this, avoiding macros altogether
Code:
const int MAX_LIVES = 9;
inline void lose_a_life ( int &x ) {
  x++;
}

int lives[MAX_LIVES];
int num_lives = 0;
lose_a_life(num_lives);

C function macros are especially tricky to write. Consider this naive implementation
Code:
#define SQUARE(x) x * x
If you try and do
Code:
y = SQUARE(x+1);
This gets expanded to
Code:
y = x+1 * x+1;
which isn't what you expected.

C++ inline functions do not have this problem. In addition, you get a lot more type checking with constants and inline functions than you do with macros.



--
 
I agree the macro thing can be eliminated in C++ however, I'm working with a lot of legacy code that we are only gradually converting to Windows apps. Until everything is converted, there are some areas where, to follow business rules, I must use the "C" macros.

Thanks for all of the help!
 
>#define SQUARE(x) x * x
It works but the right definition is:
Code:
#define SQUARE(x) ((x) * (x))
You can find examples in many .h file , for example afx.h:
Code:
#define ASSERT(f)          ((void)0)
#define ASSERT_NULL_OR_POINTER(p, type) 	ASSERT(((p) == NULL) || AfxIsValidAddress((p), sizeof(type), FALSE))

Or more complex:
Code:
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	CRuntimeClass* PASCAL class_name::_GetBaseClass() 		{ return RUNTIME_CLASS(base_class_name); } 	AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			&class_name::_GetBaseClass, NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }

-obislavu-



 
Personal opinion for anyone interested.

A lot of the MS Windows macros are basically a workround. The big problem is that if you have a huge class (like CWnd) with lots of virtual functions and lots of controls inheriting from each other, you quickly end up with a V-table nightmare. They get around this using the message map macros. Looks messy initially but it is quite a good solution.

The early MS C++ compilers didn't have RTTI so they invented some other macros to get around that problem. Basically the ones that return the class name. They didn't have try & catch either so they've got macros for those too. By the time they implemented try, catch and RTTI, too many programs had been written using the macros.

I remember using these macros in 1992 and I'm still using them.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top