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.
Related
What I'm trying to do is provide a library with some defaults set by #define directives in the library header. Those would determine what functions of the library code will be compiled with a given application. In case the application developer needs to add or remove library functions, it should "override" the library's defaults with new values without modifying the library. Besides modifying the library compiled code, those application header's #define values will, in turn, add or remove parts of the application code itself. This is for an embedded system, so even small memory savings are important.
Below are the 4 test files. I can't get it working if it's even possible to do this. Maybe the right question is: What's the correct order of #define / #undef inside the project files?
library.h:
#ifndef MY_LIBRARY_H
#define MY_LIBRARY_H
#include <stdio.h>
#define FUNCTION_1 true
#define FUNCTION_2 false
class Class {
public:
Class();
~Class();
#if FUNCTION_1
void Function_1(void);
#endif
#if FUNCTION_2
void Function_2(void);
#endif
};
#endif // MY_LIBRARY_H
library.cpp:
#include "library.h"
Class::Class() { /* Constructor */ };
Class::~Class() { /* Destructor */ };
#if FUNCTION_1
void Class::Function_1(void) {
printf("Hi, this is %s running ...\n\r", __func__);
}
#endif
#if FUNCTION_2
void Class::Function_2(void) {
printf("Hi, this is %s running ...\n\r", __func__);
}
#endif
tst-09.h
#ifndef TST_09_H
#define TST_09_H
#include <library.h>
#undef FUNCTION_2 // .....................................................
#define FUNCTION_2 true // THIS IS WHERE I'M TRYING TO OVERRIDE THE LIB DEFAULTS
#endif // TST_09_H
tst-09.cpp:
#include "tst-09.h"
int main(void) {
Class object;
#if FUNCTION_1
object.Function_1();
#endif
#if FUNCTION_2
object.Function_2();
#endif
}
Take advantage of the capabilities of your linker. If you want to exclude unused or unnecessary code from you binary, one way to do that is to put each function in its own source module. (Some compiler packages support Function Level Linking, where the linker can remove unreferenced functions.)
Trying to use macros the way you show in your question would need them to be defined on the command line (and the library rebuilt with any change).
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.
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.
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.
I have encountered the #define pre-processor directive before while learning C, and then also encountered it in some code I read. But apart from using it to definite substitutions for constants and to define macros, I've not really understook the special case where it is used without a "body" or token-string.
Take for example this line:
#define OCSTR(X)
Just like that! What could be the use of this or better, when is this use of #define necessary?
This is used in two cases. The first and most frequent involves
conditional compilation:
#ifndef XYZ
#define XYZ
// ...
#endif
You've surely used this yourself for include guards, but it can also be
used for things like system dependencies:
#ifdef WIN32
// Windows specific code here...
#endif
(In this case, WIN32 is more likely defined on the command line, but it
could also be defined in a "config.hpp" file.) This would normally
only involve object-like macros (without an argument list or
parentheses).
The second would be a result of conditional compilation. Something
like:
#ifdef DEBUG
#define TEST(X) text(X)
#else
#define TEST(X)
#endif
That allows writing things like:
TEST(X);
which will call the function if DEBUG is defined, and do nothing if it
isn't.
Such macro usually appears in pair and inside conditional #ifdef as:
#ifdef _DEBUG
#define OCSTR(X)
#else
#define OCSTR(X) SOME_TOKENS_HERE
#endif
Another example,
#ifdef __cplusplus
#define NAMESPACE_BEGIN(X) namespace X {
#define NAMESPACE_END }
#else
#define NAMESPACE_BEGIN(X)
#define NAMESPACE_END
#endif
One odd case that I recently dug up to answer a question turned out to be simply commentary in nature. The code in question looked like:
void CLASS functionName(){
//
//
//
}
I discovered it was just an empty #define, which the author had chosen to document that the function accessed global variables in the project:
C++ syntax: void CLASS functionName()?
So not really that different from if it said /* CLASS */, except not allowing typos like /* CLAAS */...some other small benefits perhaps (?)
I agree with every answer, but I'd like to point out a small trivial thing.
Being a C purist I've grown up with the assertion that EACH AND EVERY #define should be an expression, so, even if it's common practice using:
#define WHATEVER
and test it with
#ifdef WHATEVER
I think it's always better writing:
#define WHATEVER (1)
also #debug macros shall be expressions:
#define DEBUG (xxx) (whatever you want for debugging, value)
In this way, you are completely safe from misuse of #macros and prevents nasty problems (especially in a 10 million line C project)
This can be used when you may want to silent some function. For example in debug mode you want to print some debug statements and in production code you want to omit them:
#ifdef DEBUG
#define PRINT(X) printf("%s", X)
#else
#define PRINT(X) // <----- silently removed
#endif
Usage:
void foo ()
{
PRINT("foo() starts\n");
...
}
#define macros are simply replaced, literally, by their replacement text during preprocessing. If there is no replacement text, then ... they're replaced by nothing! So this source code:
#define FOO(x)
print(FOO(hello world));
will be preprocessed into just this:
print();
This can be useful to get rid of things you don't want, like, say, assert(). It's mainly useful in conditional situations, where under some conditions there's a non-empty body, though.
As you can see in the above responses, it can be useful when debugging your code.
#ifdef DEBUG
#define debug(msg) fputs(__FILE__ ":" (__LINE__) " - " msg, stderr)
#else
#define debug(msg)
#endif
So, when you are debugging, the function will print the line number and file name so you know if there is an error. And if you are not debugging, it will just produce no output
There are many uses for such a thing.
For example, one is for the macro to have different behavior in different builds. For example, if you want debug messages, you could have something like this:
#ifdef _DEBUG
#define DEBUG_LOG(X, ...) however_you_want_to_print_it
#else
#define DEBUG_LOG(X, ...) // nothing
#endif
Another use could be to customize your header file based on your system. This is from my mesa-implemented OpenGL header in linux:
#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__))
# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */
# define GLAPIENTRY
# else
# define GLAPIENTRY __stdcall
# endif
#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
# define GLAPIENTRY __stdcall
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
# define GLAPIENTRY
#endif /* WIN32 && !CYGWIN */
#ifndef GLAPIENTRY
#define GLAPIENTRY
#endif
And used in header declarations like:
GLAPI void GLAPIENTRY glClearIndex( GLfloat c );
GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
GLAPI void GLAPIENTRY glClear( GLbitfield mask );
...
(I removed the part for GLAPI)
So you get the picture, a macro that is used in some cases and not used in other cases could be defined to something on those cases and nothing to those other cases.
Other cases could be as follows:
If the macro doesn't take parameters, it could be just to declare some case. A famous example is to guard header files. Another example would be something like this
#define USING_SOME_LIB
and later could be used like this:
#ifdef USING_SOME_LIB
...
#else
...
#endif
Could be that the macro was used at some stage to do something (for example log), but then on release the owner decided the log is not useful anymore and simply removed the contents of the macro so it becomes empty. This is not recommended though, use the method I mentioned in the very beginning of the answer.
Finally, it could be there just for more explanation, for example you can say
#define DONT_CALL_IF_LIB_NOT_INITIALIZED
and you write functions like:
void init(void);
void do_something(int x) DONT_CALL_IF_LIB_NOT_INITIALIZED;
Although this last case is a bit absurd, but it would make sense in such a case:
#define IN
#define OUT
void function(IN char *a, OUT char *b);