C++ class generation with pre-processor directives - c++

I am trying to generate a class given below with the help of recursive Macros/ pre-processor directives. I cannot use templates as I am building the type (a class). The macro users must be able to create this class without repeating the variables. I do not want to use containers for the variables as they can have meaningful names.
class IInterface;
class XYZ
{
int Mark1, Mark2, Mark3 /* variables to be passed */;
int count;
XYZ(IInterface * I)
{
count = 0;
// initialization values to be passed
Mark1 = 10; count++; I -> add(Mark1);
Mark2 = 20; count++; I -> add(Mark2);
Mark3 = 30; count++; I -> add(Mark3);
}
};
I am trying to put place holders and then expand them.
#define CLASS(_name) class _name {\
int VARS; \
int count; \
_name(IInterface * I) \
{ \
count = 0; \
VAR = val; count++; I -> add(VAR); \
} \
};
#define INIT // expansion code
CLASS(XYZ)
INIT(Mark1, 10) // variables should be sent only once for all the placeholders
INIT(Mark2, 20)
INIT(Mark3, 30)
How can I expand INIT to replace the placeholders?
I would like to know if this is feasible/ recommended.

This is not perhaps the "answer" directly to the question but achieves the same aim.
Macros in general are "evil" but can be useful at times. Here, however, they remain evil as anyone using the class later on will be hard-pressed to work out its actual definition, and errors will be much harder to decipher.
Therefore the recommendation is to use a scripting language as a pre-build step that can read in the configuration of your classes and generate the C++ files from it.
Then users of the classes will see actual C++ headers that look comprehensible.
Perl or Python might be used as the scripting language for this purpose. I would probably choose Perl.
You would then make this a pre-build step.
The generated headers would be the target, the scripted definition which is in a format you decide is the input, and a make script would know therefore if the targets are up-to-date.
For the input (class definition) file, you could use XML or JSON format, both of which give you nested key-value pairs with repeating groups. Whichever you choose has the advantages that
They are well known formats, understood by developers who may need to read or write them
There is already code to parse them so you won't need to write an actual parser, instead you'd just use the parsed data to generate your output file.

Related

How to do string formatting in BetterC mode?

I'd like to use something like the "Concepts" package from Atila Neves.
I implemented the check of an object against a type signature myself in a simple naive way. I can check struct objects against interfaces which I define within compile-time-evaluated delegate blocks to make them work with BetterC. I only used compile-time function evaluation with enums which receive return values of executed delegate code blocks.
Now I faced problems with std.format.format which uses TypeInfo for %s formatters which gives errors when compiling in BetterC. For code generation I'd like to use token strings because they have syntax highlighting. But proper usage of them requires string interpolation or string formatting. core.stdc.stdio.snprintf is no alternative because CTFE can only interprete D source code.
This is not technically a problem. I can just turn token strings into WYSIWYG strings.
But I wonder why I can't use it. The official documentation says, compile-time features are unrestricted for BetterC (I assume this includes TypeInfo). Either it is plain wrong or I am doing it wrong.
template implementsType(alias symbol, type)
if (isAbstractClass!type)
{
enum implementsType = mixin(implementsTypeExpr);
enum implementsTypeExpr =
{
import std.format : format;
auto result = "";
static foreach(memberName; __traits(allMembers, type))
{
result ~= format(
q{__traits(compiles, __traits(getMember, symbol, "%1$s")) && }~
q{covariantSignature!(__traits(getMember, symbol, "%1$s"), __traits(getMember, type, "%1$s")) && }
, memberName);
}
return (result.length >= 3)? result[0 .. $-3] : result;
}();
}
TypeInfo are not available with BetterC.
There's a bc-string dub package that provides a limited string formatter that will work in BetterC.

Dynamically creating a map at compile-time

I'm implementing Lua in a game engine. All of the functions being exported to Lua have headers that start with luavoid, luaint or luabool just for quick reference of the expected parameters, and so I can see at a glance that this function is being exported.
#define luavoid(...) void
luavoid(std::string s) TextMsg()
{
std::string s;
ExtractLuaParams(1, s);
::TextMsg(s.c_str());
}
To actually export a function to Lua, they're added to a dictionary. On startup, the map is used to call lua_register.
std::unordered_map<std::string, ScriptCall> _callMap = {
{ "TextMsg", TextMsg },
...
}
There will be a lot of functions exported. Rather than have to maintain this map manually, I'd like to automate its creation.
My first instinct was something with macros at compile-time. I gave up on it initially and started writing a program to parse the code (as a pre-build event), since all the functions can be text-matched with the luaX macros. It would create a header file with the map automatically generated.
Then I went back to doing it at compile-time after figuring out a way to do it. I came up with this solution as an example before I finally implement it in the game:
using MapType = std::unordered_map<std::string, int>;
template <MapType& m>
struct MapMaker
{
static int MakePair(std::string s, int n)
{
m[s] = n;
return n;
}
};
#define StartMap(map) MapType map
#define AddMapItem(map, s, n) int map##s = MapMaker<map>::MakePair(#s, n)
StartMap(myMap);
AddMapItem(myMap, abc, 1);
AddMapItem(myMap, def, 2);
AddMapItem(myMap, ghi, 3);
void main()
{
for (auto& x : myMap)
{
std::cout << x.first.c_str() << "->" << x.second << std::endl;
}
}
It works.
My question is, how horrible is this and can it be improved? All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
Be gentle(-ish). This is my first attempt at coding with templates like this. I assume this falls under template metaprogramming.
how horrible is this and can it be improved?
Somewhere between hideous and horrendous. (Some questions better left unasked.) And yes...
All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
The simplest thing to do is:
#define ADDFN(FN) { #FN, FN }
std::unordered_map<std::string, ScriptCall> _callMap = {
ADDFN(TextMsg),
...
};
This uses the macros to automate the repetition in the string literal function names and identifiers - there's nothing further substantive added by your implementation.
That said, you could experiment with automating things further than your implementation, perhaps something like this:
#define LUAVOID(FN, ...) \
void FN(); \
static auto addFN ## __LINE__ = myMap.emplace(#FN, FN); \
void FN()
LUAVOID(TextMsg, string s)
{
...
}
See it running here.
The idea here is that the macro generates a function declaration so that it can register the function, then a definition afterwards. __LINE__ likely suffices for uniqueness of the identifiers - assuming you have one file doing this, and that your compiler substitutes a numeric literal (which all compilers I've used do, but I can't remember if the Standard mandates that). The emplace function has a non-void return type so can be used directly to insert to the map.
Be gentle(-ish). This is my first attempt at coding with templates like this.
Sorry.
I assume this falls under template metaprogramming.
It's arguable. Many C++ programmers (myself included) think of "metaprogramming" as involving more advanced template usage - such as variable-length lists of parameters, recursive instantiations, and specialisation - but many others consider all template usage to be "metaprogramming" since the templates provide instructions for how to create instantiations, which is technically sufficient to constitute metaprogramming.

What's the safest way to define short function name aliases in C++?

Suppose I have a class Utility in a file utility.h:
class Utility {
public:
static double longDescriptiveName(double x) { return x + 42; }
};
And then I find that I use the function longDescriptiveName(...) a LOT. So like an irresponsible C++ programmer that I am when I've had too much coffee, I create a new file utilitymacros.h and add the following there:
#define ldn Utility::longDescriptiveName
Now I include "utilitymacros.h" in any *.cpp where I use ldn(...) and my heart is filled with joy over how much more convinient it is to type 3 letters vs 28.
Question: Is there a safer (more proper) way of doing this than with #define?
I've noticed that I have to include "utilitymacros.h" after including boost headers, which I obviously don't like because it's a sign of clashes (though the Boost errors I get are not very clear as to what the clash is).
Clarification 1: On Code Readability
In case you might say that this negatively affects code readability, I assure you it does not, because it's a small set of functions that are used A LOT. An example that is widely know is stoi for stringToInteger. Another is pdf for probabilityDensityFunction, etc. So if I want to do the following, stoi is more readable in my opinion:
int x = stoi(a) + stoi(b) + stoi(c) + stoi(d);
Than:
int x = Utility::stringToInteger(a) + Utility::stringToInteger(b)
+ Utility::stringToInteger(c) + Utility::stringToInteger(d);
Or:
int x = Utility::stringToInteger(a);
x += Utility::stringToInteger(b);
x += Utility::stringToInteger(c);
x += Utility::stringToInteger(d);
Clarification 2: Editor Macro
I use Emacs as my IDE of choice and a Kinesis keyboard so you KNOW I use a ton of keyboard macros, custom keyboard shortcuts, as well as actually modifying what I see in the editor vs what's actually stored in the h/cpp file. But still, I feel like the simplicity and visual readability (as argued above) of using a function abbreviation in a few select cases really is the result I'm looking for (this is certainly subject to a degree).
Instead of macro, you could write inline function that forwards the call to the actual function:
inline double ldn(double x)
{
return Utility::longDescriptiveName(x);
}
That is certainly safer than macro.
You could use a function reference:
double (&ldn)(double) = Utility::longDescriptiveName;
How about configuring a snippit/macro/similar thing in your text editor? This way you only have to type ldn or something like that and the code doesn't have to run through the preprocessor risking difficult to find bugs later.
I don't know if this helps, but I think part of the problem may be the use of overly general namespaces (or class names, in this case), such as Utility.
If instead of Utility::stringToInteger, we had
namespace utility {
namespace type_conversion {
namespace string {
int to_int(const std::string &s);
}
}
}
Then the function could locally be used like this:
void local_function()
{
using namespace utility::type_conversion::string;
int sum = to_int(a) + to_int(b) + to_int(c) + to_int(d);
}
Analogously, if classes/structs and static functions are used (and there can be good reasons for this), we have something like
strut utility {
struct type_conversion {
struct string {
static int to_int(const std::string &s);
};
};
};
and the local function would look something like this:
void local_function()
{
typedef utility::type_conversion::string str;
int sum = str::to_int(a) + str::to_int(b)
+ str::to_int(c) + str::to_int(d);
}
I realize I am not telling you anything about syntax you didn't know already; it's more a reminder of the fact that the organization and structure of namespaces and classes itself plays an important role in making code more readable (and writable).
One alternative is to rename your function and put it in a namespace instead of a class, since it is static anyway. utility.h becomes
namespace Utility {
// long descriptive comment
inline double ldn(double x) { return x + 42; }
}
Then you can put using namespace Utility; in your client code.
I know there are lots of style guides out there saying short names are a bad thing, but I don't see the point of obeying some style and then circumventing it.
You can use alias template (since C++11).
using shortName = my::complicate::function::name;

Advantage of macro over in-line in C++

We know that in-line are favorable as they are checked by the compiler and same operation ( like ++x ) does not evaluate more than once when passed as an argument as compared to macros.
But in an interview I was asked the specific advantages or the circumstances when a macro is more favorable to inline in C++.
Does anyone know the answer or can give a thought on this question ?
The only thing I can think of is there are some tricks that you can do with a macro that can't be done with an inline function. Pasting tokens together at compile-time, and that sort of hackery.
Here is a specific situation where macros are not only preferred, they are actually the only way to accomplish something.
If you want to write a logging function which logs not only some message, but the file & line number of where the instance occured, you can either call your function directly, typing in the file & line values (or macros) directly:
LogError("Something Bad!", __FILE__, __LINE__);
...or, if you want it to work automatically, you must rely on a macro (warning: not compiled):
#define LogErrorEx(ERR) (LogError(ERR, __FILE__, __LINE__))
// ...
LogErrorEx("Something Else Bad!");
This cannot be achieved using templates, default parameters, default construction, or any other device in C++.
Sometimes you want to extend the language in ways that aren't possible with any other method.
#include <iostream>
#define CHECK(x) if (x); else std::cerr << "CHECK(" #x ") failed!" << std::endl
int main() {
int x = 053;
CHECK(x == 42);
return 0;
}
This prints CHECK(x == 42) failed!.
In C++ specifically, one usage of MACROs that seem pop up very often (except for the debug print with file and line) is the use of MACROs to fill in a set of standard methods in a class that cannot be inherited from a base class. In some libraries that create custom mechanisms of RTTI, serialization, expression templates, etc., they often rely on a set of static const variables and static methods (and possibly special semantics for some overloaded operators that cannot be inherited) which are almost always the same but need to be added to any class that the user defines within this framework. In these cases, MACROs are often provided such that the user doesn't have to worry about putting all the necessary code (he only has to invoke the MACRO with the require info). For example, if I make a simple RTTI (Run-Time Type Identification) system, I might require that all classes have a TypeID and be dynamically castable:
class Foo : public Bar {
MY_RTTI_REGISTER_CLASS(Foo, Bar, 0xBAADF00D)
};
#define MY_RTTI_REGISTER_CLASS(CLASSNAME,BASECLASS,UNIQUEID) \
public:\
static const int TypeID = UNIQUEID;\
virtual void* CastTo(int aTypeID) {\
if(aTypeID == TypeID)\
return this;\
else\
return BASECLASS::CastTo(aTypeID);\
};
The above could not be done with templates or inheritance, and it makes the user's life easier and avoids code repetition.
I would say that this kind of use of MACROs is by far the most common in C++.
As already said, macros can use preprocessor directives: __FILE__, __LINE__ for instance, but of course #include and #define can also be useful to parameter behaviour:
#ifdef __DEBUG__
# define LOG(s) std:cout << s << std:endl
#else
# define LOG(s)
#endif
Depending wether __DEBUG__ is defined or not (via #define or via compiler options), the LOG macro will be active or not. This is an easy way to have debug info everywhere in your code that can be easily de-activated.
You can also think of changing the way memory is allocated (malloc will be redefined to target a memory pool instead of the standard heap for instance, etc...).
Inline functions are, as the name indicates, restricted to functional tasks, execution of some code.
Macros have a much broader application they may expand e.g to declarations or replace entire language constructs. Some examples (written for C and C++) that can't be done with functions:
typedef struct POD { double a; unsigned b } POD;
#declare POD_INITIALIZER { 1.0, 37u }
POD myPOD = POD_INITIALIZER;
#define DIFFICULT_CASE(X) case (X)+2 :; case (X)+3
#define EASY_CASE(X) case (X)+4 :; case (X)+5
switch (a) {
default: ++a; break;
EASY_CASE('0'): --a; break;
DIFFICULT_CASE('A'): a = helperfunction(a); break;
}
#define PRINT_VALUE(X) \
do { \
char const* _form = #X " has value 0x%lx\n"; \
fprintf(stderr, _form, (unsigned long)(X)); \
} while (false)
In the context of C++, Boost has a lot of more examples that are more involved and more useful.
But because with such macros you are in some sort extending the language (not strictly, the preprocessor is part of it) many people dislike macros, particularly in the C++ community, a bit less in the C community.
In any case, if you use such constructs you should always be very clear in what the should achieve, document well, and fight against the temptation to obfuscate your code.
A macro is just like a text replacement definition.
These essential differences that come into my mind are:
It must not be function-like. I mean it must not necessarily contain some consistent set of brackets for example.
It can be used elsewhere. Like in a class declaration scope or even in the global scope. So it must not be in the scope of another function.
You must use them if you want to perform actions that are impossible to be performed using functions:
initializing complicated tables (makes core more readable)
ease declaration of some special members like event IDs or tag classes (used a lot in MFC IMPLEMENT_DYNAMIC)
squeeze repetitive declarations at the beginning of functions
the already mentioned use of __LINE__, __FILE__, ... for logging
#include <stdio.h>
#define sq(x) x*x
int main()
{
printf("%d", sq(2+1));
printf("%d", sq(2+5));
return 0;
}
The output for this code are 5 and 17. Macros expand textually. Its not like functions.
Explanation for this example:
sq(2+1) = 2+1*2+1 = 2+2+1 = 5
sq(2+5) = 2+5*2+5 = 2+10+5 = 17
I would add two uses:
MIN and MAX, until C++0x, because the return type had to be declared by hand, mixed min and max as inlined functions would have been nightmarish, while a simple macro did it in the blink of an eye.
privacy: you can always undef the macro before exiting your header, you cannot "undeclare" an inline function (or another symbol). This is due to the absence of proper modularity in C and C++ languages.

Initialize global array of function pointers at either compile-time, or run-time before main()

I'm trying to initialize a global array of function pointers at compile-time, in either C or C++. Something like this:
module.h
typedef int16_t (*myfunc_t)(void);
extern myfunc_array[];
module.cpp
#include "module.h"
int16_t myfunc_1();
int16_t myfunc_2();
...
int16_t myfunc_N();
// the ordering of functions is not that important
myfunc_array[] = { myfunc_1, myfunc_2, ... , myfunc_N };
func1.cpp, func2.cpp, ... funcN.cpp (symbolic links to a single func.cpp file, so that different object files are created: func1.o, func2.o, func3.o, ... , funcN.o. NUMBER is defined using g++ -DNUMBER=N)
#include "module.h"
#define CONCAT2(x, y) x ## y
#define CONCAT(x, y) CONCAT2(x, y)
int16_t CONCAT(myfunc_, NUMBER)() { ... }
When compiled using g++ -DNUMBER=N, after preprocessing becomes:
func1.cpp
...
int16_t myfunc_1() { ... }
func2.cpp
...
int16_t myfunc_2() { ... }
and so on.
The declarations of myfunc_N() and the initialization of myfunc_array[] are not cool, since N changes often and could be between 10 to 200. I prefer not to use a script or Makefile to generate them either. The ordering of functions is not that important, i can work around that. Is there a neater/smarter way to do this?
How To Make a Low-Level Function Registry
First you create a macro to place pointers to your functions in a special section:
/* original typedef from question: */
typedef int16_t (*myfunc)(void);
#define myfunc_register(N) \
static myfunc registered_##myfunc_##N \
__attribute__((__section__(".myfunc_registry"))) = myfunc_##N
The static variable name is arbitrary (it will never be used) but it's nice to choose an expressive name. You use it by placing the registration just below your function:
myfunc_register(NUMBER);
Now when you compile your file (each time) it will have a pointer to your function in the section .myfunc_registry. This will all compile as-is but it won't do you any good without a linker script. Thanks to caf for pointing out the relatively new INSERT AFTER feature:
SECTIONS
{
.rel.rodata.myfunc_registry : {
PROVIDE(myfunc_registry_start = .);
*(.myfunc_registry)
PROVIDE(myfunc_registry_end = .);
}
}
INSERT AFTER .text;
The hardest part of this scheme is creating the entire linker script: You need to embed that snippet in the actual linker script for your host which is probably only available by building binutils by hand and examining the compile tree or via strings ld. It's a shame because I quite like linker script tricks.
Link with gcc -Wl,-Tlinkerscript.ld ... The -T option will enhance (rather than replace) the existing linker script.
Now the linker will gather all of your pointers with the section attribute together and helpfully provide a symbol pointing before and after your list:
extern myfunc myfunc_registry_start[], myfunc_registry_end[];
Now you can access your array:
/* this cannot be static because it is not know at compile time */
size_t myfunc_registry_size = (myfunc_registry_end - myfunc_registry_start);
int i;
for (i = 0; i < myfunc_registry_size); ++i)
(*myfunc_registry_start[i])();
They will not be in any particular order. You could number them by putting them in __section__(".myfunc_registry." #N) and then in the linker gathering *(.myfunc_registry.*), but the sorting would be lexographic instead of numeric.
I have tested this out with gcc 4.3.0 (although the gcc parts have been available for a long time) and ld 2.18.50 (you need a fairly recent ld for the INSERT AFTER magic).
This is very similar to the way the compiler and linker conspire to execute your global ctors, so it would be a whole lot easier to use a static C++ class constructor to register your functions and vastly more portable.
You can find examples of this in the Linux kernel, for example __initcall is very similar to this.
I was going to suggest this question is more about C, but on second thoughts, what you want is a global container of function pointers, and to register available functions into it. I believe this is called a Singleton (shudder).
You could make myfunc_array a vector, or wrap up a C equivalent, and provide a function to push myfuncs into it. Now finally, you can create a class (again you can do this in C), that takes a myfunc and pushes it into the global array. This will all occur immediately prior to main being called. Here are some code snippets to get you thinking:
// a header
extern vector<myfunc> myfunc_array;
struct _register_myfunc {
_register_myfunc(myfunc lolz0rs) {
myfunc_array.push_back(lolz0rs);
}
}
#define register_myfunc(lolz0rs) static _register_myfunc _unique_name(lolz0rs);
// a source
vector<myfunc> myfunc_array;
// another source
int16_t myfunc_1() { ... }
register_myfunc(myfunc_1);
// another source
int16_t myfunc_2() { ... }
register_myfunc(myfunc_2);
Keep in mind the following:
You can control the order the functions are registered by manipulating your link step.
The initialization of your translation unit-scoped variables occurs before main is called, i.e. the registering will be completed.
You can generate unique names using some macro magic and __COUNTER__. There may be other sneaky ways that I don't know about. See these useful questions:
Unnamed parameters in C
Unexpected predefined macro behaviour when pasting tokens
How to generate random variable names in C++ using macros?
Your solution sounds much too complicated and error prone to me.
You go over your project with a script (or probably make) to place the -D options to the compiler, anyhow. So I suppose you are keeping a list of all your functions (resp. the files defining them).
I'd use proper names for all the functions, nothing of your numbering scheme and then I would produce the file "module.cpp" with that script and initialize the table with the names.
For this you just have to keep a list of all your functions (and perhaps filenames) in one place. This could be easier be kept consistent than your actual scheme, I think.
Edit: Thinking of it even this might also be overengineering. If you have to maintain a list of your functions somewhere in any case, why not just inside the file "module.cpp"? Just include all the header files of all your functions, there, and list them in the initializer of the table.
Since you allow C++, the answer is obviously yes, with templates:
template<int N> int16_t myfunc() { /* N is a const int here */ }
myfunc_array[] = { myfunc<0>, myfunc<1>, myfunc<2> }
Now, you might wonder if you can create that variable-length initializer list with some macro. The answer is yes, but the macro's needed are ugly. So I'n not going to write them here, but point you to Boost::Preprocessor
However, do you really need such an array? Do you really need the name myfunc_array[0] for myfunc<0> ? Even if you need a runtime argument (myfunc_array[i]) there are other tricks:
inline template <int Nmax> int16_t myfunc_wrapper(int i) {
assert (i<Nmax);
return (i==Nmax) ? myfunc<Nmax> : myfunc_wrapper(i-1);
}
inline int16_t myfunc_wrapper(int i) {
return myfunc_wrapper<NUMBER>(i); // NUMBER is defined on with g++ -DNUMBER=N
}
Ok I worked out a solution based on Matt Joiner's tip:
module.h
typedef int16_t (*myfunc_t)(void);
extern myfunc_array[];
class FunctionRegistrar {
public:
FunctionRegistrar(myfunc_t fn, int fn_number) {
myfunc_array[fn_number - 1] = fn; // ensures correct ordering of functions (not that important though)
}
}
module.cpp
#include "module.h"
myfunc_array[100]; // The size needs to be #defined by the compiler, probably
func1.cpp, func2.cpp, ... funcN.cpp
#include "module.h"
static int16_t myfunc(void) { ... }
static FunctionRegistrar functionRegistrar(myfunc, NUMBER);
Thanks everyone!