The following code compiles successfully with g++ version 5.1.0. Notice the catch without a corresponding try in the member function foo::bar(). I was wondering if this syntax was legal and if so what effect it had?
struct foo
{
void bar()
{
}
catch (...)
{
}
};
int main ()
{
foo f;
f.bar();
return 0;
}
Originally seen in Catch block in constructor without try
The example you give,
struct foo
{
void bar()
{
}
catch (...)
{
}
};
… is not valid standard C++.
It might be a g++ language extension.
The catches in the question you linked to look like function catch blocks, except that also that requires a try keyword.
As others were quick to point out, the quoted code is not well-formed C++. It was allowed through due to an oversight in the rewritten C++ parser that's used in recent GCC 4/5/6 branches.
I filed this as GCC Bug/PR c++/71909. As can be seen there, commits have just been made to all 3 branches, to ensure that a function-catch block will only be accepted if a matching function-try block has already been encountered. A 3-day turnaround, that's pretty good :-)
Thanks to Richard for bringing this up!
Related
C++17 has a new attribute, [[nodiscard]].
Suppose, that I have a Result struct, which has this attribute:
struct [[nodiscard]] Result {
};
Now, if I call a function which returns Result, I got a warning if I don't check the returned Result:
Result someFunction();
int main() {
someFunction(); // warning here, as I don't check someFunction's return value
}
This program generates:
warning: ignoring return value of function declared with 'nodiscard'
attribute [-Wunused-result]
So far, so good. Now suppose, that I have a special function, for which I still want to return Result, but I don't want this warning generated, if the check is omitted:
Result someNonCriticalFunction();
int main() {
someNonCriticalFunction(); // I don't want to generate a warning here
}
It is because, someNonCriticalFunction() does something non-critical (for example, something like printf - I bet that no-one checks printf's return value all the time); most cases, I don't care if it fails. But I still want it to return Result, as in some rare cases, I do need its Result.
Is it possible to do this somehow?
Possible solutions which I don't like:
I would not like calling it as (void)someNonCriticalFunction(), because this function is called a lot of times, it is awkward
creating a wrapper around someNonCriticalFunction(), which calls (void)someNonCriticalFunction(): I don't want to have a differently named function just because of this
removing [[nodiscard]] from Result, and add it to every function which returns Result
Why not make use of std::ignore from the <tuple> header—that would make the discard explicit:
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
std::ignore = MyFunction();
return 0;
}
Compiler explorer of this code snippet: https://godbolt.org/z/eGPsjajz8
CPP Reference for std::ignore: https://en.cppreference.com/w/cpp/utility/tuple/ignore
I recommend the option you ruled out:
"removing [[nodiscard]] from Result, and add it to every function which returns Result."
But since you don't seem happy with it, here's another solution, using bog-standard inheritance:
struct [[nodiscard]] Result {
};
struct DiscardableResult: public Result {
};
For the functions where you can discard the result, use DiscardableResult as return type:
Result func1();
DiscardableResult func2();
func1(); // will warn
func2(); // will not warn
They say that every problem in computer science can be solved by adding another layer of indirection:
template <bool nodiscard=true>
struct Result;
template <>
struct Result<false> {
// the actual implementation
};
template <>
struct [[nodiscard]] Result<true>
: Result<false>
{
using Result<false>::Result;
};
This is effectively making Result conditionally [[nodiscard]], which allows:
Result<true> someFunction();
Result<false> someNonCriticalFunction();
int main() {
someFunction(); // warning here
someNonCriticalFunction(); // no warning here
}
Although really, this is identical to:
removing [[nodiscard]] from Result, and add it to every function which returns Result
which gets my vote to begin with.
You can suppress the warning with another C++17 attribute, namely [[maybe_unused]]
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
[[maybe_unused]] auto v = MyFunction();
return 0;
}
This way you also avoid the confusing dependency to std::tuple which comes with std::ignore, even CppCoreGuidelines is openly recommending to use std::ignore for ignoring [[nodiscard]] values:
Never cast to (void) to ignore a [[nodiscard]]return value. If you
deliberately want to discard such a result, first think hard about
whether that is really a good idea (there is usually a good reason the
author of the function or of the return type used [[nodiscard]] in the
first place). If you still think it's appropriate and your code
reviewer agrees, use std::ignore = to turn off the warning which is
simple, portable, and easy to grep.
Looking at C++ reference, officially std::ignore is only specified to be used in std::tie when unpacking tuples.
While the behavior of std::ignore outside of std::tie is not formally
specified, some code guides recommend using std::ignore to avoid
warnings from unused return values of [[nodiscard]] functions.
cast the result to a (void *).
int main()
{
(void *)someFunction(); //Warning will be gone.
}
This way you "used" your result as far as the compiler is concerned. Great for when you are using a library where nodiscard has been used and you really don't care to know the result.
On a recent bug hunt, I found an issue with returning a pointer to a member of a temporary variable. The offending (simplified) code was:
struct S {
S(int i) : i(i) {}
int i;
int* ptr() { return &i; }
};
int* fun(int i) { return S(i).ptr(); } // temporary S dies but pointer lives on
int main() {
int* p = fun(1);
return *p; // undefined
}
How to prevent this? GCC & Clang have -Waddress-of-temporary and -Wreturn-stack-address but they seem to loose trail because of ptr() acting as a middle man for the dirty deeds. They are only triggered when the pointer is taken directly:
int* fun(int i) { return &S(i).i; } // rightly fails to compile
My project also incorporates cppcheck in continuous integration but it also can't pick it up (raised here).
Which static analysis tool can prevent this class of bugs?
EDIT: GCC does pick it up since version 6.1.0 with -Wreturn-local-addr and (surprisingly) -O2 switched on.
I am a Cppcheck developer.
My project also incorporates cppcheck in continuous integration but it also can't pick it up.
interesting bug. This is the kind of bug that cppcheck wants to warn about. We have some related checks but this slipped through unfortunately.
Not really surprising given the regex nature of cppcheck.
I don't personally understand why some people say cppcheck is a regex tool.
It uses AST, context sensitive valueflow analysis, etc to detect bugs. So does GCC and Clang. Cppcheck is sometimes claimed to be a regex tool but GCC and Clang are not.
I have 220 "unreachable code" warnings in Boost.Variant, class boost::detail::variant::invoke_visitor:
template <typename T>
result_type internal_visit(T& operand, int)
{
return visitor_(operand);
}
.
boost_1_50_0\boost\variant\variant.hpp(859): warning C4702: unreachable code
line return visitor_(operand);.
First of all, how is this possible at all to have unreachable code in this simple single-line function? Which code is unreachable?
I cannot reproduce this warning in a simple case, seems because I don't understand what exactly causes it. The warning appeared after I implemented operator== for classes used in boost::variant.
Environment: VC++ 2010, Boost 1.50
EDIT:
the warning happens only in Release build (optimized), and only if I compare boost::variants. I use boost::variant with primitive and custom types. Custom types implements typical bool operator(CT const& lh, CT const& rh) as free functions.
I had this problem myself in VS 2017. If the compiler determines visitor_(T&) will always throw an exception, the "unreachable" part is the return. If you were to unwrap that into the following:
auto v = visitor_(operand);
return v;
The compiler would call out return v; as unreachable. In my case, I was using a Policy-based class and a NullPolicy threw exceptions. I ended up just removing the exception.
Fun fact: if you have LTCG on, you only get the error during the linking stage, so you don't even know where to start. Turning off LTCG but leaving on optimizations will at least let you narrow it down by making compilation of offending files fail.
Just in case someone else stumbles over the same thing: (I experienced this with MSVS 2017 v15.7.4)
class Widget
{
public:
void bar()
{
foo = 0; // C4702 here
}
void foobar()
{
return; // NOTE direct return here
bar();
}
private:
int foo;
};
This was in old code where someone had "commented out" the entire function foobar() leaving the original code for "future reference". (yes, source control is very hard to use)
Now in release mode the compiler inlined the function bar() which resulted in a C4702: unreachable code warning, but it indicated the first line of function bar() where seemingly nothing was wrong. (actually each line of code after the return; triggered the warning)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a generally accepted idiom for indicating C++ code can throw exceptions?
How do you indicate in your code when a C++ function is possible to throw something? I don't mean through documentation, but through syntax.
For example I tried placing a throw(std::exception) at the end of the function declaration, but that gave me a warning saying that "C++ exception specification ignored except to indicate a function is not __declspec(nothrow)", which I guess means the compiler ignored the throw and proceeded as if it were not there.
I also tried adding a throw() (without anything in the parenthesis) at the end of the declaration, but — contrary to my expectations — that means the function is expected to never throw anything: "function assumed not to throw an exception but does".
Atm I'm using throw(...) to syntactically indicate the function may throw as this doesn't give me any errors or warnings. Do you have any other suggestions as to how I might indicate this through syntax?
You don't. Exception specifiers do not mean "Here's what I can throw", they mean "if anything other than this gets thrown, go to std::terminate". This behavior is counterintuitive to the point that MSVC++ does not and will not support them.
The semantics of C++ is that you must assume a function can always throw.
Most of the compilers are non conforming to the standard when it comes to Exception specifications. Exceptions specifications are considered as an experiment that failed.
For example:
If you have a blank exception specification then what gets called? the unexpected() method or a bad_exception will be thrown and if both in what order?
#include "stdafx.h"
#include <stdio.h>
#include <exception>
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
void myunexpected ()
{
cerr << "unexpected called\n";
}
void doSomething(void) throw();
void doSomething(void) throw()
{
A obj;
obj.i= 100;
throw obj;
}
int _tmain(int argc, _TCHAR* argv[])
{
set_unexpected (myunexpected);
try
{
doSomething();
}
catch (bad_exception be)
{
puts("Caught something");
}
catch (A &obj)
{
puts("Caught Integer");
}
return 0;
}
If you run this code on Visual studio, you will see that the exception just gets caught by the appropriate handler.
So to conclude, Exception specifications is a failed experiment and it's best to avoid them.
Basically, throw specifiers are worthless, as was discovered after their introduction, unfortunately, and current compilers ignore them. They're deprecated, and quality libraries don't include them. Just don't bother with them. C++0x officially deprecates them, and only has a noexcept keyword.
I'm developing a C api for some functionality written in C++ and I want to make sure that no exceptions are propagated out of any of the exported C functions.
The simple way to do it is making sure each exported function is contained in a:
try {
// Do the actual code
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Let's say I know one exception that is often missed inside the C++ code is std::bad_alloc and I want to treat it specially I'd write something like this instead:
try {
// Run the actual code
} catch (std::bad_alloc& e) {
return ERROR_BAD_ALLOC;
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Is it possible to decompose this in some clever way so that I can globally treat some errors differently without adding a new catch statement for the exception handler around every exported function?
I'm aware of that this is possible to solve using the preprocessor, but before going down that road, I'd make sure there is no other way to do it.
You can use only one handler function for all possible exceptions, and call it from each or your API implementation functions, as below:
int HandleException()
{
try
{
throw;
}
// TODO: add more types of exceptions
catch( std::bad_alloc & )
{
return ERROR_BAD_ALLOC;
}
catch( ... )
{
return ERROR_UNHANDLED_EXCEPTION;
}
}
And in each exported function:
try
{
...
}
catch( ... )
{
return HandleException();
}
There already is a good answer. But just FYI, its called 'exception-dispatcher' idiom, see C++ FAQ.
What about:
try{
//Your code here
} catch(std::exception e)
{
return translateExceptionToErrorCode(e);
} catch(...)
{
return UNKNOWN_EXCEPTION_THROWN;
}
Jem answer is a little more simpler than this solution. But it is possible to substitute the use of a preprocessor macro with the use of templates. Something like this (more refinements you could made):
template <class T, void (T::*FUNC)()>
class CatchWrapper
{
public:
static void WrapCall(T* instance)
{
try
{
(instance->*FUNC)();
}
catch (std::bad_alloc&)
{
// Do Something 1
}
catch (std::exception& e)
{
// Do Something 2
}
catch (...)
{
// Do Something 3
}
}
};
class Foo
{
public:
void SomeCall()
{
std::cout << "Do Something" << std::endl;
}
};
int main(int argc, char* argv[])
{
Foo i;
CatchWrapper<Foo, &Foo::SomeCall>::WrapCall(&i);
return 0;
}
Do not ever use catch(...), unless you plan on more or less immediately re-throwing. You will certainly lost any error information you might have had to help you figure out the cause of the error.
I like your second scheme a little better - catch a known set of exceptions, ideally because they are the only ones your code will throw, and let the rest through - allowing the app to crash is possibly the best thing to do since you have invoked unknown behaviour it is best to "crash responsibly".
It would be a shame to loose error information at the language boundary. You really should try to translate all exceptions into an error code usable from C.
How you do it really depends on what your exception classes look like. If you control your exception class hierarchy, you can ensure that each class provides a translation using a virtual method. If not, you may still find it practical to use a translator function and test the types of the 'std::exception'-derived exception it receives to translate it into an error code, much like Jem suggested (remember: thrown exceptions will hurt performance anyway, so don't worry about the translation being slow).