Suppose I have an header that is meant to be included several times generating code from a template parameterised over a macro DATA. I use it in this way:
#define DATA this
#include <header.hpp>
#undef DATA
#define DATA that
#include <header.hpp>
#undef DATA
#define DATA the_other
#include <header.hpp>
#undef DATA
Is there a way to automate this repeated inclusion given a list of the values of DATA? Something like:
#define DATAS (this, that, the_other)
#include <header.hpp>
#undef DATAS
I tried with some __VA_OPT__ magic, and inside of header.hpp I can isolate the first element of the list and the tail of the list, but the problem is that I cannot redefine DATAS in terms of itself for the next inclusion.
Is this possible at all?
Yes, it is possible.
You can use Boost Preprocessor (which is independent of all other Boost Packages and only has to be downloaded, no library needs to be built or installed) to get the needed ready-to-use macros. You can also try to understand Boost Preprocessor and recreate the needed features.
The example is taken from Ari's answer. It could be expanded to provide several data elements to each iteration, e.g. for initializing the ints and floats with specific values.
// header.hpp - sample header, which uses DATA to create variables
// uses Boost preprocessor only for simple concatenation
// you can use your custom header here
#include <boost/preprocessor/cat.hpp>
int BOOST_PP_CAT(int_, DATA) = 1;
float BOOST_PP_CAT(float_, DATA) = 2.2f;
// main.cpp - wants to define lots of variables
// provides header name, list of symbol suffixes
// repeated.hpp will include header.hpp 3 times with DATA set to this, that and the_other
// (Space after REP_PARAMS is important)
#define REP_PARAMS ("header.hpp")(this, that, the_other)
#include "repeated.hpp"
#undef REP_PARAMS
#include <iostream>
using namespace std;
int main()
{
cout << "int_this: " << int_this << endl;
cout << "int_that: " << int_that << endl;
cout << "int_the_other: " << int_the_other << endl;
cout << "----------------------------------------------------------"
<< endl;
cout << "float_this: " << float_this << endl;
cout << "float_that: " << float_that << endl;
cout << "float_the_other: " << float_the_other << endl;
return 0;
}
// repeated.hpp - helper header
// all the magic
// it mostly extracts the REP_PARAMS sequence
// TODO error-checking, e.g. that REP_PARAMS exists and is a sequence of length two, that second element of REP_PARAMS is a tuple
#if !BOOST_PP_IS_ITERATING
// iteration has not started yet, include used boost headers
// initialize iteration with 3 parameters from 0 to < size of tuple,
// include itself (repeated.hpp)
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_TUPLE_SIZE(BOOST_PP_SEQ_TAIL(REP_PARAMS)), "repeated.hpp"))
#include BOOST_PP_ITERATE()
#else
// set DATA to i-th element in tuple, include specified header (header.hpp)
#define DATA BOOST_PP_TUPLE_ELEM(BOOST_PP_ITERATION(), BOOST_PP_SEQ_TAIL(REP_PARAMS))
#include BOOST_PP_SEQ_HEAD(REP_PARAMS)
#undef DATA
#endif
The maximum list size is 256. By default it is limited to 64, but can be increased with the BOOST_PP_LIMIT_TUPLE macro.
I have to admit I wouldn't even consider using any preprocessing tricks for that. This is a classical scripting problem.
Instead you could write a small script that creates that header for you and inserts that at the beginning of the file. You could then add that as a step in your build system to run it. This technique gives you a LOT of power going forward:
You can add the same header to many scripts rather easily
You can see all the custom headers in a clean json format
You could easily get the script to add multiple #define <key> <value>-s before the include
You could change formatting easily and quickly
Here is an example script that does that:
import json
def prepend_headers(fout, headers):
for header in headers:
include = header['include']
define = header['define']
for k, v in define.items():
fout.write(f'#define {k} {v}\n')
fout.write(f'#include {include}\n')
for k, _ in define.items():
fout.write(f'#undef {k}\n')
fout.write('\n')
def main(configfile):
with open(configfile) as fin:
config = json.load(fin)
input_file = config['input']
with open(input_file) as fin:
input_content = fin.read()
output_file = config['output']
with open(output_file, 'w') as fout:
headers = config['headers']
prepend_headers(fout, headers)
fout.write(input_content)
if __name__ == '__main__':
import sys
configfile = sys.argv[1]
sys.exit(main(configfile))
If you use the following configuration:
{
"input": "class.cpp.template",
"output": "class.cpp",
"headers": [
{
"include": "<header.hpp>",
"define": {
"DATA": "this",
"OBJ": "him"
}
},
{
"include": "<header.hpp>",
"define": {
"DATA": "that"
}
},
{
"include": "<header.hpp>",
"define": {
"DATA": "the_other"
}
}
]
}
And the following template file:
#include <iostream>
class Obj {
};
int main() {
Obj o;
std::cout << "Hi!" << std::endl;
return 0;
}
The result you get is this:
#define DATA this
#define OBJ him
#include <header.hpp>
#undef DATA
#undef OBJ
#define DATA that
#include <header.hpp>
#undef DATA
#define DATA the_other
#include <header.hpp>
#undef DATA
#include <iostream>
class Obj {
};
int main() {
Obj o;
std::cout << "Hi!" << std::endl;
return 0;
}
Using a template class might be annoying, so you might decide to add some hints in the output file so you could "replace" them with every build you run.
This is not doable using preprocessor only. However, it is probably worth mentioning that there is something called X-Macro that could have been used for something close to what you are asking if you weren't using preprocessor macros for each case.
The reason is that it cannot be used here is that you cannot use #define or #include in the definition of a macro.
For example, this is doable for defining this, that and the_other as variables from a file called data.def that has them as a list:
// data.def
ELEMENT(this)
ELEMENT(that)
ELEMENT(the_other)
Then in main.cc:
//main.cc
#define ELEMENT(d) int int_##d = 1;
#include "data.def"
#undef ELEMENT
#define ELEMENT(d) int float_##d = 2.2;
#include "data.def"
#undef ELEMENT
int main() {
std::cout << "int_this: " << int_this << std::endl;
std::cout << "int_that: " << int_that << std::endl;
std::cout << "int_the_other: " << int_the_other << std::endl;
std::cout << "----------------------------------------------------------"
<< std::endl;
std::cout << "float_this: " << float_this << std::endl;
std::cout << "float_that: " << float_that << std::endl;
std::cout << "float_the_other: " << float_the_other << std::endl;
}
Output:
int_this: 1
int_that: 1
int_the_other: 1
---------------------------------------------------------------
float_this: 2
float_that: 2
float_the_other: 2
But something like this is not going to work because you would be defining a macro in another macro:
#define ELEMENT(d) #define DATA d; \
#include "data.def" \
#undef DATA
#undef ELEMENT
Related
The following preprocessor-based identifier-to-string lookup table:
#include <iostream>
// included generated file
#define KEY_a valueA
#define KEY_b valueB
///////
#define LOOKUP_(_key_) KEY_ ## _key_
#define QUOTE_(_str_) #_str_
#define EXPAND_AND_QUOTE_(_str_) QUOTE_(_str_)
#define LOOKUP(_key_) EXPAND_AND_QUOTE_(LOOKUP_(_key_))
int main() {
std::cout << LOOKUP(a) << std::endl;
std::cout << LOOKUP(b) << std::endl;
std::cout << LOOKUP(c) << std::endl;
}
Output:
valueA
valueB
KEY_c
The first #defines come from an #included header generated by an external script before the compilation.
The LOOKUP macro correctly handles existing key in the table, and substitutes the given value as string literal.
But for non-existing keys, it substitutes the key as string literal.
Is there a way to instead make it substitute a given constant for non-existing keys, without causing a compile-time error, and all within the preprocessing stage?
So for example, the LOOKUP(c) and LOOKUP(whatever) should all be substituted to "undefined", without c or whatever occuring in the included generated file.
The names of the keys should not be outputted to the compiled binary, so ideally they should never be seen by the compiler.
Here's a simple, if hacky, solution. By making the definition of KEY_x a list of two elements (the first of which will be ignored), it permits adding a default value:
#include <iostream>
// included generated file
#define KEY_a _,valueA
#define KEY_b _,valueB
///////
#define LOOKUP_(key) KEY_ ## key
#define QUOTE_(_,str,...) #str
#define EXPAND_AND_QUOTE_(...) QUOTE_(__VA_ARGS__)
#define LOOKUP(key) EXPAND_AND_QUOTE_(LOOKUP_(key),undefined)
int main() {
std::cout << LOOKUP(a) << std::endl;
std::cout << LOOKUP(b) << std::endl;
std::cout << LOOKUP(c) << std::endl;
}
Test on coliru
I'm trying to expand my C++ game hacking skills as when I was starting (2 years ago) I made a bad decision: continue in game hacking with vb.net instead of learning c++ (as I had some vb.net knowledge and 0 knowledge with other languages)
So, now as the very first steps I have to create my toolkit, where I will be using my own templates:
Nathalib.h (my template with all common functions for game hacking).
#pragma once
#include <iostream>
#include <Windows.h>
#include <string>
#include <TlHelp32.h>
#include <stdio.h>
using namespace std;
DWORD ProcessID;
int FindProcessByName(string name)
{
HWND hwnd = FindWindowA(0, name);
GetWindowThreadProcessId(hwnd, &ProcessID);
if (hwnd)
{
return ProcessID;
}
else
{
return 0;
}
}
Hack.cpp (obviously the cheat, will be different for every game).
#pragma once
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <Nathalib.h>
using namespace std;
int main()
{
While(True)
{
cout << FindProcessByName("Calculator") << endl;
getchar();
cout << "-----------------------------------" << endl << endl;
}
return 0;
}
Target.cpp (as we're not bad boys, I must provide my own target).
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
#define CHAR_ARRAY_SIZE 128
int main()
{
int varInt = 123456;
string varString = "DefaultString";
char arrChar[CHAR_ARRAY_SIZE] = "Long char array right there ->";
int * ptr2int;
ptr2int = &varInt;
int ** ptr2ptr;
ptr2ptr = &ptr2int;
int *** ptr2ptr2;
ptr2ptr2 = &ptr2ptr;
while(True) {
cout << "Process ID: " << GetCurrentProcessId() << endl;
cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
cout << "varString (0x" << &varString << ") = " << varString << endl;
cout << "varChar (0x" << &arrChar << ") = " << arrChar << endl;
cout << "ptr2int (0x" << hex << &ptr2int << ") = " << ptr2int << endl;
cout << "ptr2ptr (0x" << hex << &ptr2ptr << ") = " << ptr2ptr << endl;
cout << "ptr2ptr2 (0x" << hex << &ptr2ptr2 << ") = " << ptr2ptr2 << endl;
cout << "Press ENTER to print again." << endl;
getchar();
cout << "-----------------------------------" << endl << endl;
}
return 0;
}
I don't know why the header file is not being recognized.
This is the correct way to include header files? Should I create a namespace/class/object for calling it?
It's the correct way creating a header file? Or I should create another kind of project/resource for this purpose?
How should I call my library methods? Like LibraryName.MethodName?
I just come from other languages and some ideas/features are not available in the other languages (that's why I'm interested in this one)
If there's something I forgot to add, please tell me and I will update
Thanks
There are multiple errors - please check your textbook.
You include your own headers with #include "". System headers are included with #include<>
The header file generally contains function declarations. Function bodies go into the corresponding .cpp file.
You call your library functions by their name. If they're in a namespace, that might mean the format is namespacename::functionname(arguments).
There are two ways to include headers, using "" or <>
with <> the file will be searched in the system search path (which is not the $PATH variabel, but the list of paths provided with `-I' together with standard headers already known by compiler) and included if found
with "" the file will be search in the current folder and in the system search path
Assuming your header is in th esame folder of hack.cpp, you should use
#include "Nathalib.h"
First off, your header lacks include guards, #pragma once only works with msvc++.
Your header file is probably not in PATH, so you need to specify it's path relative to your project. If your header file is in the same root as your cpp file, all you need to do is change the include statement for that header file to #include "Nathalib.h" otherwise you'll have to specify the relative path.
To add to other aswers- why you should put declaration of function in .h file, while its definition to .cpp file: Writing function definition in header files in C++
I suggest to find some c++ tutorials for example: http://www.tutorialspoint.com/cplusplus/cpp_functions.htm
You should learn tutorials first, making some exercises on simply code. Personally I prefer check then most simply code for new programming construct. Then more complicated.
After such learning you may use for reference also : http://www.cplusplus.com and https://en.cppreference.com/w/
This question already has answers here:
How do I temporarily disable a macro expansion in C/C++?
(6 answers)
Closed 5 years ago.
The goal here is to simply get a, b, c out instead of their actual values. The setup is "simple enough":
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>
// Define "invalid" sequence first
#define SEQ (a)(b)(c)
// Try to create "final" value with `std::string("elem")`
// Brought in for explicit `std::string`, but no dice
#define MAKE_XSTRING(x) MAKE_STRING(x)
#define MAKE_STRING(x) std::string(#x)
// oh, the humanity! vvvvvvvvvvvv or BOOST_PP_STRINGIZE
#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem))
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ)
So what I'm expecting at this point is what I have: a new sequence with (std::string("a")) etc:
// confirmation: vvvvvvvvvvvvvvvv
// warning: Humans: (std::string("a")) (std::string("b")) (std::string("c"))
#pragma message "Humans: " BOOST_PP_STRINGIZE(SEQ_HUMAN)
Thinking I'm so very clever and have gotten my values sorted out in some explicit strings, now I define the actual values for what the "real" code needs.
// Now that we have the "final" values, actually define the real values
// in real code, it's some lengthy nested namespaces (inconvenient to type)
#define a 123
#define b 456
#define c 789
And at long last, lets print them to make sure they aren't expanded:
// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << elem << std::endl
int main(int argc, const char **argv) {
std::cout << "Humans: " << std::endl
BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN);
}
But it seems the aliens did indeed take over:
Humans:
1. 123
2. 456
3. 789
Given that they're supposed to be std::string("a")...how the heck are the real values getting back in there?! I thought maybe the ("a") from the std::string constructor was creating issues, but it doesn't seem so (BOOST_PP_STRINGIZE results in same behavior). Any suggestions?
The macro indeed expands into code tokens:
test.cpp|24 col 1| note: #pragma message: Humans: (std::string("123")) (std::string("456")) (std::string("789"))
Now when you insert the code tokens into your GOTTA_PRINT_EM_ALL macro, you get
<< ((0)+1) << ". " << std::string(\"123\") << std::endl << ((1)+1) << ". " << std::string(\"456\") << std::endl << ((2)+1) << ". << std::string(\"789\")" << std::endl
Completely expectedly printing
Humans:
1. 123
2. 456
3. 789
To get the "code tokens" you need to stringize them as well:
// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl
Printing
Humans:
1. std::string("123")
2. std::string("456")
3. std::string("789")
See it Live On Coliru
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>
#include <string>
#define a 123
#define b 456
#define c 789
#define SEQ (a)(b)(c)
// Try to create "final" value with `std::string("elem")`
// Brought in for explicit `std::string`, but no dice
#define MAKE_STRING(x) std::string(#x)
#define MAKE_XSTRING(x) MAKE_STRING(x)
#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem))
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ)
// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl
int main() {
std::cout << "Humans: " << std::endl
BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN);
}
I am trying to implement automatic class registration at runtime (I think this technique goes under the name of "register pattern"). In the following example I am storing an int in a static member vector, but the goal would be to store function pointers that can be called later.
My understanding is that, since the member registeredClasses in my code below is declared static, there should be only one instance of it throughout the program. However this seems not to be the case:
classregister.h
#ifndef CLASSREGISTER_H
#define CLASSREGISTER_H
#include <vector>
#include <iostream>
class ClassRegister
{
public:
static std::vector<int> registeredClasses; //declaration
ClassRegister(int id) {
std::cerr << "registering " << id << " ";
registeredClasses.push_back(id);
std::cerr << "new size: " << registeredClasses.size() << "\n";
}
//code below just for testing
ClassRegister() {}
static int getSize() {
return registeredClasses.size();
}
};
#define REGISTER_CLASS(cls) \
static ClassRegister myClass_##cls(1);
#endif // CLASSREGISTER_H
classregister.cpp
#include "classregister.h"
std::vector<int> ClassRegister::registeredClasses; //definition
class1.h (class2.h follows the same pattern, omitted for brevity)
#ifndef CLASS1_H
#define CLASS1_H
#include "classregister.h"
class Class1
{
public:
Class1();
};
REGISTER_CLASS(Class1)
#endif // CLASS1_H
class1.cpp (class2.cpp follows the same pattern, omitted for brevity)
#include "class1.h"
Class1::Class1()
{
}
main.cpp
#include "classregister.h"
#include <iostream>
int main(int argc, char *argv[])
{
std::cerr << "registering classes works...\n\n";
std::cerr << "but reading from main() does not...\n";
std::cerr << "checking size directly: " << ClassRegister::registeredClasses.size() << "\n";
std::cerr << "checking size through function: " << ClassRegister::getSize() << "\n";
std::cerr << "checking size on instance: " << ClassRegister().getSize() << "\n";
std::cerr << "\n";
std::cerr << "registration from main() uses a different register...\n";
ClassRegister(2);
ClassRegister(3);
ClassRegister(4);
std::cerr << "\n";
std::cerr << "...which is not the one used in the header files\n";
std::cerr << "checking size directly: " << ClassRegister::registeredClasses.size() << "\n";
std::cerr << "checking size on instance: " << ClassRegister().getSize() << "\n";
std::cerr << "checking size through function: " << ClassRegister::getSize() << "\n";
std::cerr << "\n";
}
The issue I have is that it works only "sometimes". Initial output:
registering 1 new size: 1
registering 1 new size: 2
registering classes works...
but reading from main() does not...
checking size directly: 0
checking size through function: 0
checking size on instance: 0
registration from main() uses a different register...
registering 2 new size: 1
registering 3 new size: 2
registering 4 new size: 3
...which is not the one used in the header files
checking size directly: 3
checking size on instance: 3
checking size through function: 3
I removed class1.cpp and class2.cpp, declaring the constructors in the header files, eg. Class1() {}. Regsitration did not work at all:
//no output here
registering classes works...
//...
Then I reverted the change and suddenly I get the expected output:
registering 1 new size: 1
registering 1 new size: 2
registering classes works...
but reading from main() does not... //it does work this time
checking size directly: 2
checking size through function: 2
checking size on instance: 2
registration from main() uses a different register...
registering 2 new size: 3
registering 3 new size: 4
registering 4 new size: 5
...which is not the one used in the header files
checking size directly: 5
checking size on instance: 5
checking size through function: 5
I have been researching on this issue, but failed to understand the cause. My guess is that it has something to do with the compilation order (but how does registration work then?) or with linkage / storage duration. Can someone shed some light on this?
I think that the trick you need here is in ClassRegister instead of a static data member, use a function with a static local. This is sometimes called a singleton, although I don't know if that is really the correct term for it.
Code would probably look like:
typedef std::vector<int> register_type;
register_type& getRegister() {
static register_type registeredClasses; //declaration
return registeredClasses;
}
When you implement automatic class registration scheme, you should be careful about static initialization order, multi-threading.
The reason it didn't work when you removed .cpp files is because the header files are not compiled and therefore no one knows there were any declarations.
I am trying to achieve the following but in a way that follows the c++ standard :
#include <iostream>
using namespace std;
#define MAKE_BOTH(MAKE_FUNC) \
MAKE_FUNC(FIRST) \
MAKE_FUNC(SECOND) \
MAKE_FUNC(THIRD) \
MAKE_FUNC(FOURTH)
#define MAKE_STRINGS(NAME) #NAME,
const char* genericString[] {
MAKE_BOTH(MAKE_STRINGS)
};
#define MAKE_ENUM(NAME) NAME = (1L << __COUNTER__),
enum genericEnum {
MAKE_BOTH(MAKE_ENUM)
};
int main()
{
cout << FIRST << endl;
cout << SECOND << endl;
cout << THIRD << endl;
cout << FOURTH << endl;
}
If you think a while about this code, this creates both, enums and array of "strings" which consists of the same names as enums. The examle code expands to :
const char* genericString[] {
"FIRST",
"SECOND",
"THIRD",
"FOURTH"
};
enum genericEnum {
FIRST = 1L << 0; (1)
SECOND = 1L << 1; (2)
THIRD = 1L << 2; (4)
FOURTH = 1L << 3; (8)
};
Basically the enums are assigned power of 2 values, the question is - is there a relatively simple way of achieving the same thing without using COUNTER ?
The problem is similar to this one:
Counting preprocessor macros
but I have to increase the value of counter each time the macro is used at compile time, I could not figure out how to do it without using the non-standard COUNTER macro.
Please beware the c++ 11 is not an option, but using boost is, I tried the boost approach as well but it is not possible to call the #include directive by a macro which unables me from incrementing the boost preprocessor counter.
You may generate something like this:
enum genericEnum
{
MY_ENUM_BASE=0,
FIRST,
PAST_FIRST= (FIRST<<1)-1,
SECOND,
PAST_SECOND= (SECOND<<1)-1,
THIRD,
PAST_THIRD= (THIRD<<1)-1,
FOURTH,
PAST_FOURTH= (FOURTH<<1)-1,
};
using standard macroprocessor without using COUNTER,
i.e. defining MAKE_ENUM as
#define MAKE_ENUM(NAME) NAME, PAST##_NAME= (NAME<<1)-1,