namespace first {
namespace second {
class Third {
static void foo() {
std::cout << "foo\n";
}
};
}
}
void bar() {
std::cout << "bar\n";
}
#define first::second::Third::foo bar//this doesn't work
so, what's the correct way to map a nested function to another one?
Update:
a more similar situation is:
struct ReleaseVersion {
static void foo() {
std::cout << "release version\n";
}
};
struct DebugVersion {
static void foo() {
std::cout << "debug version\n";
}
};
#ifdef _DEBUG
#define ReleaseVersion::foo DebugVersion::foo
#else
#define DebugVersion::foo ReleaseVersion::foo
#endif
what I want to do is just like malloc and _malloc_dbg, when #define _CRTDBG_MAP_ALLOC, in debug mode, malloc will be mapped to _malloc_dbg, and in release mode, _malloc_dbg will be mapped to malloc
Update again
a more more similar situation is:
namespace first {
namespace second {
struct ReleaseVersion {
static void foo() {
std::cout << "release version\n";
}
};
struct DebugVersion {
static void foo(const char* file, long line) {
std::cout << "debug version\n";
}
};
}
}
#ifdef _DEBUG
#define ReleaseVersion::foo() DebugVersion::foo(__FILE__, __LINE__)
#else
#define DebugVersion::foo(file, line) ReleaseVersion::foo()
#endif
so, these 2 version of functions may have different parameters, I cannot just call one.
I know I can just do this
#ifdef _DEBUG
#define Foo() first::second::DebugVersion::foo(__FILE__, __LINE__)
#else
#define Foo() first::second::ReleaseVersion::foo()
but in this way, I must always use Foo(), even in the final release mode, it's still a macro.
I want to know if there are more flexible way to to do this.
One Solution
#ifdef _DEBUG
#define foo() foo(__FILE__, __LINE__)
#define ReleaseVersion DebugVersion
#else
#define foo(file, line) foo()
#define DebugVersion ReleaseVersion
#endif
int main() {
first::second::DebugVersion::foo(__FILE__, __LINE__);
first::second::ReleaseVersion::foo();
return 0;
}
it may be dangerous when there are another foo() or RealeaseVersion/DebugVersion in other namespaces,
but if you can make sure there won't, I think it can be an acceptable solution.
Your #define is the wrong way around:
#define bar first::second::Third::foo
means that bar will be replaced by first::second::Third::foo, which, I believe, is what you want.
This is the opposite of typedef, where things are the other way around.
I'm not exactly sure what you want, but this works:
namespace first {
namespace second {
class Third {
public: static void foo() {
std::cout << "foo\n";
}
};
}
}
#define bar first::second::Third::foo
int main()
{
bar();
}
The way malloc/free works is by a macro replacement:
#ifdef WANT_DEBUG_MALLOC
#define malloc(x) debug_malloc(x, __FILE__, __LINE__)
#define free(x) debug_free(x, __FILE__, __LINE__)
#endif
When the preprocessor sees struct foo *p = malloc(sizeof(struct foo) * 10); it will replace it with struct foo *p = debug_malloc(sizeof(struct foo) * 10, "myfile.c", 103);
However, as mentioned above, you can't really use namespaces when doing the macro replacement. You have to EITHER replace the namespace alone, or replace the function name alone. Of course, it's possible to have two macros, one to substitute the namespace, and one for substituting the function name. But it gets pretty messy pretty quickly, so best avoided, I'd say.
I would rather using inline functions
#ifdef _DEBUG
static inline void DoFoo() { DebugVersion::foo(); }
#else
static inline void DoFoo() { ReleaseVersion::foo(); }
#endif
Related
I got stuck with quite peculiar problem, and I at the moment have no idea how to solve it.
I am using the following block of macros to generate functions with similar names:
#define CONCAT_IMPLEMENTATION(arg1, arg2) arg1 ## arg2
#define CONCAT(arg1, arg2) CONCAT_IMPLEMENTATION(arg1, arg2)
#define UNIQUE_FUNCTION_NAME(index) CONCAT(f_, index)
#define GENERATE_FUNCTION() void UNIQUE_FUNCTION_NAME(__COUNTER__) ()
So code like this:
GENERATE_FUNCTION()
{
std::cout << "first function" << std::endl;
}
GENERATE_FUNCTION()
{
std::cout << "second function" << std::endl;
}
is replaced with:
void f_0 ()
{
std::cout << "first function" << std::endl;
}
void f_1 ()
{
std::cout << "second function" << std::endl;
}
Is there any way to implement a macro or a function that would call all the generated functions?
That is to say it would call functions from f_0 to f_N, where N is a current value of __COUNTER__ macro.
Something like that:
#define RUN_ALL_GENERATED_FUNCTIONS() // ??? //
int main()
{
RUN_ALL_GENERATED_FUNCTIONS();
return 0;
}
Looks rather impossible up to me. Could you give me any suggestions, please?
There is no need for macros here, just push function pointers into a vector then you can iterate through the vector calling each function in turn. One possible implementation would be:
#include <vector>
#include <functional>
#include <iostream>
struct Functions
{
static std::vector<std::function<void()>> functions;
template <typename T>
static T make_function(T f)
{
functions.push_back(f);
return f;
}
static void call()
{
for (auto& f : functions)
{
f();
}
}
};
std::vector<std::function<void()>> Functions::functions;
auto f_1 = Functions::make_function([]
{
std::cout << "first function" << std::endl;
});
auto f_2 = Functions::make_function([]
{
std::cout << "second function" << std::endl;
});
int main()
{
f_1();
f_2();
Functions::call();
}
If you really need to you could still wrap Functions::make_function into a macro.
There is no magic in preprocessor. To overload, you have to enumerate all possible cases anyway.
#define RUN_ALL_GENERATED_FUNCTIONS_1() UNIQUE_FUNCTION_NAME(0)();
#define RUN_ALL_GENERATED_FUNCTIONS_2() RUN_ALL_GENERATED_FUNCTIONS_1()UNIQUE_FUNCTION_NAME(1)();
#define RUN_ALL_GENERATED_FUNCTIONS_3() RUN_ALL_GENERATED_FUNCTIONS_2()UNIQUE_FUNCTION_NAME(2)();
#define RUN_ALL_GENERATED_FUNCTIONS_4() RUN_ALL_GENERATED_FUNCTIONS_3()UNIQUE_FUNCTION_NAME(3)();
#define RUN_ALL_GENERATED_FUNCTIONS() do{ CONCAT(RUN_ALL_GENERATED_FUNCTIONS_, __COUNTER__)() }while(0)
int main() {
RUN_ALL_GENERATED_FUNCTIONS();
// do{ f_0();f_1(); }while(0);
}
Note that __COUNTER__ is non-portable, you might as well use descriptive function names (and readability of the code is important and __func__ will expand to something meaningful) and put pointers to these functions into a custom linker section with __attribute__, then iterate over that section to execute all functions. It's typical to do that - within testing frameworks and in kernel, with .init and .fini etc. sections.
I hava a macro to call static function for each args.
For example:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
My question is that I need to use foo with variable number of arguments, is it possible to use __VA_ARGS__ ?
Like the line below:
#define FOO(...) __VA_ARGS__::do() ?
Thanks
Macro expansion does not work like argument pack expansion with variadic templates. What you have will expand to:
X,Y::do();
And not to
X::do(); Y::do();
As you hoped. But in C++11 you could use variadic templates. For instance, you could do what you want this way:
#include <iostream>
struct X { static void foo() { std::cout << "X::foo()" << std::endl; }; };
struct Y { static void foo() { std::cout << "Y::foo()" << std::endl; }; };
struct Z { static void foo() { std::cout << "Z::foo()" << std::endl; }; };
int main()
{
do_foo<X, Y, Z>();
}
All you need is this (relatively simple) machinery:
namespace detail
{
template<typename... Ts>
struct do_foo;
template<typename T, typename... Ts>
struct do_foo<T, Ts...>
{
static void call()
{
T::foo();
do_foo<Ts...>::call();
}
};
template<typename T>
struct do_foo<T>
{
static void call()
{
T::foo();
}
};
}
template<typename... Ts>
void do_foo()
{
detail::do_foo<Ts...>::call();
}
Here is a live example.
You cannot do this directly, __VA_ARGS__ is always treated as a single unit consisting of all the parameters separated by a comma. The preprocessor provides no built-in way to find the number of parameters, to separate them or to loop over them.
This answer to a similar question shows the basic solution using the preprocessor: Find out how many items there are in your argument list and pass it on to a macro that does take this exact amount of parameters.
I’d recommend not to do this but instead use Andy Prowls C++11 solution or even restructure your code so you don’t need this at all.
Actually you can partially workaround this.
You can directly and freely extract every member of neither __VA_ARGS__ nor variadic templates of C++11. But you can have the very first element. For example let's say we have a macro named OUT(...) and we want to produce std::cout << A << B << C ... where A, B, C are the variadic arguments of macro. Try this:
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define BAR(...) GET_3_OF(__VA_ARGS__)
int main()
{
std::cout << BAR(1,2,3,4,5);
return 0;
}
This is of course not the solution you are after. But you can augment the number of GET_N_OF to do what you want. Note that SEPERATOR is << so that we MACRO can write 1 << 2 << 3 and so on.
Now, we have a problem in this code. Please change BAR(1,2,3,4,5) with BAR(1) You will see that it is giving an error. This is because it was expecting 3 arguments, although it is not problem to have more arguments (because it is variadic) we are having extra SEPERATOR. So in order to solve this problem instead of using BAR(...) use GET_N_OF(...) (since you know the number of arguments):
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define GET_4_OF(element1, ...) element1 SEPERATOR GET_3_OF(__VA_ARGS__)
#define GET_5_OF(element1, ...) element1 SEPERATOR GET_4_OF(__VA_ARGS__)
int main()
{
std::cout << GET_5_OF(1,2,3,4,5);
std::cout << GET_1_OF(1);
return 0;
}
Please note that if you do not know what you are doing do not use MACROs at all! My response was just to share fun MACRO code that may be beneficial for you. I always discourage the usage of MACROs until they are remarkably necessary.
Let's say we have a C++ library with a class like this:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
Typical usage of this class would include stack allocation:
TheClass object;
object.magic();
We need to create a C wrapper for this class. The most common approach looks like this:
struct TheClassH;
extern "C" struct TheClassH* create_the_class() {
return reinterpret_cast<struct TheClassH*>(new TheClass());
}
extern "C" void the_class_magic(struct TheClassH* self) {
reinterpret_cast<TheClass*>(self)->magic();
}
However, it requires heap allocation, which is clearly not desired for such a small class.
I'm searching for an approach to allow stack allocation of this class from C code. Here is what I can think of:
struct TheClassW {
char space[SIZEOF_THECLASS];
}
void create_the_class(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
new(cpp_self) TheClass();
}
void the_class_magic(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
cpp_self->magic();
}
It's hard to put real content of the class in the struct's fields. We can't just include C++ header because C wouldn't understand it, so it would require us to write compatible C headers. And this is not always possible. I think C libraries don't really need to care about content of structs.
Usage of this wrapper would look like this:
TheClassW object;
create_the_class(&object);
the_class_magic(&object);
Questions:
Does this approach have any dangers or drawbacks?
Is there an alternative approach?
Are there any existing wrappers that use this approach?
You can use placement new in combination of alloca to create an object on the stack. For Windows there is _malloca. The importance here is that alloca, and malloca align memory for you accordingly and wrapping the sizeof operator exposes the size of your class portably. Be aware though that in C code nothing happens when your variable goes out of scope. Especially not the destruction of your object.
main.c
#include "the_class.h"
#include <alloca.h>
int main() {
void *me = alloca(sizeof_the_class());
create_the_class(me, 20);
if (me == NULL) {
return -1;
}
// be aware return early is dangerous do
the_class_magic(me);
int error = 0;
if (error) {
goto fail;
}
fail:
destroy_the_class(me);
}
the_class.h
#ifndef THE_CLASS_H
#define THE_CLASS_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
class TheClass {
public:
TheClass(int me) : me_(me) {}
void magic();
int me_;
};
extern "C" {
#endif
size_t sizeof_the_class();
void *create_the_class(void* self, int arg);
void the_class_magic(void* self);
void destroy_the_class(void* self);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif // THE_CLASS_H
the_class.cc
#include "the_class.h"
#include <iostream>
#include <new>
void TheClass::magic() {
std::cout << me_ << std::endl;
}
extern "C" {
size_t sizeof_the_class() {
return sizeof(TheClass);
}
void* create_the_class(void* self, int arg) {
TheClass* ptr = new(self) TheClass(arg);
return ptr;
}
void the_class_magic(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->magic();
}
void destroy_the_class(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->~TheClass();
}
}
edit:
you can create a wrapper macro to avoid separation of creation and initialization. you can't use do { } while(0) style macros because it will limit the scope of the variable. There is other ways around this but this is highly dependent on how you deal with errors in the code base. A proof of concept is below:
#define CREATE_THE_CLASS(NAME, VAL, ERR) \
void *NAME = alloca(sizeof_the_class()); \
if (NAME == NULL) goto ERR; \
// example usage:
CREATE_THE_CLASS(me, 20, fail);
This expands in gcc to:
void *me = __builtin_alloca (sizeof_the_class()); if (me == __null) goto fail; create_the_class(me, (20));;
There are alignment dangers. But maybe not on your platform. Fixing this may require platform specific code, or C/C++ interop that is not standardized.
Design wise, have two types. In C, it is struct TheClass;. In C++, struct TheClass has a body.
Make a struct TheClassBuff{char buff[SIZEOF_THECLASS];};
TheClass* create_the_class(struct TheClassBuff* self) {
return new(self) TheClass();
}
void the_class_magic(struct TheClass* self) {
self->magic();
}
void the_class_destroy(struct TheClass* self) {
self->~TheClass();
}
C is supposed to make the buff, then create a handle from it and interact using it. Now usually that isn't required as reinterpreting pointer to theclassbuff will work, but I think that is undefined behaviour technically.
Here is another approach, which may or may not be acceptable, depending on the application specifics. Here we basically hide the existence of TheClass instance from C code and encapsulate every usage scenario of TheClass in a wrapper function. This will become unmanageable if the number of such scenarios is too large, but otherwise may be an option.
The C wrapper:
extern "C" void do_magic()
{
TheClass object;
object.magic();
}
The wrapper is trivially called from C.
Update 2/17/2016:
Since you want a solution with a stateful TheClass object, you can follow the basic idea of your original approach, which was further improved in another answer. Here is yet another spin on that approach, where the size of the memory placeholder, provided by the C code, is checked to ensure it is sufficiently large to hold an instance of TheClass.
I would say that the value of having a stack-allocated TheClass instance is questionable here, and it is a judgement call depending on the application specifics, e.g. performance. You still have to call the de-allocation function, which in turn calls the destructor, manually, since it is possible that TheClass allocates resources that have to be released.
However, if having a stack-allocated TheClass is important, here is another sketch.
The C++ code to be wrapped, along with the wrapper:
#include <new>
#include <cstring>
#include <cstdio>
using namespace std;
class TheClass {
public:
TheClass(int i) : x(i) { }
// cout doesn't work, had to use puts()
~TheClass() { puts("Deleting TheClass!"); }
int magic( const char * s, int i ) { return 123 * x + strlen(s) + i; }
private:
int x;
};
extern "C" TheClass * create_the_class( TheClass * self, size_t len )
{
// Ensure the memory buffer is large enough.
if (len < sizeof(TheClass)) return NULL;
return new(self) TheClass( 3 );
}
extern "C" int do_magic( TheClass * self, int l )
{
return self->magic( "abc", l );
}
extern "C" void delete_the_class( TheClass * self )
{
self->~TheClass(); // 'delete self;' won't work here
}
The C code:
#include <stdio.h>
#define THE_CLASS_SIZE 10
/*
TheClass here is a different type than TheClass in the C++ code,
so it can be called anything else.
*/
typedef struct TheClass { char buf[THE_CLASS_SIZE]; } TheClass;
int do_magic(TheClass *, int);
TheClass * create_the_class(TheClass *, size_t);
void delete_the_class(TheClass * );
int main()
{
TheClass mem; /* Just a placeholder in memory for the C++ TheClass. */
TheClass * c = create_the_class( &mem, sizeof(TheClass) );
if (!c) /* Need to make sure the placeholder is large enough. */
{
puts("Failed to create TheClass, exiting.");
return 1;
}
printf("The magic result is %d\n", do_magic( c, 232 ));
delete_the_class( c );
return 0;
}
This is just a contrived example for illustration purposes. Hopefully it is helpful. There may be subtle problems with this approach, so testing on your specific platform is highly important.
A few additional notes:
THE_CLASS_SIZE in the C code is just the size of a memory buffer in which
a C++'s TheClass instance is to be allocated; we are fine as long as
the size of the buffer is sufficient to hold a C++'s TheClass
Because TheClass in C is just a memory placeholder, we might just as
well use a void *, possibly typedef'd, as the parameter type in the
wrapper functions instead of TheClass. We would reinterpret_cast
it in the wrapper code, which would actually make the code clearer:
pointers to C's TheClass are essentially reinterpreted as C++'s TheClass anyway.
There is nothing to prevent C code from passing a TheClass* to the
wrapper functions that doesn't actually point to a C++'s TheClass
instance. One way to solve this is to store pointers to properly
initialized C++ TheClass instances in some sort of a data structure
in the C++ code and return to the C code handles that can be used to
look up these instances.
To use couts in the C++ wrapper we need to link with
the C++ standard lib when building an executable. For example, if
the C code is compiled into main.o and C++ into lib.o, then on
Linux or Mac we'd do gcc -o junk main.o lib.o -lstdc++.
It worth to keep each piece of knowledge in a single place, so I would suggest to make a class code "partially readable" for C. One may employ rather simple set of macro definitions to enable it to be done in short and standard words. Also, a macro may be used to invoke constructor and destructor at the beginning and the end of stack-allocated object's life.
Say, we include the following universal file first into both C and C++ code:
#include <stddef.h>
#include <alloca.h>
#define METHOD_EXPORT(c,n) (*c##_##n)
#define CTOR_EXPORT(c) void (c##_construct)(c* thisPtr)
#define DTOR_EXPORT(c) void (c##_destruct)(c* thisPtr)
#ifdef __cplusplus
#define CL_STRUCT_EXPORT(c)
#define CL_METHOD_EXPORT(c,n) n
#define CL_CTOR_EXPORT(c) c()
#define CL_DTOR_EXPORT(c) ~c()
#define OPT_THIS
#else
#define CL_METHOD_EXPORT METHOD_EXPORT
#define CL_CTOR_EXPORT CTOR_EXPORT
#define CL_DTOR_EXPORT DTOR_EXPORT
#define OPT_THIS void* thisPtr,
#define CL_STRUCT_EXPORT(c) typedef struct c c;\
size_t c##_sizeof();
#endif
/* To be put into a C++ implementation coce */
#define EXPORT_SIZEOF_IMPL(c) extern "C" size_t c##_sizeof() {return sizeof(c);}
#define CTOR_ALIAS_IMPL(c) extern "C" CTOR_EXPORT(c) {new(thisPtr) c();}
#define DTOR_ALIAS_IMPL(c) extern "C" DTOR_EXPORT(c) {thisPtr->~c();}
#define METHOD_ALIAS_IMPL(c,n,res_type,args) \
res_type METHOD_EXPORT(c,n) args = \
call_method(&c::n)
#ifdef __cplusplus
template<class T, class M, M m, typename R, typename... A> R call_method(
T* currPtr, A... args)
{
return (currPtr->*m)(args...);
}
#endif
#define OBJECT_SCOPE(t, v, body) {t* v = alloca(t##_sizeof()); t##_construct(v); body; t##_destruct(v);}
Now we can declare our class (the header is useful both in C and C++, too)
/* A class declaration example */
#ifdef __cplusplus
class myClass {
private:
int y;
public:
#endif
/* Also visible in C */
CL_STRUCT_EXPORT(myClass)
void CL_METHOD_EXPORT(myClass,magic) (OPT_THIS int c);
CL_CTOR_EXPORT(myClass);
CL_DTOR_EXPORT(myClass);
/* End of also visible in C */
#ifdef __cplusplus
};
#endif
Here is the class implementation in C++:
myClass::myClass() {std::cout << "myClass constructed" << std::endl;}
CTOR_ALIAS_IMPL(myClass);
myClass::~myClass() {std::cout << "myClass destructed" << std::endl;}
DTOR_ALIAS_IMPL(myClass);
void myClass::magic(int n) {std::cout << "myClass::magic called with " << n << std::endl;}
typedef void (myClass::* myClass_magic_t) (int);
void (*myClass_magic) (myClass* ptr, int i) =
call_method<myClass,myClass_magic_t,&myClass::magic,void,int>;
and this is a using C code example
main () {
OBJECT_SCOPE(myClass, v, {
myClass_magic(v,178);
})
}
It's short and working! (here's the output)
myClass constructed
myClass::magic called with 178
myClass destructed
Note that a variadic template is used and this requires c++11. However, if you don't want to use it, a number of fixed-size templates ay be used instead.
Here's how one might do it safely and portably.
// C++ code
extern "C" {
typedef void callback(void* obj, void* cdata);
void withObject(callback* cb, void* data) {
TheClass theObject;
cb(&theObject, data);
}
}
// C code:
struct work { ... };
void myCb (void* object, void* data) {
struct work* work = data;
// do whatever
}
// elsewhere
struct work work;
// initialize work
withObject(myCb, &work);
What I did in alike situation is something like:
(I omit static_cast, extern "C")
class.h:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
class.cpp
<actual implementation>
class_c_wrapper.h
void* create_class_instance(){
TheClass instance = new TheClass();
}
void delete_class_instance(void* instance){
delete (TheClass*)instance;
}
void magic(void* instance){
((TheClass*)instance).magic();
}
Now, you stated that you need stack allocation. For this I can suggest rarely used option of new: placement new. So you'd pass additional parameter in create_class_instance() that is pointing to an allocated buffer enough to store class instance, but on stack.
This is how I would solve the issue (basic idea is to let interprete C and C++ the same memory and names differently):
TheClass.h:
#ifndef THECLASS_H_
#define THECLASS_H_
#include <stddef.h>
#define SIZEOF_THE_CLASS 4
#ifdef __cplusplus
class TheClass
{
public:
TheClass();
~TheClass();
void magic();
private:
friend void createTheClass(TheClass* self);
void* operator new(size_t, TheClass*) throw ();
int x;
};
#else
typedef struct TheClass {char _[SIZEOF_THE_CLASS];} TheClass;
void create_the_class(struct TheClass* self);
void the_class_magic(struct TheClass* self);
void destroy_the_class(struct TheClass* self);
#endif
#endif /* THECLASS_H_ */
TheClass.cpp:
TheClass::TheClass()
: x(0)
{
}
void* TheClass::operator new(size_t, TheClass* self) throw ()
{
return self;
}
TheClass::~TheClass()
{
}
void TheClass::magic()
{
}
template < bool > struct CompileTimeCheck;
template < > struct CompileTimeCheck < true >
{
typedef bool Result;
};
typedef CompileTimeCheck< SIZEOF_THE_CLASS == sizeof(TheClass) >::Result SizeCheck;
// or use static_assert, if available!
inline void createTheClass(TheClass* self)
{
new (self) TheClass();
}
extern "C"
{
void create_the_class(TheClass* self)
{
createTheClass(self);
}
void the_class_magic(TheClass* self)
{
self->magic();
}
void destroy_the_class(TheClass* self)
{
self->~TheClass();
}
}
The createTheClass function is for friendship only - I wanted to avoid the C wrapper functions to be publicly visible within C++. I caught up the array variant of the TO, because I consider this better readable than the alloca approach. Tested with:
main.c:
#include "TheClass.h"
int main(int argc, char*argv[])
{
struct TheClass c;
create_the_class(&c);
the_class_magic(&c);
destroy_the_class(&c);
}
I hava a macro to call static function for each args.
For example:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
My question is that I need to use foo with variable number of arguments, is it possible to use __VA_ARGS__ ?
Like the line below:
#define FOO(...) __VA_ARGS__::do() ?
Thanks
Macro expansion does not work like argument pack expansion with variadic templates. What you have will expand to:
X,Y::do();
And not to
X::do(); Y::do();
As you hoped. But in C++11 you could use variadic templates. For instance, you could do what you want this way:
#include <iostream>
struct X { static void foo() { std::cout << "X::foo()" << std::endl; }; };
struct Y { static void foo() { std::cout << "Y::foo()" << std::endl; }; };
struct Z { static void foo() { std::cout << "Z::foo()" << std::endl; }; };
int main()
{
do_foo<X, Y, Z>();
}
All you need is this (relatively simple) machinery:
namespace detail
{
template<typename... Ts>
struct do_foo;
template<typename T, typename... Ts>
struct do_foo<T, Ts...>
{
static void call()
{
T::foo();
do_foo<Ts...>::call();
}
};
template<typename T>
struct do_foo<T>
{
static void call()
{
T::foo();
}
};
}
template<typename... Ts>
void do_foo()
{
detail::do_foo<Ts...>::call();
}
Here is a live example.
You cannot do this directly, __VA_ARGS__ is always treated as a single unit consisting of all the parameters separated by a comma. The preprocessor provides no built-in way to find the number of parameters, to separate them or to loop over them.
This answer to a similar question shows the basic solution using the preprocessor: Find out how many items there are in your argument list and pass it on to a macro that does take this exact amount of parameters.
I’d recommend not to do this but instead use Andy Prowls C++11 solution or even restructure your code so you don’t need this at all.
Actually you can partially workaround this.
You can directly and freely extract every member of neither __VA_ARGS__ nor variadic templates of C++11. But you can have the very first element. For example let's say we have a macro named OUT(...) and we want to produce std::cout << A << B << C ... where A, B, C are the variadic arguments of macro. Try this:
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define BAR(...) GET_3_OF(__VA_ARGS__)
int main()
{
std::cout << BAR(1,2,3,4,5);
return 0;
}
This is of course not the solution you are after. But you can augment the number of GET_N_OF to do what you want. Note that SEPERATOR is << so that we MACRO can write 1 << 2 << 3 and so on.
Now, we have a problem in this code. Please change BAR(1,2,3,4,5) with BAR(1) You will see that it is giving an error. This is because it was expecting 3 arguments, although it is not problem to have more arguments (because it is variadic) we are having extra SEPERATOR. So in order to solve this problem instead of using BAR(...) use GET_N_OF(...) (since you know the number of arguments):
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define GET_4_OF(element1, ...) element1 SEPERATOR GET_3_OF(__VA_ARGS__)
#define GET_5_OF(element1, ...) element1 SEPERATOR GET_4_OF(__VA_ARGS__)
int main()
{
std::cout << GET_5_OF(1,2,3,4,5);
std::cout << GET_1_OF(1);
return 0;
}
Please note that if you do not know what you are doing do not use MACROs at all! My response was just to share fun MACRO code that may be beneficial for you. I always discourage the usage of MACROs until they are remarkably necessary.
My current implementation, simplified:
#include <string>
#include <memory>
class Log
{
public:
~Log() {
// closing file-descriptors, etc...
}
static void LogMsg( const std::string& msg )
{
static std::unique_ptr<Log> g_singleton;
if ( !g_singleton.get() )
g_singleton.reset( new Log );
g_singleton->logMsg( msg );
}
private:
Log() { }
void logMsg( const std::string& msg ) {
// do work
}
};
In general, I am satisfied with this implementation because:
lazy instantiation means I don't pay unless I use it
use of unique_ptr means automatic cleanup so valgrind is happy
relatively simple, easy-to-understand implementation
However, the negatives are:
singletons aren't conducive to unit-testing
dissonance in the back of my mind for introducing a pseudo-global (a bit of a code smell)
So here are my questions directed towards those developers who are successful in exorcising all singletons from their C++ code:
What kind of non-Singleton implementation do you use for application-wide logging?
Is the interface as simple and accessible as a Log::LogMsg() call above?
I want to avoid passing a Log instance all over my code, if at all possible - note: I am asking because, I, too, want to exorcise all Singletons from my code if there is a good, reasonable alternative.
First: the use of std::unique_ptr is unnecessary:
void Log::LogMsg(std::string const& s) {
static Log L;
L.log(s);
}
Produces exactly the same lazy initialization and cleanup semantics without introducing all the syntax noise (and redundant test).
Now that is out of the way...
Your class is extremely simple. You might want to build a slightly more complicated version, typical requirements for log messages are:
timestamp
level
file
line
function
process name / thread id (if relevant)
on top of the message itself.
As such, it is perfectly conceivable to have several objects with different parameters:
// LogSink is a backend consuming preformatted messages
// there can be several different instances depending on where
// to send the data
class Logger {
public:
Logger(Level l, LogSink& ls);
void operator()(std::string const& message,
char const* function,
char const* file,
int line);
private:
Level _level;
LogSink& _sink;
};
And you usually wrap the access inside a macro for convenience:
#define LOG(Logger_, Message_) \
Logger_( \
static_cast<std::ostringstream&>( \
std::ostringstream().flush() << Message_ \
).str(), \
__FUNCTION__, \
__FILE__, \
__LINE__ \
);
Now, we can create a simple verbose logger:
Logger& Debug() {
static Logger logger(Level::Debug, Console);
return logger;
}
#ifdef NDEBUG
# define LOG_DEBUG(_) do {} while(0)
#else
# define LOG_DEBUG(Message_) LOG(Debug(), Message_)
#endif
And use it conveniently:
int foo(int a, int b) {
int result = a + b;
LOG_DEBUG("a = " << a << ", b = " << b << " --> result = " << result)
return result;
}
The purpose of this rant ? Not all that is a global need be unique. The uniqueness of Singletons is generally useless.
Note: if the bit of magic involving std::ostringstream scares you, this is normal, see this question
I'd go with the simple, pragmatic solution:
you want a solution that is globally accessible. For the most part, I try to avoid globals, but for loggers, let's face it, it's usually impractical.
So, we do need something to be globally accessible.
But, we don't want the additional "there can be only one" restriction that a singleton confers. Some of your unit tests might want to instantiate their own private logger. Others might want to replace the global logger, perhaps.
So make it a global. A plain old simple global variable.
This still doesn't fully solve the problem with unit testing, admittedly, but we can't always have everything we want. ;)
As pointed out in the comment, you need to consider the initialization order for globals, which, in C++, is partly undefined.
In my code, that is generally not a problem, because I rarely have more than one global (my logger), and I stick rigidly to a rule of never allowing globals to depend on each others.
But it's something you have to consider, at least.
I really like the following interface since it uses streaming. Of course you can add channels, time and thread information to it. Another possible extension is to use the __FILE__ and __LINE__ macros and add it as parameters to the constructor. You could even add a variadic template function if you do not like the stream syntax. If you want to store some configuration you could add them to some static variables.
#include <iostream>
#include <sstream>
class LogLine {
public:
LogLine(std::ostream& out = std::cout) : m_Out(out) {}
~LogLine() {
m_Stream << "\n";
m_Out << m_Stream.rdbuf();
m_Out.flush();
}
template <class T>
LogLine& operator<<(const T& thing) { m_Stream << thing; return *this; }
private:
std::stringstream m_Stream;
std::ostream& m_Out;
//static LogFilter...
};
int main(int argc, char *argv[])
{
LogLine() << "LogLine " << 4 << " the win....";
return 0;
}
// file ILoggerImpl.h
struct ILoggerImpl
{
virtual ~ILoggerImpl() {}
virtual void Info(std::string s) = 0;
virtual void Warning(std::string s) = 0;
virtual void Error(std::string s) = 0;
};
// file logger.h //
#include "ILoggerImpl.h"
class CLogger: public ILoggerImpl
{
public:
CLogger():log(NULL) { }
//interface
void Info(std::string s) {if (NULL==log) return; log->Info(s); }
void Warning(std::string s) {if (NULL==log) return; log->Warning(s); }
void Error(std::string s) {if (NULL==log) return; log->Error(s); }
//
void BindImplementation(ILoggerImpl &ilog) { log = &ilog; }
void UnbindImplementation(){ log = NULL; }
private:
ILoggerImpl *log;
};
// file: loggers.h //
#include "logger.h"
extern CLogger Log1;
extern CLogger Log2;
extern CLogger Log3;
extern CLogger Log4;
extern CLogger LogB;
/// file: A.h //
#include "loggers.h"
class A
{
public:
void foo()
{
Log1.Info("asdhoj");
Log2.Info("asdhoj");
Log3.Info("asdhoj");
}
private:
};
/// file: B.h //
#include "loggers.h"
class B
{
public:
void bar()
{
Log1.Info("asdhoj");
Log2.Info("asdhoj");
LogB.Info("asdhoj");
a.foo();
}
private:
A a;
};
////// file: main.cpp ////////////////
#include "loggers.h"
#include "A.h"
#include "B.h"
#include "fileloger.h"
#include "xmllogger.h"
CLogger Log1;
CLogger Log2;
CLogger Log3;
CLogger Log4;
CLogger LogB;
// client code
int main()
{
std::unique_ptr<ILoggerImpl> filelog1(new CFileLogger("C:\\log1.txt"));
Log1.BindImplementation(*filelog1.get());
std::unique_ptr<ILoggerImpl> xmllogger2(new CXmlLogger("C:\\log2.xml"));
Log2.BindImplementation(*xmllogger2.get());
std::unique_ptr<ILoggerImpl> xmllogger3(new CXmlLogger("C:\\logB.xml"));
LogB.BindImplementation(*xmllogger3.get());
B b;
b.bar();
return 0;
};
// testing code
///////file: test.cpp /////////////////////////////////
#include "loggers.h"
CLogger Log1;
CLogger Log2;
CLogger Log3;
CLogger Log4;
int main()
{
run_all_tests();
}
///////file: test_a.cpp /////////////////////////////////
#include "A.h"
TEST(test1)
{
A a;
}
TEST(test2, A_logs_to_Log1_when_foo_is_called())
{
A a;
std::unique_ptr<ILoggerImpl> filelog1Mock(new CFileLoggerMock("C:\\log1.txt"));
Log1.BindImplementation(*filelog1.get());
EXPECT_CALL(filelog1Mock Info...);
a.foo();
Log1.UnbindImplementation();
}