Macro Code-Generation Too Ugly?

S

Shao Miller

Good day to all.

In another C-devoted forum, there appeared to be consensus that using
macros to automatically expand as code for serializing and deserializing
and defining structures was not worth the trade-off between redundancy
and legibility.

This is a quick poll of opinion here, if you please.

Some advantages:
- All source remains within the scope of C
- Less typing

Some disadvantages:
- More challenging for humans to interpret
- Partial C parsers such as IDEs won't likely be able to determine
structure definitions and definition locations

As quick example:

#define M_TEST(B_, U_, T_, N_, D_, E_) \
\
B_(test) \
U_(T_(M_SER_TD_BE_U16), N_(alpha), D_("The alpha member")) \
U_(T_(M_SER_TD_BE_U8), N_(beta), D_("The beta member")) \
U_(T_(M_SER_TD_BE_U32), N_(gamma), D_("The gamma member")) \
E_

which could be expanded by various macros into various declarations,
definitions, and statements. Is that just way too ugly?

A suggestion was that a specification file could be easier to read and
another tool could auto-generate C source code. An enhancement of that
suggestion was that the spec. file could even resemble C! If so, what
might be a pleasant way to mark up a struct definition with meta-data?
Would something like:

struct foo {
SERIALIZE_WITH_MEMCPY char some_array[20];
SERIALIZE_AS_BEUINT32 uint32_t some_uint;
};

be pleasant? Or what about:

struct foo {
char __XXX(SERIALIZE_WITH_MEMCPY) some_array[20];
uint32_t __XXX(SERIALIZE_WITH_MEMCPY) some_uint;
};

? What do you think? Thanks! :)
 
I

Ian Collins

Good day to all.

In another C-devoted forum, there appeared to be consensus that using
macros to automatically expand as code for serializing and deserializing
and defining structures was not worth the trade-off between redundancy
and legibility.

This is a quick poll of opinion here, if you please.

Some advantages:
- All source remains within the scope of C
- Less typing

Some disadvantages:
- More challenging for humans to interpret
- Partial C parsers such as IDEs won't likely be able to determine
structure definitions and definition locations

It must have been a sensible forum. Code generation is the way to go.

With code generation both the specification and the resulting code
(should you have to debug it) are human readable.
 
F

Francois Grieu

In another C-devoted forum, there appeared to be consensus that using macros to automatically expand as code for serializing and deserializing and defining
structures was not worth the trade-off between redundancy and legibility.

I recently tried to raise interest on that here with
"Serialisation/deserialisation of argument/results",
with little success.

This is a quick poll of opinion here, if you please.

Some advantages:
- All source remains within the scope of C
- Less typing

- Easiest to port.
- not so frontally yet-another-language
Some disadvantages:
- More challenging for humans to interpret
- Partial C parsers such as IDEs won't likely be able to determine structure definitions and definition locations

- When things get more complex than fixed-size fields,
(e.g. the size of a field depends on the value of
another field), it gets ugly.


I think both methods are preferable to the one I currently wrestle
with: hand-generated serialization/de-serialization code.

Francois Grieu
 
B

Ben Bacarisse

Francois Grieu said:
I recently tried to raise interest on that here with
"Serialisation/deserialisation of argument/results",
with little success.

It depends how you interpret the mixture of response and silence that
you got! My reading would be that there is an almost universal view
that some sort of extended type description plus automatic code
generation is the way to go. The fact that no one suggested a way to do
this using the C pre-processor suggests that it is not considered to
viable in the general case.

You posed a very general question, and that gave rise to very general
answers, so it is possible that you are dealing with some limited case
that makes PP driven code generation look viable, but that did not come
out of your original posting.
- Easiest to port.
- not so frontally yet-another-language

Other methods can be quite easy to port. For example, an interface
processor written in standard C is not likely to be any less portable
than the code it generates.

I think this is a very strong objection. C macro code does not scale
well in my experience. It can be very hard to maintain above a certain
degree of complexity.
- When things get more complex than fixed-size fields,
(e.g. the size of a field depends on the value of
another field), it gets ugly.

<snip>
 
S

Shao Miller

I recently tried to raise interest on that here with
"Serialisation/deserialisation of argument/results",
with little success.

I'll try to find your thread; thanks.

Well I think that some of that macro stuff can look pretty ugly, indeed!
Perhaps not _too_ ugly, but that's why I appreciate the opinions.
- Easiest to port.
- not so frontally yet-another-language

Aha. :)
- When things get more complex than fixed-size fields,
(e.g. the size of a field depends on the value of
another field), it gets ugly.

Yes, the fixed-size thing seem relatively easy.
I think both methods are preferable to the one I currently wrestle
with: hand-generated serialization/de-serialization code.

For what it's worth, here's the toy that prompted me to ask,
essentially, if it was a worth-while direction to pursue... Assuming
you have git, bash, gcc, you could try:

git clone http://git.zytor.com/users/sha0/serialize.git; cd
serialize; bash ./build.sh; ./sdeftest

With any luck, there isn't much UB so it shouldn't hurt your files or
pets. :)

But still, I'm curious as to what might be a pleasant way to "mark up" C
struct definitions which could be used by another tool to auto-generate
code. I think that such a strategy would be less "frontally
yet-another-language," too.
 
S

Shao Miller

It must have been a sensible forum. Code generation is the way to go.

Thanks for the opinion. :)

Speaking of which, if using macro expansion and GCC, one can -save-temps
and then the .i files are essentially the generated code. Heheh.
Regardless of that, a spec. file for use with a code generating tool
could certainly be easier to read than wild macros.
With code generation both the specification and the resulting code
(should you have to debug it) are human readable.

Agreed!
 
L

luser- -droog

I think this is a very strong objection.  C macro code does not scale
well in my experience.  It can be very hard to maintain above a certain
degree of complexity.

Is this a specific fault of cpp or is it intrinsic to macro-processing
in general?
At what point do you need to make a little language?
 
B

Ben Bacarisse

luser- -droog said:
Is this a specific fault of cpp or is it intrinsic to macro-processing
in general?

A part of it is intrinsic to macro processing in general -- especially
in those where expansion can yield text that is re-parsed (rather than
just re-expanded). Token-based macro processors (like C's) are a little
better but then C's PP lacks a general syntax to quote and group items
so complex cpp code often ends up using all sorts of tricks. They are
not (at least to me) very readable.
At what point do you need to make a little language?

Ah, that's a tough call. When Perl 6 is finished the balance will
change.
 
M

Mark Bluemel

Ah, that's a tough call. When Perl 6 is finished the balance will
change.

Is that due before or after I receive my flying car and nuclear fusion
makes electricity too cheap to meter?
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top