user1569339
user1569339

Reputation: 683

Using C preprocessor macros for function naming idiomatic?

I'm writing a Scheme interpreter. For each built-in type (integer, character, string, etc) I want to have the read and print functions named consistently:

READ_ERROR Scheme_read_integer(FILE *in, Value *val);
READ_ERROR Scheme_read_character(FILE *in, Value *val);

I want to ensure consistency in the naming of these functions

#define SCHEME_READ(type_) Scheme_read_##type_
#define DEF_READER(type_, in_strm_, val_) READ_ERROR SCHEME_READ(type_)(FILE *in_strm_, Value *val_)

So that now, instead of the above, in code I can write

DEF_READER(integer, in, val) 
{ 
 // Code here ...
}

DEF_READER(character, in, val) 
{
 // Code here ...
}

and

if (SOME_ERROR != SCHEME_READ(integer)(stdin, my_value)) do_stuff(); // etc.

Now is this considered an unidiomatic use of the preprocessor? Am I shooting myself in the foot somewhere unknowingly? Should I instead just go ahead and use the explicit names of the functions?

If not are there examples in the wild of this sort of thing done well?

Upvotes: 2

Views: 114

Answers (2)

Emmet
Emmet

Reputation: 6411

I'm usually a big fan of macros, but you should probably consider inlined wrapper functions instead. They will add negligible runtime overhead and will appear in stack backtraces, etc., when you're debugging.

Upvotes: 1

Eric
Eric

Reputation: 843

I've seen this done extensively in a project, and there's a severe danger of foot-shooting going on.

The problem happens when you try to maintain the code. Even though your macro-ized function definitions are all neat and tidy, under the covers you get function names like Scheme_read_integer. Where this can become an issue is when something like Scheme_read_integer appears on a crash stack. If someone does a search of the source pack for Scheme_read_integer, they won't find it. This can cause great pain and gnashing of teeth ;)

If you're the only developer, and the code base isn't that big, and you remember using this technique years down the road and/or it's well documented, you may not have an issue. In my case it was a very large code base, poorly documented, with none of the original developers around. The result was much tooth-gnashing.

I'd go out on a limb and suggest using a C++ template, but I'm guessing that's not an option since you specifically mentioned C.

Hope this helps.

Upvotes: 2

Related Questions