Multi-statement Macros in C++ - c++

In C++, is it possible to make a multi-statement macro with nested if statements inside of it like the one below? I've been attempting it for a while now and I'm getting a scope issue for the second if statement not being able to see 'symbol'. Maybe I need to understand macros further.
#define MATCH_SYMBOL( symbol, token)
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
other steps;
}

For a multi-line macro you need to add a \ character to the end of all but the last line to tell the macro processor to continue parsing the macro on the next line, like so:
#define MATCH_SYMBOL( symbol, token) \
if(something == symbol){ \
if( symbol == '-'){ \
}else if (symbol != '-'){ \
} \
other steps; \
}
Right now, it's trying to interpret it as a 1-line macro and then some actual code at the top of your file, which isn't what you want:
#define MATCH_SYMBOL( symbol, token)
// and then... wrongly thinking this is separate...
if(something == symbol){ // symbol was never defined, because the macro was never used here!
if( symbol == '-'){
}else if (symbol != '-'){
}
other steps;
}

If you're using C++ you should avoid using macros altogether. They are not type-safe, they're not namespace-aware, they're hard to debug and just they're plain messy.
If you need a type-independent function, use templates:
template <typename T>
bool match_symbol(T symbol, T token) {
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
...
or if the parameters can be different types:
template <typename T, typename V>
bool match_symbol(T symbol, V token) {
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
...

Note that some of the answers here have a problem.
For example, for a normal statement you can do this:
if (foo)
function();
else
otherstuff();
If you followed some of the suggestions here, but if replace function with a macro, it might expand to:
if (foo)
if (something) { /* ... */ }
else { /* ... */ }; // <-- note evil semicolon!
else
otherstuff();
So a common (ugly) hack that people do to avoid this is:
#define MATCH_SYMBOL(symbol, token) \
do \
{ \
if(something == symbol) \
{ \
if( symbol == '-') \
{ \
} \
else if (symbol != '-') \
{ \
} \
other steps; \
} \
} \
while (0) // no semicolon here
This is so that the "statement" MATCH_SYMBOL(a, b) can end with a semicolon just like a normal statement. You also have braces around the multiple statements.
If you think nobody's crazy enough to use this technique, think again. It's very common in the Linux kernel, for example.

You need to have a backslash (\) at the end of all the lines in the macro but the last one.

The way of the C++:
inline void MATCH_SYMBOL(const Symbol& symbol, const Token& token) {
/* ... */
if (something == symbol) {
if ('-' == symbol) {
/* ... */
}
else if ('-' != symbol) {
/* ... */
}
}
/* ...other steps... */
}

also, see if you can replace the macro with a function.
?
MATCH_SYMBOL(Sym const & symbol, Tok const & token)
{
...
}

One can also define macro function and implement the function than
#define MATCH_SYMBOL( symbol, token) match_symbol(symbol,token)

Related

replace goto inside a macro with something else

I'm attempting to remove goto statement inside Mach7, because goto is not allowed in constexpr function:
#define MatchQ(s) { \
XTL_MATCH_PREAMBULA(s) \
enum { __base_counter = XTL_COUNTER }; \
typedef mch::unified_switch<source_type> switch_traits; \
XTL_PRELOADABLE_LOCAL_STATIC(XTL_CPP0X_TYPENAME switch_traits::static_data_type,static_data,match_uid_type,XTL_EMPTY()); \
XTL_CPP0X_TYPENAME switch_traits::local_data_type local_data; \
bool processed = false; \
size_t jump_target = switch_traits::choose(subject_ptr,static_data,local_data); \
XTL_CONCAT(ReMatch,__LINE__): \
switch (jump_target) \
{ \
XTL_NON_REDUNDANCY_ONLY(default:) \
{ XTL_REDUNDANCY_ONLY(try){{ \
if (switch_traits::on_default(jump_target,local_data,static_data)) \
goto XTL_CONCAT(ReMatch,__LINE__); \
XTL_SUBCLAUSE_FIRST
The codes above use goto here: goto XTL_CONCAT(ReMatch,__LINE__);, which is possible to jump to upside of switch statement.
How to replace goto here with something else?
with the help of #ozlsn and gcc -E, the replacement is done.
persuade codes:
while(true)
{
bool continue_flag = false;
switch(var)
{
default:
if(something)
continue_flag = true;
break;
// do something
OtherCases:
// do something
}
if (!contine_flag)
break;
}
full commit here: https://github.com/FirstLoveLife/Mach7/commit/3db24a337a7643018ed9e12ac95f53f9a036251c
Here is a related QA: Using continue in a switch statement

'else if' logical statements in gnuplot

The new gnuplot (5.x) has new syntax for logic, but I cannot get the 'else if' statement to work. For example:
if(flag==1){
plot sin(x)
}
else{
plot cos(x)
}
does work, but:
if(flag==1){
plot sin(x)
}
else if(flag==2){
plot cos(x)
}
else if(flag==3){
plot tan(x)
}
does not. I have tried many combinations of {} and placement of 'if' and 'else' to no avail. Does anyone know how to correctly implement 'else if' in gnuplot 5.x?
The gnuplot guide (http://www.bersch.net/gnuplot-doc/if.html) has no examples of the new logic syntax using 'else if' but does have examples using the old syntax, but I would rather avoid the old.
Based on a brief inspection of the source code of command.c in the latest version of Gnuplot, I would say that this feature is not supported. To be more specific, the relevant part can be found on line 1163 (see below). The parser first makes sure that the if is followed by a condition enclosed in parentheses. If the following token is a {, it activates the new syntax, isolates the entire if block enclosed in a pair of matching {} and optionally looks for an else which is however permitted to be followed also only with a {}-enclosed clause. Because of this, a simple script such as:
if(flag == 1){
print 1;
}else if(flag == 2){
print 2;
}
indeed produces the error message expected {else-clause}. One workaround would be to nest the if statements as:
if(flag == 1){
}else{
if(flag == 2){
}else{
if(flag == 3){
}
}
}
which is admittedly slightly more verbose...
void
if_command()
{
double exprval;
int end_token;
if (!equals(++c_token, "(")) /* no expression */
int_error(c_token, "expecting (expression)");
exprval = real_expression();
/*
* EAM May 2011
* New if {...} else {...} syntax can span multiple lines.
* Isolate the active clause and execute it recursively.
*/
if (equals(c_token,"{")) {
/* Identify start and end position of the clause substring */
char *clause = NULL;
int if_start, if_end, else_start=0, else_end=0;
int clause_start, clause_end;
c_token = find_clause(&if_start, &if_end);
if (equals(c_token,"else")) {
if (!equals(++c_token,"{"))
int_error(c_token,"expected {else-clause}");
c_token = find_clause(&else_start, &else_end);
}
end_token = c_token;
if (exprval != 0) {
clause_start = if_start;
clause_end = if_end;
if_condition = TRUE;
} else {
clause_start = else_start;
clause_end = else_end;
if_condition = FALSE;
}
if_open_for_else = (else_start) ? FALSE : TRUE;
if (if_condition || else_start != 0) {
clause = new_clause(clause_start, clause_end);
begin_clause();
do_string_and_free(clause);
end_clause();
}

C++ Parsing char array as a script file (syntax)

I have made a simple Script reading class in C++ which allows me to read and parse scripts.
Basically there's a FILE class, which then I proceed to open with "fopen".
In functions I proceed to call "fgetc" and "ftell" to parse the script file as needed, note this ain't an interpreter.
Every script file is supposed to follow a syntax, but this is why I'm asking here for a solution.
Here's how a script looks like:
# Script File Comment
USERNAME = "Joe"
PASSWORD = "pw0001"
ACCESSLEVEL = 3
DATABASE = ("localhost",3306,"db","user","password")
Basically I have a few functions:
// This function searches for "variables"
nextToken();
// After I have the variable, e.g: USERNAME, PASSWORD, ACCESSLEVEL or DATABASE
// I proceed to call this function
// This function reads the char array for (,-{}()[]=) these are symbols
readSymbol();
// In a condition I check what "token/variable" I got and proceed to read
// it accordingly
// e.g; for USERNAME I do:
readString(); // reads text inside "
// e.g; for ACCESSLEVEL I do:
readNumber(); // reads digits until the next char ain't a digit
// e.g; for DATABASE I do:
readSymbol(); // (
readString(); // 127.0.0.1
readSymbol(); // ,
readNumber(); // 3306
readSymbol(); // ,
readString(); // db
readSymbol(); // ,
readString(); // user
readSymbol(); // ,
readString(); // password
readSymbol(); // )
I would like to be able to read a variable declaration like this:
DATABASELIST = {"data1","data2","data3"}
or
DATABASELIST = {"data1"}
I could easily do readSymbol and readString to read for 3 different string definitions inside the variable, however this list is supposed to have custom user data, like 5 different strings, or 8 different strings - depends.
And I seriously have no idea how can I do this with the parser I wrote.
Please note that I am basing this in some Pseudo code I took from a scripter for this type of format, I have the pseudo code extracted from IDA, if you would like to see it for better understanding post here
Here's an example of my "readSymbol" function.
READSYMBOL
int TReadScriptFile::readSymbol()
{
int currentData = 0;
int stringStart = -1;
// Check if we can't read anymore
if (end)
return 0;
while (true)
{
// Basically get chars in the script
currentData = fgetc(File);
// Check for end of file
if (currentData == -1)
{
end = true;
break;
}
if (stringStart == -1)
{
if (isdigit(currentData) || isalpha(currentData))
{
printf("TReadScriptFile::readSymbol: Symbol expected\n");
close();
return 0;
}
else if
(
currentData == '=' || currentData == ',' ||
currentData == '(' || currentData == ')' ||
currentData == '{' || currentData == '}' ||
currentData == '>' || currentData == '<' ||
currentData == ':' || currentData == '-'
)
{
#ifdef __DEBUG__
printf("Symbol: %c\n", currentData);
#endif
stringStart = ftell(File);
break;
}
}
}
return 1;
}
NEXTTOKEN
int TReadScriptFile::nextToken()
{
int currentData = 0;
int stringStart = -1;
int stringEnd = -1;
RecursionDepth = -1;
memset(String, 0, 4000);
// Check if we can't read anymore
if (end)
return 0;
while (true)
{
// ** Syntax **
if (isdigit(getNext()) || getNext() == -1)
{
printf("No more tokens left.\n");
end = true;
close();
return 0;
}
// End
// Basically get chars in the script
currentData = fgetc(File);
// Check for end of file
if (currentData == -1)
{
end = true;
break;
}
// Syntax Checking Part, this really isn't needed but w/e
if (stringStart == -1)
{
if (currentData == '=' || isdigit(currentData))
{
printf("TReadScriptFile::nextToken: Syntax Error: string expected\n");
close();
return 0;
}
}
// End Syntax Checking
// It's a comment line, we should skip
if (currentData == '#')
{
seekNewLn();
continue;
}
// There are no variables, yet
if (stringStart == -1)
{
// We found a letter, we are near a token!
if (isalpha(currentData))
{
stringStart = ftell(File);
// We might as well add the letter to the string
RecursionDepth++;
String[RecursionDepth] = currentData;
continue;
}
}
else if (stringStart != -1)
{
// Let's wait until we get an identifier or space
// We found a digit, error
if (isdigit(currentData))
{
printf("TReadScriptFile::nextToken: string expected\n");
close();
return 0;
}
// We found a space, maybe we should stop looking for tokens?
else if (isspace(currentData))
{
#ifdef __DEBUG__
printf("Token: %s\n", String);
#endif
break;
}
RecursionDepth++;
String[RecursionDepth] = currentData;
}
}
return 1;
}
I found a good example of the approach I followed here:
http://llvm.org/docs/tutorial/LangImpl1.html
One mechanism to deal with DATABASE_LIST would be this:
After finding the variable DATABASE_LIST read a symbol using readSymbol() checking if it is a { then in a loop do readString() add it to a std::vector (or some other suitable container) then check for a , or } (using readSymbol()) . If it is a ,(comma) then you go back and read another string add to the vector etc. until you do finally reach } . When you are finished you'd have a vector (dynamic array) of strings that represent a DATABASE_LIST

CppUnit expect exception with Assert Throw compiles with warning C4127 [duplicate]

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.

'wcsncasecmp' was not declared in this scope

I have included file JSONValue from simpleJSON, which is used for parsing the json string.
While compiling I am getting this error that 'wcsncasecmp' was not declared in this scope.
on this line. While searching more i ot that wcsncasecmp is a GNU-specific function, I am using windows, so can anyone help me out.
else if ((simplejson_wcsnlen(*data, 4) && wcsncasecmp(*data, L"true", 4) == 0) || (simplejson_wcsnlen(*data, 5) && wcsncasecmp(*data, L"false", 5) == 0))
{
bool value = wcsncasecmp(*data, L"true", 4) == 0;
(*data) += value ? 4 : 5;
return new JSONValue(value);
}
.
I'll be greatful for any help.
On windows there is _wcsnicmp that you can use.
More ref: _strnicmp, _wcsnicmp, _mbsnicmp, _strnicmp_l, _wcsnicmp_l, _mbsnicmp_l
Please define WIN32 macro in your source or in Visual Studio please add it to the project / Properties / C/C++ / Preprocessor definition.
#define WIN32
Internally it will define wcsncasecmp as _wcsnicmp like Rohan has already mentioned.
This is a known problem of SimpleJSON.
// Win32 incompatibilities
#if defined(WIN32) && !defined(__GNUC__)
#define wcsncasecmp _wcsnicmp
static inline bool isnan(double x) { return x != x; }
static inline bool isinf(double x) { return !isnan(x) && isnan(x - x); }
#endif