How to concatenate strings, integers and floating point numbers without using objects? - c++

I'd like to add information in a crash dump file, in case my application crashes.
Therefore I've created a __try-__except clause:
__try
{
Do_Something();
}
__except (ShowCrashdumpInformation(_T(__FUNCTION__));
Instead of just __FUNCTION__, I'd like to add more information, but how can I do that?
The simpliest way is to use a CString, but this is blocked because of compiler error C2712 (Cannot use __try in functions that require object unwinding).
So, I'd like to use LPCTSTR strings (which are widely used in my application).
As a result it should look like (CString alternative):
CString temp; temp.Format(_T("Do_Something, int=[%d], float=[%f], string=[%s]), iParam, fParam, strParam);
Do anybody have an idea?
Thanks

By far the easiest solution is to simply sidestep the problem. Just forward the exact arguments, not converted, to a (template) function which does the actual writing to file. Since the __catch is not in the template function itself, but one level up the stack, you're safe.

You could use preprocessor macros to "stringify" the standard __LINE__ macro, and rely on the compiler adjacent string-literal concatenation.
Perhaps something like this:
#define STRx(x) #x
#define STR(x) STRx(x)
#define FILE_FUNCTION_LINE (__FILE__ ":" __FUNCTION__ ":" STR(__LINE__))
...
ShowCrashdumpInformation(_T(FILE_FUNCTION_LINE))
As long as you have literal values, you could use the STR macro to "stringify" them and then use adjacent string concatenation.
It's not possible using variables though, only using literal values.

Related

is there any way to get debug info like __FILE__ without using macro function in c/c++?

I'm writing a logger module, so I would like to print the debug infos like __FILE__ and __LINE__ in c/c++. So I used macro function like:
/// here's just an example
/// function str_format() returns a std::string in format like printf() in c
#define info(str, ...) (cout << str_format(str, ##__VA_ARGS__) << __FILE__ << ":" << __LINE__)
in most cases, it works fine. but 'define' just has more influence than I thought.
to give an example, if a member variable in c++ class needs initialize:
class test{
private:
int info;
public:
test(int a) : info(a) {}
};
this would cause an unexpected error, the compiler would take info as a macro function!
even the header file of logger(which is logger.h) is not included in the class test's file, as long as the third file include them both, and include 'logger.h' before 'test.h' would cause this problem! that's really annoying.
So, is there any way other than #undef (since the test.h has nothing to with logger.h) to solve this problem? or let's say how can I get debug info like FILE without using macro function?
As far as __FILE__ and __LINE__ is concerned, C++20 introduced std::source_location for this. There is no equivalent non-macro based solution in prior C++ standards.
As far as a non-macro logging solution overall, the most common approach involves implementing the logging function as a variadic template with a parameter pack, that ends up formatting the log message, from its parameters.
No, there is no other way. You'll have to either not use file information (really, who cares what your file is called? Most likely you actually care about the call stack at a problem location, which is what exceptions give you) or use better names than info. In fact the convention for macros is to use all caps, like INFO.

String concatenate to self in preprocessor

I found a lot of questions and answers concatenating strings with the C or C++ preprocessor; for instance this question (but there are many more).
What I couldn't find was whether it was possible to concatenate to the same string. To be more clear, something like this
#define MY_STRING "Hello"
#define MY_STRING MY_STRING " world"
// Now MY_STRING is "Hello world"
If I had to write it during "runtime", I would write something like
char my_string[80];
strcpy(my_string, "Hello");
strcat(my_string, " world"); // <- similar to this operation, but in preprocessor
Please note, however, that this is not what I'm trying to do; I want the concatenation to be performed at compile time.
Is this possible? Or a define is "immutable"?
This question is not about a particular flavor of C or C++; if this can be implemented in only one of the two languages or only with some particular compiler please specify it in the answer
EDIT: as Lightness Races in Orbit partially guessed, the main point of my question revolves around conditional compilation and, moreover, expandability.
As for conditional compilation, what I currently do is
#if COND_1
#define STR_COND_1 " val1"
#else
#define STR_COND_1 ""
#endif
#if COND_2
#define STR_COND_2 " val2"
#else
#define STR_COND_2 ""
#endif
#define STR STR_COND_1 STR_COND_2
The problem here is that this can lead to errors when the conditions become too many (it's easy to forget one), while a concatenation does not have this problem.
As for expandability, I mean that if I have to add another module which adds its string to the STR one (for instance, COND_3), I have to manually add it to the STR definition, while with a concatenation it is automatic.
Now, these examples are really easy, so forgetting it is difficult, but when you have a project where these things are scattered around in lots of files forgetting one variable is easy and can lead to a lot of time wasted
You can't redefine a preprocessor macro. So, no.
If you don't mind doing it all in one go, two literals can be concatenated so:
#define MY_STRING "hello" " world"
Or use different names. Here's an example, introducing a conditional as I expect that is the real crux of your problem that you have omitted from the question:
#define MY_STRING_BASE "hello"
#ifdef FOO
#define MY_STRING MY_STRING_BASE " world"
#else
#define MY_STRING MY_STRING_BASE
#endif
Macros cannot be redefined. Any build-in solution that fully suits your need does not come to my mind but what about usage of simple regex in order to generate list of all conditions?
Assuming that each condition macro starts with STR_COND_ following regex run over all files shall produce the list of all conditions:
(STR_COND_\w+)

Capture __LINE__ and __FILE__ without #define

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.

Is it possible to make the execution of a program skip fprintf-statements/How to create my own fprintf-function?

In my C++-code there are several fprintf-statements, which I have used for debugging. Since I might need them again, I would prefer not to comment them out for the moment.
However, I need the execution of the program to be fast, so I would like to avoid them being printed out, as they are for the moment (I redirected stderr to a file).
Preferably this would be determined by the user passing an argument to the program, which I would extract like this:
main (int argc, char *argv[])
{
int isPrint=0;
if (argc > 1 ) {
isPrint = atoi ( argv[2]);
}
}
I thought of renaming fprintf to another name, and then from that function do a fprintf-call using the same parameters, based on the value of isPrint; however, then I realized that fprintf can have so many different kind of arguments and a various number of arguments; and that I don't know any generic way of declaring my own function with those requirements.
So I wonder how to create a function,which works exactly like fprintf, but which takes the extra parameter isPrint; or how to solve the above problem in another way.
Complementary information after first post:
One solution would be to add this before each fprintf-statement:
if (isPrint == true )
The typical approach is to use the preprocessor to compile away the calls to fprintf().
You would do something like this:
#if defined DEBUG
#define LOG(a) fprintf a
#else
#define LOG(a)
#endif
And in the code you would do:
LOG(("The value is %f", some_variable));
Note the double parenthesis, that's just to make the syntax work. You can do it nicer, but this is simpler to explain.
Now, you would either just edit the code to #define or #undef the DEBUG preprocessor symbol at the top of the file, or pass suitable options to the compiler (-D for GCC).
First note that if this is just for debugging, I'd agree that the typical way is to use macros or preprocessor defines to tell the compiler to include logging or not.
However, if you don't want it removed entirely by the compiler (so that you can turn the printing on or off with an argument), you could write your own log function that takes isPrint and some string, and then use snprintf() to format the string before you call it.
Something along these lines:
void myLog(int isPrint, char *message)
{
if(isPrint == 1)
{
fprintf(logFile, "%s", message);
}
}
char msg[64];
snprintf(msg, 64, "Test Message %d", 10);
myLog(isPrint, msg);
It may also be possible to wrap fprintf() in your own varags function, but that would be more complicated.
For debugging purpose you can use the variable argument macro:
#ifdef DEBUG
#define FPRINTF(...) fprintf(__VA_ARGS__)
#else
#define FPRINTF(...)
#endif
Be attentive that, if you use fprintf directly instead of FPRINTF then since you are defining a library function, it should appear after #include<> of that function.
It depends how much flexibilty you've got in changing the code and whether you want to be able to switch this off at runtime or just compile time.
I'd suggest you wrap it in your own variadic function (for tips look here) and then you've encapsulated the functionality.
Your function will essentially be just a thin wrapper round fprintf() but at this point you can then either use the preprocessor to ensure that your logging function does nothing if you compile it out, or you can do an integer comparison with, say, a logging level at runtime so that the underlying fprintf() only gets called if your debugging level is high enough.

Using C++ Macros To Check For Variable Existence

I am creating a logging facility for my library, and have made some nice macros such as:
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__)
#define WARING myWarningClass(__FILE__, __FUNCTION__, __LINE__)
where myDebuggingClass and myWarningClass both have an overloaded << operator, and do some helpful things with log messages.
Now, I have some base class that users will be overloading called "Widget", and I would like to change these definitions to something more like:
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, this)
#define WARNING myWarningClass(__FILE__, __FUNCTION__, __LINE__, this)
so that when users call 'DEBUG << "Some Message"; ' I can check to see if the "this" argument dynamic_casts to a Widget, and if so I can do some useful things with that information, and if not then I can just ignore it. The only problem is that I would like users to be able to also issue DEBUG and WARNING messages from non-member functions, such as main(). However, given this simple macro, users will just get a compilation error because "this" will not be defined outside of class member functions.
The easiest solution is to just define separate WIDGET_DEBUG, WIDGET_WARNING, PLAIN_DEBUG, and PLAIN_WARNING macros and to document the differences to the users, but it would be really cool if there were a way to get around this. Has anyone seen any tricks for doing this sort of thing?
Declare a global Widget* const widget_this = NULL; and a protected member variable widget_this in the Widget class, initialized to this, and do
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, widget_this)
Macros are basically a straight text substitution done by the preprocessor. There's no way for a macro to know the context from which it's being called to do the sort of detection you're interested in.
The best solution is probably separate macros as you suspect.
I don't think you can do this with a macro. You can probably manage to do it with SFINAE, but code that uses SFINAE (at least directly) is1 hard to write, harder to debug, and virtually impossible for anybody but an expert to read or understand. If you really want to do this, I'd try to see if you can get Boost enable_if (or a relative thereof) to handle at least part of the dirty work.
1 ...at least in every case I've ever seen, and I have a hard time imagining it being otherwise either.
Inspired by solipist, but slightly simpler in the implementation:
class Widget {
protected:
::myDebuggingClass myDebuggingClass(char const* file, char const* function, int line) {
return ::myDebuggingClass(file, function, line, this);
}
// ...
This eliminates the need for a shadowed variable; it relies on simple class name lookup rules.
The only way I can think of to possibly get this to work is to define a global variable:
Widget * this = NULL;
If that even compiles (I have my doubts, but don't have a compiler to test it), member functions will use the nearest scoped variable (the real his pointer), and everything else will get a null. Everyone's happy (so to speak...)
you could use weak reference to detect variable or function whether exist.
eg:
detect int a exist:
int a attribute((weak));
if (a)
exist
else
not exist