How to define a pattern in macro in C++? - c++

I have a file having too many section like
[Section]
[Section.Ia32]
[Section.x64].... so more
so, I need to define single macro to when parsing the file we can get the section using one macro. currently I am trying like,
#define APattern = "(^(\\s)*\\[Section(\\.\\w+)*\\])";
it's compile succesfully... but it is not working.
For e.g
CString a = Section;
a.compareNoCase(APattern);
it is not working..
thanks

I think the syntax in your define is incorrect. In c++ a
define
is without
"=",
rather like
#define SQR(a) (a * a).
So in your define an argument is missing as well. Do not use the
";"
at the end of the line.
And for second, you are passing the result as an argument to the function
a.compareNoCase(),
which might be incorrect in meaning of which type is returned by your define.

With #define everything you have after the name is just pasted. So for yuor example the result will be:
CString a = Section;
a.compareNoCase( = "(^(\\s)*\\[Section(\\.\\w+)*\\])"; );
You can see for yourself it is invalid syntax. For correct definition you an go backwards:
a.compareNoCase( "(^(\\s)*\\[Section(\\.\\w+)*\\])" );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-->
#define APattern "(^(\\s)*\\[Section(\\.\\w+)*\\])"

I think you have 2 problems, the first one, regarding C macro syntax, rightly addressed by fiscblog answer (+1), the other is that seems you are actually expecting a regular expression match, that is over CString capabilities. See for instance this answer to get regular expressions matching working in Visual C++
To be true, I would address the problem using sscanf, more or less like
#define ASection(In, Section) (sscanf(In, " [Section(%^[)])", Section) == 1)

Related

multiple lines macro in C

does anyone know why this is syntactically wrong?
Im trying to covert this
#define OUTS_FROM_FP(_fp, _argCount) ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))
to this
#define OUTS_FROM_FP(_fp, _argCount) {\
((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
cout<<"Hello World"<<endl; \
}
outs = OUTS_FROM_FP(fp, vsrc1); --this is how it is being called
I get a lot of errors when running this: they start from statements that say that variables that were passed to the macro before are unused
Expanded, the original macro will look like this:
outs = ((u4*) ((u1*)SAVEAREA_FROM_FP(fp) - sizeof(u4) * (vsrc)));
That's (as far as I can tell as you didn't provide much context) valid code.
Your modified macro expands the same statement to this:
outs = { /* ... */ };
Your compiler gets all kinds of confused as you are attempting to assign a code block to a variable...
All the usual caveats regarding the use of macros in general aside, you could use the comma operator to get your modified macro "working":
#define OUTS_FROM_FP( _fp, _argCount ) \
cout << "Hello world\n", \
((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))
(The output is put first, as statements separated by the comma operator evaluate to the result of the last statement -- putting the output first makes the macro still evaluate to the same value as the original macro.)
All in all, you're probably better off turning that macro into a function.
Assuming that _fp and _argCount are variables or simple expressions, the original version is an expression of type u4*.
The second is more complicated. The braces make it a block, but syntactically you’re using it as an expression. This is not allowed in the C++ standard, but is supported by g++ and some other compilers. Since you say you’re using GCC, the value of this expression is the value of the last line of the block, which in this case is cout<<"Hello World"<<endl. If you were using a compiler which did not support statement expressions, you’d get a more confused syntax error.
I expect that unless you can convert an ostream to a u4 pointer (which, given what context we have, seems very unlikely), this won’t work. In this simple case, you can fix it by simply switching the order of the lines in the block. In a more complicated case, which I expect is the end goal, you probably would need to do something like
#define OUTS_FROM_FP(_fp, _argCount) {\
u4* result = ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
cout<<"Hello World"<<endl; \
result; \
}
This saves the output of the macro to a temporary variable, does whatever calculations you want (which can change result), and then on the last line “returns” result outside the macro. This is less portable than DevSolar’s solution, but it works better if you need to create temporary variables, and in my opinion is more readable.
However, as others point out in the comments, there is little reason (at least that we can see) to keep this as a macro instead of converting it to a function. Functions are much more robust in a variety of ways. Reasons you might still want to keep it as a macro include the definition of SAVEAREA_FROM_FP changing or the types u4 and u1 being different in different places. Neither of these would not be good programming practice, but you can’t control what others have done before and I don’t know enough about Dalvik to say it isn’t the case.

Passing parameters to a no-op macro in C++

I am getting the following error message
error: '0' cannot be used as a function
when trying to compile the following line:
NOOP(0 != width);
NOOP is defined as follows:
#define NOOP (void)0
The source code is part of a SDK - so it should be okay. And I have found out that (void)0 actually is a valid way to descibe "no operation" in C++. But why would you want to pass a boolean parameter to a function which does nothing? And how do you get rid of the error message?
The MACRO is not defined with any parameters on it, so after the preprocessor replaces code, that statement ends up looking like this:
(void)0(0 != width);
Which confuses the compiler into thinking you are trying to use the "()" operator on 0. (i.e. using 0 as a function)
I recommend that you drop the "(0 != width)" (it is misleading) and just write NOOP;
"(void)0(0!=width);" is not valid C++, so it's not OK. (void)0; by itself doesn't do anything in C++, so can be used as a noop. Instead of your current define, I would use:
#define NOOP(X) (void)0
This tells the C++ preprocessor that there is a preprocessor function called NOOP that takes one parameter of any type, and replaces that entire function call with (void)0. So if you have a line of code that says NOOP("HELLO WORLD"), then the preprocessor replaces that entire thing with (void)0, which the C++ compiler proceeds to ignore.

Defining a Preprocessor Macro

I'm relatively new to C++ and I'm taking a class on it. Our class was assigned a lab and my teacher has said that the lab write-up is a bit hard to understand; however, he did not make any changes to the lab write-up. So, I came across this part of the lab:
Defining a Preprocessor Macro
Long-standing convention capitalizes macro names, and this macro name must be TRACE_FUNC. The macro has a single parameter, a symbol that will be replaced by a function name when you apply the macro to the code. The start of the macro looks like this:
#define TRACE_FUNC( symbol ) replacement-text`
and the preprocessor will substitute the replacement text everywhere that the TRACE_FUNC( sym ) string exists in the source code, AND feed the symbol into that replacement.
NOTE: the #define statement must be all on a single, logical line. To keep the length manageable, you can escape the newline character with a backslash at the end of the line; that will keep the preprocessor happy while allowing you to span a definition across multiple lines.
For this exercise, the replacement text must be a complete statement, including the terminating semi-colon.
The replacement text must be an output statement that prints the symbol followed by the text () called. and a newline to standard output. You can copy and modify one of the output statements from the warning.cpp source file.
warning.cpp is just a file we're using and TRACE_FUNC is being placed in a header file.
So, I read this a couple times and I'm not 100% sure what it's asking. Looking at it one way, it seems like it's asking me to create a macro called TRACE_FUNC. If you look at it another way, it's asking me to use the macro TRACE_FUNC. All of that is fine, but I don't know how to use TRACE_FUNC at all, I can't find any documentation on it anywhere and I don't know how to create a macro. When I asked for help, my teacher just kind of said. words and not ones that were very helpful because it was a very winding, confusing answer with no explanation of what TRACE_FUNC actually is.
Basically, all that my teacher said was that the symbol within TRACE_FUNC needs to be the name of one of the functions in the source code. As an example, say we had a function foo() within warning, then the symbol is supposed to be foo() (or foo, I'm not sure of that, either), from his explanation. Also, in the replacement text, apparently the name itself will be replaced if I put # in front of the symbol. I thought that supposed to denote preprocessor directives. Why am I supposed to be using it here?
Anyway, doing what my teacher says pretty much does nothing. Neither this line
#define TRACE_FUNC( foo() ) #foo() called. ;
nor this line
#define TRACE_FUNC( foo ) #foo () called. ;
replace any text, which I'm pretty sure is the operation of the #define directive. So I must be applying what my teacher said in the wrong way, but I don't really know why it's wrong or how to fix it.
So, my question. Is TRACE_FUNC actually a macro and if so, is there any documentation on it that I can read? Or am I supposed to be creating TRACE_FUNC and if so, how exactly am I supposed to do that?
Wow, what utter rubbish! You're supposed to be learning C++ right, not intricacies of the preprocessor.
Here's what you are supposed to be doing, though why is anyone's guess.
#define TRACE_FUNC(sym) std::cout << #sym << "() called\n"
void foo()
{
TRACE_FUNC(foo);
...
}
I'm assuming that there are examples from warning.cpp that use std::cout if not then you'll have to adapt the above to whatever you find in warning.cpp.
The idea is that each function starts with a use of the TRACE_FUNC macro, so you can trace the execution of your code. Why the professor thinks this is a good idea for newbies is beyond me. Even if it were a good idea, that you are expected to figure out the details for yourself is even stupider.
I could improve the macro above but that would probably confuse even more so I won't. For now I would just do what the professor says but ignore it. Hopefully he'll get onto stuff that's worth learning later.
here is a example: use the ouput print function in your libray to replace the standard function printf here
#define TRACE_FUNC(sym) printf("%s() called", #sym);
to use it as
TRACE_FUNC(printf)
the output should be
printf() called
your actual task is to print out a symbol in a defined format. so you need printf or similar function in your #define.

Creating pointer using #define

Is it possible to create pointer using #define?
Something like this:
#define *HEY
I'll use it for something like this:
#define *HEY 2
...
int *s=HEY;
No, asterisks aren't allowed in #define macro names.
Your example variable declaration wouldn't work anyway, because it doesn't contain the text *HEY, it only contains HEY, which doesn't match the defined macro name.
What's that code intended to do? Make a pointer that points to the number 2?
defines are based completely on text replacement. They can only insert text everywhere you call the name. In your question you already made two mistakes.
You may not use * in the name of the macro
if you want to call a macro you have to call it with the same name you defined it
if * would have been legal, you sould also have called it with exactly that name *HEY
By the way. There is absolutely no secret functionality hidden somewhere in macro definitions.
#define HEY 2
simply replayces every HEY in your sourcecode with a 2 before compiling. Nothing else happens.
You can replace everything you want to replace, even single opening braces if you want to.
#define OPEN (
...
cout << 2 * OPEN 3 + 4 ) << endl;
should work, even if is pretty useless

What does "#define STR(a) #a" do?

I'm reading the phoneME's source code. It's a FOSS JavaME implementation. It's written in C++, and I stumbled upon this:
// Makes a string of the argument (which is not macro-expanded)
#define STR(a) #a
I know C and C++, but I never read something like this. What does the # in #a do?
Also, in the same file, there's:
// Makes a string of the macro expansion of a
#define XSTR(a) STR(a)
I mean, what's the use of defining a new macro, if all it does is calling an existing macro?
The source code is in https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. You can find it with a CTRL+F.
In the first definition, #a means to print the macro argument as a string. This will turn, e.g. STR(foo) into "foo", but it won't do macro-expansion on its arguments.
The second definition doesn't add anything to the first, but by passing its argument to another macro, it forces full macro expansion of its argument. So XSTR(expr) creates a string of expr with all macros fully expanded.
# is the stringizing operator. The preprocessor makes a string out of the parameter.
Say you have:
STR(MyClass);
It would be preprocessed as:
"MyClass";
The level of indirection (using XSTR()) has to do with macro expansion rules.
First, you should know that this pair of macros is actually fairly common. The first does exactly what the comment says -- it turns an argument into a string by enclosing it in double quotes.
The second is used to cause macro expansion of the argument. You typically use them together something like this:
#define a value_a
printf("%s", XSTR(a));
The macro expansion will expand a out to string_a, and the stringify will turn that into a string, so the output will be value_a.
The #a is referred to as the stringizer operator. It takes the formal parameter, in this case a, and turns it in to a string by enclosing it in double quotes.
So if you have:
string s = STR("my quoted string");
cout << s;
The output would be:
"my quoted string"