I'm trying to create a proxy class for delayed load of a shared library.
One of the API function of the library is:
int AttachCWnd(CWnd* pControl);
So, I created a macro to easily declare and route calls from the proxy class to the library:
class CLibProxy {
public:
typedef int (*tAttachCWnd)(CWnd*);
tAttachCWnd m_fAttachCWnd;
};
#define DECL_ROUTE(name, ret, args) \
ret CLibProxy::name args \
{ \
if (m_hDLL) \
return m_f##name (args); \
return ret(); \
}
DECL_ROUTE(AttachCWnd, int, (CWnd* pControl));
But compilation fails on VS2010:
error C2275: 'CWnd' : illegal use of this type as an expression
Can anyone explain why?
Well, obvious mistake. Calling m_fAttachCWnd should not include the type declaration, but only the arguments:
return m_fAttachCWnd (CWnd* pControl);
should become
return m_fAttachCWnd (pControl);
Thanks #chris.
Related
I am trying to define a macro that behaves differently when used in a function context vs a class body or namespace. The purpose of this is to selectively include BOOST_LOG_NAMED_SCOPE (or achieve equivalent behavior) in the LOG_CONTEXT macro referenced here.
I have tried two approaches:
Using BOOST_PP_IF along with a preprocessor function to test whether e.g. __func__ is non-empty.
The output of g++ -E on a basic source file still contains the literal text __func__ in both global and function scope so that probably rules out any approach targeting the preprocessing phase.
Using something like sizeof(__func__) to select a specialized template that implements behavior similar to BOOST_LOG_NAMED_SCOPE. I can re-use the boost::log::attributes::named_scope::sentry object from boost log, but I'm stuck trying to figure out how to instantiate it conditionally in a function context, or at least in a way that works everywhere. The following construction seems to work fine in class definitions and functions, but fails with a "multiple definition" error when linking together multiple translation units that include a header with a LOG_CONTEXT at global or namespace scope:
#include <boost/log/attributes/named_scope.hpp>
#include <type_traits>
namespace logging {
namespace attrs = boost::log::attributes;
namespace detail {
// Default no-op on construction when not in a function.
template<typename ScopeTraits, bool InFunction>
class named_scope_helper
{};
// Specialization when in a function.
template<typename ScopeTraits>
class named_scope_helper<ScopeTraits, true> :
public attrs::named_scope::sentry
{
public:
named_scope_helper() BOOST_NOEXCEPT
: sentry(
ScopeTraits::scope_name(),
ScopeTraits::filename(),
ScopeTraits::lineno() )
{}
};
template<size_t N>
class not_1 : public std::true_type
{};
template<>
class not_1<1> : public std::false_type
{};
#define LOGGING_LOG_IN_FUNCTION \
::logging::detail::not_1<sizeof(__func__)>::value
} // namespace detail
} // namespace logging
// scope_name_t/filename_t are required since attrs::named_scope::sentry
// requires string literals.
#define LOG_CONTEXT( name_ ) \
struct __logging_log_scope_traits__ \
{ \
using scope_name_t = const char (&)[sizeof(name_)]; \
static scope_name_t scope_name() \
{ return name_; } \
using filename_t = const char (&)[sizeof(__FILE__)]; \
static filename_t filename() \
{ return __FILE__; } \
static size_t lineno() \
{ return __LINE__; } \
}; \
::logging::detail::named_scope_helper< \
__logging_log_scope_traits__, LOGGING_LOG_IN_FUNCTION> \
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_log_named_scope_sentry_);
My normal workaround for this would be to use static in the declaration of the _log_named_scope_sentry_, but that defeats the purpose.
I could add another macro that is strictly for non-execution contexts, but wanted to investigate this approach first since it would be an interesting trick to have. How can I proceed on one of the two approaches I've started above, or is there another option I haven't considered?
A general solution would be preferred but I'm only really concerned with GCC and Clang.
I'm trying to do something like that:
#define VERIFY_EXPECTATIONS \
BOOST_MPL_ASSERT((expectation1)); \
BOOST_MPL_ASSERT((expectation2)); \
BOOST_MPL_ASSERT((expectation3))
and when writing VERIFY_EXPECTATIONS; in line, say 42, I get an error about a conflicting declaration of mpl_assertion_in_line_42.
I understand what is happening (BOOST_MPL_ASSERT uses an identifier that depends on the line where the macro is invoked) but my question is: is there a known workaround to do this kind of things?
Edit:
More precisely, the expectations look like that:
#define TEST_SOME_SET_OF_PREDICATES(Arg) \
BOOST_MPL_ASSERT ((some_predicate<Arg>)); \
BOOST_MPL_ASSERT_NOT((some_other_predicate<Arg>))
TEST_SOME_SET_OF_PREDICATES(some_type);
TEST_SOME_SET_OF_PREDICATES(some_other_type);
I have implemented the predicates and I want to test them with several types.
Note:
I'm not very interested in the following:
template <typename Arg>
struct compound_predicate : boost::mpl::and_<
some_predicate<Arg>,
boost::mpl::not_<some_other_predicate<Arg> >
> {};
BOOST_MPL_ASSERT((compound_predicate<some_type>));
BOOST_MPL_ASSERT((compound_predicate<some_other_type>));
because when an assertion fails, we don't know which of the expectations was wrong.
The solution suggested by Praetorian would be the following:
template <typename Arg>
struct expectations {
BOOST_MPL_ASSERT ((some_predicate<Arg>));
BOOST_MPL_ASSERT_NOT((some_other_predicate<Arg>));
};
and then instantiate expectations with some_type and some_other_type. I would have to implement a macro that declares an object of type expectations<Arg> with a different identifier at each call. It looks a little bit like reimplementing (some part of) static assertions.
Any other ideas?
I'm using Visual Studio 2010 for win32 application development. Try to compile one existing c++ source file, which was already compiled in GCC (Linux).
#define DEFINE_PORT( parentClass, portClass, name, dataMember, callbacks,... )
do
{
dataMember = new portClass<parentClass>( *this, callbacks );
err = addProvidesPort( name, dataMember );
}
while(0)
Here I'm invoking this function as:
DEFINE_PORT( Service_impl,
ECPDataStoreProvidesPort,
ECP_DATA_STORE,
pECPDataStorePP,
&Service_impl::GetDataVersion,
&Service_impl::SetDataVersion,
&Service_impl::LoadData,
&Service_impl::StoreData,
&ECPService_impl::EnableBlobOperations,
&ECPService_impl::GetCurrentPersonalityIndex,
&ECPService_impl::SwapPersonalities,
&ECPService_impl::UpdateDataStoreBlob,
&ECPService_impl::ExtractDataStoreBlob,
&ECPService_impl::GetConstantPersonalityPtr );
ECPDataStoreProvidesPort class has constructor defined with 10 no of arguments.
Here VS compiler is not considering the variable length arguments and producing error as portclass has no overloaded constructor defined for two aruguments.
May anyone please help me out on this? What can be cause and How to handle this error?
In your expansion, callbacks is set to &Service_impl::GetDataVersion, and the rest of the arguments (the ...) are ignored.
The ... arguments should be referred to as __VA_ARGS__ in the macro body.
#define DEFINE_PORT( parentClass, portClass, name, dataMember, ... )\
do \
{ \
dataMember = new portClass<parentClass>( *this, __VA_ARGS__ );\
err = addProvidesPort( name, dataMember ); \
} \
while(0)
The following works just-fine in MSVC2008 and MSVC2010:
class Foo {
public:
static void FuncA(void) {
FuncB(); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
static void FuncB(void);
};
Yes, this is kinda weird: FuncA() calls FuncB(), even though (at that point) FuncB() is not-yet-declared. However, MSVC2008 and MSVC2010 thinks this is fine.
Apparently, gcc doesn't think this is fine -- FuncB was not declared in this scope.
ISSUE: I have a bunch of these, and it would be a "pain" to declare them, and later define them. Further, it would be hard to "order" them properly so each only calls functions after those were declared. But, I'm guessing I need to declare-first-then-define-later?
Are the rules different for whether these functions are template-or-not, or defined within a template-class or not?
Specifically, I've noticed Microsoft is very "late-compiling" where it accepts tons of inter-coupled code, and LATER resolves (at compile, when the template-parameterization is triggered), while gcc seems to want to compile now when it "sees" the code (an initial pass for correctness, and again during parameterization/invocation).
(This problem shows up as we port our Microsoft code to Linux/gcc.)
===UPDATE===
The following are "alternate" scenarios that we have (in this code-porting effort), and would your answer change based on any of these?
// Alternate-Scenario-B
class Foo2 {
public:
template<typename SOME_TYPE>
static void FuncA(const SOME_TYPE& some_type) {
FuncB(some_type); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
template<typename SOME_TYPE>
static void FuncB(const SOME_TYPE& some_type);
};
...and:
// Alternate-Scenario-C
template<typename SOME_TYPE>
class Foo3 {
public:
static void FuncA(const SOME_TYPE& some_type) {
FuncB(some_type); // "FuncB()" NOT DECLARED YET? WORKS, MSVC2008
}
static void FuncB(const SOME_TYPE& some_type);
};
===UPDATE+2===
Thanks for the comments, where consensus seems that this is valid C++ code, and should work (as #Adam suggested, a function "defined-inline" should behave as if it were defined after the class, and should be able to call functions defined in the class interface after that inline definition).
MORE INFORMATION:
Yes, I really have this compile error from the first example in the FuncA() inline implementation:
'FuncB' is not a member of 'Foo'
...using:
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
(Recall that this works on MSVC2008/MSVC2010).
I realize now that my code-example (above) is insufficient (the above example does not show this error on gcc), here are some more details:
Foo has a base-class (I don't think that should matter)
Foo defines an internal enum which is passed through these funcs (I don't think this matters)
these functions are "expanded" through a macro (I think significant -- see below)
there are fifty-six (56) of these functions (I think significant -- see below)
A more complete code example would be (and I am not proud of this):
#define FOO_FUNCS(CLASS_NAME,CLASS_ENUM) \
static void FuncA(CLASS_ENUM value_enum) { \
FuncB(value_enum); /*PROBLEM*/ \
} \
static void FuncB(CLASS_ENUM value_enum) { \
FuncC(value_enum); \
} \
/*...THERE ARE 56 FUNCS IN THIS MACRO, THREE LINES EACH...*/
class Foo : public FooParent {
public:
enum FooEnum { FOO_ONE, FOO_TWO };
FOO_FUNCS(Foo,FooEnum) // EXPAND THE 56 FUNCS
};
CODE INTENT: The FooParent base class has implementation that is intended to be "shared" by (many) derived classes. The derived classes define their own enum values. Functions that used these enum values were implemented through a macro (because the FooParent is not a template<>, and cannot rely upon the derived-enum).
Curious behavior:
If the FooA(){FooB();} nesting references a function defined "later" by only a "few-lines", then gcc compiles fine. However, if the yet-to-be-declared function is much later, like Foo2(){Foo53();}, then gcc concludes that Foo53() is not a member of the class (but it is).
Here's what I think is going on:
There seems to be an issue with lots-of-code (for 56 functions) that are physically on "one-line". If I take these functions out of the macro, AND if I remove \ escape-line-endings, then gcc compiles fine.
Thus, I think the (code-porting) answer is:
don't use a preprocessor-macro
make a FooParentBase<> template class derived from FooParent, from which we derive Foo, which requires the typename Foo::enum as a template-parameter
I'm fine with these changes (I didn't like the macro), but I find it weird that gcc seems to have an issue here.
Are there other suggestions for how to fix this? (Is the above re-factoring what you would do?)
All three of your scenarios are correct and compile with both g++ and clang.
Your code looks perfectly legal to me. Inline definitions within a class definition are supposed to be treated equivalent to declarations with an inline definition immediately following the class definition (by which time the declaration of FuncB() would be available).
My version of GCC accepts this code as valid (all three examples you post, assuming I provide trivial implementations of each FuncB(), of course).
~$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
...
I believe more information is needed here. Perhaps post your version of GCC and the specific error message you're seeing.
========REPLY TO LATER UPDATE=======
I've tried your latest example with 70 functions in the macro, and it's still working for me in gcc 4.6.3. Here is the test I tried (with the macro shortened in the obvious way):
#include <iostream>
using std::cout;
struct FooParent {
static void Func71( int ) {
cout << "Called\n";
}
};
#define FOO_FUNCS(CLASS_NAME,CLASS_ENUM) \
static void Func1(CLASS_ENUM value_enum) { \
Func2(value_enum); /PROBLEM/ \
} \
static void Func2(CLASS_ENUM value_enum) { \
Func3(value_enum); \
} \
/* Functions Func3...Func69 snipped */ \
static void Func70(CLASS_ENUM value_enum) { \
Func71(value_enum); \
} \
/...THERE ARE 70 FUNCS IN THIS MACRO, THREE LINES EACH.../
class Foo : public FooParent {
public:
enum FooEnum { FOO_ONE, FOO_TWO };
FOO_FUNCS(Foo,FooEnum) // EXPAND THE 70 FUNCS
};
int main() {
Foo::Func1(Foo::FOO_ONE);
}
I'm building a tree-based debug/logging system for C++.
Its "user interface" is a macro which passes user-defined message and call site information (file, line, object address) to special function which then performs logging.
The function uses the object address to group messages by object instance.
Currently it looks like this:
// in logging system header
#define msg (event_level, message) \
do_logging_ (event_level, __FILE__, __LINE__, this, message)
...
// in code
msg (MSG_WARNING, "some text");
I want to ask, is there some uniform way (usable in the msg macro) to get NULL instead of this where this is not defined (global/static functions)?
You can change your macro definition:
#define msg (event_level, message, THIS) \
do_logging_ (event_level, __FILE__, __LINE__, THIS, message)
Usage:
msg (MSG_WARNING, "some text", this); // in member methods
msg (MSG_WARNING, "some text", NULL); // otherwise
I think this is not possible without modifying the code in your class you want to log. If you are willing to do that, however, you could derive all classes where you want logging functionality from a template like this one:
template <typename T>
class loggable_class
{
protected:
T* get_this() { return static_cast <T*> (this); }
};
For example:
class A : public loggable_class<A>
{
...
};
An additional global definition of the function get_this() will be used in non-member functions:
inline void* get_this()
{
return NULL;
}
The logging macro would look like:
#define msg (event_level, message) \
do_logging_ (event_level, __FILE__, __LINE__, get_this(), message)