auto, try-catch, and scopes - scope

I have a piece of code like this:
auto theval = myfunc();
dosomething(theval);
Now, I want to wrap the first part in a try/catch block:
try {
auto theval = myfunc();
} catch (const std::exception& ex){
// do some error handling
}
dosomething(theval);
Unfortunately, this doesn't work, because theval is inside the try scope.
The conventional way to solve this would be to just move the declaration outside the scope like this:
auto theval;
try {
theval = myfunc();
} catch (const std::exception& ex){
// do some error handling
}
dosomething(theval);
But this doesn't work either, because auto can't be used without an initialization.
Is there a way in which I can solve this without having to explicitly use the return type of myfunc and without having to move the call to dosomething inside the try block?

One possible solution is to use decltype like this:
decltype(myfunc()) theval;
try {
theval = myfunc();
} catch (const std::exception& ex){
// do some error handling
}
dosomething(theval);
perhaps augmented with std::remove_reference<...>::type to avoid issues with functions returning references.

Related

Discuss how the finally block works

I am using Visual Studio 2019, and I have a piece of code that uses finally block, I have declared a std::string object at the beginning of each Test1(), Test2() and Test3() functions.
I put a break point inside the finally block of each function to see the str variable, and as a result the str variable is reset to Empty in the Test1() and Test2() functions. Only in Test3() function is not reset.
I discovered that str is reset if a return statement is encountered before entering the finally block.
I don't understand what is going on, in the code of my software there are many places where finally block is used like the example above, I need to understand the exact mechanism of it so that I can fix potential bugs in the application.
The following is the code of the Test functions
void Test1()
{
string str = "Test1";
try
{
int* i = NULL;
*i = 0; //This command will raise an exception
return;
}
catch (Exception^ e)
{
return;
}
finally
{
int i = 0; //'str' is rested as empty when entering here
}
}
void Test2()
{
string str = "Test2";
try
{
int* i = NULL;
return;
}
catch (Exception^ e)
{
return;
}
finally
{
int i = 0; //'str' is rested as empty when entering here
}
}
void Test3()
{
string str = "Test3";
try
{
int* i = NULL;
}
catch (Exception^ e)
{
}
finally
{
int i = 0; //'str' is NOT reset to empty when entering here
}
}
Thank you so much!
I debug and double check, found that destructor of local variables will be destroyed when encountering return statement, destructor is called before entering finally block. Only if no return statement is encountered will these destructors be called after the Finally block (regardless of whether an exception occurs or not).
Due to this inconsistency, I could only work around it by not using any finally blocks in the code anymore, replacing it with goto statements or equivalent.
P/S: I am configuring the project with SEH Exceptions (/EHa) option.

Why is ThreadAbortException-like exception not being caught

(In case you're interested, the background for this question is here, but I don't think it's critical for this particular question.)
We're trying to run a series of report exports (a third party method call) one at a time in separate threads, so we can kill off the thread if it takes too long. The ugly, but best-so-far, idea is to use Thread.Abort to kill the thread exporting a given report, then do a ResetAbort to allow the rest of the code to continue.
The proof of concept code looks like this:
public RunningMethod()
{
Report myReport = new Report();
for (int i = 0; i < 10; i++)
{
Thread reportThread = new Thread(() => DoBackgroundJob(myReport, "test" + i.ToString()));
reportThread.Start();
bool finished = reportThread.Join(TimeSpan.FromMilliseconds(100));
if (!finished)
{
reportThread.Abort();
}
}
}
protected void DoBackgroundJob(Report myReport, string reportFilename)
{
try
{
report.ExportToPdf(#"C:\" + reportFilename + ".pdf");
}
catch (ThreadAbortException)
{
}
break;
}
I'm getting a strange result when I run this...the Export line seems to throw an exception that seems like it should be a ThreadAbortException, but apparently is not, since it doesn't get caught by the catch (ThreadAbortException), but is caught by a catch (Exception).
I'd like to know what kind of exception I'm getting, but I can't see it because when I try to view it I only get "Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack."
Is there a way to determine what is happening? What exception is really being thrown here?

__finally in C++ Builder 2010 losing scope?

Here is a very strange thing which I don't think should happen:
UnicodeString test = "abc";
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
// At this point the "test" variable should still be in scope???
test = "xyz"; // PROBLEM here - test is NULL instead of "abc"! Why?
}
If I remove the return a; in the try-catch block the test variable is still defined. Is there a particular reason why after the above construct the UnicodeString seems to go out of scope? Is it a bug with C++ Builder 2010? I understand that return returns from function but it should still retain variable scope in the __finally block shouldn't it?
I did a bit more analysis and it seams that once you execute return statement all local objects from stack are acting as destroyed. If you try using heap objects instead this won't happen.
UnicodeString *test = new UnicodeString("abc");
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
ShowMessage(*test); // "abc"
*test = "xyz";
}
delete test;
Using smart pointers like unique_ptr will again result in loosing an object in __finally since return will initiate it's destruction.
(Remy posted this in comments but did not post an answer here)
When a return statement is hit within a try...finally block, what happens is that any local objects are destroyed (as they would be for any other return) before the __finally block is entered.
So by the time your code gets up to test = "xyz";, test has already been destroyed, causing undefined behaviour.
I guess it is a matter of semantics whether you call this a bug or a design flaw, but either way it is something to bear in mind when using try...finally. My personal advice would be to just not use it at all; the Standard C++ techniques of try...catch and RAII can solve any problem.

function return values c#

I am trying to get to grips with C# having not coded for many years and my previous experience being in ANSI C.
I have read a number of books and searched online but one aspect is evading me and I am hoping someone here can help.
In the past I would declare a function and if there was a possibility of something not happening within the function (i.e. file not found etc.) declare the return to be an integer. I would then return 0 if all was well and a value if not. The value would correspond to where the function failed to execute fully and I could branch accordingly from where I called it.
if(function1())
{
// all my error stuff, maybe a switch/case etc.
}
All the examples I have found in C# seem to avoid this technique and I was hoping to get some understanding here.
Thanks in anticipation.
(I know I am a fossil). :)
Exceptions are the approach you use in C# and similar languages.
It goes like this:
try
{
function();
}
catch(FileNotFoundException e)
{
// File not found
}
catch(UnauthorizedAccessException e)
{
// User doesn't have right to access file
}
// etc...
To make this work, function shouldn't return a status code but instead throw an exception in case of an error.
Please note that the exceptions I illustrated in the code block above are thrown by the framework if you try to access a file and one of those errors is happening. So you don't actually have to do this yourself.
Furthermore, in C# there is no implicit conversion from integral values to bool, i.e. if(function()) is invalid, if function returns an int. You would need to write it like this:
if(function() != 0)
{
// all your error stuff
}
There's nothing to stop you doing this (though there are better ways of handling the errors - exceptions for example).
If you do want to carry on with this approach, the biggest problem you are having is that in C# you can't treat an integer as a boolean so your if test won't compile. What you need is:
if (function1() != 0)
{
}
But to check the value you'd need:
int result = function1();
switch (result)
{
case 1:
// Handle this case
break;
case 2:
// Handle this case
break;
default:
// All OK
break;
}
It would be better to return an enumerated type for each error case so that you don't have magic numbers, but exceptions are the way to go:
try
{
function1();
}
catch (SpecificException1 e1)
{
// Handle this case
}
catch (SpecificException2 e2)
{
// Handle this case
}
What you shouldn't have is a general exception handler:
catch (Exception e)
{
}
This just hides other potential problems.
If you want to follow that pattern of checking return value instead of managing errors, you better use enumarations than plain numbers.
For example:
public enum ResultType
{
Error = 0,
Success,
Waiting
}
public ResultType function()
{
if (still_waiting)
return ResultType.Waiting;
if (error_has_occured)
return ResultType.Error;
return ResultType.Success;
}
public void Main()
{
ResultType result = function();
switch (result)
{
case ResultType.Success:
MessageBox.Show("all is good");
break;
case ResultType.Waiting:
MessageBox.Show("still waiting...");
break;
case ResultType.Error:
MessageBox.Show("error has occurred");
break;
}
}
Behind the scenes, it's still using numbers but you put some meaning to each number.
if(function()==1)
{
}
int function()
{
int returnVal =0;
// do stuff
// if true return returnVal =1 else set returnVal =0;
return returnVal;
}

Access violation, when using shared_ptr on legacy code

I implement a new module using shared_ptr etc. in our legacy app, however I get a access violation, when shared_ptr is calling the destructor.
app:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg)); // _stringmsg is initialized before
Process(msg);
break;
}
Process():
bool Process(std::tr1::shared_ptr<CDataMsg> msg)
{
try
{
switch (msg->getDataType())
{
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild> data(std::tr1::static_pointer_cast<CMyDataChild>(base));
// do some stuff with data
std::tr1::shared_ptr<CRequest> request(new CRequest(data->getParam1(), data->getParam2()));
handler->AddRequest(request->getBin());
break;
}
default:;
}
return true;
}
catch (...)
{
// exception handling
}
return false;
}
Destructor:
CDataMsg::~CDataMsg()
{
if (m_data)
delete m_data;
m_data = NULL;
}
m_data is a CMyData* (cannot be changed at this point).
CDataMsg is a container, which holds data of type CMyData. CmyDataChild is a subclass of CMyData, which is used here.
I have breakpoint in the destructor, but the debugger stops only, when shared_ptr is calling it and then I get the access violation already.
As you have confirmed in your comment msg->getData() returns a pointer to a member variable of msg (presumably m_data) and it will be deleted when this switch block scope exits:
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild>
data(std::tr1::static_pointer_cast<CMyDataChild>(base));
// do some stuff with data
std::tr1::shared_ptr<CRequest>
request(new CRequest(data->getParam1(), data->getParam2()));
handler->AddRequest(request->getBin());
break;
}
The destructor of msg will be invoked later when this switch block scope exits:
case ENUM_DATA:
{
std::tr1::shared_ptr<CDataMsg> msg(new CDataMsg(_stringmsg));
Process(msg);
break;
}
and attempt to redelete the member variable m_data.
Also:
case ENUM_MYDATATYPE:
{
std::tr1::shared_ptr<CMyData> base(msg->getData());
std::tr1::shared_ptr<CMyDataChild>
data(std::tr1::static_pointer_cast<CMyDataChild>(base));
...
}
data is pointing to the same object as base. When this scope exits base will be deleteded twice.
Whenever I see bugs like this, I immediately think double delete.
std::tr1::shared_ptr<CMyData> base(msg->getData());
if (m_data) delete m_data; //- in CDataMsg destructor
Is it possible that 'm_data' is being deleted twice? Once in the shared_ptr and once in the CDataMsg destructor.

Resources