I know it's a simple question, but I'm looking to get my C++ groove on. I would imagine some sort of abort function could be used. But I don't think that'll return any text like die('hello'); would.
There is no "print a message, then exit" in C or C++. You can quite easily write your own function for die (or panic, as I prefer to call it), something like:
void die(const std::string& msg)
{
std::cerr << msg << std::endl;
exit(1);
}
Or, if you want to avoid the problems with creating a string, which may fail under low memory conditons:
void die(const char *msg)
...
(the rest should be the same as above). The drawback here is that you can't trivially concatenate strings, e.g. die(std::string("Could not open file ") + filename); won't work with const char *.
A function that does var_dump is much harder, as there is no direct way to actually fetch the content of a variable of a an arbitrary type, or an array, in C++. You could perhaps do something like this:
template<typename T>
void var_dump(const T& var)
{
std::cout << var << endl;
}
template<typename T, size_t N>
void var_dump(const T (&var)[N])
{
for(i : var)
{
std::cout << i << endl;
}
}
The latter is a bit like this PHP code: foreach($var as $i) echo $i . "\n";. And I may have the syntax slightly wrong, not sure.
I wouldn’t recommend calling std::abort, std::exit or anything like that.
It’s brute-force, and the semantics for proper cleanup are very complicated. You are essentially leaving (at least parts of) your program behind in a very messy state.
A much better way in C++ is to throw an exception which you then catch in main:
#include <stdexcept>
struct fatal_error : std::logic_error {
fatal_error(char const* message) : std::logic_error(message) { }
};
int main() try {
… the normal program flow starts here
} catch (fatal_error const& e) {
std::cerr << e.what() << '\n';
return EXIT_FAILURE;
}
Then, instead of die, you’d simply say throw fatal_error("Something went wrong.");.
Assuming you need these equivalents for debugging purpose...
instead of die() you may invoke the debugger;
instead of var_export() you may inspect your variables content with the debugger.
Related
I used to logging in C with variable amount of arguments and formatting, and I wanna how Can I meet this in C++.
Through Q&A like this (How to make a variadic macro for std::cout?), I know how to handle variable amount. But what I still do not know is, how to format, cause I can not use methods like 'setbase' between arguments now.
For example:
// in C
#define err(fmt, ...) (printf("[%s] "fmt"\n", __FUNCTION__, ##__VA_ARGS__))
#define FATAL(fmt, ...) do{\
err(fmt, ##__VA_ARGS__);\
CLEAN_UP;\
exit(1);\
}while(0)
int main(){
if(1) FATAL("Just a test: 0x%lX, %d", 1, 2);
return 0;
}
"FATAL" here, accept variable amount of arguments with formatting, print them, and do some extra. I have no idea how to declare such a "FATAL" in C++.
You can achieve that by using the operator<< and a custom destructor on an ad-hoc logging object.
class log_error
{
public:
log_error() = default;
log_error(log_error&& other) = default;
~log_error()
{
// Do whatever you want with the input
// Add a timestamp, process/thread id
// Write it to a file, send it to a server ...
std::cerr << "[ERROR] " << ss.str() << std::endl;
throw std::runtime_error(ss.str());
}
std::stringstream ss;
};
template<typename T>
log_error operator<<(log_error&& le, const T& t)
{
le.ss << t;
return std::move(le);
}
I only included the essentials for basic usage. For more complex usage you want to consider a copy variant of the ctor / operator<<.
The usage is very idiomatic C++. But you have to remember the ():
log_error() << "Ooops " << 23 << ", 0x" << std::setbase(16) << 23;
This line will print out the message and throw an exception.
You can customize this however you want. Write to logfiles, add timestamps or other helpful information, verbosity levels and thresholds. It is even possible to have most cases completely optimized out in production builds.
Live example
C++ is not C! While you can use C-style (and often C) code this is not advisable. Firstly you should not normally rely on macros as they violate the type system, use (possibly inlined or constexpr) functions instead. Then you should not use C-style error handling technique, use exceptions instead. I'd also recommend against variadic arguments in general and finally you don't need C-style string formatting techniques -> this is C++, use stringstreams to format your code.
In your particular case I'd do something like this:
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
inline void fatal(std::string msg) {
// clean_up
throw std::runtime_error(msg);
}
int main(){
std::ostringstream msg;
msg << "Just a test: " << 1 << 2;
if(1) fatal(msg.str());
return 0;
}
I also have to point out that C++ and C are two different languages with different patterns and idioms. C++ has better alternatives for many C constructs which are more type-safe and thus preferable. IN your case, I would throw an exception in this case. If you ban catch(...) in your code, it will terminate your program. When the exception is propagated, the compiler will also call destructors of objects and thus do clean-up. If you haven't, I recommend you read up on resource-acquisition-is-initialization (RAII). Since it looks like you are transitioning from C to C++, I recommend to read the tour of C++ which shows fundamental C++ principles. For RAII, the gist is to manage resources in special handler objects which allocate in the constructor and deallocate in the destructor, and implement move semantics. This way, you cannot leak resources. Example implementations are std::vector, std::unique_ptr or std::iostream. As another example, consider mutex locking/unlocking:
class Mutex {
public:
void lock() { ... }
void unlock() { ... }
};
When you use it, it easy to forget unlocking in your code, especially when making modifications to existing code. Also, in case of exceptions, you need try/catch blocks to unlock all the time. Instead, define a MutexLocker class:
class MutexLocker
{
public:
MutexLocker(std::mullptr_t) = delete;
MutexLocker(Mutex* m): mutex_(m) {mutex_->lock();}
MutexLocker(MutexLocker const&) = delete;
MutexLocker& operator=(MutexLocker const&) = delete;
MutexLocker(MutexLocker&& l): mutex_(l.mutex_) {l.mutex_ = nullptr;}
MutexLocker& operator=(MutexLocker&& l)
{
mutex_ = l.mutex_,
l.mutex_ = nullptr;
return *this;
}
~MutexLocker() {if (mutex_) {mutex_->unlock()} };
private:
Mutex* mutex_;
};
Now, you can never forget to unlock a Mutex. The MutexLocker object cannot be copied, but you can transfer ownership. This is superior to anything you can do in C.
For formatting output, you can google "variadic template printf" which should give you some examples, e.g. on Wikipedia:
void printf(const char *s)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
throw std::runtime_error("invalid format string: missing arguments");
}
}
std::cout << *s++;
}
}
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
std::cout << value;
s += 2; // this only works on 2 characters format strings ( %d, %f, etc ). Fails miserably with %5.4f
printf(s, args...); // call even when *s == 0 to detect extra arguments
return;
}
}
std::cout << *s++;
}
}
Or you can use a library, e.g. boost::format or probably thousands of other implementations. If it is only for logging, you could take a look at a logging framework, e.g. boost.log.
First, even it often leads to harder to maintain code, you call always use C techniques in C++. stdio.h functions work natively in C++ and almost all macro are translated the same.
If you want to make use of c++ goodies (better type control at compile time)... you will have to forget old C variadic functions, notably all xprintf. There may be one interesting part anyway with templates.
Anyway the example given in the referenced Q&A is all you need here. Formatting instructions are simply injected in streams the same values are.
But here is a C++11 example showing that you can do what you want without using any macro. It is much longer than the C macro version, but it looks form me much more clear and extensible without the ugly do { ... } while 0 idom:
#include <iostream>
#include <string>
// disp is a variadic templated function injecting any arguments to a stream
// version for one single arg
template <typename T>
void disp(std::ostream& out, T arg) {
out << arg;
}
// recursively displays every arg
template <typename T, typename ... U>
void disp(std::ostream& out, T arg, U ... args) {
disp(out, arg) ;
disp(out, args...);
}
/* fatal displays its args to std::cout, preceded with "FATAL " and followed
* by a newline.
* It then does some cleanup and exits
*/
template<typename ... T>
void fatal(T ... args) {
std::cout << "FATAL ";
disp(std::cout, args...);
std::cout << std::endl;
// cleanup
exit(1);
}
int main() {
int i = 21;
int j = 32;
std::string s = "foo";
if(1) fatal(1, " " , s, " ab ", i, " 0x", std::hex, j);
return 0;
}
output is
FATAL 1 foo ab 21 0x20
Last but not least, you'd better use a throw FatalException() where FatalException is a subclass of std::exception instead of directly use exit(1). You could even write to a stringstream and pass the resulting string to the exception instead of writing to a real stream, but then you should be prepared to deal with bad_alloc exceptions.
I've got a simple Trace class that logs entering and exiting a method:
#include <iostream>
class Trace
{
public:
Trace() {std::cout << "Enter" << std::endl;}
~Trace()
{
std::cout << "Exit" << std::endl;
}
};
void foo()
{
Trace trace;
std::cout << "foo..." << std::endl;
}
int main()
{
foo();
return 0;
}
output:
Enter
foo...
Exit
Now I want to be able to enable/disable tracing. So I'll do something like this:
#include <iostream>
class Trace
{
public:
Trace() {std::cout << "Enter" << std::endl;}
~Trace()
{
std::cout << "Exit" << std::endl;
}
static bool enabled;
};
bool Trace::enabled = false;
void foo()
{
if(Trace::enabled)
Trace trace;
std::cout << "foo..." << std::endl;
}
int main()
{
Trace::enabled = true;
foo();
return 0;
}
The problem is that now the trace instance is scoped to the if statement and therefore the following output is produced:
Enter
Exit
foo...
Is there any way to get the right output in the latter case, without using smart pointers? I want to have the least overhead possible if tracing is disabled.
P.S. Please note that my real-world Trace class consists of a few more lines, not just "Enter" and "Exit".
P.S.2 Due to the performance considerations, I do not want the trace instance to be created on the stack if tracing is disabled.
Is there any way to get the right output in the latter case, without using smart pointers? I want to have the least overhead possible if tracing is disabled.
Modern compilers optimize simple smart pointers out entirely. You should feel free to use RAII and smart pointers where that makes sense in your code. Code cleanly and clearly and avoid micro-optimizations like this because they almost never help and frequently make things worse.
why not put the test on enabled inside your Trace constructor and destructor?
Rewrite your Trace class to
class Trace
{
public:
Trace()
{
if(Trace::enabled)
std::cout << "Enter" << std::endl;
}
~Trace()
{
if(Trace::enabled)
std::cout << "Exit" << std::endl;
}
static bool enabled;
};
bool Trace::enabled = false;
and just create the variable without if:
void foo()
{
Trace trace;
std::cout << "foo..." << std::endl;
}
Besides the suggestion to put the trace-enabled checking into the Trace class, as Tom already suggested,
Is it possible to extend the scope of a variable beyond the if statement without using pointers?
You shouldn't try this. Even with pointers the scope limits of a variable cannot be extended. (Well, just for the record, the scope of a variable that is declared in the if condition includes also the else clause, and therefore also chained else ifs.)
Update: A personal thought about the trace class approach
Even I thought this kind of trace helper
class Trace
{
public:
Trace(const char* scope): m_scope(scope) {
out("enter ");
}
~Trace() {
out("leave ");
}
const char* m_scope;
static void out(const char* s) {
if (enabled) {
std::cout << s << m_scope << std::endl;
}
}
static bool enabled;
};
bool Trace::enabled = false;
seems to be handy for tracking the control flow of a program, if some exceptions occur, you might prefer to miss the leave trace output. As I found out after experimenting some time with this approach, it's better to add plain trace commands.
Objects placed on the stack, have code to place them there created at compile time by the compiler. So the only way to ensure that an object is not created on the stack is to do so at compile time. There is no way to achieve this at run time.
Now assuming that you do need to optimize the trace object out (you've profiled your program), one way to achieve what you are looking for is to use macros (which are evaluated by the pre-processor just before compilation) - something like:
#define TRACE_ON // comment this to disable Trace
#ifdef TRACE_ON
#define TRACE() Trace trace
#else
#define TRACE()
#endif
and then use it like:
void foo()
{
TRACE();
std::cout << "foo..." << std::endl;
}
You want something like this:
class Trace
{
public:
Trace() {
if (enabled) {
std::cout << "Enter" << std::endl;
}
}
~Trace() {
if (enabled) {
std::cout << "Exit" << std::endl;
}
}
static bool enabled;
};
bool Trace::enabled = false;
I have a series of member functions that are all very similar, and I think I might be able to make my code more maintainable with a template or some other approach, but I am not sure how to do it.
Here is an example of one of my functions:
void CalController::bgc_cmd(const std::string& s) {
try {
this->cohort_ptr->md->set_bgcmodule(temutil::onoffstr2bool(s));
LOG(note) << "CalController turned bgc module to "
<< s <<" via cohort pointer...";
} catch (const std::runtime_error& e) {
LOG(warn) << e.what();
}
}
My other functions are identical except for:
function name (i.e. bgc_cmd(..), env_cmd(..), dsl_cmd(..)
member function (of the md class) that is called within the try...catch block
Essentially I'd like to avoid having to duplicate the try..catch block and LOG(..) message in each of my CalController::XXX_cmd(...) functions.
Using boost::function and or boost::bind would be fine, I am just going in circles and can't figure out how to set this up.
You could just write a member function to do all that stuff. No bind or template necessary since everything is a function on md that takes the same argument type. I'm going to use MD as the type of md, and I'm assuming onoffstr2bool returns a bool:
void set_cmd(void (MD::*fn)(bool), const std::string& name, const std::string& s)
{
try {
(this->cohort_ptr->md->*fn)(temutil::onoffstr2bool(s));
LOG(note) << "CalController turned " << name << " to "
<< s <<" via cohort pointer...";
} catch (const std::runtime_error& e) {
LOG(warn) << e.what();
}
}
Which you would then call like:
void CalController::bgc_cmd(const std::string& s) {
set_cmd(&MD::set_bgcmodule, "bgc module", s);
}
I think you can get what you want with a simple, regular function. No need for a template:
void CalController::do_cmd(boost::function<void (String)> fun, const std::string& s) {
try {
fun(temutil::onoffstr2bool(s));
LOG(note) << "CalController turned bgc module to "
<< s <<" via cohort pointer...";
} catch (const std::runtime_error& e) {
LOG(warn) << e.what();
}
}
Then you can make your other methods something like:
void CalController::bgc_cmd(const std::string& s) {
// here TypeOfMd is whatever the type is for this->cohort_ptr->md.
// This binds the "this pointer" for set_bgcmodule to this->cohort_ptr->md
do_cmd(boost::bind(&TypeOfMd::set_bgcmodule, this->chort_prt->md), s);
}
A few things to note here:
With C++11 lambdas and the new function classes boost isn't necessary
I think the above works, but I'm not sure that saving a few lines of code is worth the extra complexity and loss of readability. It may also get hard to maintain as you want to make minor changes like slightly different log messages for each method.
It's been a while since I wrote any C++ and even longer since I did any boost stuff so while I think the above is the right general idea, I'd be surprised if it actually compiled.
If using C++11, You can create a function with a more generic name, let's say exex_cmd.
You can then pass a lambda function as argument and execute it inside the try/catch block - no need for a template use.
//WARNING: Untested code - the point is that you get the idea. Modify at will.
void CalController::exec_cmd(const std::function<void (void)> func) {
try {
//Invoke lambda.
//The string is passed via closure implementation,
//but you can always pass it as normal argument if you want.
func();
LOG(note) << "CalController turned bgc module to "
<< s <<" via cohort pointer...";
} catch (const std::runtime_error& e) {
LOG(warn) << e.what();
}
}
Then, create 3 wrapper methods, invoking exec_cmd, but passing a different lambda as argument:
void CalcController::bgc_cmd(const std::string& s){
CalcController::exec_cmd([=] () {
//Taking closures into control, to avoid passing the string as argument.
this->cohort_ptr->md->set_bgcmodule(temutil::onoffstr2bool(s));
})
}
void CalcController::env_cmd(const std::string& s){
CalcController::exec_cmd([=] () {
//different function invocation here.
})
}
Similarly, you can do it for all your functions.
You can look here for more about C++11's lambdas.
A similar approach in plain-old C++ is to define a function pointer type and pass a function pointer to your exec_cmd, create normal functions following the type signature and pass them as arguments, or pass a member function pointer - You can look at Barry's answer for that.
I'm providing a c++ wrapper to the thread safe strerror_r in code like this:
struct MyErrno {};
std::ostream& operator<<(std::stream& os, const MyErrno& err)
{
const int len = 128
char buf [len];
os << strerror_r(errno, buf, len);
return os;
}
This is just a simple wrapper so in C++ code I can say something like
<< MyErrno() << ..
and use the threadsafe printing of the errno. It also seems to be ok to use 128 becuase the man page says strerror_r will either return a pointer to an immutable static string (presumably null terminated) or a pointer to buf after filling it in with a null terminator regardless of size...just not sure if there's something wrong with this simple wrapper (potentially buggy)
I don't understand the complete context in which you want to use this (in particular, what is the role of struct MyErrno, and what is StreamErrno, since your operator<< definition applies to a value of type sockaddr_in which isn't used).
However, in general terms, this is not a safe way to use errno, although it's a perfectly safe way to use strerror_r.
The problem is that you are mostly likely using this in a context like this:
if ((something) != OK) {
std::cerr << "Something bad happened: "
<< (some value which causes your function to be called)
<< ...
}
That is, there will probably be some system call (outputting the string "Something bad happened") between the system call which failed, leaving a value in errno, and the use of errno in your function. Pretty well any system call can cause errno to be set, even if the error is harmless; consequently, best practice is to grab the value of errno immediately. This would be a good reason to use a custom type like MyError:
struct MyError {
int error;
MyError(int err) : error(err) {}
};
std::ostream& operator<<(std::ostream& os, const MyError& e) {
// as with your function, but using `e.error` instead of `errno`
}
if ((something) != OK) {
MyError e(errno);
std::cerr << "Something bad happened: " << e
<< ...
}
I like using sentry classes in c++, but I seem to have a mental affliction that results in repeatedly writing bugs like the following:
{
MySentryClass(arg);
// ... other code
}
Needless to say, this fails because the sentry dies immediately after creation, rather than at the end of the scope, as intended. Is there some way to prevent MySentryClass from being instantiated as a temporary, so that the above code either fails to compile, or at least aborts with an error message at runtime?
I can't think of an automatic way to detect if you make this mistake or not. You could always create a macro that expands to the correct thing and use that to declare the sentry instead if you keep using it wrong.
#define MY_SENTRY_CLASS(_X) MySentryClass _sentry(_X)
and then use
MY_SENTRY_CLASS(arg);
or put a post-it on your monitor to remind you.
The only thing you could do is make the constructors private and force access through a helper function. This is far less similar than the initial construction syntax and less likely to be mistaken. You could also allocate on the heap (still a waste) but it's much easier to spot. However, if you want your class to be constructible, you can't stop people constructing rvalues of that type.
Edit: IF you know that MySentryClass always takes an argument, you could disallow construction AND and only allow operator=(arguments). This would force you to do
MySentryClass x;
x = arg;
You could do some kind of method chain for it.
MySentryClass x;
x.SetArg1(arg).SetArg2(arg2).construct();
No, there is no exit from this problem. To make objects on the stack, you have to have public constructors, and if you have public constructors, you can make the mistake you are reporting.
Not sure you'll like this solution, but the solution may well be grep:
find /path/to/project -type f -name \*.cpp -print0 | xargs grep -0 'MySentryClass('
Another thing you could do is use sed or perl to preprocess your source file, replacing MySentryClass( with \n#error MySentryClass used incorrectly\n, which hopefully will give you a line number that's close to where the error is. How to do this depends on your build system.
I think the #define is the best method.
But just as an option for not using #define:
Main
int main()
{
try
{
S arg1;
// This will not compile
// MySentry x1 = MySentry::CreateSentry(arg1);
S arg3;
MySentry x2(MySentry::CreateSentry(arg3));
S arg2;
// This will not compile
// MySentry(arg2);
S arg4;
// This will generate a runtime exception
// It will never call start() or end()
//MySentry::CreateSentry(arg4);
}
catch(std::exception const& e)
{
std::cout << "Exception : " << e.what() << "\n";
}
}
Edited. Now works better.
#include <stdexcept>
#include <iostream>
class S
{
public:
void start() {std::cout << "Start\n";}
void end() {std::cout << "End\n";}
};
class MySentry
{
struct Init
{
Init(S& s) : arg(s),bad(true) {}
~Init() {if (bad) {throw std::runtime_error("Bad usage of MySentry");}}
S& arg;
mutable bool bad;
};
public:
static Init CreateSentry(S& arg) { return Init(arg);}
explicit MySentry(Init const& arg)
: obj(arg.arg)
, bad(false)
{
arg.bad = false;
std::cout << "Created\n";
obj.start();
}
MySentry(MySentry const& rhs)
: obj(rhs.obj)
, bad(false)
{
std::cout << "Copied (this may not appear)\n";
std::cout << "If the optimizer kicks in then the copy may be elided.\n";
// But if it did not optimize out then
// We have to mark the temporaty as bad
// And not call end() in its destructor.
// Note: Never call start() here as it will always be called in the
// main private constrctor above
rhs.bad = true;
}
~MySentry()
{
if (!bad)
{
// Everything working
obj.end();
}
std::cout << "Destroyed\n";
}
private:
S& obj;
mutable bool bad;
};
What you are trying to do is perfectly legal in C++ and I don't think there is a way to disallow it.