#define A2W_EX(lpa, nChars) (\
((_lpa_ex = lpa) == NULL) ? NULL : (\
_convert_ex = (lstrlenA(_lpa_ex)+1),\
FAILED(::ATL::AtlMultiply(&_convert_ex, _convert_ex, static_cast<int>(sizeof(WCHAR)))) ? NULL : \
ATLA2WHELPER( \
(LPWSTR)_ATL_SAFE_ALLOCA(_convert_ex, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), \
_lpa_ex, \
_convert_ex / sizeof(WCHAR), \
_acp_ex)))
I am copy-pasting some macros from Visual Studio int MingW and I am getting the following error
In member function 'ATL::CComVariant& ATL::CComVariant::operator=(LPCSTR)':
C:\.../atlconv.h:635:11: error: expected primary-expression before ')' token
(LPWSTR)_ATL_SAFE_ALLOCA(_convert_ex, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), \
^
Any suggestions on how to fix this issue ?
Related
I was trying to convert 32bit game client to 64bit. But I can't compile, because the client has an inline ASM code, 64bit doesn't support __asm inline. So I can't find a solution for this. I hope I can get into this community.
define inline code:
#define PR_FLOAT_TO_INTASM __asm \
{ \
__asm fld PR_FCNV \
__asm fistp PR_ICNV \
}
#define PR_FLOAT_TO_INT(inreal, outint) \
{ \
PR_FCNV = (inreal); \
PR_FLOAT_TO_INTASM; \
(outint) = PR_ICNV > PR_FCNV ? PR_ICNV - 1 : PR_ICNV; \
}
Example code using:
float CMapOutdoor::GetTerrainHeight(float fx, float fy)
{
if (fy < 0)
fy = -fy;
long lx, ly;
PR_FLOAT_TO_INT(fx, lx);
PR_FLOAT_TO_INT(fy, ly);
WORD usCoordX, usCoordY;
usCoordX = (WORD)(lx / CTerrainImpl::TERRAIN_XSIZE);
usCoordY = (WORD)(ly / CTerrainImpl::TERRAIN_YSIZE);
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum))
return 0.0f;
CTerrain* pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return 0.0f;
return pTerrain->GetHeight(lx, ly);
}
Error code:
error C2146: syntax error : missing ';' before identifier 'PR_ICNV'
error C2146: syntax error : missing ';' before identifier 'fistp'
error C2146: syntax error : missing ';' before identifier '}'
I use QtCreator and gdb 7.7. I have an example macro:
#define getMax(a,b) ((a) > (b) ? (a) : (b))
Then somewhere in the code a breakpoint is set when that macro is used:
break at line: x = getMax(v, z);
Is it possible to see expanded macro during debugging ?
Edit1 How to check value of the variable, for example func ## Index or curr after expanded following macro:
#define WRAPABLE_HND_FUNCTN(func, ...) \
{ \
enum { num = func ## Index }; \
unsigned int curr = mCurrFunction[num]; \
while (mCurrFunction[num] < mInterface.size () && \
!mInterface[mCurrFunction[num]].enabled[num]) \
++mCurrFunction[num]; \
if (mCurrFunction[num] < mInterface.size ()) \
{ \
mInterface[mCurrFunction[num]++].obj-> func (__VA_ARGS__); \
mCurrFunction[num] = curr; \
return; \
} \
mCurrFunction[num] = curr; \
}
When I execute print handleEventIndex (which was func ## Index) I get:
554print handleEventIndex
&"print handleEventIndex\n"
~"$2 = CompScreen::handleEventIndex"
~"\n"
554^done
For print curr I get:
555print curr
&"print curr\n"
&"No symbol \"curr\" in current context.\n"
555^error,msg="No symbol \"curr\" in current context."
You will need to compile your program with full macro support:
g++ -ggdb3
When debugging on Qt Creator, enable the Debugger Log view and type the following in the resulting console:
macro expand getMax(v, z)
More information on the GDB Manual.
I have an AVOption structure:
static const AVOption options[] = {
COMMON_OPTIONS // error here
{ NULL }
};
and COMMON_OPTIONS is defined as:
#define COMMON_OPTIONS \
{ "interp", "select interpolation mode", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=INTERPOLATE_TETRAHEDRAL}, 0, NB_INTERP_MODE-1, FLAGS, "interp_mode" }, \
{NULL}
I am getting an error:
2>c:\users\awki6\desktop\ffmpeg\libavfilter\vsrc_testsrc.cpp(98): error C2143: syntax error : missing '}' before '.'
Your COMMON_OPTIONS macro has already the { NULL } and does not ends with a ,, so:
static const AVOption options[] = {
COMMON_OPTIONS
};
will solve your problem.
Past answer before the edit:
Even if we don't know what does COMMON_OPTIONS expand to, I guess that you just miss the comma after it:
static const AVOption options[] = {
COMMON_OPTIONS,
// ^
{ NULL }
};
i have problem to set in to c++ MACRO singletone function result .
this is what i have :
the macro
#define CCDICT_FOREACH(__dict__, __el__) \
CCDictElement* pTmp##__dict__##__el__ = NULL; \
if (__dict__) \
HASH_ITER(hh, (__dict__)->m_pElements, __el__, pTmp##__dict__##__el__)
and this is how i try to set it :
CCDictElement* pElement = NULL;
CCDICT_FOREACH(GameSingleTone::getInstance()->getGemsDictionary(), pElement)
{
}
the method getGemsDictionary() returns me:
CCDictionary*,gemsDictionary;
the compilation error im getting is (on the line of the MACRO):
error C2143: syntax error : missing ';' before '{'
but if i do :
CCDictionary* tempDictionary = CCDictionary::create();
tempDictionary = GameSingleTone::getInstance()->getGemsDictionary();
CCDICT_FOREACH(tempDictionary , pElement)
{
}
every thing is working .
why ?
Macros simply do text replacement. So when you do this:
CCDICT_FOREACH(GameSingleTone::getInstance()->getGemsDictionary(), pElement)
This line:
CCDictElement* pTmp##__dict__##__el__ = NULL; \
becomes this:
CCDictElement* pTmpGameSingleTone::getInstance()->getGemsDictionary()pElement = NULL;
Which is utter nonsense. This, on the other hand:
CCDICT_FOREACH(tempDictionary , pElement)
translates to this:
CCDictElement* pTmptempDictionarypElement = NULL;
Which is perfectly okay.
This question already has answers here:
do while(false) pattern [duplicate]
(7 answers)
Closed 9 years ago.
Currently I am writing unit tests in C++ with CppUnit. Recently I needed to check that an exception is thrown in a specific case using CppUnits macro:
CPPUNIT_ASSERT_THROW(
boost::get<FooClassInBoostVariant>(m_boostVariantFooOrBar),
boost::bad_get);
the warning during the compilation of the test surprised me (on VS2010, but will be a warning on other compilers as well...):
warning C4127: conditional expression is constant
I looked into the macro definition of CppUnit and found the following:
do { \
bool cpputExceptionThrown_ = false; \
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputExceptionThrown_ = true; \
} \
\
if ( cpputExceptionThrown_ ) \
break; \
\
CPPUNIT_NS::Asserter::fail( \
"Expected exception: " #ExceptionType \
" not thrown.", \
CPPUNIT_SOURCELINE() ); \
} while ( false )
Well, I totally understand how this works, the do while loop is executed only once, because of the false, and the break is used to not execute the Asserter::fail() part. But why are they doing it like this? It - of course - triggers the compiler warning, as the break condition for the while loop is obviously always "false". But isn't there a more elegant way to do this? I usually adhere to the no-warning-compilation principle, so this really bugs me.
So my question really is, why didn't they implement it like this:
{ \
bool cpputExceptionThrown_ = false; \
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputExceptionThrown_ = true; \
} \
\
if ( !cpputExceptionThrown_ ) { \
CPPUNIT_NS::Asserter::fail( \
"Expected exception: " #ExceptionType \
" not thrown.", \
CPPUNIT_SOURCELINE() ); \
} \
}
Thanks in advance!
-Hannes
The reason is to make the assertion one statement. Consider these two uses of the macro:
CPPUNIT_ASSERT_THROW(foo(), MyException); // a
CPPUNIT_ASSERT_THROW(foo(), MyException) // b - without trailing `;`!
doSomething();
With their code, you'd get an error with //b, since the code expands to do { ... } while (false) doSomething(); - you'd be missing the ; after the condition.
With your code, //b would happily compile, but //a could give you an "empty statement" warning, since that line would expand to { ... };, with the superfluos ; after the block.
Why they force you to use //a I don't know - but I like //b way more because it's just consistent to have a ; after each line. One does not have to distinguish lines with assertions from normal statements.
PS:
I am not sure but there might be more differences between { ... } blocks and do {...} while(false) statements that will allow to put an assertion macro in places where simple blocks are not allowed.
Edit: with C++11, you could use a lambda (define and call it in one place):
#define CPPUNIT_ASSERT_THROW(expression, ExceptionType) \
[&]() -> void { \
bool cpputExceptionThrown_ = false; \
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputExceptionThrown_ = true; \
} \
\
if ( cpputExceptionThrown_ ) \
return; \
\
CPPUNIT_NS::Asserter::fail( \
"Expected exception: " #ExceptionType \
" not thrown.", \
CPPUNIT_SOURCELINE() ); \
}()
However, there might be caveats, e.g. due to the lambda capturing the variables you use in the expression.
OK, I guess I found the answer by myself:
http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ gives the explanation.
It is actually a common practice to wrap multi-line macros in do { } while (false);. This is a workaround to allow for using those macros, e.g., in un-braced if else.
if (condition_a)
MULTI_LINE_MACRO();
else
MULTI_LINE_MACRO_2();
The result would be that unexpectedly only the first line gets executed, which definitely leads to unexpected behaviour. So they were not entirely incompetent I guess...
http://kernelnewbies.org/FAQ/DoWhile0 also explains why my solution would not work. The MULTI_LINE_MACRO(); within the if would expand, e.g., to
if (condition_a)
{ /* macro stuff */ }
;
else // << never executed because of the ; above.
So I guess I have to disable the warning. GCC has a workaroud for this ( ({ MACRO }) ), called a Statement Expression, but I don't think this works on VS2010.