In C++ leave scope when error occurs without exceptions - c++

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.

Related

std::async is not working in c++11, linux platform

bool tf()
{
sleep(5000);
return true;
}
int main()
{
std::future<bool> bb = std::async(std::launch::async, tf);
bool b = false;
while(1)
{
if(b == true) break;
b = bb.get();
}
return 0;
}
why don't work?
I intended to terminate program after 5 seconds. However, the program is freezing.
There is a much better alternative to the direct use of invoking a global sleep. Use the <chrono> header and the string literals it provides together with std::this_thread::sleep_for. This is less error prone, e.g.
#include <chrono>
// Bring the literals into the scope:
using namespace std::chrono_literals;
bool tf()
{
std::this_thread::sleep_for(5s);
// ^^ Awesome! How readable is this?!
return true;
}
Together with the rest of the snippet you posted, this should work as intended.

Expanding macro within macro

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

Continuations/Coroutines/Generators in C++ / gcc / linux

Background: I'm trying to figure out how to implement continuations/coroutines/generators (whatever the following is called) by posing this toy problem. The environment is C++11 on gcc 4.6 and linux 3.0 x86_64. Non-portable is fine but using an external library (boost.coroutine, COROUTINE, etc) is not allowed. I think longjmp(3) and/or makecontext(2) and friends may help but not sure.
Description:
The following toy parser is supposed to parse sequences of as and bs of equal length. ie
((a+)(b+))+
such that the length of the second bracketed production equals the third.
When it finds a production (eg aaabbb) it outputs the number of as it finds (eg 3).
Code:
#include <stdlib.h>
#include <iostream>
using namespace std;
const char* s;
void yield()
{
// TODO: no data, return from produce
abort();
}
void advance()
{
s++;
if (*s == 0)
yield();
}
void consume()
{
while (true)
{
int i = 0;
while (*s == 'a')
{
i++;
advance();
}
cout << i << " ";
while (i-- > 0)
{
if (*s != 'b')
abort();
advance();
}
}
}
void produce(const char* s_)
{
s = s_;
// TODO: data available, continue into consume()
consume();
}
int main()
{
produce("aaab");
produce("bba");
produce("baa");
produce("aabbb");
produce("b");
// should print: 3 1 4
return 0;
}
Problem:
As you can see the state of the consume call stack must be saved when yield is called and then produce returns. When produce is called again, consume must be restarted by returning from yield. The challenge would be to modify the way produce calls consume, and implement yield so they function as intended.
(Obviously reimplementing consume so that it saves and rebuilds its state defeats the purpose of the exercise.)
I think what needs to be done is something like the example on the bottom of the makecontext man page: http://www.kernel.org/doc/man-pages/online/pages/man3/makecontext.3.html, but its not clear how to translate it onto this problem. (and I need sleep)
Solution:
(Thanks to Chris Dodd for design)
#include <stdlib.h>
#include <iostream>
#include <ucontext.h>
using namespace std;
const char* s;
ucontext_t main_context, consume_context;
void yield()
{
swapcontext(&consume_context, &main_context);
}
void advance()
{
s++;
if (*s == 0)
yield();
}
void consume()
{
while (true)
{
int i = 0;
while (*s == 'a')
{
i++;
advance();
}
cout << i << " ";
while (i-- > 0)
{
advance();
}
}
}
void produce(const char* s_)
{
s = s_;
swapcontext(&main_context, &consume_context);
}
int main()
{
char consume_stack[4096];
getcontext(&consume_context);
consume_context.uc_stack.ss_sp = consume_stack;
consume_context.uc_stack.ss_size = sizeof(consume_stack);
makecontext(&consume_context, consume, 0);
produce("aaab");
produce("bba");
produce("baa");
produce("aabbb");
produce("b");
// should print: 3 1 4
return 0;
}
Its fairly straight-forward to use makecontext/swapcontext for this -- you use makecontext to create a new coroutine context and swapcontext to swap between them. In you case, you need one additional coroutine to run the consume infinite loop, and you run main and produce in the main context.
So main should call getcontext+makecontext to create a new context that will run the consume loop:
getcontext(&consume_ctxt);
// set up stack in consume_context
makecontext(&consume_ctxt, consume, 0);
and then produce will switch to it instead of calling consume directly:
void produce(const char* s_)
{
s = s_;
swapcontext(&main_ctxt, &consume_ctxt);
}
and finally yield just calls swapcontext(&consume_ctxt, &main_ctxt); to switch back to the main context (which will continue in produce and immediately return).
Note that since consume is an infinite loop, you don't need to worry too much about what happens when it returns (so the link will never be used)

How to implement final conditions properly?

This is what I'm trying to do (this is a simplification of a real project):
int param;
int result;
void isolated(int p) {
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
} catch (...) {
throw "problems..";
}
}
I can't change the way process() works, since this function is not created in the project and is a third-party function. It works with global variables param and result and we can't change this.
The problem appears when isolated() is called back from process() with another parameter. I want to catch this situation, but don't know how to do it, since finally is absent in C++. I feel that I should use RAII technique, but can't figure out how to do it in this case properly.
This is how I can make it with code duplication:
int param;
int result;
void isolated(int p) {
static bool running;
if (running) {
throw "you can't call isolated() from itself!";
}
running = true;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
running = false;
} catch (...) {
running = false; // duplication!
throw "problems..";
}
}
"finally" like situations are handled in C++ using guard objects, that do their finally thing in the destructor. This is IMHO much more powerful approach, because you have to analyze the situation to finalize in order to create a reuseable object. In this case, we need to make process rentrant, because parameters and returns are passed in globals. The solution is to save their values on entry and restore them on exit:
template<class T>
class restorer
{
T &var; // this is the variable we want to save/restore
T old_value; // the old value
restorer(const restorer&);
void operator=(const restorer&);
public:
restorer(T &v) : var(v), old_value(v) {}
~restorer() { var=old_value; }
};
int param;
int result;
int isolated(int p) {
restorer<int> rest_param(param);
restorer<int> rest_result(result);
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
Maybe I didn't get it right, but why don't you use a flag? You want to know when the isolated() is called from the process(), right?
int isolated(int p) {
static int execDeep = 0;
execDeep++;
// your code here
execDeep--;
}
Now you can check 'execDeep' value, > 1 means it is called from the process() while still being executed.
I still don't quite sure how finally is related here, but you could try Boost.ScopeExit if you want to avoid creating a scope guard structure yourself.
Example:
#include <boost/scope_exit.hpp>
#include <cstdio>
int isolated(int p) {
static bool running = false;
if (running) {
printf("Throwing %d\n", p);
throw p;
}
printf("Starting %d\n", p);
running = true;
BOOST_SCOPE_EXIT( (p)(&running) ) { // <--
printf("Stopping %d\n", p); // <--
running = false; // <--
} BOOST_SCOPE_EXIT_END // <--
// ...
if (p)
isolated(p*10);
// ...
printf("Returing %d\n", p);
return 4;
}
int main() {
printf(">> first\n");
isolated(0);
printf(">> second\n");
try {
isolated(1);
printf(">> third (should not be printed.)\n");
} catch(int p) {
printf("Caught %d\n", p);
}
isolated(0);
printf(">> fourth\n");
return 0;
}
Result:
>> first
Starting 0
Returing 0
Stopping 0
>> second
Starting 1
Throwing 10
Stopping 1
Caught 10
Starting 0
Returing 0
Stopping 0
>> fourth
Could this work?
int save = -10000000000;
int param;
int result;
int isolated(int p) {
if (save != -10000000000)
{
// run the other condition
}
else
{
save = p;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
}
If I understand correctly, you want to automatically set the running flag to false at the end of function. If that is the requirement then you can use the ScopeGuard approarch mentioned in the link.

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.