473,804 Members | 4,066 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

converting C macros to templates

Hi,

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

#define _XFUNC_primitiv e(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 1897

Andreas Micheler wrote:
Hi,

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

#define _XFUNC_primitiv e(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_primitiv e(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::*fu nc)(void *, size_t)>
class wrapper
{
public:
size_t operator()(oper ations *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<&operat ions::read> read_wrapper;
wrapper<&operat ions::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(&o ps, 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_primitiv e(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_primitiv e(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::*fu nc)(void *, size_t)>
class wrapper
{
public:
size_t operator()(oper ations *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<&operat ions::read> read_wrapper;
wrapper<&operat ions::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(&o ps, 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_primitiv e(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_primitiv e(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
3411
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 happening when I put my XML files and the .xsl files on my ISP's system for my home page. If I try to open the XML files in Netscape 7.0 on my own machine (ie, not on the ISP's system), the pages convert file and the result is displayed in HTML.
1
1916
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
2863
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 curious about how the following syntactical problem can be solved. It should apply equally to C and C++ as it mainly is a preprocessor-related problem. I tryed to define something similar to the following example: ...
11
22385
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 type specified. This is much similar like a macro expansion in C. can anyone please explain advantages of one over the other ? Thanks in advance -
33
8910
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 write type generic functions macros? #define CUBE(I) ( (I) * (I) * (I) ) Is there some more concise set of things where inline functions should be used instead of macros? Multi-statement macros, for example?
27
2636
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 the following macro: #define GET_SINGLETON_EVENT_FUNCTION(FUNCTION_NAME,MANUAL_RESET,\ INITIAL_STATE,EVENT_NAME) \
7
13085
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 a more complicated code. Something like the following: // file.h #define OBJECTIVE template <class T\ void operator()(T& chrom_,double* fitness_); // file main.cpp
6
2118
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 to include a '#' or '#define' in the output of a macro. The other problem is that we might have been using some sort of non-standard preprocessor trick to do it. Obliged if anyone can point me in the right direction or tell me what I'm trying...
5
4470
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 that will convert TO/FROM THREE_BYTE_VALUE and float #define FLOAT_TO_TBV(fval,prec) //may need some input checks to make sure no overflows
0
9710
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10593
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10340
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10329
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10085
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7626
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5663
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4304
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3830
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.