473,406 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

converting C macros to templates

Hi,

I have several long complex C macros in the math module of aUCBLogo like

#define _XFUNC_primitive(NAME)\
NodeP _##NAME(PairPP arg)\
{ ((ObjectP)(arg[1]))->var()->NAME( arg[2] );\
return Unbound;\
}

which are hard to debug, and now I thought about changing them into
templates. Is this possible in principle?
Can please someone give me some hints,
because I can't figure out how to do the conversion?
Best would be a translation of my macro example into a template,
this would help me a lot.

Thanks,
Andreas

Nov 22 '05 #1
5 1870

Andreas Micheler wrote:
Hi,

I have several long complex C macros in the math module of aUCBLogo like

#define _XFUNC_primitive(NAME)\
NodeP _##NAME(PairPP arg)\
{ ((ObjectP)(arg[1]))->var()->NAME( arg[2] );\
return Unbound;\
}

which are hard to debug, and now I thought about changing them into
templates. Is this possible in principle?


It depends on what the macros do. Templates can do some things that
macros can't and vice versa.

One thing that's going on here is that the macro call can specify a
name, which is inserted into the expansion. The user writes
_XFUNC_primitive(foo) and the macro writes a function called _foo,
which calls through this argument array through a function pointer
called foo.

(Let's not discuss the clueless intrusions into forbidden symbol
namespaces; since you didn't write this).

Templates cannot be parametrized on identifiers. They can't generate
identifiers, or insert identifiers into code. If you write a template
function called foo, all of its expansions will be various overloads of
a function called foo. Moreover, you can't pass a parameter into the
template which will specify the name of a function to be called from
the body.

What you can do is write it as a template class instead: a class which
overloads operator (). Then you can make instances of that class, and
give those instances names. The indirection upon the function pointer
can be done using a pointer-to-member.

To do that, we make the template parameter a pointer-to-member, which
points to a function pointer:

Simplified example:

#include <cstddef>
#include <iostream>

using namespace std;

struct operations {
size_t (*read)(void *, size_t);
size_t (*write)(void *, size_t);
};

template <size_t (* operations::*func)(void *, size_t)>
class wrapper
{
public:
size_t operator()(operations *op, void *ptr, size_t size)
{
return (op->*func)(ptr, size);
}
};

size_t read_func(void *buf, size_t size)
{
cout << "read_func called on " << buf << " of size " << size <<
endl;
}

size_t write_func(void *buf, size_t size)
{
cout << "write_func called on " << buf << " of size " << size <<
endl;
}

int main()
{
unsigned char buf[256];

// table of operations
operations ops = { read_func, write_func };

// use the template to generate wrapper "functions" that call
indirect thorugh
// the operations structure

wrapper<&operations::read> read_wrapper;
wrapper<&operations::write> write_wrapper;

// call the read wrapper, on the given operations structure.
Control goes
// through read_wrapper object's operator (), which calls ops.read,

// ending up in read_func.

read_wrapper(&ops, buf, sizeof buf);
return 0;
}

Nov 22 '05 #2
Thanks, Kaz!

So the answer to my question is probably NO.

Kaz Kylheku wrote:
Andreas Micheler wrote:
Hi,

I have several long complex C macros in the math module of aUCBLogo like

#define _XFUNC_primitive(NAME)\
NodeP _##NAME(PairPP arg)\
{ ((ObjectP)(arg[1]))->var()->NAME( arg[2] );\
return Unbound;\
}

which are hard to debug, and now I thought about changing them into
templates. Is this possible in principle?


It depends on what the macros do. Templates can do some things that
macros can't and vice versa.

One thing that's going on here is that the macro call can specify a
name, which is inserted into the expansion. The user writes
_XFUNC_primitive(foo) and the macro writes a function called _foo,
which calls through this argument array through a function pointer
called foo.

(Let's not discuss the clueless intrusions into forbidden symbol
namespaces; since you didn't write this).

Templates cannot be parametrized on identifiers. They can't generate
identifiers, or insert identifiers into code. If you write a template
function called foo, all of its expansions will be various overloads of
a function called foo. Moreover, you can't pass a parameter into the
template which will specify the name of a function to be called from
the body.

What you can do is write it as a template class instead: a class which
overloads operator (). Then you can make instances of that class, and
give those instances names. The indirection upon the function pointer
can be done using a pointer-to-member.

To do that, we make the template parameter a pointer-to-member, which
points to a function pointer:

Simplified example:

#include <cstddef>
#include <iostream>

using namespace std;

struct operations {
size_t (*read)(void *, size_t);
size_t (*write)(void *, size_t);
};

template <size_t (* operations::*func)(void *, size_t)>
class wrapper
{
public:
size_t operator()(operations *op, void *ptr, size_t size)
{
return (op->*func)(ptr, size);
}
};

size_t read_func(void *buf, size_t size)
{
cout << "read_func called on " << buf << " of size " << size <<
endl;
}

size_t write_func(void *buf, size_t size)
{
cout << "write_func called on " << buf << " of size " << size <<
endl;
}

int main()
{
unsigned char buf[256];

// table of operations
operations ops = { read_func, write_func };

// use the template to generate wrapper "functions" that call
indirect thorugh
// the operations structure

wrapper<&operations::read> read_wrapper;
wrapper<&operations::write> write_wrapper;

// call the read wrapper, on the given operations structure.
Control goes
// through read_wrapper object's operator (), which calls ops.read,

// ending up in read_func.

read_wrapper(&ops, buf, sizeof buf);
return 0;
}


Nov 22 '05 #3
Andreas Micheler wrote:
Hi,

I have several long complex C macros in the math module of aUCBLogo like

#define _XFUNC_primitive(NAME)\
NodeP _##NAME(PairPP arg)\
{ ((ObjectP)(arg[1]))->var()->NAME( arg[2] );\
return Unbound;\
}


Well to start with the above snipped is invalid C++ because
of the misuse of the leading underscore.

The real question is what are you trying to accomplish. The
code with an C-style cast looks extremely dubious (and frankly
if ObjectP is Object*, I've never understood why people think
that sort of typedef makes more sense than saying Object*.)
Nov 22 '05 #4
Ron Natalie wrote:
Andreas Micheler wrote:
Hi,

I have several long complex C macros in the math module of aUCBLogo like

#define _XFUNC_primitive(NAME)\
NodeP _##NAME(PairPP arg)\
{ ((ObjectP)(arg[1]))->var()->NAME( arg[2] );\
return Unbound;\
}

Well to start with the above snipped is invalid C++ because
of the misuse of the leading underscore.


I never saw any problem with a leading underscore in MSVC5 or gcc.
The real question is what are you trying to accomplish. The
code with an C-style cast looks extremely dubious (and frankly
if ObjectP is Object*, I've never understood why people think
that sort of typedef makes more sense than saying Object*.)


I use ObjectP because I have written Ptr debug templates which implement
smart pointers (for bounds checking and to debug the garbage collector
of aUCBLogo). aUCBLogo is free and OpenSource (GPL), you easily find it
with google. So you can check out Math_.cpp if you have time.

The PairPP arg is the default function argument of a primitive in
aUCBLogo. It is because the arguments vary very much between different
primitives.

The code snipet is from the math module of aUCBLogo. It implements xAdd,
xSub, xMul and so on. There are about 1600 lines of such macro code in
aUCBLogo, because in the inner functions I use different code fragments
for the computation, of i.e. multiplication of Array's of some data
structures. It is the fastes way to do it, but if there were means to
convert the code to template code the debugging would be much easier.

Best Regards,
Andreas

Nov 22 '05 #5
In article <3u************@news.dfncis.de>,
Andreas Micheler <An**************@Student.Uni-Augsburg.de> wrote:
Ron Natalie wrote:
...
Well to start with the above snipped is invalid C++ because
of the misuse of the leading underscore.


I never saw any problem with a leading underscore in MSVC5 or gcc.


The you've just been lucky so far.

It's just as easy/hard not to do it, so best to just avoid it
so as to not bump heads with the rules, which basically says
those names are for the "compiler and library" implementor
(there are specific situations that should be avoided,
but I just avoid all _ prefixed names in my "end user code",
that is, where Comeau C++ is not involved).
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: nanookfan | last post by:
Hi all, I'm having a bizarre problem converting XML files to HTML using an XSLT. The problem is only occuring in my Netscape 7.0 browser. What makes it more bizarre is that it is only...
1
by: Rafal 'Raf256' Maj | last post by:
Hi, is there a commend to undefine all macros #define inside a file? in example: #define FOR(x) for (..............) #define MyMacro1(x,y) ........... // ... code ...
11
by: Ben Hetland | last post by:
....in certain cituations they can be useful if not for anything else, then at least for saving a lot of repetetetetetitititive typing. :-) Beyond the point of "do something better instead", I'm...
11
by: San | last post by:
hi there, I am new to c++ and tryig to learn the basics of the c++ concepts. While I was reading the templates, I realize that the templates are a syntax that the compilar expands pased upon the...
33
by: Robert Seacord | last post by:
When writing C99 code is a reasonable recommendation to use inline functions instead of macros? What sort of things is it still reasonable to do using macros? For example, is it reasonable to...
27
by: Cephalobus_alienus | last post by:
Hello, I know that macros are evil, but I recently came across a problem that I couldn't figure out how to solve with templates. I wanted to create a set of singleton event objects, and wrote...
7
by: aaragon | last post by:
Hi everyone, I have a simple question. I'm trying to make a macro in one file so I can use it in main.cpp. The idea is that I the user of my code has simple to type the macro definition to replace...
6
by: Thant Tessman | last post by:
Back before C++ templates, I was taught a trick whereby one built C macros that built other C macros. I can't remember how the heck we did it. The problem is that there seems to be no standard way...
5
by: (2b|!2b)==? | last post by:
As part of a data storage project, I am storing floats in 3 byte ints as follows: * First 21 bits represent number * Last 3 bits represent the number of decimal places I need to write macros...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.