Expanding macro within macro - c++

In the following example I expect to see
doSomething
asserting in "doSomething()"
However i dont see any output on console.
When I use HUTAssert(doSomething()) in main() , I see the expected output, so I expect this has to do with expending a macro within another macro
#include <iostream>
using namespace std;
#define LOPTAssertEnabled 1
#define HUTAssert(expr) ( (expr)? (void(0)) : assertMe(#expr) )
#define HAOPAssert(expr) ((isLOPTAssertEnabled())? HUTAssert(#expr) : void(expr))
void assertMe(char const* expr) {
std::cout <<" asserting in "<<expr;
}
bool doSomething() {
std::cout <<" did something "<<std::endl;
return false;
}
bool isLOPTAssertEnabled() {
return LOPTAssertEnabled;
}
int main() {
HAOPAssert(doSomething());
}

You can easily see what preprocessor is doing. For example, with gcc (g++) you can use the "-E" option to see what preprocessor is producing. In your case, you are getting this:
void assertMe(char const* expr) {
std::cout <<" asserting in "<<expr;
}
bool doSomething() {
std::cout <<" did something "<<std::endl;
return false;
}
bool isLOPTAssertEnabled() {
return 1;
}
int main() {
((isLOPTAssertEnabled())? ( ("doSomething()")? (void(0)) :
assertMe("\"doSomething()\"") ) : void(doSomething()));
}
I believe, this is not what your are expecting. However, if you strip off #, which is "stringfying" your token, from HUTAssert(#expr), I believe it will be close to what you are expecting

Related

Clang issues -Wunused-value depending on whether the code is called from a macro

I use a special assertion macros called CHECK. It is implemented like this:
#define CHECK(condition) check(condition).ok ? std::cerr : std::cerr
The user can choose to provide additional information that is printed if the assertion fails:
CHECK(a.ok());
CHECK(a.ok()) << a.to_string();
Notice the ternary operator in macro definition. It ensures that a.to_string() is executed only when the assertion fails. So far so good. I've been using this (and other similar) macros for a long time without any problems.
But recently I found that clang issues “expression result unused [-Wunused-value]” warning regarding the second std::cerr if CHECK is used inside another macro:
#define DO(code) do { code } while(0)
int main() {
do { CHECK(2 * 2 == 4); } while(0); // no warning
DO( CHECK(2 * 2 == 4); ); // warning
}
Full example: https://godbolt.org/z/5bfnEGqsn.
This makes no sense to me. Why would this diagnostic depend on whether the code was expanded from a macro or not? GCC issues no warnings in either case.
Two questions:
Is there any reason for such behavior or should I file this as clang bug?
How can I suppress this without disabling “-Wunused-value” altogether? I've tried [[maybe_unused]] and __attribute__((unused)) but they don't seem to work on statements.
I don't think that this is a good solution what I suggest here but you could change your code so that you will always use your std::cerr, by changing your check(condition).ok ? std::cerr : std::cerr to check(condition).ok ? std::cerr << "" : std::cerr << "":
#include <iostream>
struct CheckResult {
CheckResult(bool ok_arg) : ok(ok_arg) {}
~CheckResult() { if (!ok) abort(); }
bool ok;
};
inline CheckResult check(bool ok) {
if (!ok) std::cerr << "Assertion failed!\n";
return CheckResult(ok);
}
#define CHECK(condition) \
check(condition).ok ? std::cerr << "" : std::cerr << ""
#define DO(code) \
do { code } while(0)
int main() {
do { CHECK(2 * 2 == 4); } while(0);
DO( CHECK(2 * 2 == 4); );
}
Another thing you could do is to use a function that returns that std::cerr:
#include <iostream>
struct CheckResult {
CheckResult(bool ok_arg) : ok(ok_arg) {}
~CheckResult() { if (!ok) abort(); }
bool ok;
};
inline CheckResult check(bool ok) {
if (!ok) std::cerr << "Assertion failed!\n";
return CheckResult(ok);
}
[[maybe_unused]] inline std::ostream & get_ostream() {
return std::cerr;
}
#define CHECK(condition) \
check(condition).ok ? get_ostream() : get_ostream()
#define DO(code) \
do { code } while(0)
int main() {
do { CHECK(2 * 2 == 4); } while(0);
DO( CHECK(2 * 2 == 4); );
}
The [[maybe_unused]] here is not about the returned value but about the function in case that you change your code so that it is not used under certain conditions (maybe not needed here).
My major concern about your approach is this statement:
Notice the ternary operator in macro definition. It ensures that a.to_string() is executed only when the assertion fails.
Without reading the documentation and just looking at CHECK(a.ok()) << a.to_string(); on one would assume that a.to_string() will only be executed if the assertion fails.
For a standpoint of code review or collaboration, this can be really problematic.

How to defer computation in C++ until needed?

In C++(*), is it possible to have a structure that "defers" some computation until needed (and maybe never does the computation if not necessary)? My use case is as follows: I have roughly a dozen bool variables, each of which is computed with some function call. Following that, there is a rather long (and complex) conditional statement that uses those bool variables in different combinations to determine what action the code will take next.
Here is some contrived sample code to hopefully better illustrate what I'm doing:
bool const b1 = func1(param1,param2,param3);
bool const b2 = func2(param4);
// ...
bool const b15 = func15(param35,param36,param37,param38);
if (b1 && !b5 && (b2 || b3)) { do_something1(); }
else if (b3 && !b15 || (b4 && b9 && b6)) { do_something2(); }
else if (b14 || b10 || (!b11 && b7)) { do_something3(); }
else if (b8) {
if (!b1 || !b6) { do_something4(); }
else if ( /* ... */ ) // ... etc
}
// ... and on and on
That is a purely contrived example, but hopefully it illustrates the idea.
Clearly this code could be re-written without the bools, and the functions called directly in the big conditional statement. But I feel that would make the already not-easy-to-read code even harder to read, and more error prone. And this logic could change, so I feel the bools make it easier to manage from a refactoring perspective as well.
Furthermore, any bool might be referenced multiple times within the conditional; so using the functions directly means execution could be duplicated. (I was thinking std::bind might get me there from a readability perspective; but it would still potentially call any of the funcN() calls multiple times.)
What I'm looking for is the best of both words, like a "deferred" compute. What if instead of being computed and assigned explicitly at the start of the code, I could say, "only evaluate these as needed (and remember the result)". The big conditional statement is such that, generally, not all bools actually need to be computed to determine what happens next. The goal here is improved performance, as this code is called often. So I'm trying to reduce the amount of work done on each iteration.
(*) Preferably C++14 (or older), as that's what my employer is using.
Edit: What about something like this:
#include <iostream>
#include <functional>
//////////////////////////////////////////////////////////////////////////////
class Sum
{
public:
int sum(int const a, int const b) { ++n_calls_; return (a+b); }
int getNCalls() const { return n_calls_; }
private:
int n_calls_ = 0;
};
//////////////////////////////////////////////////////////////////////////////
template <class BoundFunc, typename RetType>
class DeferredCompute
{
public:
DeferredCompute(BoundFunc const& f) : func_(f) { }
RetType operator()()
{
if (!computed_)
{
value_ = func_();
computed_ = true;
}
return value_;
}
private:
bool computed_ = false;
RetType value_;
BoundFunc const& func_;
};
//////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
Sum s;
auto boundSum = std::bind(&Sum::sum, &s, 75, 25);
DeferredCompute<decltype(boundSum), int> deferredSum(boundSum);
// call function directly repeatedly
for (int i=0; i<5; ++i)
{
std::cout << "boundSum()=" << boundSum() << std::endl;
}
std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;
// should only call once
for (int i=0; i<5; ++i)
{
std::cout << "deferredSum()=" << deferredSum() << std::endl;
}
std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;
return 0;
}
Output:
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
s.getNCalls()=5
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
s.getNCalls()=6
std::async with the option std::launch::deferred is what you're looking for.
https://en.cppreference.com/w/cpp/thread/async
eg
auto future = std::async(std::launch::deferred, [](){return 5;});
// future isn't calculated yet
auto result = future.get();
// result = 5, and will remain cached while in scope.
At first, I would try using some lambda-closures.
const auto b1 = [&]() { return func1(param1,param2,param3); };
const auto b2 = [&]() { return func2(param4); };
// ...
const auto b15 = [&]() { return func15(param35,param36,param37,param38); };
if (b1() && !b5() && (b2() || b3())) { do_something1(); }
...
If you need to cache the bool results but not for the entire
lifetime of the program (static), this solution could
make it (three levels of lambda-closure; it's "Inception").
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
void
test(int i)
{
auto cache=[](auto expr)
{
return [expr, res=false, done=false]() mutable
{
if(!done) { res=expr(); done=true; }
return res;
};
};
auto b1=cache([&]() { std::cout << "(eval b1)"; return i>2; });
auto b2=cache([&]() { std::cout << "(eval b2)"; return i<5; });
std::cout << "1: b1=" << b1() << " b2=" << b2() << '\n';
std::cout << "2: b1=" << b1() << " b2=" << b2() << '\n';
}
int
main()
{
for(int i=0; i<6; ++i)
{
std::cout << "~~~~~~~~\n";
test(i);
}
return 0;
}
/**
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)1
2: b1=1 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)1
2: b1=1 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)0
2: b1=1 b2=0
**/
For the sake of readability and maintainability you could organise the program as a state machine. That provides you with the benefit of separating the state transitions and actions from one another, plus it should be reasonably simple to rewire the logic later should the necessity arise.
See here for some examples:
C++ code for state machine
What if instead of being computed and assigned explicitly at the start of the code, I could say, "only evaluate these as needed (and remember the result)"
/// #brief only evaluate these as needed (and remember the result)
class lazy final
{
mutable std::future<bool> value_;
public:
template<typename Functor>
lazy(Functor &&f)
: value_{ std::async(std::launch::deferred,
std::forward<Functor>(f)) }
{
}
operator bool() const
{
return value_.get();
}
};
client code:
auto b1 = lazy::lazy{[&]{ return func1(param1,param2,param3); }};
auto b2 = lazy::lazy{[&]{ return func2(param4); }};
// ...
bool const b15 = lazy::lazy{[&]{ return func15(param35,param36,param37,param38); }};
// rest remains the same as your contrieved example
I have not compiled this code. If working in c++14 (as you mention) you may need a factory function similar to this:
template<typename Functor>
auto make_lazy(Functor&& f) { return lazy<Functor>(std::forward<Functor>(f)); }
The only thing that changes is the declaration of your bX variables. You may also consider adding code that tells you how often each lazy evaluation is called in practice, declaring those bX variables first, and launching them immediately, in parallel, instead of in a deferred manner. But only do that after you measure performance both ways.

In C++ leave scope when error occurs without exceptions

In bash we can say:
(
set -e
function OnError { caller | { read line file; echo "in $file:$line" >&2; }; }
trap OnError ERR ## catch exception
echo hello ## step 1
false
echo "never come here"
)
# continue here
Every command returns exit code. Flag -e tells bash to check every result and exit if it is non-zero.
Exceptions in C++ provides similar logic:
#include <iostream>
using namespace std;
void step1(){
cout<<"hello"<<endl;
}
void step2(){
throw std::runtime_error("step2 always fail");
}
void step3(){
cout<<"never come here"<<endl;
}
int main(){
try{
step1();
step2(); // throws
step3(); // never come here
}catch(...){
cerr<<"caught error"<<endl;
}
// continue here
}
And this works pretty same. But need additional manipulations to detect from where exception was thrown.
Often C++ developers refuse using exceptions with -fno-exceptions. And code become looking like C – need to check result for every action.
#include <iostream>
using namespace std;
int step1(){
cout<<"hello"<<endl;
return 0;
}
int step2(){
return -1;
}
int step3(){
cout<<"never come here"<<endl;
return 0;
}
#define CHECK(err,msg) \
if(err){ \
cerr<<"error in "<<msg<<endl; \
break; \
}
int main(){
while(0){
CHECK(step1(),"step1");
CHECK(step2(),"step2");
CHECK(step3(),"step3");
}
// continue here;
}
And that looks slightly cumbersome. But here we can directly track file:line.
I would like to have clean code without exceptions. Like:
#include <iostream>
using namespace std;
enum Result {SUCCESS,FAIL};
Result step1(){
cout<<"hello"<<endl;
return SUCCESS;
}
Result step2(){
return FAIL;
}
Result step3(){
cout<<"never come here"<<endl;
return SUCCESS;
}
int main(){
{
step1(); // success
step2(); // fail , interrupt execution and go out of scope
step3(); // never come here
}
// continue here
}
How to achieve same behavior as in bash keeping code simple and and clean without exceptions?
You can (ab)use the fact that C++ uses lazy evaluation for checking boolean logic:
#include <iostream>
using namespace std;
bool step1(){
cout<<"hello"<<endl;
return true;
}
bool step2(){
return false;
}
bool step3(){
cout<<"never come here"<<endl;
return true;
}
bool executeSteps() {
return step1() && step2() && step3();
}
int main(){
executeSteps();
}
Since step2() returns false, the whole condition cannot evaluate to true, so the rest of it isn't even checked.
You don't even need a separate function for that (although ignoring the result of boolean calculations might be confusing to the readers):
int main(){
step1() && step2() && step3();
}
There are several implementations for such approach:
From https://buckaroo.pm/posts/error-handling-in-cpp:
loopperfect/neitherstd::expectedBoost Outcomebeark/ftl
and also https://github.com/TartanLlama/expected, imo the best.

Why doesn't my DirectX program recognize that I've released the escape key? (C++)

EDIT: After even more code modification, the error is still there, modified code shown:
KeyDown():
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
PollKeyboard():
LPDIRECTINPUTDEVICE8 di_keyboard;
void PollKeyboard()
{
long result = di_keyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);
char para[16];
itoa(result, para, 17);
if(result != DI_OK) MessageBox(NULL, para, "ERROR", MB_OK);
}
When I try to put MessageBox within a KeyDown() if statement (as seen below in the game loop), the MessageBox simply coninues to appear even if I stop pressing the key, ie: I press , the "Would you like to quit?" message box appears, I say no, It disappears and then instantly reappears, as if I were still holding the key.
This is my loop:
void GameRun(HWND hWnd) //called once every frame
{
PollKeyboard();
if(GetTickCount - start >= 30)
{
if(KeyDown(DIK_LEFT))
MoveLeft();
if(KeyDown(DIK_RIGHT))
MoveRight();
}
if(d3ddev->BeginScene())
{
//rendering
}
if(KeyDown(DIK_ESCAPE))
{
//any MessageBox()
int result = MessageBox(hWnd, "I'm causing so much trouble!", "IMMORTAL", MB_YESNOCANCEL);
if(result == IDYES)
//end
}
}
EDIT: The catch in PollKeyboard() displays the sequence 53gd6bcc, I could not, however, find the error code it corresponds to.
EDIT: After another test, I saw that even if the MessageBox is not within a KeyDown() if statement, the glitch still occurs.
EDIT: After a bit more testing, it appears that MessageBox itself is causing the glitch.
Because the sample code works, something else in your program is causing the bug. Try moving bits of the code below into your own until it works, then you will know which section of code was culprit.
Sample Code
Alright, huge code block coming up. This code works correctly for me. (Escape, along with all other keys successfully activate and deactivate). It's large, commented, and explains things fairly well. Try this, if it works, we'll examine other parts of your program, if not, I can only leave you with "Good luck", and take what you want:
// DirectInput
#define DIRECTINPUT_VERSION 0x0800
#include<dinput.h>
// Standard stuff
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
// Link from code, MSVC specific, could be done in project settings
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
// Utility lexical_cast, use Boost if possible.
// Simple replacement, converts a stream-able `T`
// to a string
template <typename T>
const std::string lexical_cast(const T& pValue)
{
std::stringstream ss;
ss << pValue;
return ss.str();
}
// Utility function + macro to execute DirectX code with exceptions.
// Kinda ugly, but helpful for us.
void check_error(HRESULT pResult, const std::string& pFuncName)
{
// DI_OK == S_OK, but S_OK is more general, so we'll use that
if (pResult != S_OK)
{
throw std::runtime_error("Error executing: " + pFuncName +
"! Returned: " + lexical_cast(pResult));
}
}
// Macro, makes calling the function easier. It is wrapped in
// an `if` statement for reasons outlined in:
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.5
#define CHECK_ERROR(x) if (true) { check_error(x, #x); } else (void)0
// The above gives the warning:
// "warning C4127: conditional expression is constant", disable below:
#pragma warning(disable: 4127)
// Manages input
class input_manager
{
public:
// Constants
static const int NumberKeys = 256;
// Creation
input_manager(void)
{
// Create input and keyboard (like I said, ugly macro, but helpful :] )
CHECK_ERROR(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, reinterpret_cast<void**>(&_input), 0));
CHECK_ERROR(_input->CreateDevice(GUID_SysKeyboard, &_keyboard, 0));
CHECK_ERROR(_keyboard->SetDataFormat(&c_dfDIKeyboard));
CHECK_ERROR(_keyboard->Acquire());
}
~input_manager(void)
{
// Free resources. Note: Many programmers
// unnecessarily wrap this stuff in
// `if (_keyboard !=0)`, and then
// `_keyboard = 0`. This is completely unnecessary,
// because destructors are only run one time.
// Also, I can assume they are valid, because if they
// weren't, we wouldn't be here (an exception would have
// been thrown)
_keyboard->Unacquire();
_keyboard->Release();
_input->Release();
// Also, if we wrapped this into a nice RAII class, we wouldn't
// be forced to write a destructor, but this is outside the scope.
// Feel free to ask how; additionally, since we're on the topic, if you'd
// like more tips handling input (I've written PLENTY of input managers)
// I'm free for asking about things like testing for triggers rather than pressed
// ("was it pressed, regardless if it's being held now" versus
// "is it being pressed"), etc.
}
// Operations
void update(void)
{
CHECK_ERROR(_keyboard->GetDeviceState(NumberKeys, reinterpret_cast<void*>(&_keys)));
}
// Query
bool key_pressed(int pKey) const
{
return test_key(pKey);
}
// Might wrap into an operator[] for convenience.
private:
// Constants
static const int PressMask = 0x80;
// Sorry for the confusion, but indeed, with
// `char`s the mask is simply 0x80.
// Utility
bool test_key(int pKey) const
{
return (_keys[pKey] & PressMask) != 0;
}
// Members
LPDIRECTINPUT8 _input;
LPDIRECTINPUTDEVICE8 _keyboard;
char _keys[NumberKeys];
};
void test_keys(const input_manager& input)
{
bool anyPressed = false;
for (unsigned i = 0; i < input_manager::NumberKeys; ++i)
{
if (input.key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
anyPressed = true;
}
}
if (!anyPressed)
{
std::cout << "No keys pressed." << std::endl;
}
}
void execute(void)
{
input_manager input;
std::cout << "Press Q to quit." << std::endl;
bool running = true;
while (running)
{
input.update();
if (input.key_pressed(DIK_Q))
{
running = false;
}
test_keys(input);
Sleep(0); // give some processor time
}
}
int main(void)
{
// Place real code in an execute function, so main
// is clean and ready to catch exceptions:
try
{
execute();
}
catch (const std::exception& e)
{
// Error!
std::cerr << "Unhandled exception:" << e.what() << std::endl;
}
}
Old suggestion:
Try catching the return value from GetDeviceState:
HRESULT result = // v Prefer C++-style casts
di_keyboard->GetDeviceState(sizeof(keys), reinterpret_cast<void*>(&keys);
if (result != DI_OK)
{
// uh-oh
std::cout << result << std::endl;
}
Compare it against the table here.
Old Semi-Answer:
Shortly after editing in the code in the Extra Stuff section, I realized the error, sorry I didn't catch it earlier. You're testing the wrong bit :)
Observe:
// v HERE! Should be 0x8000, not 0x80.
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
Try that:
int KeyDown(int key)
{
return (keys[key] & 0x8000);
}
Also, this should be moved into a constant to avoid magic numbers:
// somewhere, probably in the private section of the class or in a detail namespace:
static const int PushedMask = 0x8000;
// code reads better:
int KeyDown(int key)
{
return (keys[key] & PushedMask);
}
Lastly, in C++ you have a bool type, so take advantage of it!
// v here
bool KeyDown(int key)
{
return (keys[key] & PushedMask);
}
I know Visual Studio will warn about this conversion from int to bool, so you can get rid of it while also making your intents clearer:
bool KeyDown(int key)
{
return (keys[key] & PushedMask) != 0; // or == 1, your choice
}
Extra Stuff:
Try the following code:
#include <iostream>
#include <windows.h>
bool key_pressed(int pKeyCode)
{
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
}
void test_keys(void)
{
for (unsigned i = 0; i < 255; ++i)
{
if (key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
}
}
}
int main(void)
{
bool running = true;
while (running)
{
if (key_pressed(VK_ESCAPE))
{
running = false;
}
test_keys();
Sleep(0);
}
}
This works for me (responds to all keys, quits on escape). Minimal test case for GetAsyncKeyState. If this does not work, please add OS, Keyboard, etc, in your comment.
If you create a MessageBox(Null,...) you won't have any control over the window after it's creation. IE, the window won't disappear when you depress the key.
As for why it keeps on appearing, seems to have something to do with this:
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
keys consits of 1 byte long characters, while input_bit_num is a 2 byte value. While I don't honestly know which bit it is that you're looking for (0xff - 0x00 is the domain of 1 byte).
Honestly, I'm surprised that your code runs, unless the & operation is carrying over into keys[key-1] in which case any KeyDown is undefined, and KeyDown(...) when key is 0 is particularly dangerous.

What is good practice for generating verbose output?

what is good practice for generating verbose output? currently, i have a function
bool verbose;
int setVerbose(bool v)
{
errormsg = "";
verbose = v;
if (verbose == v)
return 0;
else
return -1;
}
and whenever i want to generate output, i do something like
if (debug)
std::cout << "deleting interp" << std::endl;
however, i don't think that's very elegant. so i wonder what would be a good way to implement this verbosity switch?
The simplest way is to create small class as follows(here is Unicode version, but you can easily change it to single-byte version):
#include <sstream>
#include <boost/format.hpp>
#include <iostream>
using namespace std;
enum log_level_t {
LOG_NOTHING,
LOG_CRITICAL,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
};
namespace log_impl {
class formatted_log_t {
public:
formatted_log_t( log_level_t level, const wchar_t* msg ) : fmt(msg), level(level) {}
~formatted_log_t() {
// GLOBAL_LEVEL is a global variable and could be changed at runtime
// Any customization could be here
if ( level <= GLOBAL_LEVEL ) wcout << level << L" " << fmt << endl;
}
template <typename T>
formatted_log_t& operator %(T value) {
fmt % value;
return *this;
}
protected:
log_level_t level;
boost::wformat fmt;
};
}//namespace log_impl
// Helper function. Class formatted_log_t will not be used directly.
template <log_level_t level>
log_impl::formatted_log_t log(const wchar_t* msg) {
return log_impl::formatted_log_t( level, msg );
}
Helper function log was made template to get nice call syntax. Then it could be used in the following way:
int main ()
{
// Log level is clearly separated from the log message
log<LOG_DEBUG>(L"TEST %3% %2% %1%") % 5 % 10 % L"privet";
return 0;
}
You could change verbosity level at runtime by changing global GLOBAL_LEVEL variable.
int threshold = 3;
class mystreambuf: public std::streambuf
{
};
mystreambuf nostreambuf;
std::ostream nocout(&nostreambuf);
#define log(x) ((x >= threshold)? std::cout : nocout)
int main()
{
log(1) << "No hello?" << std::endl; // Not printed on console, too low log level.
log(5) << "Hello world!" << std::endl; // Will print.
return 0;
}
You could use log4cpp
You can wrap your functionality in a class that supports the << operator which allows you to do something like
class Trace {
public:
enum { Enable, Disable } state;
// ...
operator<<(...)
};
Then you can do something like
trace << Trace::Enable;
trace << "deleting interp"
1. If you are using g++ you could use the -D flag, this allows the compilator to define a macro of your choice.
Defining the
For instance :
#ifdef DEBUG_FLAG
printf("My error message");
#endif
2. I agree this isn't elegant either, so to make it a bit nicer :
void verbose(const char * fmt, ... )
{
va_list args; /* Used as a pointer to the next variable argument. */
va_start( args, fmt ); /* Initialize the pointer to arguments. */
#ifdef DEBUG_FLAG
printf(fmt, &args);
#endif
/*This isn't tested, the point is to be able to pass args to
printf*/
}
That you could use like printf :
verbose("Error number %d\n",errorno);
3. A third solution easier, and more C++ and Unix like is to pass an argument to your program that is going to be used - as the macro earlier - to initialize a particular variable (that could be a global const).
Example :
$ ./myprogram -v
if(optarg('v')) static const verbose = 1;