For the below C++ code, I am getting an compiler error:
class Mkt
{
int k;
public:
Mkt(int n): k(n)
{
throw;
}
~Mkt()
{
cout<<"\n\nINSIDE Mkt DTOR function:\t"<<endl;
}
void func1()
{
cout<<"\n\nINSIDE FUNC1 function....value of k is:\t"<<k<<endl;
}
};
int main(int argc, char* argv[] )
{
try
{
std::auto_ptr<Mkt> obj(new Mkt(10)); //no implicit conversion
obj.func1(); //error C2039: 'func1' : is not a member of 'std::auto_ptr<_Ty>'
}
catch(...)
{
cout<<"\n\nINSIDE EXCEPTION HANDLER..........."<<endl;
}
return 0;
}
I am not able to understand why I am getting the error C2039? I am using VS 2008 compiler.
Pls help.
Thanks
It is auto_ptr, this means, that it is pointer :). You must use operator->:
obj->func1();
You have to use ->
obj->func1();
auto_ptr doesn't have func1(), but it has operator ->() that will yield a Mkt* pointer stored inside and then -> will be used again on that pointer and this will call the Mkt::func1() member function.
Be aware that after you fix the compilation problem (change dot-operator into -> operator) you will encounter a huge run-time problem.
Mkt(int n): k(n)
{
throw;
}
throw without an argument is meant to be used inside catch-blocks and causes re-throwing handled exception. Called outside catch-blocks will result in a call to abort function and your program termination.
You probably meant something like
throw std::exception();
or, better,
throw AnExceptionDefinedByYou();
This is very basic thing in c++ .. auto_ptr - the "ptr" stands for "pointer",
Related
I need to hook into C++'s exception throwing mechanism like this:
namespace __cxxabiv1
{
extern "C" void __cxa_throw(void* voidPointerToActualObject, std::type_info* stdTypeInfoOfActualObject, void (*destructor)(void *))
{
// If thrownException is a custom exception type or something deriving from it, poke a value into it.
}
}
If you're wondering "Why would you do that?"
I have this simple example of throwing an exception that's part of a very simple class hierarchy:
#include <stdexcept>
class Upper : public std::exception
{
public:
int pokeMe = 111111;
};
class Lower : public Upper {};
int main()
{
throw Lower();
}
#include <cxxabi.h>
namespace __cxxabiv1
{
extern "C" void __cxa_throw(void* voidPointerToActualObject, std::type_info* stdTypeInfoOfActualObject, void (*destructor)(void *))
{
// The point is to do the equivalent of this:
Lower* staticallyTypedPointerToActualObject = reinterpret_cast<Lower*>(voidPointerToActualObject);
auto thisWorks = dynamic_cast<Upper*>(staticallyTypedPointerToActualObject);
thisWorks->pokeMe = 222222;
// But we don't know the actual static type, so we can't get a statically typed pointer. We only have a void* and a type_info:
auto abiTypeInfoOfActualObject = dynamic_cast<const abi::__class_type_info*>(stdTypeInfoOfActualObject);
auto abiTypeInfoOfUpper = dynamic_cast<const abi::__class_type_info*>(&typeid(Upper));
Upper* thisDoesNotWork = reinterpret_cast<Upper*>(abi::__dynamic_cast(voidPointerToActualObject, abiTypeInfoOfActualObject, abiTypeInfoOfUpper, -1));
thisDoesNotWork->pokeMe = 333333;
// Elided for clarity: Call the original __cxa_throw function here
// Instead, suppress these warnings:
(void)destructor; // Unused parameter
while (1) { } // Return from non-returning function
}
}
I don't see a reason why __dynamic_cast shouldn't be able to upcast, but it returns nullptr.
Why? And how do I get it to work?
It seems to be able to do downcasts just fine, BTW:
auto abiTypeInfoOfActualObject = dynamic_cast<const abi::__class_type_info*>(&typeid(Upper)); // Plonking this here for testing
auto abiTypeInfoOfUpper = dynamic_cast<const abi::__class_type_info*>(&typeid(Lower)); // Casting to Lower instead of Upper
Lower* thisDoesNotWork = reinterpret_cast<Lower*>(abi::__dynamic_cast(voidPointerToActualObject, abiTypeInfoOfActualObject, abiTypeInfoOfUpper, -1));
I managed to dig up this archived conversation from 2004:
The ABI document does not require that __dynamic_cast perform a
derived-to-base cast. Those __dynamic_cast operations that can
actually be performed statically by the compiler must be performed
statically by the compiler -- the runtime library does not expect to
be called in that situation.
So that answers that question. Greeeeeeat.
But the conversation luckily mentions:
Yes; the holder knows the static type; it can throw a pointer of that
type. The cast operation can catch the pointer type it's looking for,
or fail the cast with catch(...).
That gave me the idea to try this (simplified version):
namespace __cxxabiv1
{
using ThrowFunction = decltype(__cxa_throw)*;
ThrowFunction oldThrowFunction = nullptr;
extern "C" void __cxa_throw(void* voidPointerToActualObject, std::type_info* stdTypeInfoOfActualObject, void (*destructor)(void *))
{
if (oldThrowFunction == nullptr)
{
oldThrowFunction = (ThrowFunction)dlsym(RTLD_NEXT, "__cxa_throw");
}
try
{
oldThrowFunction(voidPointerToActualObject, stdTypeInfoOfActualObject, destructor);
}
catch (Upper& ex)
{
ex.pokeMe = 333333;
}
catch (...)
{
}
oldThrowFunction(voidPointerToActualObject, stdTypeInfoOfActualObject, destructor);
}
}
And I can't believe it but it actually works!
Edit: Disclaimer: It seems that this way, the destructor callback is actually called twice, because if use std::string pokeMe, the string is trashed by the time I get to the second call to oldThrowFunction. I'll experiment around with over the next few days.
Edit2: That's indeed the case. I couldn't find anything indicating whether __cxa_throw accepts nullptr as the destructor argument (it didn't crash for me, at least), so the safest bet is to pass a pointer to an empty dummy function:
void dummyDestructor(void*)
{
}
//...
oldThrowFunction(voidPointerToActualObject, stdTypeInfoOfActualObject, &dummyDestructor);
Edit 3: Goddamnit! It seems that this causes memory corruption. malloc crashes with a segfault at a later point when doing this.
Back to square -5.
I have a simple class:
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- Ambiguity is here! I want to call 'void f()'
}
I want to resolve ambiguity of a method call in favour of the exception-throwing method by any means.
The rationale behind such interface:
To have the noexcept(true) and noexcept(false) interface,
To allow optionally get extra information via a pointer in the noexcept(false) variant - while the noexcept(true) variant will always pack this information inside an exception.
Is it possible at all? Suggestions for a better interface are also welcome.
Having functions with this kind of signatures is obviously a bad design as you've found out. The real solutions are to have different names for them or to lose the default argument and were presented already in other answers.
However if you are stuck with an interface you can't change or just for the fun of it here is how you can explicitly call void f():
The trick is to use function pointer casting to resolve the ambiguity:
a.f(); // <- ambiguity is here! I want to call 'void f()'
(a.*(static_cast<void (A::*)()>(&A::f)))(); // yep... that's the syntax... yeah...
Ok, so it works, but don't ever write code like this!
There are ways to make it more readable.
Use a pointer:
// create a method pointer:
auto f_void = static_cast<void (A::*)()>(&A::f);
// the call is much much better, but still not as simple as `a.f()`
(a.*f_void)();
Create a lambda or a free function
auto f_void = [] (A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
// or
void f_void(A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
f_void(a);
I don't know if this is necessary better. The call syntax is definitely simpler, but it might be confusing as we are switching from a method call syntax to a free function call syntax.
Both versions f have different meanings.
They should have two different name, as:
f for the throwing one, because using it means that your are confident on success, and failure would be an exception in the program.
try_f() or tryF() for the error-return based one, because using it means that failure of the call is an expected outcome.
Two different meanings should be reflected in the design with two different name.
Because it seems fundamentally obvious to me, I may be missing something or may not fully understand your question. However, I think this does exactly what you want:
#include <utility>
class A {
public:
bool f(int* status) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- now calls 'void f()'
a.f(nullptr); // calls 'bool f(int *)'
}
I simply removed the default argument from the noexcept variant. It's still possible to call the noexcept variant by passing nullptr as an argument, which seems a perfectly fine way of indicating that you want to call that particular variant of the function - after all, there's going to have to be some syntactic marker indicating which variant you want to call!
I agree with other users' suggestions to simply remove the default argument.
A strong argument in favour of such a design is that it would be in line with the new C++17 filesystem library, whose functions typically offer callers the choice between exceptions and error reference parameters.
See for example std::filesystem::file_size, which has two overloads, one of them being noexcept:
std::uintmax_t file_size( const std::filesystem::path& p );
std::uintmax_t file_size( const std::filesystem::path& p,
std::error_code& ec ) noexcept;
The idea behind this design (which is originally from Boost.Filesystem) is almost identical to yours, except of the default argument. Remove it and you do it like a brand new component of the standard library, which obviously can be expected not to have a completely broken design.
In C++14 it's ambiguous because noexcept is not part of the function signature. With that said...
You have a very strange interface. Although f(int* status = nullptr) is labelled noexcept, because it has a twin that does throw a exception, you are not really giving the caller a logical exception guarantee. It seems you simultaneously want f to always succeed while throwing an exception if the precondition is not met (status has a valid value, i.e not nullptr). But if f throws, what state is the object in? You see, your code is very hard to reason about.
I recommend you take a look at std::optional instead. It'll signal to the reader what you are actually trying to do.
C++ already has a type specifically used as an argument to disambiguate between throwing and non-throwing variants of a function: std::nothrow_t. You can use that.
#include <new>
class A {
public:
bool f(std::nothrow_t, int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // Calls 'void f()'
a.f(std::nothrow); // Calls 'void f(std::nothrow_t, int*)'
}
Though I would still prefer an interface where the name distinguishes the variants, or possibly one where the distinction isn't necessary.
Here's a purely compile-time method.
It may be useful if your compiler happens to have trouble optimizing away function pointer calls.
#include <utility>
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
template<void (A::*F)()>
struct NullaryFunction {
static void invoke(A &obj) {
return (obj.*F)();
}
};
int main() {
A a;
// a.f(); // <- Ambiguity is here! I want to call 'void f()'
NullaryFunction<&A::f>::invoke(a);
}
So you are trying to throw an exception if the code is unprepared for an error return?
Then, how about
class ret
{
bool success;
mutable bool checked;
int code;
public:
ret(bool success, int code) : success(success), checked(false), code(code) { }
~ret() { if(!checked) if(!success) throw code; }
operator void *() const { checked = true; return reinterpret_cast<void *>(success); }
bool operator!() const { checked = true; return !success; }
int code() const { return code; }
};
This is still an Abomination unto Nuggan though.
By removing the if(!success) check in the destructor, you can make the code throw whenever a return code is not looked at.
I have the following code:
class ClassA
{
public:
ClassA(std::string str);
std::string GetSomething();
};
int main()
{
std::string s = "";
try
{
ClassA a = ClassA(s);
}
catch(...)
{
//Do something
exit(1);
}
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
I would like the last line could access the a variable. How could I achieve that, given ClassA doesn't have default constructor ClassA() and I would not like to use pointers? Is the only way to add a default constructor to ClassA?
You can't or shouldn't. Instead you could just use it within the try block, something like:
try
{
ClassA a = ClassA(s);
std::string result = a.GetSomething();
}
catch(...)
{
//Do something
exit(1);
}
The reason is that since a goes out of scope after the try block referring to the object after that is undefined behavior (if you have a pointer to where it were).
If you're concerned with a.GetSomething or the assignment throws you could put a try-catch around that:
try
{
ClassA a = ClassA(s);
try {
std::string result = a.GetSomething();
}
catch(...) {
// handle exceptions not from the constructor
}
}
catch(...)
{
//Do something only for exception from the constructor
exit(1);
}
You can use some sort of optional or just use std::unique_ptr.
int main()
{
std::string s = "";
std::unique_ptr<ClassA> pa;
try
{
pa.reset(new ClassA(s));
}
catch
{
//Do something
exit(1);
}
ClassA& a = *pa; // safe because of the exit(1) in catch() block
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
Of course, just extending the try block to include the usage of a is the simplest solution.
Also, if you were really planning to exit(1) or otherwise abort the program on failure then simply don't put a try block here at all. The exception will propagate up, aborting the program if it is not caught .
One alternative is to use std::optional . This is the same sort of concept as using a pointer, but it uses automatic allocation and so you are less likely to create a memory leak. This is currently experimental status; you can use boost::optional instead if your compiler doesn't have std::experimental::optional:
#include <experimental/optional>
using std::experimental::optional;
using std::experimental::in_place;
// ...
optional<ClassA> a;
try
{
a = optional<ClassA>(in_place, s);
}
catch(...)
{
// display message or something
}
std::string result;
if ( a )
result = a->GetSomething();
I'd like to reiterate though that this is a bit of a spaghetti style and it'd be better to design your code differently so you aren't continually testing whether construction succeeded or failed.
This requires ClassA be movable or copyable. The in_place is a special argument which invokes a perfect forwarding constructor for the remaining arguments. Without in_place you can only give an actual ClassA as constructor argument, it doesn't consider implicit conversions to ClassA. (This is how optional avoids the ambiguity between copy-construction and list-initialization from object of the same type).
I have a general question regarding the syntax of throwing an object. Consider:
#include <stdio.h>
struct bad { };
void func() {
throw bad;
}
int main(int, char**) {
try {
func();
} catch(bad) {
printf("Caught\n");
}
return 0;
}
This code does not compile (g++ 4.4.3), as the 'throw' line must be replaced with:
throw bad();
Why is this? If I'm creating a stack-allocated bad, I construct it like so:
bad b;
// I can't use 'bad b();' as it is mistaken for a function prototype
I've consulted Stroustrup's book (and this website), but was unable to find any explanation for what seems to be an inconsistency to me.
throw bad;
doesn't work because bad is a data type, a structure (struct bad). You cannot throw a data type, you need to throw an object, which is an instance of a data type.
You need to do:
bad obj;
throw obj;
because that creates an object obj of bad structure and then throws that object.
You need to throw an instance of the struct.
void func() {
bad b;
throw b;
}
The difference is that throw's argument is an object, not a type. Declaring a variable as bad b is of the syntax [type] [object_name];. And type != instance.
This question provides more clarity on the problem described here. I did some more investigation and found that the stack unwinding is not happening in the following piece of code:
class One
{
public:
int x ;
};
class Wrapper
{
public:
Wrapper(CString csText):mcsText(csText)
{
CString csTempText;
csTempText.Format("Wrapper constructor :: %s\n", mcsText);
OutputDebugString(csTempText);
}
~Wrapper()
{
CString csTempText;
csTempText.Format("Wrapper destructor :: %s\n", mcsText);
OutputDebugString(csTempText);
}
CString mcsText;
};
class Test
{
public:
void notifyError()
{
try
{
int x = 10;
}
catch(...) {}
}
void OnRecvBuffer()
{
try
{
Wrapper a("AddRef");
One* p = NULL;
p->x = 10;
}
catch(...)
{
notifyError();
}
}
};
int main()
{
Test* pTest = new Test;
pTest->OnRecvBuffer();
OutputDebugString("Test");
}
I compiled this code using VC6 SP5 compiler and the output is "Wrapper constructor :: AddRef!!!" (i.e. the destructor of wrapper object which was constructed on stack is not called. Is this the expected behavior ? or is it a bug with VC compiler ? Can I use some compiler flags so that the stack unwinding happens in this case?
The C++ standard does not give anything to work with in case of Undefined Behavior. Even if MS does. That's a platform specific thing -- so beware. Some such floating point exceptions are turned to Win32 exceptions which you can attempt to catch with _set_se_translator(). The problem is you can catch Win32 exceptions but then your stack will not be unwound properly. At least that is not something you can bet your life on. Wherein lies the futility of the exercise.
Update: The exception is thrown intentionally to check the stack unwinding. The question is why Wrapper class's destructor is not getting called. – Naveen
If this is the case -- don't do it. There are better ways to throw exceptions than via Undefined Behavior.
E.g:
void OnRecvBuffer()
{
try
{
Wrapper a("AddRef");
throw 42; // this'll throw an exception without invoking UB
}
catch(...)
{
notifyError();
}
}
You cannot dereference a NULL pointer. You are invoking Undefined Behavior here:
One* p = NULL;
p->x = 10;
After that line all bets are off and you could have killed us all ;)
p is a pointer to a One object. It should contain the address of an One object. You have initialized it to 0 -- there is no object at address 0. 0 is not a valid address for any object (this is guranteed by the standard).
If you want to use SEH, you must use _set_se_translator function and /EHa compiler option.
Because C++ regular exception does not handle this kind of exception, you have to use SEH which does not know anything about the app and does not unwind.
This is undefined behavior:
One* p = NULL;
p->x = 10;
At this point the application is free to crash without unwinding the stack.
If you want to test the stack unwinding replace this with:
throw 42; // Life the Universe and Everything thrown away
You should not dynamically allocate all your objcts this is C++ not Java!
int main()
{
Test pTest; // Note the lack of new!
pTest.OnRecvBuffer();
OutputDebugString("Test");
}