Is it possible to define a string from startup arguments?
For example, I have this code in header file:
#define MsgBox "Hello there!"
How to make it so that the #define string comes from the command line arguments?
So if I would start my application like this: app.exe -Test! - the MsgBox would be defined as "Test!".
Sorry if this is a bad explanation but hopefully at least some of you understood.
It is important to get the #define MsgBox from command line arguments, not from the program's entry point. All the code should be in the header file.
To be honest with you, I haven't tried anything because I have no idea where to start.
This is not possible because #define is a preprocessor command. That is, you can think of it as a find and replace that takes place at compile time. (They can be used for other things, but crucially, it is evaluated at compile time).
Why not just use a variable? That way it is type safe as well.
Update: Using the define
Say you have stored the argument in some global lpCmdLine
Then your define becomes
#define MsgBox lpCmdLine
Related
Trying to determine a "modern" implementation for the following C-style code:
#define logError(...) log(__FILE__, __LINE__, __VA_ARGS__)
Is is possible to capture this using variadic templates or something similar that does not rely on a #define ?
Desired use case:
logError( "Oh no! An error occurred!" );
Where __FILE__, and __LINE__ are captured under the hood, but reflect the file name and line number of where logError was called from.
Macros are indeed your only choice, at least until std::source_location makes it into the standard and fulfills your wish.
Actually the preprocessor is the only choice when you want to work with line numbers and filenames.
For the compiler it's not possible to use line numbers and filenames as arguments for function calls (or storing them in a variable).
In my company we had the exactly same issue with logging. We ended up with an external script scanning the source files and then building proper functions to call.
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)
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.
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
It seems I often spend way too much time trying to get a #define macro to do exactly what i want. I'll post my current dilemma below and any help is appreciated. But really the bigger question is whether there is any utility someone could recommend, to quickly display what a macro is actually doing? It seems like even the slow trial and error process would go much faster if I could see what is wrong.
Currently, I'm dynamically loading a long list of functions from a DLL I made. The way I've set things up, the function pointers have the same nanes as the exported functions, and the typedef(s) used to prototype them have the same names, but with a prepended underscore. So I want to use a define to simplify assignments of a long long list of function pointers.
For example, In the code statement below, 'hexdump' is the name of a typedef'd function point, and is also the name of the function, while _hexdump is the name of the typedef. If GetProcAddress() fails, a failure counter in incremented.
if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;
So let's say I'd like to replace each line like the above with a macro, like this...
GETADDR_FOR(hexdump )
Well this is the best I've come up with so far. It doesn't work (my // comment is just to prevent text formatting in the message)...
// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail;
And again, while I'd APPRECIATE an insight into what silly mistake I've made, it would make my day to have a utility that would show me the error of my ways, by simply plugging in my macro.
Go to https://godbolt.org/. Enter your code in the left pane and select compiler as gcc put the argument as -E in the right pane. Your pre-processed code will appear on the right.
You can just run your code through the preprocessor, which will show you what it will be expanded into (or spit out errors as necessary):
$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/"")))
GETADDR_FOR(hexdump)
$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter
GETADDR_FOR(hexdump)
In GCC, it's gcc -E foo.c to only preprocess the file.
Visual Studio uses the /P argument.
http://visualstudiogallery.msdn.microsoft.com/59a2438f-ba4a-4945-a407-a1a295598088 - visual studio plugin to expand macroses
You appear to be confused about what the exact syntax is for stringifying or token pasting in C preprocessor macros.
You might find this page about C preprocessor macros in general helpful.
In particular, I think this macro should read like this:
#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail
The trailing ; should be skipped because you will likely be typing this as GETADDR_FOR(hexdump);, and if you don't it will look very strange in your C code and confuse many syntax highlighters.
And as someone else mentioned gcc -E will run the preprocessor and skip the other compilation steps. This is useful for debugging preprocessor problems.
You might want to take a look at Boost Wave. Like most of Boost, it's really more a library than a utility, but it does have a driver to act as a complete preprocessor.