How do I replace this preprocessor macro with a #include? - c++

UPDATE:
Obviously, you'd want to do this using templates or a base class rather than macros. Unfortunately for various reasons I can't use templates, or a base class.
At the moment I am using a macro to define a bunch of fields and methods on various classes, like this:
class Example
{
// Use FIELDS_AND_METHODS macro to define some methods and fields
FIELDS_AND_METHODS(Example)
};
FIELDS_AND_METHODS is a multi-line macro that uses stringizing and token-pasting operators.
I would like to replace this with the following kind of thing
class Example
{
// Include FieldsNMethods.h, with TYPE_NAME preprocessor symbol
// defined, to achieve the same result as the macro.
#define TYPE_NAME Example
#include "FieldsNMethods.h"
};
Here I #define the name of the class (previously the parameter to the macro), and the FieldsNMethods.h file contains the content of the original macro. However, because I'm #including I can step into the code at runtime, when debugging.
However I am having trouble 'stringizing' and 'token pasting' the TYPE_NAME preprocessor symbol in the FieldsNMethods.h file.
For example, I want to define the destructor of the class in FieldsNMethods.h, so this would need to use the value of TYPE_NAME as below:
~TYPE_NAME()
{
//...
}
But with TYPE_NAME replaced by its value.
Is what I'm attempting possible? I can't use the stringizing and token-pasting operators directly, because I'm not in a macro definition.

This cries out for a template.
class Example<class T>
{
...class definition...
};
The direct answer to the last part of your question - "given that I'm not in a macro definition any more, how do I get pasting and stringizing operators to work" - is "You can't". Those operators only work in macros, so you'd have to write macro invocations in order to get them to work.
Added:
#mackenir said "templates are not an option". Why are templates not an option? The code is simulating templates the old-fashioned pre-standard, pre-template way, and does so causing much pain and grief. Using templates would avoid that pain -- though there'd be a conversion operation.
#mackenir asked "is there a way to make things work with macros?" Yes, you can, but you should use templates - they are more reliable and maintainable. To make it work with macros, then you'd have to have the function names in the code in the included header be macro invocations.
You need to go through a level of indirection to get this to work correctly:
#define PASTE_NAME(x, y) PASTE_TOKENS(x, y)
#define PASTE_TOKENS(x, y) x ## y
#define TYPE_NAME Example
int PASTE_NAME(TYPE_NAME, _function_suffix)(void) { ... }
This level of indirection is an often necessary idiom for both tokenizing and stringizing operators.
Additional comments from #mackenir indicate continued problems. Let's make it concrete.
At the moment I am using a macro to define a bunch of fields and methods on various classes, like this:
class Example
{
// Use FIELDS_AND_METHODS macro to define some methods and fields
FIELDS_AND_METHODS(Example)
};
FIELDS_AND_METHODS is a multi-line macro that uses stringizing and token-pasting operators.
I would like to replace this with the following kind of thing
class Example
{
// Include FieldsNMethods.h, with TYPE_NAME preprocessor symbol
// defined, to achieve the same result as the macro.
#define TYPE_NAME Example
#include "FieldsNMethods.h"
};
OK. To make this concrete, we need a FIELDS_AND_METHODS(type) macro that is multi-line and uses token-pasting (I'm not going to deal with stringizing - the same basic mechanisms will apply, though).
#define FIELDS_AND_METHODS(type) \
type *next; \
type() : next(0) { } \
type * type ## _next() { return next; }
With luck, this declares a member of the type 'pointer to argument type', a constructor for that type, and a method (Example_next in this case) that returns that pointer.
So, this might be the macro - and we need to replace it such that the '#include' does the equivalent job.
The content of fieldsNmethods.h becomes:
#ifndef TYPE_NAME
#error TYPE_NAME not defined
#endif
#define FNM_PASTE_NAME(x, y) FNM_PASTE_TOKENS(x, y)
#define FNM_PASTE_TOKENS(x, y) x ## y
TYPE_NAME *next;
TYPE_NAME() : next(0) { }
TYPE_NAME * FNM_PASTE_NAME(TYPE_NAME, _next)() { return next; }
#undef FNM_PASTE_NAME
#undef FNM_PASTE_TOKENS
Note that the header would not contain multiple-inclusion guards; its raison d'etre is to allow it to be included multiple times. It also undefines its helper macros to permit multiple inclusion (well, since the redefinitions would be identical, they're 'benign' and wouldn't cause an error), and I prefixed them with FNM_ as a primitive namespace control on the macros. This generates the code I'd expect from the C pre-processor. and G++ doesn't witter but produces an empty object file (because the types declared are not used in my example code).
Note that this does not require any changes to the calling code except the one outlined in the question. I think the question should be improved using the SPOT "Single Point of Truth" principle (or DRY "Don't Repeat Yourself"):
#define TYPE_NAME Example
class TYPE_NAME
{
// Include FieldsNMethods.h, with TYPE_NAME preprocessor symbol
// defined, to achieve the same result as the macro.
#include "FieldsNMethods.h"
};

You have to add an extra layer of macros:
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define TOKENPASTE(x, y) TOKENPASTE2(x, y)
#define TOKENPASTE2(x, y) x ## y
The reason is that when you have a macro, the preprocessor normally recursively expands the arguments before performing the macro substitution. However, if any argument is used with the stringizing operator # or the token-pasting operator ##, it is not expanded. Therefore, you need an extra layer of macros, where the first layer expands the arguments, and the second layer performs the stringizing or token pasting.
If the arguments need to be expanded multiple times (such as #define A B, #define B C, #define C D, STRINGIZE(A)), then you need to add that many more layers before you apply the # or ## operators.

You should wrap the stringifying with another macro (2 are necessary because of how the preprocessor works)
In FieldsNMethods.h
#define MAKE_STR_X( _v ) # _v
#define MAKE_STR( _v ) MAKE_STR_X( _v )
char *method() { return MAKE_STR( TYPE_NAME ); }

No, you can't define class or function definitions on the fly. They have to be specified, either by typing them in directly or by defining them in the preprocessor.
Typically, there is no need to generate classes like this, and the class definitions are created before compilation, whether by typing everything in or using some sort of code generation. Sometimes there is a separate code generation step (in current Visual Studio, for example, you can define pre- and post-processing steps).
Now, if you needed to create different versions of some classes for different data types, you'd use templates. You can't create rubber-stamp classes of differing names that way.
One last question: why are you doing this? I've never been in a position where something like that would look useful in C++, and in languages where this does make sense there are facilities to do it.

Related

Can you feed a macro to another macro as an argument, without the initial macro being expanded?

Background: My code, which I cannot post here will eventually run on a microcontroller, and the macros just offer a way to create multiple pin definition functions, via 1 single macro define mechanic. I use windows and gcc to experiment around with those.
I tried to abstract the problem as much as possible. I use the std console functions cause it is convenient for me to display it in the console window. As such, I also save the file as .cpp and compile it with g++ on windows.
Say I set up my code like this:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x) MACRO2(_x)
#define BAR 3
void fooBAR(int num)
{
std::cout << num << std::endl;
}
If I run the following code (working example)
int main()
{
MACRO2(BAR);
return 0;
}
first BAR gets inserted into ##_x and thus defines the function name which is to be called and then BAR gets inserted as the argument of that function and gets expanded to its value, so we get fooBAR(3). The code works, there are no errors.
Now if I try to add a macro in between (and this is the real world situation I am faced with for reasons I cannot go into), my code looks like this:
int main()
{
MACRO1(BAR);
return 0;
}
But this code throws an error, because when MACRO1(BAR) gets substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and MACRO2(3) leads to foo3(3) which isn't defined, as confirmed by the error log:
error: 'foo3' was not declared in this scope
So the requirements are:
I need to pass BAR into MACRO1 and it needs to be passed to MACRO2 without being expanded
The word BAR has to stay exactly as it is, I know I could use ## in order to prevent it from expanding, but then I would need to add a char to BAR and the function call wouldn't work anymore.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
But this code throws an error, because when MACRO1(BAR) gets
substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and
MACRO2(3) leads to foo3(3)
Yes. This is the specified preprocessor behavior for your particular set of macros.
After they are identified, the arguments to a function-like macro are fully macro-expanded before being substituted into the macro's replacement text, except where they are operands of the ## or # preprocessor operator. Any appearances of those operators are evaluated, and then the resulting text is rescanned, along with any following text as appropriate, for additional macros to expand.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
Only where the argument is the operand of a ## or # operator. The latter doesn't help you, but the former affords a workaround: you can pass an additional, empty argument so that you can perform a concatenation without changing the wanted argument:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,dummy) MACRO2(_x##dummy)
#define BAR 3
int main()
{
MACRO1(BAR,);
return 0;
}
That expands to
int main()
{
fooBAR(3);
return 0;
}
If you want to avoid the extra comma, then you can do so by making MACRO1 variadic:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,...) MACRO2(_x##__VA_ARGS__)
#define BAR 3
int main()
{
MACRO1(BAR);
return 0;
}
That expands to the same thing as the other.
Do note that both of these approaches afford the possibility of an error being introduced by providing unwanted extra argument values to the top-level macro. One would probably suppose that most such errors would be caught at compile time, as the expansion would result in broken code, like the attempt in the question. But it is hard to rule out the possibility that such an error would coincidentally expand to something that happened to be valid, but wrong.
One way to accomplish this is to change slightly the definition of BAR.
#define MACRO2(_x) foo##_x(_x())
#define MACRO1(_x) MACRO2(_x)
#define BAR() 3

Must a "is defined" macro check and its call be in separate conditions?

I was struggling to find an answer amoung many that refer to this topic on SO, but here's some seemingly innocent looking code that fails to compile when F is not a defined macro,
int main() {
#if defined(F) && F(0, 2, 0)
return 0;
#endif
return 1;
}
The problem, according to this section of the GCC manual is that inside #if expressions "all macros in the expression are expanded before actual computation of the expression’s value begins", so this in an invalid check, since when F is undefined, I see,
test.cpp:2:20: error: missing binary operator before token "("
#if defined(F) && F(0, 2, 0)
^
My question: is the only way to correctly do this check like so?
int main() {
#if defined(F)
#if F(0, 2, 0)
return 0;
#endif
#endif
return 1;
}
I find this quite ugly and unintuitive, so I'm hoping there's a nicer way to do such things in the preprocessor.
Assuming your F macro is defined in some header file, you could place the following code somewhere between the include and its first usage:
#ifndef F
#define F(a,b,c) 0
#endif
Or another reasonable default. That's a common solution for your problem. Another is to not allow such macros to be
not defined, but require either the default value or whatever it's expected to do. This latter approach is
a bit safer for e.g. configuration files, as it makes clear the author did consider the macro and intentionally
picked a value (i.e. he did not just forget to define it). It's also easier if the definition is in the same file.
Your test would then just be:
#if F(0, 2, 0)
Avoiding the nested condition (which would cause additional trouble if there was an #else required somewhere.
Two words of advise:
Use macros carefully and sparesely, only when reasonble. Expecially C++ provides features which reduce the need for macros.
Don't use single-letter names for macros. Remember they are textual replacements, bejond the normal language syntax. Use self-explanatory names instead (this does not only apply to macros, but for those it's even more relevant).

When and why use a #define macro(x) instead of function?

Seeing this question made me wonder why the approach (toy example):
#define foo(x) bar[x] = 0
would ever be preferred over the function:
void foo(unsigned x){ bar[x] = 0; }
Before the question linked above, I've only seen this once before, in the PolarSSL library, where I assumed it to be some sort of optimisation, and tried not to think too much about it.
I assume that using the preprocessor macro replaces the 'call' to be the '(not-) function body' everywhere it exists; whereas the void function may or may not be optimised out by the compiler, and therefore may result in a lot of branching for a small and simple operation or two.
Is there any other benefit?
When is the macro method preferred, and when is it better to trust the compiler?
Firstly, I'd hope your macro was actually:
#define foo(x) do { bar[x] = 0; } while (0)
for proper semicolon swallowing.
One thing in favour of macros is because you think your compiler's optimiser is not good enough. You're probably wrong. But if you've actually looked at the output carefully and know what you are doing, you might be right, which is why it's often used in the Linux kernel.
Another reason is that macros are typeless, so you might do:
#define foo(x,t) do { t[x] = 0; } while (0)
which will work for any type t. Lack of type checking is often a disadvantage, but it can be useful when defining something you want to work with any type.
Defining macro just to make the code faster is useless. A good compiler will inline
function call. However, macros can be useful when you need to use their result as constant.
#define ENCODED(a,b,c,d) (((((((a)<<8)+b)<<8)+c)<<8)+d)
switch (a) {
case ENCODED('f','o','o','0'): ...
case ENCODED('b', 'a', 'r', '1'): ...
}
When you want to define new identifiers:
#define LIB_VERSION v101
#define VERSIONNED(x) x##LIB_VERSION
void VERSIONNED(myfunction)(int x) { ... }
When you want to do some other "magics",. For example:
#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}
When you want to define a "generic" function working with several types. Just for illustration:
#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}
and probably some other situations which I do not remember right now.
Is there any other benefit?
There are few situational benefits of using macro. Just for an example, you may use __LINE__ and __FILE__ to see where this macro is getting called for debugging.
#define foo(x) bar[x] = 0; PrintFunction("...", __FILE__,__LINE__)
The macro would never give you stronger type checking like function.
When is the macro method preferred, and when is it better to trust the compiler?
Hence, Macro should be preferred only when you don't have any choice left to use a function, because most of the times you may trust the compiler optimizer.

Calling a function name built with __LINE__

Suppose, I have built an unique function body from below code:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void)
How can I call this function ?
Macro definition taken from: Creating C macro with ## and __LINE__ (token concatenation with positioning macro).
No. You cannot. Because you cannot determine a function name at runtime. (i.e. either to call Unique_22 or Unique_44. However you can definitely call Unique<22> or Unique<44>)
So you can use template solution instead. Declare Unique as below:
template<unsigned int LINE> void Unique ();
And #define the macro like this:
#define UNIQUE template<> Unique<__LINE__>() {}
I advice to use __COUNTER__ instead of __LINE__ if your compiler supports it.
[Note: which means that in any line you can call the UNIQUE only once and also the macro should be expanded in global or namespace scope (not inside a method).]
After replacing the code with the one given in the answer to the SO question you pointed so that it works, ... you can't call this function directly since you can't know for sure its name, that will change if the code change. I have no clue about how this can be useful in code (maybe scanning an object for symbol like Unique_[0-9]+? Anyway, it would be an indirect use, in code, as said, you can't use it reliably.

C++ compile time program wide unique numbers

I've come up with a solution to a problem but I'm not sure if it'll always work or just on my compiler. First, the problem: I've noticed in a number of situations it's desirable to have a template class that gets re-instantiated each time it's used even when given the same types (say your template class has static members that are initialized to function calls that have some important side effect -- and you want this side effect to be done every time the template is used). The easy way to do this is to give your template an extra integer parameter:
template<class T, class U, int uniqueify>
class foo
{
...
}
But now you have to manually make sure that every time you use foo you pass it a different value for uniqueify. The naive solution is to use __LINE__ like this:
#define MY_MACRO_IMPL(line) foo<line>
#define MY_MACRO MY_MACRO_IMPL(__LINE__)
This solution has an issue though -- __LINE__ gets reset for each translation unit. So if two translation units use the template on the same line, the template only gets instantiated once. That may seem unlikely, but imagine how difficult to debug the compiler error it would be if it did happen. Similarly you could try using __DATE__ as a parameter somehow, but that only has seconds precision and it's the time when compiling started, not when it reaches that line, so if you're using a parallel version of make it's rather plausible to have two translation units with the same __DATE__.
Another solution is that some compilers have a special non-standard macro, __COUNTER__ that starts at 0 and increments every time you use it. But it suffers from the same problem -- it gets reset for each invocation of the preprocessor, so it gets reset each translation unit.
Yet another solution, is to use __FILE__ and __LINE__ together:
#define MY_MACRO_IMPL(file, line) foo<T, U, file, line>
#define MY_MACRO MY_MACRO_IMPL(T, U, __FILE__, __LINE__)
But you can't pass char literals as template parameters according to the standard because they don't have external linkage.
Even if this did work, whether __FILE__ contains the absolute path to the file or just the name of the file itself isn't defined in the standard, so if you had two identical named files in different folders, this could still break. So here is my solution:
#ifndef toast_unique_id_hpp_INCLUDED
#define toast_unique_id_hpp_INCLUDED
namespace {
namespace toast {
namespace detail {
template<int i>
struct translation_unit_unique {
static int globally_unique_var;
};
template<int i>
int translation_unit_unique<i>::globally_unique_var;
}
}
}
#define TOAST_UNIQUE_ID_IMPL(line) &toast::detail::translation_unit_unique<line>::globally_unique_var
#define TOAST_UNIQUE_ID TOAST_UNIQUE_ID_IMPL(__LINE__)
#endif
Why this works isn't really clear without a usage example, but first an overview. The key insight I had was to see that every time you make a global variable or a static member variable, you're creating a program wide unique number in the form of the address of that variable. So this gives us a unique number that's available at compile time. __LINE__ makes sure we won't get clashes within the same translation unit, and the outer anonymous namespace makes sure the variables are different instances (and thus get differing addresses) across translation units.
Example usage:
template<int* unique_id>
struct special_var
{
static int value;
}
template<int* unique_id>
int special_var<unique_id>::value = someSideEffect();
#define MY_MACRO_IMPL(unique_id) special_var<unique_id>
#define MY_MACRO MY_MACRO_IMPL(TOAST_UNIQUE_ID)
And foo.cpp becomes:
#include <toast/unique_id.hpp>
...
typedef MY_MACRO unique_var;
typedef MY_MACRO unique_var2;
unique_var::value = 3;
unique_var2::value = 4;
std::cout << unique_var::value << unique_var2::value;
Despite being the same template, and the user providing no differentiating parameters, unique_var and unique_var2 are distinct.
I'm mostly worried about the address in of the variable in the anonymous namespace actually being available at compile time. Technically, an anonymous namespace is like declaring internal linkage, and template parameters can't have internal linkage. But the way the standard says to treat anonymous namespaces is just like the variable was declared as part of a namespace with a program-wide unique name, which means that technically it does have external linkage, even though we don't usually think of it as such. So I think the standard is on my side, but I'm not sure.
I don't know if I've done the best job of explaining why this would be useful, but for the sake of this discussion, it is, I swear ;)
This technique is not safe in general, for two reasons.
__LINE__ can be equal on two different lines in the same translation unit, either through #line directives, or (more commonly) through use on the same line number in multiple header files.
You will have ODR violations if you use TOAST_UNIQUE_ID or anything derived from it within in inline function or template definition in a header file.
That said, if you never use this in header files, and don't use #line in your main source file, and only use the macro once per line, it seems safe. (You can remove that last restriction by switching from __LINE__ to __COUNTER__.)
This should be safe - but simpler way would be to just use FILE. Also, an int isn't enough on a 64-bit platform. Use an intptr_t:
template<const char *file, int line>
class unique_value {
static char dummy;
unique_value() { }
public:
static intptr_t value() { return (intptr_t)&dummy; }
};
#define UNIQUE_VALUE (unique_value<__FILE__, __LINE__>::value())
Further, keep in mind that this will break down when used within a macro or template.
Also, templates with static values with side effects are a bad idea - remember that the side effects occur in arbitrary order, before main() is called - and burying initialization side effects in random functions is not very good for maintainability.