Modify log class to accept variables in string - C++ - c++

I am trying to modify my log class to accept variables in my string. For example, if I wanted to output that there are 7 players in an area.
Here is my write to log function:
void Log::writeSuccess(string text,...)
{
// Write the sucessfull operation to the logfile
logfile << "<---> " << text << endl;
}
And here is my calling code:
int playernum = 7;
errorLog.writeSuccess("There are %i players in the area", playernum);
It just ends up outputting to the file: There are %i players in the area
Any way to fix this?

I wonder how on earth does your program even compile?!
You call writeSuccess with 2 arguments, whereas it is declared to take only one argument.
You should look at boost format

The problem with using printf-style format strings is that those strings are
dependent on the types of the provided arguments, and
dependent on the order of the provided arguments.
Not only is this error-prone when you are writing those lines. In my experience the types and order of the arguments will easily change in software that is actively maintained and extended, and it's much harder still to keep the format strings in sync with changes applied later, than it is to do so when you initially write the code.
The problem of needing to manually keep the parameter types in sync with the format string can easily be solved in C++, streams have proven that 25 years ago. Boost.Format even manages to combine format strings with type safety.
A different approach, solving both problems, is taken by some logging libraries I have seen: They use a syntax where you specify which parameter is to be inserted at a specific place in a string by using the parameter's name, and they free you from having to think about the parameter's type by individually converting all parameters to strings before inserting them:
log( "i now has the value of #(i), current size is #(x.get_size(y))",
LOG_PARAM(i) + LOG_PARAM(x.get_size(y)) );

If you don't want to use stdarg.h which doesn't look good in c++ IMO. you can do something like this. Keep in mind that although this is a small class (you can add to it for better logging), its not the most efficient way to do it.
#include <iostream>
#include <sstream>
class Log
{
public:
Log() : os()
{
}
~Log()
{
fprintf(stderr, "%s\n", os.str().c_str());
}
template<typename T>
std::ostringstream &operator<<(const T &t)
{
os << "Log file - " << t;
return os;
}
private:
std::ostringstream os;
};
int main(int argc, char *argv[])
{
//usage
for (int i = 0; i < 10; ++i)
Log() << "Hello world " << i;
return 0;
}

Look at stdarg standard library. It allows you to handle variable number of parameters.

In case you can't or won't use boost:
void Log::writeSuccess(const char* const fmt, ...) {
va_list ap;
va_start(ap, fmt);
char buff[1024];
vsnprintf(buff, sizeof(buff), fmt, ap);
logfile << buff;
}
Note: it assumes that the written length is limited.
Update: with gcc it's possible to do this in a type-safe way, you need the following declaration.
class Log {
void writeSuccess(const char* const fmt, ...) __attribute__ ((format (printf, 2, 3)));
//...
};
Info here. Note: it's a warning, not a compile error. If you ignore warnings that's your problem..:)

Related

Calling a function using a string containing the function's name

I have a class defined as
class modify_field
{
public:
std::string modify(std::string str)
{
return str;
}
};
Is there any way to store this function name inside a string in main function and then call it.
I tried this but it's not working.
int main()
{
modify_field mf;
std::string str,str1,str2;
str = fetch_function_name(); //fetch_function_name() returns string modify
str2 = "check";
cout << str; //prints modify
str1 = str + "(" +str2 + ")";
mf.str1();
}
I know this is wrong. But I just want to know if there is any way to call a function name using variable.
This is not directly possible in C++. C++ is a compiled language, so the names of functions and variables are not present in the executable file - so there is no way for the code to associate your string with the name of a function.
You can get a similar effect by using function pointers, but in your case you are trying to use a member function as well, which complicates matters a little bit.
I will make a little example, but wanted to get an answer in before I spend 10 minutes to write code.
Edit: Here's some code to show what I mean:
#include <algorithm>
#include <string>
#include <iostream>
#include <functional>
class modify_field
{
public:
std::string modify(std::string str)
{
return str;
}
std::string reverse(std::string str)
{
std::reverse(str.begin(), str.end());
return str;
}
};
typedef std::function<std::string(modify_field&, std::string)> funcptr;
funcptr fetch_function(std::string select)
{
if (select == "forward")
return &modify_field::modify;
if (select == "reverse")
return &modify_field::reverse;
return 0;
}
int main()
{
modify_field mf;
std::string example = "CAT";
funcptr fptr = fetch_function("forward");
std::cout << "Normal: " << fptr(mf, example) << std::endl;
fptr = fetch_function("reverse");
std::cout << "Reverse: " << fptr(mf, example) << std::endl;
}
Of course, if you want to store the functions in a map<std::string, funcptr>, then that is entirely possible.
You have two choices:
1 - manually create a map with pointers to the functions you need and their identifiers as a string key so you can perform lookups, or..
2 - create a dynamic link library/shared object and use name lookup to get the pointer. Use extern "C" to prohibit identifier mangling. You may not be able to use certain C++ features and performance will be slightly worse, depending on your actual usage scenario.
It surely possible with C functions, but will be really tricky and unportable for C++ - because different OSes (and even different compilers on the same OS) uses different ABIs for C++, so real function names differ quite significantly from what you named them in your code.
If C functions is ok (e.g. you can declare them as extern "C"), you can use dlsym for POSIX OSes and GetProcAddress for windows. Of course, you'll need to add this functions into dynamic symbols table - something like '-rdynamic' flag for ld, or __declspec(dllexport) (hope that was right - haven't used if for a long time) on windows.
If the functions have same signature you can create a map of string to std::function objects. See more about std::function here: std::function
Maybe a pointer to this function is more adequate. It allows you to easily chose between functions to call:
#include<iostream>
using namespace std;
class modify_field
{
public:
std::string modify_1(std::string str)
{
return str;
}
std::string modify_2(std::string str)
{
return str + str;
}
};
int main()
{
string (modify_field::* fun_ptr) (string) = &modify_field::modify_1;
modify_field m;
cout << (m.*fun_ptr)("test") << endl;
fun_ptr = &modify_field::modify_2;
cout << (m.*fun_ptr)("test") << endl;
}
If you placed all the functions that you would like to lookup by name in a set of source files that you then generate a DLL with, you could use the dlopen() and dlsym() functions to find the entry point.
An example of how to do this can be found in the man pages of dlsym() on your machine, or you could refer to this link.
This only works well on functions that are unmangled (i.e. with C++ you may have some issues). You may either have to define these entry points as "extern C" to prevent mangling, or come up with some other mechanism to guess the mangled name for a C++ entry point. I have never done the latter so there are bound to be some nuances there that I'm oblivious to.
If you are using Windows (wasn't clear what OS you are on), you should lookup the documentation of GetProcAddress() which is available online here.
A good tutorial on the subject in general, and this one does talk about how to do all this with C++ can be found here.

In C++, how can I get the current thread's call stack?

I'm writing this error handler for some code I'm working in, in C++. I would like to be able to make some sort of reference to whatever I have on the stack, without it being explicitly passed to me. Specifically, let's say I want to print the names of the functions on the call stack, in order. This is trivial in managed runtime environments like the JVM, probably not so trivial with 'simple' compiled code. Can I do this?
Notes:
Assume for simplicity that I compile my code with debugging information and no optimization.
I want to write something that is either platform-independent or multi-platform. Much prefer the former.
If you think I'm trying to reinvent the wheel, just link to the source of the relevant wheel and I'll look there.
Update:
I can't believe how much you need to bend over backwards to do this... almost makes me pine for another language which shall not be mentioned.
There is a way to get a back-trace in C++, though it is not portable. I cannot speak for Windows, but on Unix-like systems there is a backtrace API that consists primarily of the following functions:
int backtrace(void** array, int size);
char** backtrace_symbols(void* const* array, int size);
void backtrace_symbols_fd(void* const* array, int size, int fd);
You can find up to date documentation and examples on GNU website here. There are other sources, like this manual page for OS X, etc.
Keep in mind that there are a few problems with getting backtrace using this API. Firstly, there no file names and no line numbers. Secondly, you cannot even get backtrace in certain situations like if the frame pointer is omitted entirely (default behavior of recent GCC compilers for x86_64 platforms). Or maybe the binary doesn't have any debug symbols whatsoever. On some systems, you also have to specify -rdynamic flag when compiling your binary (which has other, possible undesirable, effects).
Unfortunately, there is no built-in way of doing this with the standard C++. You can construct a system of classes to help you build a stack tracer utility, but you would need to put a special macro in each of the methods that you would like to trace.
I've seen it done (and even implemented parts of it) using the strategy outlined below:
Define your own class that stores the information about a stack frame. At the minimum, each node should contain the name of the function being called, file name / line number info being close second.
Stack frame nodes are stored in a linked list, which is reused if it exists, or created if it does not exist
A stack frame is created and added to the list by instantiating a special object. Object's constructor adds the frame node to the list; object's destructor deletes the node from the list.
The same constructor/destructor pair are responsible for creating the list of frames in thread local storage, and deleting the list that it creates
The construction of the special object is handled by a macro. The macro uses special preprocessor tokens to pass function identification and location information to the frame creator object.
Here is a rather skeletal proof-of-concept implementation of this approach:
#include <iostream>
#include <list>
using namespace std;
struct stack_frame {
const char *funName;
const char *fileName;
int line;
stack_frame(const char* func, const char* file, int ln)
: funName(func), fileName(file), line(ln) {}
};
thread_local list<stack_frame> *frames = 0;
struct entry_exit {
bool delFrames;
entry_exit(const char* func, const char* file, int ln) {
if (!frames) {
frames = new list<stack_frame>();
delFrames = true;
} else {
delFrames = false;
}
frames->push_back(stack_frame(func, file, ln));
}
~entry_exit() {
frames ->pop_back();
if (delFrames) {
delete frames;
frames = 0;
}
}
};
void show_stack() {
for (list<stack_frame>::const_iterator i = frames->begin() ; i != frames->end() ; ++i) {
cerr << i->funName << " - " << i->fileName << " (" << i->line << ")" << endl;
}
}
#define FUNCTION_ENTRY entry_exit _entry_exit_(__func__, __FILE__, __LINE__);
void foo() {
FUNCTION_ENTRY;
show_stack();
}
void bar() {
FUNCTION_ENTRY;
foo();
}
void baz() {
FUNCTION_ENTRY;
bar();
}
int main() {
baz();
return 0;
}
The above code compiles with C++11 and prints this:
baz - prog.cpp (52)
bar - prog.cpp (48)
foo - prog.cpp (44)
Functions that do not have that macro would be invisible on the stack. Performance-critical functions should not have such macros.
Here is a demo on ideone.
It is not easy. The exact solution depends very much on the OS and Execution environment.
Printing the stack is usually not that difficult, but finding symbols can be quite tricky, since it usually means reading debug symbols.
An alternative is to use an intrusive approach and add some "where am I" type code to each function (presumably for "debug builds only"):
#ifdef DEBUG
struct StackEntry
{
const char *file;
const char *func;
int line;
StackEntry(const char *f, const char *fn, int ln) : file(f), func(fn), line(ln) {}
};
std::stack<StackEntry> call_stack;
class FuncEntry
{
public:
FuncEntry(const char *file, const char *func, int line)
{
StackEntry se(file, func, line);
call_stack.push_back(se);
}
~FuncEntry()
{
call_stack.pop_back();
}
void DumpStack()
{
for(sp : call_stack)
{
cout << sp->file << ":" << sp->line << ": " << sp->func << "\n";
}
}
};
#define FUNC() FuncEntry(__FILE__, __func__, __LINE__);
#else
#define FUNC()
#endif
void somefunction()
{
FUNC();
... more code here.
}
I have used this technique in the past, but I just typed this code in, it may not compile, but I think it's clear enough . One major benefit is that you don't HAVE to put it in every function - just "important ones". [You could even have different types of FUNC macros that are enabled or disabled based on different levels of debugging].

void pointers in C++

I saw this example on a website, and the websites mentions:-
"One of its uses (void pointers) may be to pass generic parameters to a function"
// increaser
#include <iostream>
using namespace std;
void increase (void* data, int psize)
{
if ( psize == sizeof(char) )
{ char* pchar; pchar=(char*)data; ++(*pchar); }
else if (psize == sizeof(int) )
{ int* pint; pint=(int*)data; ++(*pint); }
}
int main ()
{
char a = 'x';
int b = 1602;
increase (&a,sizeof(a));
increase (&b,sizeof(b));
cout << a << ", " << b << endl;
return 0;
}
wouldn't it be simpler to write code like the following?
void increaseChar (char* charData)
{
++(*charData);
}
void increaseInt (int* intData)
{
++(*intData);
}
int main ()
{
char a = 'x';
int b = 1602;
increaseChar (&a);
increaseInt (&b);
cout << a << ", " << b << endl;
string str;
cin >> str;
return 0;
}
It is less code, and really straightforward. And in the first code I had to send the size of the data type here I don't!
It would be best to make the function type safe and generic. It would also be best to take the argument by reference instead of by pointer:
template <typename T>
void increment(T& data) {
++data;
}
void* should be avoided wherever possible in C++, because templates and inheritance provide type-safe alternatives.
Your solution works only for int or char. Consider the situation you want to go through array of some custom type( struct, for example ). In your code you will need to add a method to do that, however in the example above no line of could should be added to get the work example.
"One of its uses (void pointers) may be to pass generic parameters to a function"
Not a good-style use, to be certain. Passing generic parameters to functions is done by:
a) templates (and possibly template specializations) which allows to write safe code,
b) OOP approaches.
I like your second increaseInt and increaseChar solution better. You can rewrite it as:
template<typename T>
void increase(T* pData)
{
++(*pData);
}
It will work for any type which supports ++ and be safe.
Sometimes you'd still need a void pointer as a "generic parameter" - for example when using the popular pthread library. When you spawn a thread, you may send it some arbitrary data (of any type you want), and it's done using - well - a void* pointer. The pthread library is in C not C++, which may be one of the reasons, but you might want to interface with it from C++ and this will indeed require you to use the void* pointer as a "generic type". Not much harm done there, though; just remember that for everyday coding there are more elegant solutions.
Actually I think the example is quite bad. One of the canonical examples would be the C library's qsort, where you pass in void* as well as a function which interprets the data.
However, in C++, there are better mechanisms available which are less likely to silently malfunction.
Hence, the use of void* to pass generic data around should probably be limited to
instances where code bloat is important, and
code which interacts with other language, in particular C.
When you are programming C (not C++) void* is you only way to do something generic. Nevertheless the example is terrible. This scheme is often used for callback mechanics, where you pass a function pointer and a void*. For example:
void handle_crash(void* data)
{
Log* log = (Log*)data;
log->print("We crashed.");
}
Log log;
set_crash_handler(&handle_crash, &log);
You will see this often on C frameworks such as libxml2 or spidermonkey. In the case of C this is the only thing there is to accomplish it. It is not a very robust solution.
In case you are working with C++ you have more options. Basic generic programming can be done with templates or overloading as mentioned in other answers. In case you need solid callback mechanic you might want to look into libsigc++ or other "signals and slots" frameworks.
Your code is definitely preferable. void* loses any pretense to type safety, your typesafe overloads are much better. Good instincts.
To support more types generically in C++ you would define a class or function template, not use void*. References would be preferable to pointers, but your code could be changed to this:
template <class T> T increase(T* value)
{
return ++(*value);
}
int main(int argc, char* argv[])
{
int i(0);
increase<int>(&i);
char c(0);
increase<char>(&c);
return 0;
}
What's the website, as a matter of interest?

converting a variable name to a string in C++

I'd like to output some data to a file. For example assume I have two vectors of doubles:
vector<double> data1(10);
vector<double> data2(10);
is there an easy way to output this to a file so that the first row contains the headings 'data1' and 'data2' followed by the actual contents. The function which
outputs the data will be passed various different arrays so hardcoding the name
of the heading is not possible - ideally I'd like to convert the variable name
to some string and then output that string followed by the contents of the vector array. However, I'm not sure how to convert the variable name 'data1' to a string,
or indeed if it can easily be done (from reading the forums my guess is it can't)
If this is not possible an alternative might be to use an associative
container such as map or perhaps more simply a 'pair' container.
pair<vector<double>,string> data1(10,'data1');
Any suggestions would be welcome!
You can use the preprocessor "stringify" # to do what you want:
#include <stdio.h>
#define PRINTER(name) printer(#name, (name))
void printer(char *name, int value) {
printf("name: %s\tvalue: %d\n", name, value);
}
int main (int argc, char* argv[]) {
int foo = 0;
int bar = 1;
PRINTER(foo);
PRINTER(bar);
return 0;
}
name: foo value: 0
name: bar value: 1
(Sorry for printf, I never got the hang of <iostream>. But this should be enough.)
try this:
#define GET_VARIABLE_NAME(Variable) (#Variable)
//in functions
int var=0;
char* var_name= GET_VARIABLE_NAME(var);
I had the same problem. After a little bit of experimentation I created following macros that convert names of variables, fields, functions, methods and types to strings.
#define MACRO_VARIABLE_TO_STRING(Variable) (void(Variable),#Variable)
#define MACRO_FUNCTION_TO_STRING(Function) (void(&Function),#Function)
#define MACRO_METHOD_TO_STRING(ClassName,Method) (void(&ClassName::Method),#Method)
#define MACRO_TYPE_TO_STRING(Type) (void(sizeof(Type)),#Type)
The code uses comma operator and void conversion to force compiler to check if variable, function, etc. really exists. The nice thing is that it works well with uninitialized variables too. I tested it on both VC and GCC with all pedantic options I found out without any warning messages.
int GetAndPrintValue(const char* VariableName)
{
std::cout << VariableName << std::endl;
return 10;
}
int Variable=GetAndPrintValue(MACRO_VARIABLE_TO_STRING(Variable));
I use such code when I write parsers that reads data from input stream and if parsed variable is out of bounds it throws an exception with name of variable that failed my validity checks.
Slightly adapted from #sarnold's answer, for C++:
#define DEBUG(x) std::cout << #x << " = " << x << std::endl;
An example program which uses this:
int main() {
int foo = 1;
DEBUG(foo);
return 0;
}
You can use the preprocessor, there's a stringify token, but it's only available from the source, not to a function (you'd get the argument name).
I had a similar quest. In Qt, I got tired of constantly writing the variable name as a string without autocomplete when writing to qDebug().
After a lot of trial and error with different macros and functions, I found that this macro works great:
#define PRINT(x) ", " << #x << ": " << x
Example usage:
int someVariable = 42;
double anotherVariable = 13.37;
qDebug().nospace() << "Some text" << PRINT(someVariable) << PRINT(anotherVariable);
Output:
Some text, someVariable: 42, anotherVariable: 13.37
I guess this (or something very similar) will work for std::cout as well.
A bit late to the party, but I hope this can help anyone out there!
I'd have thought the obvious answer is to make the function that performs the output take the heading text as a string parameter.
For this case I have made nameof() macro. It returns a std::string name of a variable, type or member. It works like nameof() in C#.
For Example:
#include "nameof.h"
std::vector<double> data1(10);
std::string name = nameof(data1); // "data1"
struct Foo1
{
struct Foo2
{
Foo1* foo1;
};
Foo1* foo1;
Foo2 foo2;
};
name = nameof(Foo1::foo1->foo2.foo1); // "foo1"
name = nameof(123); // std::logic_error exception

Macro C++ Issues __VA_ARGS__

What (if any) are some potential problems with a C++ macro usage like this?
Would an inline function be a more appropriate solution?
#define EVENT_INFO(_format_, ...) CMyEvent::Generate(__FILE__, __LINE__, CMyEvent::EVT_HIGH, _format_, __VA_ARGS__)
void
CMyEvent::Generate(
const char* file, // filename
int line, // line number
CMyEvent::LEVEL level, // severity level
const char *format, // format of the msg / data
...) // variable arguments
{
// Get a message from the pool
CMyEvent* p_msg = GetMessageFromPool();
if(p_msg != NULL)
{
va_list arguments; // points to each unnamed argument
va_start(arguments, format);
// Fill the object with strings and data.
p_msg->Fill(file, line, level, 0, format, arguments);
va_end(arguments);
}
}
As you're using C++, you can avoid the pitfalls of using variable argument lists which are subject to many problems:
No check on quantity of arguments
No check on argument type
To make it more C++, do something like:
#define EVENT_INFO(args) EventLogStream (__FILE__, __LINE__, __PRETTY_FUNCTION__) << args
and invoke it like (warning: all code here is pseudocode and may be syntactically incorrect, but you should get the basic idea):
EVENT_INFO ("The answer to " << the_question << " is " << answer); // usually 42
The EventLogStream is similar to the cout object and like cout, you can provide class specific output:
class Vector3D
{
EventLogStream &operator << (EventLogStream &out) { out << "{" << x << ", " << y << ", " << z << "}"; }
}
If you could rewrite your messaging to use operator<<(), perhaps using std::ostreams with a custom stream buffer, you wouldn't need variable arguments or the ugly (IMHO) macro, and it would look a lot more like C++ than C.
variadic macro is great for use on logging. much better than using iostreams. inline function won't work unless you are willing to pass __FILE__, __LINE__ manually.
You can enclose format with parentheses for safety (not necessary IMHO)