Destructor not being called with smart or raw pointer [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Continuing from a previous question:
On this code, the destructors for Apple and Fruit don't get called at all. I have std::cerr statements in both and there's some clean up code in Apple that doesn't run. I thought calling delete was enough? Am I doing RAII correctly? I've also replaced the raw pointer with std::unique_ptr and the same result.
int32_t Fruit::frutificate(const Settings& settings) {
Fruit *listener;
if (settings.has_domain_socket()) {
listener = new Apple(settings);
} else {
listener = new Orange(settings);
}
int r = uv_run(listener->loop, UV_RUN_DEFAULT);
delete listener;
return r;
}
Update:
All classes have virtual destructors.

First, your immediate problem almost certainly that is that ~Fruit() is not virtual. Add that (virtual ~Fruit() = default or virtual ~Fruit() {} to class Fruit) and your code (as posted) will magically start to work.
However that is not what your code should be. Just working, well, not good enough.
There are a number of improvements you can make to your code. As a first improvement we'll use a unique_ptr: (as #Deduplicator mentioned above in comments)
int32_t Fruit::frutificate(const Settings& settings) {
std::unique_ptr<Fruit> listener;
if (settings.has_domain_socket()) {
listener.reset( new Apple(settings) );
} else {
listener.reset( new Orange(settings) );
}
int r = uv_run(listener->loop, UV_RUN_DEFAULT);
return r;
}
which uses RAII to ensure the lifetime of the listener is bounded. Much better, no more manual delete (which could be missed by accident, or exception).
In C++14, the .reset(new Blah(whatever)) can be replaced with = std::make_unique<Blah>(whatever);, and now your code never explicitly calls new and delete, which is a good habit to get into. However your code is tagged C++11, so I'll leave the C++11 version up above.
While that is better, we can do best. There is no need for using the free store (heap) at all.
A simple way to avoid the free store use is: (stolen from #Jarod in comments above)
int32_t Fruit::frutificate(const Settings& settings) {
if (settings.has_domain_socket()) {
return uv_run(Apple(settings).loop, UV_RUN_DEFAULT);
} else {
return uv_run(Orange(settings).loop, UV_RUN_DEFAULT);
}
}
which has the disadvantage of repeating the uv_run code (and can thus breed bugs). We can fix this with a lambda:
int32_t Fruit::frutificate(const Settings& settings) {
auto fruit_the_uv = [&](Fruit&& fruit) {
return uv_run(fruit.loop, UV_RUN_DEFAULT);
};
if (settings.has_domain_socket()) {
return fruit_the_uv( Apple(settings) );
} else {
return fruit_the_uv( Orange(settings) );
}
}
where we factor out the common code into a lambda, and then invoke it on the two branches. I used rvalue references as we are passing in temporary fruit.
Plus, fruit_the_uv reminds me of a 90s rap song whenever I read it. And that is a plus.

Related

Is it bad to return int for error checking in c++ [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
In C many functions return int if they need to let the calling code know if something went wrong in a function call.
C++ has exceptions which do the same thing but more formalized by the language. One advantage (or sometimes disadvantage) of returning an int instead is that you don't force the calling code to address when something has gone wrong, so it can ignore the warning if it doesn't matter in the context
Is it bad practice in C++ to return an int to indicate that something has gone wrong. Additionally, if it is bad practice what are better alternatives.
Is it bad practice in C++ to return an int to indicate that something
has gone wrong. Additionally, if it is bad practice what are better
alternatives.
Yes, it's terrible practice. If there is an error, always throw an exception. Unchecked errors are a pointless source of bugs, they work really poorly in certain language constructs like constructors, and they're hard to reason about in generic code.
If the operation succeeded but with some warning, you could consider using an enumeration (not int!) for the warning, although typically such operations can return multiple warnings.
i'd recommend a enum class for errorCodes, that way you do not accidentally mix them up with other errors or some actual int values
e.g.
enum class MyResultCode
{
NoError = 0,
InternalError,
DatabaseError,
}
as user4581301 suggested, you can add NumberErrors as a last enum value and accompany the enum class with some human-readable strings. This way you can log or display a nice error message
One of the main advantages of exceptions is, that you can isolate error handling code from business logic. Say you have a long chain of functions and the last function in the chain has to return an error:
int funcA()
{
try
{
return funcB();
}
catch(...)
{
// handle exception
}
}
int funcB()
{
return funcC();
}
int funcC()
{
// do some stuff
}
If an exception is thrown in funcC the exception will propagate to the closest try/catch block. Since there is not an immediate try/catch in funcC, all objects created in funcC will be destroyed and then it will move to funcB to look for a try/catch block and the same process will repeat. So by the time we hit the top level caller, the stack will be unwound so all objects created in the stack will be safely disposed of. Basically we handled the exceptional code only in one place funcA(). Also by using exceptions, you get contextual information as to what happened, for example:
int divide(int a, int b)
{
if(b == 0)
{
throw "Division by zero error";
}
return a / b;
}
With custom error codes, you to propagate the error manually all the way to the top so we will end up with error handling code in every layer:
// using error codes
int funcA()
{
int ret = funcB();
if(ret == someErrorCode)
{
return someErrorCode;
}
else
{
// do some stuff
return goodValue;
}
}
int funcB()
{
int ret = funcC();
if(ret == someErrorCode)
{
return someErrorCode;
}
else
{
// do some stuff
return goodValue;
}
}
int funcC()
{
// do some stuff
}

create function signature that return both true and false while providing details upon failure [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
The short version of this question is how to implement a single function that return both true and false while providing details upon failure (false)?
Say I want to create static function remove() that will get a path as a string and remove it from the file system.
Assuming remove operation may cause some unexpected errors, I'd like to be able to return a status.
Version 1
static bool remove( const string& path );
This will return true if path was removed and false otherwise.
But what if I need more details regarding the failure of the remove process?
Version 2
static void remove( const string& path );
This function now throw some exception on failure which will basically return the reason why remove process failed. This mandates each caller to use try-catch when calling this function which can be a bit annoying and ugly if you don't care about the result.
I trying to generate a clean signature that will allow me to combine both versions into a single one.
remove function is just one of many static utility functions so I'd like to avoid having to leave both versions (even though they are not overrideable at the moment).
Suggestion 1:
static bool remove( const string& path, bool throw_on_fail );
Now the caller can alternate both versions of the function by passing a boolean flag.
I don't like this suggestion. As I said remove function is just one of many static utility functions. I don't think adding boolean argument for each function is such a good idea.
Suggestion 2:
static EResultCode remove( const string& path );
Here we have an enum as the result.
This one is a bit better but I can already see such bugs as the next if statement if remove("f1"). getting int value 4 from remove() does not imply success.
Suggestion 3:
static Result remove( const string& path );
Here we have a class Result that will contain both Boolean and detailed description.
This seems like an overkill to me.
Question
I looked at the API of common c++ libraries interface, wx & boost. could not find overwhelming insights there.
I'm trying to come up with a generic signature for all those functions. which way would you go?
I would definitely go with the Result class approach.
Ignoring the question of whether exceptions are the right tool to handle a file-not-found error in the first place, an additional bool parameter to enable or disable them will make client code less readable because of all the true and false arguments whose meaning is completely unclear unless the reader consults remove()'s documentation or at least its signature:
remove("file.txt", true); // what's true?!
I would also refrain from error references. It is so frustrating when you (the function's client) are forced to use additional local variables which you might not even need later on. Very C++-unlike. This approach will eventually result in a lot of client code like this:
Error dummy;
remove("file.txt", dummy);
The Result class approach means clients will have to type a bit more if they need to know the details of an error, but their code will become much clearer and readable as a result of it. Your concern that this may put an additional burden on clients seems unfounded, at least if I imagine myself as the client of remove() :)
struct status {
std::string msg;
bool success;
status(): success(true) {}
status(std::string msg_): success(false), msg(msg_) {}
explicit operator bool() const { return success; }
};
static status const success;
status func1() { return true; }
status func2() { return success; }
status func3() { return status("something went wrong); }
if (func1()) { std::cout << "success!" << std::endl; }
if (func1().success) { std::cout << "success!" << std::endl; }
auto rc = func3();
if (!rc) { std::cout << "error" << rc.msg << std::endl; }
If you have a function remove(), and that functions purpose is to remove things from the file system, we should expect it to work in the normal case.
In the case where is can't work for some reason (there are a multitude of reasons it could fail) we should treat that as an exception to the normal working case.
I would suggest:
void remove() {...}
And calling it:
try
{
remove("/home/olduser");
}
catch(std::runtime_error& e)
{
std::cerr << "Failed to remove: " << e.what() << '\n';
}
Exceptions are part of the language for a reason, use them.
You said you looked to boost (and others) for inspiration. Look at the implementation of boost::asio. Almost all of the functions there have two overloads, one that takes an error code to report into, and one that has the same behavior but simply throws the error code as an exception in the case of failure.
Providing both may be overkill. My preference is to rely on exception handling, as it was specifically designed for handling these types of situations.
What I did in one case is have the function return a char
const*, with a nullptr for success, and the error message for
failure. Still, in this case, the functions were extern "C",
so I didn't have nearly as many alternatives. In C++, I'd
probably define a class, and return it. The class could have an
implicit conversion to bool if you wanted, but I'm not
convinced that it's a good idea; I'd have a succeeded function
which returned bool: it's a lot clearer.
Note that even in this case, you'll have to store the return
value into a local variable, in order to have the additional
information still present after you've detected the failure; you
cannot simply write:
if ( remove( path ) ) {
// error
} else {
// success
}
but need to write:
Results results = remove( path );
if ( !results ) {
// error, do something with results.message()
} else {
// success
}
Also rather painful, almost as much as a try catch.
You can use something like
static bool remove( const string& path, tStatus& myStatus );
And define tStatus as whatever type you want to return errors as. Could be as simple as typedef int tStatus;
You may use:
static bool remove(const string& path, std::nothrow_t);
static void remove(const string& path);
You could also let the function return a bool, and among the parameters you pass a reference to a structure that may contain the reason. Like this:
bool remove(const string& path, FailReason* fr){
//if the FailReason is a null pointer we don't fill it
If(fr != 0);
}
You can pass null in the fail struct

Returning a pointer in C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
I think my question sounds stupid and welcome downvote on me. If you are implementing a method in C++ which needs to return a pointer, is it safe to do that? If not, why?
Not a simple question. For instance: Best way of returning a pointer.
Ideally, you should try to avoid returning values that come with side-effects or obligations.
// This may be ok, it implies no burden on the user.
Manager* GetManager();
// But what if the user decides to call delete on the value you return?
// This is not unusual in C code, but carries a hidden contract:
// I allocate - you free.
const char* GetFilename(int fd)
{
char* filename = malloc(256);
sprintf(filename, "/tmp/tmpfile.%d", fd);
return filename;
}
C++ is about encapsulation and abstraction. You can codify the contract with your consumer by encapsulating a pointer you want to return. The idea here is that instead of exposing a pointer, you expose an object which is responsible for ownership of the pointer. Infact, recent versions of the language already do this for you with std::unique_ptr, std::shared_ptr and std::weak_ptr.
But a crude, simple RAII example might be:
class StrDupPtr
{
char* m_alloc;
public:
StrDupPtr(const char* src)
: m_alloc(strdup(src))
{}
~StrDupPtr()
{
free(m_alloc);
}
operator const char* () const { return m_alloc; }
// etc.
};
You're still returning a pointer here, but you've encapsulated it with a management contract and removed burden from the end-user to manage your resources.
You can't always avoid it, and when you have to, yes it can be dangerous.
int* AllocateMeSomeMemory()
{
int* memory = malloc(4 * sizeof(int));
// here, have four ints.
return memory;
}
int main() {
int* memory = AllocateMeSomeMemory();
memory[42] = 0xDeath; // yeah, it's not a valid hex number, but that's not really the problem.
}
Another common problem with pointers is that there's no way to tell how many people have them. Here's a contrived example:
void transferItem(userid_t user1, userid_t user2, itemid_t item) {
Account* a1 = GetAccount(user1);
Account* a2 = GetAccount(user2);
if (a1 != a2) {
transferItemInternal(a1, a2, item);
}
delete a2;
delete a1; // Sorry Dave, I can't do that. How about a nice game of CRASH?
}
Normally, a2 and a1 will be different, but when they're not...
Another common failure pattern with pointers is asynchronous callbacks:
// ask the database for user details, call OnLoginResult with userObj when we're done.
void login(int socket, userid_t userId, passwordhash_t pass) {
User* userObj = GetUserObj(userId, socket);
Query* query = Database()->NewQuery("SELECT * FROM user WHERE id = ? AND password = ?", userId, pass);
Database()->Queue(query, OnLoginResult, userObj);
}
void OnDisconnect(int socket, int reason) {
User* userObj = GetUserBySocket(socket);
if (userObj) {
UnregisterUserObj(userObj);
delete userObj;
}
}
void OnLoginResult(void* param) {
User* userObj = static_cast<UserObj*>(param);
// all well and good unless the user disconnected while waiting.
...
}
Yes it is. I assume you mean "Allocate and return" a pointer.
Its common to have initialisation functions which allocate a pointer to an object of some type, and then initialise the object itself. It will then be up to a different part of the program to release the memory.
Well it always depends on what you are doing. A pointer is simply a memory address, so it is similar to simply returning an integer. You should do more research on pointers and how to properly implement them
I sense this question might be closed quite soon, but I'll try to answer anyway.
Yes, it's "safe", as long as you're careful. In fact, it's a very common way to do things, particularly if you're interfacing with C APIs. Having said that, it's best to avoid doing so if you can, because C++ generally provides better alternatives.
Why should you avoid it? Firstly, let's say you have a method that looks like this:
MyStruct* get_data();
Is the return value a pointer to a single instance of MyStruct, or the start of an array? Do you need to free() the returned pointer? Or perhaps you need to use delete? Can the return value be NULL, and what happens if it is? Without looking at the documentation, you have no way of knowing any of these things. And the compiler has no way of knowing either, so it can't help you out in any way.
Better options:
If you want to return an array of values, use a std::array (if the size is fixed at compile-time), or a std::vector (if the size isn't known till run-time).
If you're trying to avoid copying a large struct, then return a reference, or a const reference if possible. That way the caller knows they won't receive a NULL value.
If you really need to return a pointer, than consider using a smart pointer instead -- that will help you sort out ownership issues. For example, std::shared_ptr uses reference counting, and std::unique_ptr ensures that a given pointer only ever has one owner.

Lazy object creation in C++, or how to do zero-cost validation

I've stumbled across this great post about validating parameters in C#, and now I wonder how to implement something similar in C++. The main thing I like about this stuff is that is does not cost anything until the first validation fails, as the Begin() function returns null, and the other functions check for this.
Obviously, I can achieve something similar in C++ using Validate* v = 0; IsNotNull(v, ...).IsInRange(v, ...) and have each of them pass on the v pointer, plus return a proxy object for which I duplicate all functions.
Now I wonder whether there is a similar way to achieve this without temporary objects, until the first validation fails. Though I'd guess that allocating something like a std::vector on the stack should be for free (is this actually true? I'd suspect an empty vector does no allocations on the heap, right?)
Other than the fact that C++ does not have extension methods (which prevents being able to add in new validations as easily) it should be too hard.
class Validation
{
vector<string> *errors;
void AddError(const string &error)
{
if (errors == NULL) errors = new vector<string>();
errors->push_back(error);
}
public:
Validation() : errors(NULL) {}
~Validation() { delete errors; }
const Validation &operator=(const Validation &rhs)
{
if (errors == NULL && rhs.errors == NULL) return *this;
if (rhs.errors == NULL)
{
delete errors;
errors = NULL;
return *this;
}
vector<string> *temp = new vector<string>(*rhs.errors);
std::swap(temp, errors);
}
void Check()
{
if (errors)
throw exception();
}
template <typename T>
Validation &IsNotNull(T *value)
{
if (value == NULL) AddError("Cannot be null!");
return *this;
}
template <typename T, typename S>
Validation &IsLessThan(T valueToCheck, S maxValue)
{
if (valueToCheck < maxValue) AddError("Value is too big!");
return *this;
}
// etc..
};
class Validate
{
public:
static Validation Begin() { return Validation(); }
};
Use..
Validate::Begin().IsNotNull(somePointer).IsLessThan(4, 30).Check();
Can't say much to the rest of the question, but I did want to point out this:
Though I'd guess that allocating
something like a std::vector on the
stack should be for free (is this
actually true? I'd suspect an empty
vector does no allocations on the
heap, right?)
No. You still have to allocate any other variables in the vector (such as storage for length) and I believe that it's up to the implementation if they pre-allocate any room for vector elements upon construction. Either way, you are allocating SOMETHING, and while it may not be much allocation is never "free", regardless of taking place on the stack or heap.
That being said, I would imagine that the time taken to do such things will be so minimal that it will only really matter if you are doing it many many times over in quick succession.
I recommend to get a look into Boost.Exception, which provides basically the same functionality (adding arbitrary detailed exception-information to a single exception-object).
Of course you'll need to write some utility methods so you can get the interface you want. But beware: Dereferencing a null-pointer in C++ results in undefined behavior, and null-references must not even exist. So you cannot return a null-pointer in a way as your linked example uses null-references in C# extension methods.
For the zero-cost thing: A simple stack-allocation is quite cheap, and a boost::exception object does not do any heap-allocation itself, but only if you attach any error_info<> objects to it. So it is not exactly zero cost, but nearly as cheap as it can get (one vtable-ptr for the exception-object, plus sizeof(intrusive_ptr<>)).
Therefore this should be the last part where one tries to optimize further...
Re the linked article: Apparently, the overhaead of creating objects in C# is so great that function calls are free in comparison.
I'd personally propose a syntax like
Validate().ISNOTNULL(src).ISNOTNULL(dst);
Validate() contructs a temporary object which is basically just a std::list of problems. Empty lists are quite cheap (no nodes, size=0). ~Validate will throw if the list is not empty. If profiling shows even this is too expensive, then you just change the std::list to a hand-rolled list. Remember, a pointer is an object too. You're not saving an object just by sticking to the unfortunate syntax of a raw pointer. Conversely, the overhead of wrapping a raw pointer with a nice syntax is purely a compile-time price.
PS. ISNOTNULL(x) would be a #define for IsNotNull(x,#x) - similar to how assert() prints out the failed condition, without having to repeat it.

To GOTO or not to GOTO? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Currently I am working on a project where goto statements are heavely used. The main purpose of goto statements is to have one cleanup section in a routine rather than multiple return statements.
Like below:
BOOL foo()
{
BOOL bRetVal = FALSE;
int *p = NULL;
p = new int;
if (p == NULL)
{
cout<<" OOM \n";
goto Exit;
}
// Lot of code...
Exit:
if(p)
{
delete p;
p = NULL;
}
return bRetVal;
}
This makes it much easier as we can track our clean up code at one section in code, that is, after the Exit label.
However, I have read many places it's bad practice to have goto statements.
Currently I am reading the Code Complete book, and it says that we need to use variables close to their declarations. If we use goto then we need to declare/initialize all variables before first use of goto otherwise the compiler will give errors that initialization of xx variable is skipped by the goto statement.
Which way is right?
From Scott's comment:
It looks like using goto to jump from one section to another is bad as it makes the code hard to read and understand.
But if we use goto just to go forward and to one label then it should be fine(?).
I am not sure what do you mean by clean up code but in C++ there is a concept called "resource acquisition is initialization" and it should be the responsibility of your destructors to clean up stuff.
(Note that in C# and Java, this is usually solved by try/finally)
For more info check out this page:
http://www.research.att.com/~bs/bs_faq2.html#finally
EDIT: Let me clear this up a little bit.
Consider the following code:
void MyMethod()
{
MyClass *myInstance = new MyClass("myParameter");
/* Your code here */
delete myInstance;
}
The problem: What happens if you have multiple exits from the function? You have to keep track of each exit and delete your objects at all possible exits! Otherwise, you will have memory leaks and zombie resources, right?
The solution: Use object references instead, as they get cleaned up automatically when the control leaves the scope.
void MyMethod()
{
MyClass myInstance("myParameter");
/* Your code here */
/* You don't need delete - myInstance will be destructed and deleted
* automatically on function exit */
}
Oh yes, and use std::unique_ptr or something similar because the example above as it is is obviously imperfect.
I've never had to use a goto in C++. Ever. EVER. If there is a situation it should be used, it's incredibly rare. If you are actually considering making goto a standard part of your logic, something has flown off the tracks.
There are basically two points people are making in regards to gotos and your code:
Goto is bad. It's very rare to encounter a place where you need gotos, but I wouldn't suggest striking it completely. Though C++ has smart enough control flow to make goto rarely appropriate.
Your mechanism for cleanup is wrong: This point is far more important. In C, using memory management on your own is not only OK, but often the best way to do things. In C++, your goal should be to avoid memory management as much as possible. You should avoid memory management as much as possible. Let the compiler do it for you. Rather than using new, just declare variables. The only time you'll really need memory management is when you don't know the size of your data in advance. Even then, you should try to just use some of the STL collections instead.
In the event that you legitimately need memory management (you have not really provided any evidence of this), then you should encapsulate your memory management within a class via constructors to allocate memory and deconstructors to deallocate memory.
Your response that your way of doing things is much easier is not really true in the long run. Firstly, once you get a strong feel for C++ making such constructors will be 2nd nature. Personally, I find using constructors easier than using cleanup code, since I have no need to pay careful attention to make sure I am deallocating properly. Instead, I can just let the object leave scope and the language handles it for me. Also, maintaining them is MUCH easier than maintaining a cleanup section and much less prone to problems.
In short, goto may be a good choice in some situations but not in this one. Here it's just short term laziness.
Your code is extremely non-idiomatic and you should never write it. You're basically emulating C in C++ there. But others have remarked on that, and pointed to RAII as the alternative.
However, your code won't work as you expect, because this:
p = new int;
if(p==NULL) { … }
won't ever evaluate to true (except if you've overloaded operator new in a weird way). If operator new is unable to allocate enough memory, it throws an exception, it never, ever returns 0, at least not with this set of parameters; there's a special placement-new overload that takes an instance of type std::nothrow and that indeed returns 0 instead of throwing an exception. But this version is rarely used in normal code. Some low-level codes or embedded device applications could benefit from it in contexts where dealing with exceptions is too expensive.
Something similar is true for your delete block, as Harald as said: if (p) is unnecessary in front of delete p.
Additionally, I'm not sure if your example was chose intentionally because this code can be rewritten as follows:
bool foo() // prefer native types to BOOL, if possible
{
bool ret = false;
int i;
// Lots of code.
return ret;
}
Probably not a good idea.
In general, and on the surface, there isn't any thing wrong with your approach, provided that you only have one label, and that the gotos always go forward. For example, this code:
int foo()
{
int *pWhatEver = ...;
if (something(pWhatEver))
{
delete pWhatEver;
return 1;
}
else
{
delete pWhatEver;
return 5;
}
}
And this code:
int foo()
{
int ret;
int *pWhatEver = ...;
if (something(pWhatEver))
{
ret = 1;
goto exit;
}
else
{
ret = 5;
goto exit;
}
exit:
delete pWhatEver;
return ret;
}
really aren't all that different from each other. If you can accept one, you should be able to accept the other.
However, in many cases the RAII (resource acquisition is initialization) pattern can make the code much cleaner and more maintainable. For example, this code:
int foo()
{
Auto<int> pWhatEver = ...;
if (something(pWhatEver))
{
return 1;
}
else
{
return 5;
}
}
is shorter, easier to read, and easier to maintain than both of the previous examples.
So, I would recommend using the RAII approach if you can.
Your example is not exception safe.
If you are using goto to clean up the code then, if an exception happens before the cleanup code, it is completely missed. If you claim that you do not use exceptions then you are mistaken because the new will throw bad_alloc when it does not have enough memory.
Also at this point (when bad_alloc is thrown), your stack will be unwound, missing all the cleanup code in every function on the way up the call stack thus not cleaning up your code.
You need to look to do some research into smart pointers. In the situation above you could just use a std::auto_ptr<>.
Also note in C++ code there is no need to check if a pointer is NULL (usually because you never have RAW pointers), but because new will not return NULL (it throws).
Also in C++ unlike (C) it is common to see early returns in the code. This is because RAII will do the cleanup automatically, while in C code you need to make sure that you add special cleanup code at the end of the function (a bit like your code).
I think other answers (and their comments) have covered all the important points, but here's one thing that hasn't been done properly yet:
What your code should look like instead:
bool foo() //lowercase bool is a built-in C++ type. Use it if you're writing C++.
{
try {
std::unique_ptr<int> p(new int);
// lots of code, and just return true or false directly when you're done
}
catch (std::bad_alloc){ // new throws an exception on OOM, it doesn't return NULL
cout<<" OOM \n";
return false;
}
}
Well, it's shorter, and as far as I can see, more correct (handles the OOM case properly), and most importantly, I didn't need to write any cleanup code or do anything special to "make sure my return value is initialized".
One problem with your code I only really noticed when I wrote this, is "what the hell is bRetVal's value at this point?". I don't know because, it was declared waaaaay above, and it was last assigned to when? At some point above this. I have to read through the entire function to make sure I understand what's going to be returned.
And how do I convince myself that the memory gets freed?
How do I know that we never forget to jump to the cleanup label? I have to work backwards from the cleanup label, finding every goto that points to it, and more importantly, find the ones that aren't there. I need to trace through all paths of the function just to be sure that the function gets cleaned up properly. That reads like spaghetti code to me.
Very fragile code, because every time a resource has to be cleaned up you have to remember to duplicate your cleanup code. Why not write it once, in the type that needs to be cleaned up? And then rely on it being executed automatically, every time we need it?
In the eight years I've been programming I've used goto a lot, most of that was in the first year when I was using a version of GW-BASIC and a book from 1980 that didn't make it clear goto should only be used in certain cases. The only time I've used goto in C++ is when I had code like the following, and I'm not sure if there was a better way.
for (int i=0; i<10; i++) {
for (int j=0; j<10; j++)
{
if (somecondition==true)
{
goto finish;
}
//Some code
}
//Some code
}
finish:
The only situation I know of where goto is still used heavily is mainframe assembly language, and the programmers I know make sure to document where code is jumping and why.
As used in the Linux kernel, goto's used for cleanup work well when a single function must perform 2 or more steps that may need to be undone. Steps need not be memory allocation. It might be a configuration change to a piece of code or in a register of an I/O chipset. Goto's should only be needed in a small number of cases, but often when used correctly, they may be the best solution. They are not evil. They are a tool.
Instead of...
do_step1;
if (failed)
{
undo_step1;
return failure;
}
do_step2;
if (failed)
{
undo_step2;
undo_step1;
return failure;
}
do_step3;
if (failed)
{
undo_step3;
undo_step2;
undo_step1;
return failure;
}
return success;
you can do the same with goto statements like this:
do_step1;
if (failed) goto unwind_step1;
do_step2;
if (failed) goto unwind_step2;
do_step3;
if (failed) goto unwind_step3;
return success;
unwind_step3:
undo_step3;
unwind_step2:
undo_step2;
unwind_step1:
undo_step1;
return failure;
It should be clear that given these two examples, one is preferable to the other. As to the RAII crowd... There is nothing wrong with that approach as long as they can guarantee that the unwinding will always occur in exactly reverse order: 3, 2, 1. And lastly, some people do not use exceptions in their code and instruct the compilers to disable them. Thus not all code must be exception safe.
You should read this thread summary from the Linux kernel mailing lists (paying special attention to the responses from Linus Torvalds) before you form a policy for goto:
http://kerneltrap.org/node/553/2131
In general, you should design your programs to limit the need for gotos. Use OO techniques for "cleanup" of your return values. There are ways to do this that don't require the use of gotos or complicating the code. There are cases where gotos are very useful (for example, deeply nested scopes), but if possible should be avoided.
The downside of GOTO is pretty well discussed. I would just add that 1) sometimes you have to use them and should know how to minimize the problems, and 2) some accepted programming techniques are GOTO-in-disguise, so be careful.
1) When you have to use GOTO, such as in ASM or in .bat files, think like a compiler. If you want to code
if (some_test){
... the body ...
}
do what a compiler does. Generate a label whose purpose is to skip over the body, not to do whatever follows. i.e.
if (not some_test) GOTO label_at_end_of_body
... the body ...
label_at_end_of_body:
Not
if (not some_test) GOTO the_label_named_for_whatever_gets_done_next
... the body ...
the_label_named_for_whatever_gets_done_next:
In otherwords, the purpose of the label is not to do something, but to skip over something.
2) What I call GOTO-in-disguise is anything that could be turned into GOTO+LABELS code by just defining a couple macros. An example is the technique of implementing finite-state-automata by having a state variable, and a while-switch statement.
while (not_done){
switch(state){
case S1:
... do stuff 1 ...
state = S2;
break;
case S2:
... do stuff 2 ...
state = S1;
break;
.........
}
}
can turn into:
while (not_done){
switch(state){
LABEL(S1):
... do stuff 1 ...
GOTO(S2);
LABEL(S2):
... do stuff 2 ...
GOTO(S1);
.........
}
}
just by defining a couple macros. Just about any FSA can be turned into structured goto-less code. I prefer to stay away from GOTO-in-disguise code because it can get into the same spaghetti-code issues as undisguised gotos.
Added: Just to reassure: I think one mark of a good programmer is recognizing when the common rules don't apply.
Using goto to go to a cleanup section is going to cause a lot of problems.
First, cleanup sections are prone to problems. They have low cohesion (no real role that can be described in terms of what the program is trying to do ), high coupling (correctness depends very heavily on other sections of code), and are not at all exception-safe. See if you can use destructors for cleanup. For example, if int *p is changed to auto_ptr<int> p, what p points to will be automatically released.
Second, as you point out, it's going to force you to declare variables long before use, which will make it harder to understand the code.
Third, while you're proposing a fairly disciplined use of goto, there's going to be the temptation to use them in a looser manner, and then the code will become difficult to understand.
There are very few situations where a goto is appropriate. Most of the time, when you are tempted to use them, it's a signal that you're doing things wrong.
The entire purpose of the every-function-has-a-single-exit-point idiom in C was to put all the cleanup stuff in a single place. If you use C++ destructors to handle cleanup, that's no longer necessary -- cleanup will be done regardless of how many exit points a function has. So in properly-designed C++ code, there's no longer any need for this kind of thing.
Since this is a classic topic, I will reply with Dijkstra's Go-to statement considered harmful (originally published in ACM).
Goto provides better don't repeat yourself (DRY) when "tail-end-logic" is common to some-but-not-all-cases. Especially within a "switch" statement I often use goto's when some of the switch-branches have tail-end-commonality.
switch(){
case a: ... goto L_abTail;
case b: ... goto L_abTail;
L_abTail: <commmon stuff>
break://end of case b
case c:
.....
}//switch
You have probably noticed than introducing additional curly-braces is enough to satisfy the compiler when you need such tail-end-merging in-the-middle of a routine. In other words, you don't need to declare everything way up at the top; that's inferior readability indeed.
...
goto L_skipMiddle;
{
int declInMiddleVar = 0;
....
}
L_skipMiddle: ;
With the later versions of Visual Studio detecting the use of uninitialized variables, I find myself always initializing most variables even though I think they may be assigned in all branches - it's easy to code a "tracing" statement which refs a variable that was never assigned because your mind doesn't think of the tracing statement as "real code", but of course Visual Studio will still detect an error.
Besides don't repeat yourself, assigning label-names to such tail-end-logic even seems to help my mind keep things straight by choosing nice label names. Without a meaningful label your comments might end up saying the same thing.
Of course, if you are actually allocating resources then if auto-ptr doesn't fit, you really must use a try-catch, but tail-end-merge-don't-repeat-yourself happens quite often when exception-safety is not an issue.
In summary, while goto can be used to code spaghetti-like structures, in the case of a tail-end-sequence which is common to some-but-not-all-cases then the goto IMPROVES the readability of the code and even maintainability if you would otherwise be copy/pasting stuff so that much later on someone might update one-and-not-the-other. So it's another case where being fanatic about a dogma can be counterproductive.
The only two reasons I use goto in my C++ code are:
Breaking a level 2+ nested loops
Complicated flows like this one (a comment in my program):
/* Analysis algorithm:
1. if classData [exporter] [classDef with name 'className'] exists, return it,
else
2. if project/target_codename/temp/classmeta/className.xml exist, parse it and go back to 1 as it will succeed.
3. if that file don't exists, generate it via haxe -xml, and go back to 1 as it will succeed.
*/
For code readability here, after this comment, I defined the step1 label and used it in step 2 and 3. Actually, in 60+ source files, only this situation and one 4-levels nested for are the places I used goto. Only two places.
A lot of people freak out with gotos are evil; they are not. That said, you will never need one; there is just about always a better way.
When I find myself "needing" a goto to do this type of thing, I almost always find that my code is too complex and can be easily broken up into a few method calls that are easier to read and deal with. Your calling code can do something like:
// Setup
if(
methodA() &&
methodB() &&
methodC()
)
// Cleanup
Not that this is perfect, but it's much easier to follow since all your methods will be named to clearly indicate what the problem might be.
Reading through the comments, however, should indicate that your team has more pressing issues than goto handling.
The code you're giving us is (almost) C code written inside a C++ file.
The kind of memory cleaning you're using would be OK in a C program not using C++ code/libraries.
In C++, your code is simply unsafe and unreliable. In C++ the kind of management you're asking for is done differently. Use constructors/destructors. Use smart pointers. Use the stack. In a word, use RAII.
Your code could (i.e., in C++, SHOULD) be written as:
BOOL foo()
{
BOOL bRetVal = FALSE;
std::auto_ptr<int> p = new int;
// Lot of code...
return bRetVal ;
}
(Note that new-ing an int is somewhat silly in real code, but you can replace int by any kind of object, and then, it makes more sense). Let's imagine we have an object of type T (T could be an int, some C++ class, etc.). Then the code becomes:
BOOL foo()
{
BOOL bRetVal = FALSE;
std::auto_ptr<T> p = new T;
// Lot of code...
return bRetVal ;
}
Or even better, using the stack:
BOOL foo()
{
BOOL bRetVal = FALSE;
T p ;
// Lot of code...
return bRetVal;
}
Anyway, any of the above examples are magnitudes more easy to read and secure than your example.
RAII has many facets (i.e. using smart pointers, the stack, using vectors instead of variable length arrays, etc.), but all in all is about writing as little code as possible, letting the compiler clean up the stuff at the right moment.
All of the above is valid, you might also want to look at whether you might be able to reduce the complexity of your code and alleviate the need for goto's by reducing the amout of code that is in the section marked as "lot of code" in your example. Additionaly delete 0 is a valid C++ statement
Using GOTO labels in C++ is a bad way to program, you can reduce the need by doing OO programming (deconstructors!) and trying to keep procedures as small as possible.
Your example looks a bit weird, there is no need to delete a NULL pointer. And nowadays an exception is thrown when a pointer can't get allocated.
Your procedure could just be wrote like:
bool foo()
{
bool bRetVal = false;
int p = 0;
// Calls to various methods that do algorithms on the p integer
// and give a return value back to this procedure.
return bRetVal;
}
You should place a try catch block in the main program handling out of memory problems that informs the user about the lack of memory, which is very rare... (Doesn't the OS itself inform about this too?)
Also note that there is not always the need to use a pointer, they are only useful for dynamic things. (Creating one thing inside a method not depending on input from anywhere isn't really dynamic)
I am not going to say that goto is always bad, but your use of it most certainly is. That kind of "cleanup sections" was pretty common in early 1990's, but using it for new code is pure evil.
The easiest way to avoid what you are doing here is to put all of this cleanup into some kind of simple structure and create an instance of it. For example instead of:
void MyClass::myFunction()
{
A* a = new A;
B* b = new B;
C* c = new C;
StartSomeBackgroundTask();
MaybeBeginAnUndoBlockToo();
if ( ... )
{
goto Exit;
}
if ( ... ) { .. }
else
{
... // what happens if this throws an exception??? too bad...
goto Exit;
}
Exit:
delete a;
delete b;
delete c;
StopMyBackgroundTask();
EndMyUndoBlock();
}
you should rather do this cleanup in some way like:
struct MyFunctionResourceGuard
{
MyFunctionResourceGuard( MyClass& owner )
: m_owner( owner )
, _a( new A )
, _b( new B )
, _c( new C )
{
m_owner.StartSomeBackgroundTask();
m_owner.MaybeBeginAnUndoBlockToo();
}
~MyFunctionResourceGuard()
{
m_owner.StopMyBackgroundTask();
m_owner.EndMyUndoBlock();
}
std::auto_ptr<A> _a;
std::auto_ptr<B> _b;
std::auto_ptr<C> _c;
};
void MyClass::myFunction()
{
MyFunctionResourceGuard guard( *this );
if ( ... )
{
return;
}
if ( ... ) { .. }
else
{
...
}
}
A few years ago I came up with a pseudo-idiom that avoids goto, and is vaguely similar to doing exception handling in C. It has been probably already invented by someone else so I guess I "discovered it independently" :)
BOOL foo()
{
BOOL bRetVal = FALSE;
int *p=NULL;
do
{
p = new int;
if(p==NULL)
{
cout<<" OOM \n";
break;
}
// Lot of code...
bRetVal = TRUE;
} while (false);
if(p)
{
delete p;
p= NULL;
}
return bRetVal;
}
I think using the goto for exit code is bad since there's a lot of other solutions with low overhead such as having an exit function and returning the exit function value when needed. Typically in member functions though, this shouldn't be needed, otherwise this could be indication that there's a bit too much code bloat happening.
Typically, the only exception I make of the "no goto" rule when programming is when breaking out of nested loops to a specific level, which I've only ran into the need to do when working on mathematical programming.
For example:
for(int i_index = start_index; i_index >= 0; --i_index)
{
for(int j_index = start_index; j_index >=0; --j_index)
for(int k_index = start_index; k_index >= 0; --k_index)
if(my_condition)
goto BREAK_NESTED_LOOP_j_index;
BREAK_NESTED_LOOP_j_index:;
}
That code has a bunch of problems, most of which were pointed out already, for example:
The function is too long; refactoring out some code into separate functions might help.
Using pointers when normal instances will probably work just fine.
Not taking advantage of STL types such as auto_ptr
Incorrectly checking for errors, and not catching exceptions. (I would argue that checking for OOM is pointless on the vast majority of platforms, since if you run out of memory you have bigger problems than your software can fix, unless you are writing the OS itself)
I have never needed a goto, and I've always found that using goto is a symptom of a bigger set of problems. Your case appears to be no exception.
Using "GOTO" will change the "logics" of a program and how you enterpret or how you would imagine it would work.
Avoiding GOTO-commands have always worked for me so guess when you think you might need it, all you maybe need is a re-design.
However, if we look at this on an Assmebly-level, jusing "jump" is like using GOTO and that's used all the time, BUT, in Assembly you can clear out, what you know you have on the stack and other registers before you pass on.
So, when using GOTO, i'd make sure the software would "appear" as the co-coders would enterpret, GOTO will have an "bad" effect on your software imho.
So this is more an explenation to why not to use GOTO and not a solution for a replacement, because that is VERY much up to how everything else is built.
I may have missed something: you jump to the label Exit if P is null, then test to see if it's not null (which it's not) to see if you need to delete it (which isn't necessary because it was never allocated in the first place).
The if/goto won't, and doesn't need to delete p. Replacing the goto with a return false would have the same effect (and then you could remove the Exit label).
The only places I know where goto's are useful are buried deep in nasty parsers (or lexical analyzers), and in faking out state machines (buried in a mass of CPP macros). In those two cases they've been used to make very twisted logic simpler, but that is very rare.
Functions (A calls A'), Try/Catches and setjmp/longjmps are all nicer ways of avoiding a difficult syntax problem.
Paul.
Ignoring the fact that new will never return NULL, take your code:
BOOL foo()
{
BOOL bRetVal = FALSE;
int *p=NULL;
p = new int;
if(p==NULL)
{
cout<<" OOM \n";
goto Exit;
}
// Lot of code...
Exit:
if(p)
{
delete p;
p= NULL;
}
return bRetVal;
}
and write it like this:
BOOL foo()
{
BOOL bRetVal = FALSE;
int *p = new int;
if (p!=NULL)
{
// Lot of code...
delete p;
}
else
{
cout<<" OOM \n";
}
return bRetVal;
}