C++ Macro define and undefine - c++

I want to use macros to quickly create inlined functions in headers, these functions are related to a base class which I am subclassing. I'll put the definitions inside the base class header but I do not want to pollute everything that include these headers with all macro definitions, so I would like to write something like this (which unfortunately doesn't work):
#define BEGIN_MACROS \
#define MACRO_1(...) ...\
#define MACRO_2(...) ...\
#define MACRO_3(...) ...
#define END_MACROS \
#undef MACRO_1\
#undef MACRO_2\
#undef MACRO_3
And then use it like:
BEGIN_MACROS
MACRO_1(...)
MACRO_2(...)
MACRO_3(...)
END_MACROS
perhaps should I use something like this?
#include "definemacros.h"
MACRO_1(...)
MACRO_2(...)
MACRO_3(...)
#include "undefmacros.h"
And put definitions and "undefinitions" in two separate headers...
Or is there a better approach overall to overcome this kind of problems?
Or do you suggest to avoid at all the use of macros and/or macros in headers?
Edited to include specific use case:
definition:
#define GET_SET_FIELD_VALUE_INT(camelcased, underscored)\
inline int rget ## camelcased () { return this->getFieldValue( #underscored ).toInt(); }\
inline void rset ## camelcased (int value) { this->setFieldValue( #underscored , value); }
use:
class PaymentRecord : public RecObj
{
public:
GET_SET_FIELD_VALUE_INT(PriceIndex, price_index)
//produces this
inline int rgetPriceIndex() { return this->getFieldValue("price_index").toInt(); }
inline void rsetPriceIndex(int value) { this->setFieldValue("price_index", value); }
};

you can not stack up more defines into single line (at least to my knowledge... What I would try to do is encapsulate those into 2 separate files instead like this:
file macro_beg.h:
#define MACRO_1(...) ...
#define MACRO_2(...) ...
#define MACRO_3(...) ...
file macro_end.h:
#undef MACRO_1
#undef MACRO_2
#undef MACRO_3
It just like your second case but the macros are not in single line ...
#include "macro_beg.h"
MACRO_1(...);
MACRO_2(...);
MACRO_3(...);
#include "macro_end.h"
But as Some programmer dude commented this might not work properly or at all depending on the compiler preprocessor and macro complexity or nesting with class/template code. For simple stuff however this should work.

Related

Add dynamically methods to a class : using macro function into header file

Trying to avoid write a repeating code; I used macros to delare methods into a class.
I want to define a macro function into header file like :
cracker.h
#include<message.h>
class Cracker {
#define DECLARE_MSG(MSG_NAME, MSG_TYPE,ALREADY_DEFINED) \
{ \
if(!ALREADY_DEFINED)
{ \
virtual bool cbProcessMsg_##MSG_NAME (API::MSG_NAME##Msg const & msg); \
}\
#include "message.h"
#undef DECLARE_MSG
};
message.h
DECLARE_MSG(AddOrder , 'A', false);
DECLARE_MSG(DeleteOrder , 'B', true);
DECLARE_MSG(ReplaceOrder , 'C', false);
...
But this code does note compile because I have not the right to add if statement outside a function.
Is there any alternative to do that ?
There's a couple of items worth highlighting:
1.
Macros do not know scope; the only way you can remove it's definition is to undefine it.
2.
macros are pasted into the code as is; and then compiled. A macro isn't a function itself, it's a code generation tool. This means that even if 'ALREADY_DEFINED' is true, you'll get another definition.
3.
What you're trying to do is add a function into the class outside of the class definition. You just can't do this. Ever.
4.
Header guards will save you pain for medium to large projects; you should get into the habbit of using them early.
While not quite the same, what it looks like you want to do is look up what the factory pattern is.
Use BOOST_PP_IIF if you (can) use the boost-library:
#define DECLARE_MSG(MSG_NAME, MSG_TYPE,ALREADY_DEFINED) \
BOOST_PP_IIF(ALREADY_DEFINED,, \
virtual bool cbProcessMsg_##MSG_NAME (API::MSG_NAME##Msg const & msg); \
)
You should use 0 and 1 instead of false and true here.
But if you don't, you can 'branch' definitions by concating name and number to another macro:
// two definitions for PP_CONCAT to expand macros, etc...
#define PP__CONCAT(a, b) a ## b
#define PP_CONCAT(a, b) PP__CONCAT(a, b)
// to expand your macro you should pass it through another macro
#define PP_EXPAND(...) __VA_ARGS__
#define DECLARE_MESSAGE_0(MSG_NAME, MSG_TYPE) /** the def when ALREADY_DEFINED = 0 */
#define DECLARE_MESSAGE_1(MSG_NAME, MSG_TYPE) /** the other branch */
#define DECLARE_MESSAGE(MSG_NAME, MSG_TYPE, ALREADY_DEFINED) \
PP_EXPAND(PP_CONCAT(DECLARE_MESSAGE_, ALREADY_DEFINED)(MSG_NAME, MSG_TYPE))
When you have problems understanding the preprocessor, you should check out the output with the option -E / running the code with the command cpp(which stands for c-preprogressor and not cplusplus(->c++))
However there may be another way to do the same thing, with templates and inheritance...

Alternative ways to create file scope in Unity Builds

I'm trying to use Unity Builds to shorten the build time of a c++ project on Windows. One of several problems I met is the single file scope issue.
Once all source codes are included in a single source file, they all share the same file scope. All locally defined symbols using same name will be duplicate and causing compile errors.
Currently, I have to change each duplicated names with a file postfix to avoid duplication. But I think there might be better solutions.
I'd like to share my current solution.
In generation of unity_build_source_<index>.cpp files, define a UNITY_BUILD macro and wrap each include source code with macros:
// unity_build_souce file, automatically generated, do not edit manually.
#define UNITYBUILD_CONCATENATE_DETAIL(x, y) x##y
#define UNITYBUILD_CONCATENATE(x, y) UNITYBUILD_CONCATENATE_DETAIL(x, y)
#define UNITYBUILD_MAKE_UNIQUE(x) UNITYBUILD_CONCATENATE(x, _UNITYBUILD_COUNTER)
#define UNITY_BUILD
// for each source code
#define _UNITY_BUILD_COUNTER 1
#include <path/to/source1.cpp>
#undef _UNITY_BUILD_COUNTER
#define _UNITY_BUILD_COUNTER 2
#include <path/to/source2.cpp>
#undef _UNITY_BUILD_COUNTER
// ...
In source codes, use UNITYBUILD_MAKE_UNIQUE macro for names that is duplicated.
#ifdef UNITY_BUILD
#define a_duplicated_variable UNITYBUILD_MAKE_UNIQUE(a_duplicated_variable)
#define ADuplicatedClass UNITYBUILD_MAKE_UNIQUE(ADuplicatedClass)
#define aDuplicatedFunction UNITYBUILD_MAKE_UNIQUE(aDuplicatedFunction)
#endif
namespace
{
int a_duplicated_variable = 3;
class ADuplicatedClass
{
public:
ADuplicatedClass(int ){}
};
}
void aDuplicatedFunction()
{
ADuplicatedClass c(a_duplicated_variable);
}
#ifdef UNITY_BUILD
#undef a_duplicated_variable
#undef ADuplicatedClass
#undef aDuplicatedFunction
#endif
I know this solution is still bad looking. Compared with manually change each duplicated symbols, it keeps the old names the look as they were.

Correct to place an #undef directive in C++ headers/implementation files

I am writing a class (separated in header file myClass.h and implementation file myClass.cpp) which I want to use with both standard C++ and the Qt framework. Since the differences in the code are very small (and I wanted to try it out once), I decided to #define USINGQT 1 in order to toggle the small sections of code via
#if USINGQT==1
//Qt code
#else
//standard code
#endif
Now I came to the conclusion that it'd be convenient to use QStrings throughout the whole class instead of std::strings when "activating" the USINGQT switch. However, the method above would render the code extremely messy. My solution (in the header file):
#if USINGQT==1
#include <QString>
#define string QString
#else
#include <string>
#define string std::string
#endif
Now to the question:
Consider the files to look like
---myclass.h-------------------------
#ifndef MYCLASS_H
#define MYCLASS_H
#define USINGQT 1 //1=on, else off
#if USINGQT==1
#include <QString>
#define string QString
#else
#include <string>
#define string std::string
#endif
namespace mySpace {
class MyClass {
string qtOrStd;
string foo();
//etc...
};
} //namespace
#endif //MYCLASS_H
-------------------------------------
---myclass.cpp-----------------------
#include "myclass.h"
using namespace mySpace;
//implementations
string MyClass::foo() //string symbol occurs, as does the USINGQT
-------------------------------------
Where is the correct place to #undef the string and USINGQT symbols? At the end of the header file (which would then require a redefinition and "undefinition" in the implementation file as well) or just at the end of the implementation file?
I should capitalize the string macro as well, shouldn't I...? >.>
If I put the macro definitions inside the namespace I receive approx. 800 error messages with entries like "no member of mySpace::std" among others. Can you say something about that without further information? Otherwise it compiles just fine.
EDIT: I may should have told you that I want the macros to only apply to this specific header AND its implementation file. Despite the fact that I will of course go for the typedefs - in the macro case, I'd guess, I should place the #undef at the end of the implementation file. Because the macros won't be redefined because of the include guards.
Firstly you do not need to toggle USINGQT by making it equal to 1 you can simply #define USINGQT and then use #ifdef USINGQT for your if statement.
In terms of your ability to toggle which string library you use I would suggest using a typedef alongside a pre-processor if statement. This would avoid any namespace issues. An example of this is shown below.
// -------------- Some config file -------------=
#define USINGQT
// -------------- MyClass.h --------------------=
// Header guard
#ifndef MyClass
#define MyClass
// Conditional Header types
#ifdef USINGQT
// QT OPTION
typedef QString my_string;
#else
// Not QT
typedef std::string my_string;
#endif
class MyClass {
public:
my_string some_string;
MyClass()
{
my_string = "hello world";
}
};
#endif
I do not see any reason to #undef the macro. Surely you want all your code to be compiled with one state of that macro? Then you will not need to #undef it.
However, I also strongly suggest you to use typedef for your string definition. This will anyway be clearer, you will not think about capitalizing it, and you can even put it into your namespace. Use :: if you need to access global namespace:
#define USINGQT
#ifdef USINGQT
#include <QString>
#else
#include <string>
#endif
namespace mySpace {
#ifdef USINGQT
typedef ::QString string;
#else
typedef ::std::string string;
#endif
}
Also note (as shown above) that if you need just a boolean value for macro, then you don't need to make it 1 or 0, just use #ifdef/#ifndef.
After this, in your .cpp, just use mySpace::string and never bother about macroses.
You don't have to #undef macros unless another file tries to re-define it. You can't #undef a macro before you're done using it and therefore, if you #define a macro in a header and want to use it in files that include the header, then you cannot #undef it in that header.
1) Where is the correct place to #undef the string and USINGQT symbols? At the end of the header file ...
Only if you use it in that header... but you apparently do use it a file that includes the header, so no.
or just at the end of the implementation file?
Undefining a macro at the end of an implementation file is pointless, because there will be no code after the end of the file to which the macro applies anymore. Just let it stay defined.
2) I should capitalize the string macro as well, shoudln't I...? >.>
You don't have to capitalize macros, but it's a convention. That said, defining a macro by the same name as a standard class is just asking for trouble. You should use a typedef instead of a macro here in order to get meaningful error messages in case of name conflicts. And use another name like string_t or define the typedef in a namespace.
3) If I put the macro definitions inside the namespace I receive approx. 800 error messages
The errors don't come from defining the macros inside a namespace. The errors come from using the macros as-if they were part of the namespace. For example, if you say:
namespace mySpace {
#define string std::string
}
mySpace::string s;
then the string will be replaced with std::string and the typename becomes mySpace::std::string. Since you haven't defined a std namespace inside mySpace, this is wrong. What you need to understand is that namespaces don't have any effect on preprocessor macros. Which makes it harder to avoid name conflicts which is one reason why you usually want to avoid pre-processor macros.
If the USINGQT macro applies to all of your code such that it must be same for all files, you may want to not define it in a header at all, but instead pass it as an argument to the compiler. That way you can easily compile with different values without changing a file.
About your edit:
Even if you want the macro to be defined differently in another file, then undefining it at the end of the implementation has no effect, because the implementation file won't be included by the files that include the header. You should avoid a situation where you need multiple, different definitions (or lack of definitions) of macros, but if you're in such a situation, then yes, your only solution is to define it separately in each file that needs it and then undefine at the end of any header that needs it. But you're not in a such situation because you can use a type alias instead.

Force one include file to be included before another

Imagine I have two .hpp files:
#ifndef _DEF_FILE_1_
#define _DEF_FILE_1_
inline void some_function_1(){
/*do stuff*/
}
#endif
and
#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#ifdef _DEF_FILE_1_
inline void some_function_2(){
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2(){
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
My problem arises when I don't know in which order the files are included, e.g:
in the main.cpp i can have something like :
#include "file1.hpp"
#include "file2.hpp"
int main(){
some_function_2();
/*will call the function that uses some_function_1()*/
}
or
#include "file2.hpp"
#include "file1.hpp"
int main(){
some_function_2();
/*will call the function that doesn't use some_function_1()*/
}
Is there a way to make sure that as soon as both file1.hpp and file2.hpp
are included, then some_function_2() will call some_function_1()?
PS: One solution would be to include file1.hpp in file2.hpp but I can't do
that because I developp a code that may or may not depend on some library
that the end-user may or may not have.
PPS: The only other solution I can think of (even if I don't know how to
achieve this) would be to "delete" the definition of some_method_2() when
file1.hpp is included and then reinclude file2.hpp.
I believe proper solution would be to rewrite some_function_2() using SFINAE mechanism and template instead of preprocessor tricks. That way instantiation will happen in cpp file where it would be known if some_function_1() exists and order of include will not matter.
Your users should know if they have "some library" or, you should have some way of determining if that library is present. So you could do something like:
In file2.hpp
#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#ifdef _DEF_HAS_SOME_LIBRARY_
#include "file1.hpp"
inline void some_function_2(){
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2(){
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
Or if possible eliminate file1.hpp entirely, and put some_function_1() in the location of #include "file1.hpp" above.
Now main.cpp should only include file2.hpp.
// optionally #define _DEF_HAS_SOME_LIBRARY_
#include "file2.hpp"
int main(){
some_function_2();
/*will call the function that uses some_function_1()*/
}
though, a solution that avoids the preprocessor would be better in my opinion.
If you don't know whether the file exists and need to handle that, well, neither c nor c++ preprocessor handle file existence checks. This is one of the reasons behind configure tools.
You need to probe for this information beforehand, and set it before compiling. There many ways to do it. Usually a tool / script, creates some configure.h header with appropriate defines is created. E.g. containing such line #define FILE1_HPP_EXISTS 1.
Then you can always rely on presence of configure.h and it will provide information you need.
If your compiler allows it you might use the _has_include macro:
Just change you file2.hpp to:
#ifndef _DEF_FILE_2_
#define _DEF_FILE_2_
#if defined(__has_include) && __has_include("file1.hpp")
# include "file1.hpp"
inline void some_function_2() {
/*do stuff using some_function_1()*/
}
#else
inline void some_function_2() {
/*do the same stuff without using some_function_1()*/
}
#endif
#endif
But keep in mind that this is a compiler specific extension.

Variadic Macros

I came across this code that involved variadic Macros and I wanted to know what that meant
#define DECLARE_LEGACY_TYPES(...) //This all of the macro - I am not holding out on anything
Now There is this class as this
Header file: .h
namespace LG_Wrapper
{
template <LG_Thread Thread>
class EffectApplication : public ktApplication
{
public:
static EffectApplication<Thread>& GetInstance();
protected:
.....
.....
static boost::recursive_mutex mResource;
}
}
DECLARE_LEGACY_TYPES(EffectApplication); <---- What does this do ?
I wanted to know what effect the macro has ?
Update:
I have received numerous downvotes on this as this question gives of the impression that something is missing that I did not post the entire content of the macro. There is nothing more to the macro. I wish there was. This question is related to this which was closed. The macro literally just ends after (...)
#define DECLARE_LEGACY_TYPES(...)
but there isnt. That is one of the reason why I am here as I am not sure how to deal with this situation. Does this macro have not effect then ?
More Info:
This is what I have in another file
I am using the following defined in my project setting
LG_WRAPPER_EXPORTS
LG_THREAD_NAME=GAME
Following is the code
namespace LG_Wrapper
{
enum LG_Thread
{
GAME,
OTHER
};
/*
If the library itself is including this file
*/
#ifdef LG_WRAPPER_EXPORTS
#ifndef LG_THREAD_NAME
#error You must define LG_THREAD_NAME!
#endif
//Legacy types should not be used internally
#define DECLARE_LEGACY_TYPES(...)
#else // LG_WRAPPER_EXPORTS
//Legacy typenames are provided for convenience to the client
#define DECLARE_LEGACY_TYPES(ClassType) \
typedef LG_Wrapper::##ClassType##<LG_Wrapper::GAME> ClassType; \
#endif // LG_WRAPPER_EXPORTS
}
This is actually pretty common, but it depends on other code that wasn't mentioned in the other code you looked at:
#if USING_OLD_COMPILER //when using an older compiler, use this to declare legacy types
#define DECLARE_LEGACY_TYPES(...) STUFF(__VA_ARGS__)
#else //new compiler doesn't have to do anything special
#define DECLARE_LEGACY_TYPES(...)
#endif
//in older compilers we had to declare legacy types for this
//newer compilers don't need this step, so this does nothing at all in them.
DECLARE_LEGACY_TYPES(EffectApplication);
I don't actually know this macro, so I don't know it's actual purpose. But it's common to see macros without definitions for similar tricks as this.