Using a macro, can I change what type an object is being cast to?

E

Eric Lilja

Using a macro, can I change what type an object is being cast to?

I know, the initial respone to question might be an instinctive "ugly, don't
even think about it!" or "don't use macros at all", but I still would like
to know because I am trying to encapsulate a third-party C-based
callback-oriented gui toolkit inside C++ classes and I would like to try
something.

So say you have:
long some_address = some_valid_address;
((SomeClass*)some_address)->foo();

I want to test something and I would like to know if I can write a macro
that casts some_address to the pointer of another class (actually a subclass
of SomeClass). Since macros are part of the preprocessor and the
preprocessor is run before the compiler, a macro can replace the actual code
seen by the compiler, yes? I don't think I've ever made my own macro, I only
use the preprocessor for #ifndef, #ifdef etc.

So why do I want to do this? Well, as I said I am trying to encapsulate a
third-party C-based gui toolkit that revolves around callbacks. My parent
class has a static member function that acts a dummy callback (called by the
system), and using the parameters it finds a pointer to itself (actually a
pointer to a subclass) and uses that to call non-static member functions.
The problem is that the system seems to be calling this static member
function before the subclass object has been constructed fully thus calling
the parent version of some virtual functions the first few calls.

Thanks for reading and replying

/ Eric
 
M

modemer

Yes, you could use macro as you like, C++ compiler does still support macro.
As long as you could guarantee the syntex is correct in C++ after
proprocessed.

Just mention about your example, it's not good to use "long" variable to
store a "pointer" even though it's not a problem in some platforms, but
always "void *" is the best choise. There is not any relationship between
long data type and 32/64 bits address.
 
V

Victor Bazarov

Eric said:
Using a macro, can I change what type an object is being cast to?

No. Using a macro you can substitute one text with another before
compiling your code.
I know, the initial respone to question might be an instinctive "ugly, don't
even think about it!" or "don't use macros at all", but I still would like
to know because I am trying to encapsulate a third-party C-based
callback-oriented gui toolkit inside C++ classes and I would like to try
something.

So say you have:
long some_address = some_valid_address;
((SomeClass*)some_address)->foo();

I want to test something and I would like to know if I can write a macro
that casts some_address to the pointer of another class (actually a subclass
of SomeClass). Since macros are part of the preprocessor and the
preprocessor is run before the compiler, a macro can replace the actual code
seen by the compiler, yes? I don't think I've ever made my own macro, I only
use the preprocessor for #ifndef, #ifdef etc.

Technically, you won't make your own macro this time either :)
So why do I want to do this? Well, as I said I am trying to encapsulate a
third-party C-based gui toolkit that revolves around callbacks. My parent
class has a static member function that acts a dummy callback (called by the
system), and using the parameters it finds a pointer to itself (actually a
pointer to a subclass) and uses that to call non-static member functions.
The problem is that the system seems to be calling this static member
function before the subclass object has been constructed fully thus calling
the parent version of some virtual functions the first few calls.

I am not sure how using macros will fix that.
Thanks for reading and replying

You can define a macro like this:

#define CAST(what,towhat) ((towhat)what)
...
long some_address = some_valid_address;
CAST(some_address, SomeClass*)->foo();

What it buys you is a different question.

V
 
K

Karl Heinz Buchegger

Eric said:
So why do I want to do this? Well, as I said I am trying to encapsulate a
third-party C-based gui toolkit that revolves around callbacks. My parent
class has a static member function that acts a dummy callback (called by the
system), and using the parameters it finds a pointer to itself (actually a
pointer to a subclass) and uses that to call non-static member functions.
The problem is that the system seems to be calling this static member
function before the subclass object has been constructed fully thus calling
the parent version of some virtual functions the first few calls.

And you think, that casting the pointer will help with that?
If the object isn't fully constructed, the most likely thing is
that you produce a crash (if you are lucky). If you are unlucky
the system just executes whatever it finds in memory, thinking
this is your function.

Why not install the callback *after* the object has been constructed
fully. That would avoid all those problems.
 
E

Eric Lilja

Karl Heinz Buchegger said:
And you think, that casting the pointer will help with that?
If the object isn't fully constructed, the most likely thing is
that you produce a crash (if you are lucky). If you are unlucky
the system just executes whatever it finds in memory, thinking
this is your function.

Why not install the callback *after* the object has been constructed
fully. That would avoid all those problems.

Yes, I am leaning towards that alternative. A simple constructor that does
nothing really but construct the objects fully, vtables and all then a
create member function that does most of what my constructor is doing now. I
just need to document that (and document it well) after constructing an
object all operations except the create() are invalid until create has been
called (and it may only be called once).

Some pointed out that I should use void* not long, but I don't have choice
in the matter. The arguments passed to the callback are specified by the
system not me.

I just wanted to try the macro version to see what happens. I have a feeling
it won't work but at least I will have learned something regarding macros
and how they can be used.
Karl Heinz Buchegger
(e-mail address removed)

/ Eric
 
G

Guest

Eric Lilja said:
A simple constructor that does
nothing really but construct the objects fully, vtables and all then a
create member function that does most of what my constructor is doing now. I
just need to document that (and document it well) after constructing an
object all operations except the create() are invalid until create has been
called (and it may only be called once).

For reference, what you are describing is sometimes called "two-phase
construction;" and sometimes "post-construction," which usually is mentioned
with "pre-destruction."

Ali
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top