How to make a string into a reference? - c++

I have looked into this, but it's not what I wanted: Convert string to variable name or variable type
I have code that reads an ini file, stores data in a QHash table, and checks the values of the hash key, (see below) if a value is "1" it's added to World.
Code Examples:
World theWorld;
AgentMove AgentMovement(&theWorld);
if(rules.value("AgentMovement") == "1")
theWorld.addRule(&AgentMovement);
INI file:
AgentMovement=1
What I want to do is, dynamically read from the INI file and set a reference to a hard coded variable.
for(int j = 0; j < ck.size(); j++)
if(rules.value(ck[j]) == "1")
theWorld.addRule("&" + ck[j]);
^
= &AgentMovement
How would you make a string into a reference as noted above?

This is a common theme in programming: A value which can only be one of a set (could be an enum, one of a finite set of ints, or a set of possible string values, or even a number of buttons in a GUI) is used as a criteria to perform some kind of action. The simplistic approach is to use a switch (for atomic types) or an if/else chain for complex types. That is what you are currently doing, and there is nothing wrong with it as such:
if(rules.value(ck[j]) == "1") theWorld.addRule(&AgentMovement);
else if(rules.value(ck[j]) == "2") theWorld.addRule(&AgentEat);
else if(rules.value(ck[j]) == "3") theWorld.addRule(&AgentSleep);
// etc.
else error("internal error: weird rules value %s\n", rules.value(ck[j]));
The main advantages of this pattern are in my experience that it is crystal clear: anybody, including you in a year, understands immediately what's going on and can see immediately which criteria leads to which action. It is also trivial to debug which can be a surprising advantage: You can break at a specific action, and only at that action.
The main disadvantage is maintainability. If the same criteria (enum or whatever) is used to switch between different things in various places, all these places have to be maintained, for example when a new enum value is added. An action may come with a sound, an icon, a state change, a log message, and so on. If these do not happen at the same time (in the same switch), you'll end up switching multiple times over the action enum (or if/then/else over the string values). In that case it's better to bundle all information connected to an action in a data structure and put the structures in a map/hash table with the actions as keys. All the switches collapse to single calls. The compile-time initialization of such a map could look like this:
struct ActionDataT { Rule rule; Icon icon; Sound sound; };
map<string, AcionDataT> actionMap
= {
{"1", {AgentMovement, moveIcon, moveSound} }
{"2", {AgentEat, eatIcon, eatSound } } ,
//
};
The usage would be like
for(int j = 0; j < ck.size(); j++)
theWorld.addRule(actionMap[rules.value(ck[j])].rule);
And elsewhere, for example:
if(actionFinished(action)) removeIcon(actionMap[action].icon);
This is fairly elegant. It demonstrates two principles of software design: 1. "All problems in computer science can be solved by another level of indirection" (David Wheeler), and 2. There is often a choice between more data or more code. The simplistic approach is code-oriented, the map approach is data oriented.
The data-centrist approach is indispensable if switches occur in more than one situation, because coding them out each time would be a maintenance nightmare.
Note that with the data-centrist approach none of the places where an action is used has to be touched when a new action is added. This is essential. The mechanism resembles (in principle and implementation, actually) the call of a virtual member function. The calling code doesn't know and isn't really interested in what is actually done. Responsibility is transferred to the object. The calling code may perform actions later in the life cycle of a program which didn't exist when it was written. By contrast, compare it to a program with many explicit switches where every single use must be examined when an action is added.
The indirection involved in the data-centrist approach is its disadvantage though, and the only problem which cannot be solved by another level of indirection, as Wheeler remarked. The code becomes more abstract and hence less obvious and harder to debug.

You have to provide the mapping from the names to the object by yourself. I would wrap it into a class, something like this:
template <typename T>
struct ObjectMap {
void addObject(std::string name,T* obj){
m[name] = obj;
}
T& getRef(std::string name) const {
auto x = m.find(name);
if (x != m.end() ) { return *(x->second);}
else { return dummy; }
}
private:
std::map<std::string,T*> m;
T dummy;
}
The problem with this approach is that you have to decide what to do if an object is requested that is actually not in the map. A reference always has to reference something (in contrast to a pointer that can be 0). I decided to return the reference to a dummy object. However, you might want to consider to use pointers instead of references. Another option might be to throw an error in case the object is not in the map.

Related

Tuples: No matching function for call to 'get'

I have 3 structs : Student, Citizen, Employee. I want user to be able to choose what struct they want to work with (std::vector of structs, actually). Since there's no way to define type at runtime, I created all 3 vectors, but will use only one of them (depending on the user's choice), others will stay empty:
std::vector<Student> container_student;
std::vector<Citizen> container_citizen;
std::vector<Employee> container_employee;
auto containers = make_tuple(container_student, container_citizen, container_employee);
std::cout << "Enter:\n0 to operate \"Student\" struct\n1 to operate \"Citizen\" struct\n2 to operate \"Employee\" struct\n";
std::cin >> container_type;
auto container = std::get<container_type>(containers);
But I get No matching function for call to 'get', even though container_type is an int and containers is a tuple.
Edit: understandable, auto can't make magic and I still try to make container's type to depend on runtime. But even if I try to use std::get<container_type>(containers) (probably define would help) instead of container in functions etc., I get the same error, which is not understandable.
Unfortunately, what you're proposing isn't possible in C++. The C++ typing and template system works at compile-time, where information read in from the user isn't available. As a result, anything passed into a template's angle braces needs to be determinable at compile-time. In your case, the number the user enters, indicating which option they want to select, is only knowable at runtime.
There are some routes you could take to achieve the same result, though. For example, one option would be to do something like this:
if (container_type == 0) {
auto container = std::get<0>(containers);
/* ... */
} else if (container_type == 1) {
auto container = std::get<1>(containers);
/* ... */
} /* etc */
Here, all the template angle braces are worked out at compile-time. (Then again, if this is what you're going to be doing, you wouldn't need the tuple at all. ^_^)
Another option would be to use templates, like this:
template <typename T> void doSomething(std::vector<T>& container) {
/* Put your code here */
}
/* Then, back in main... */
if (container_type == 0) {
doSomething(container_student);
} else if (container_type == 1) {
doSomething(container_citizen);
} /* etc */
This still requires you to insert some code to map from integer types to the functions you want to call, but it leaves you the freedom to have a container variable (the one in doSomething) that you can treat generically at that point.
It's basically the Fundamental Theorem of Software Engineering in action - all problems can be solved by adding another layer of indirection. :-)
Hope this helps!

Creating and freeing a temporary dummy variable in C++

I'm using the Qt framework to create a ui for my business logic.
The class responsible for building the ui provides several methods which, step by step, initialize the ui elements, layout them, group them and, finally, format (i.e. void MyUi::init3_formatUiElements()) them.
Naturally, some ui elements need numerous layout settings set, so this method might look like
void MyUi::init3_formatUiElements() {
_spinBox_distance->setMinimum(0.0);
_spinBox_distance->setMaximum(10.0);
_spinBox_distance->setSingleStep(0.5);
_spinBox_distance->setSuffix(" meters");
//...
//same for other widgets
return;
}
Objects like QDoubleSpinBox* _spinBox_distance are member fields of the MyUi class.
I would like to have a "temporary alias" for _spinBox_distance, in that the above method body simplifies to
void MyUi::init3_formatUiElements() {
//create alias x for _spinBox_distance here
x->setMinimum(0.0);
x->setMaximum(10.0);
x->setSingleStep(0.5);
x->setSuffix(" meters");
//...
//free alias x here
//same for other widgets: create alias x for next widget
//...
//free alias x here
return;
}
This would speed up the typing process and would make code fragments more copy/paste-able, especially for ui elements of a similar type.
Apart from scoping each block in curly braces
{ QDoubleSpinBox*& x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ QLabel*& x = _label_someOtherWidget;
//...
}
is there an elegant way to achieve this?
I tried the above syntax without scoping, but destructing x then of course leads to destruction of the underlying widget.
Maybe
QDoubleSpinBox** x = new QDoubleSpinBox*;
x = &_spinBox_distance;
(*x)->setMinimum(0.0);
//...
delete x;
but that doesn't make things much more type-easy (three extra lines, pointers to pointers, (*x))... :D
EDIT: This one does not work as after delete x, can't be redeclared another type.
What about using a macro ?
#define Set(argument) _spinBox_distance->set##argument
and
Set(Minimum(0.0));
Set(Maximum(10.0));
Set(SingleStep(0.5));
Set(Suffix(" meters"));
Or
#define Set(Argument, Value) _spinBox_distance->set##argument(Value)
Set(Minimum, 0.0);
Set(Maximum, 10.0);
Set(SingleStep, 0.5);
Set(Suffix, " meters");
Collecting the fundamental conceptual thoughts about the problem in question from the comments section, I may post the syntactical/technical answer to the question. This approach, without a doubt, should not be chosen in any kind of "complex" situation (or rather not at all).
bad coding style:
same name for different things
name which doesn't tell you anything about the object
move repeated code to dedicated functions, which...
may specialize on several ui types
are template functions
...
in case of Qt: Use Qt Designer.
...
{ auto x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ auto x = _label_someOtherWidget;
//...
}
will do the trick.
I think your code looks fine as it is, I find it much more useful to have the code be easy to read/understand than it is to have the code be easy to write. Remember that you write the code once, then have to read it many times afterwards.
In cases like this I make it easier to write with good old (and oft blamed for mistakes) copy and paste. Grab _spinBox_distance->set and just paste, finish the line, paste, finish the line, etc...
If, however, you find yourself writing those 4 setters in a row over and over again, then put them in 1 function that takes in the 4 parameters.
void SetParameters(QDoubleSpinBox* spinBox_distance, double min, double max, double step, std::string suffix)
{
//the setters
}

Is it a good practice to use nested switches in C++? Is there any alternative method to avoid this?

Currently I am having a function which has two arguments of type enums, the function requires to compare both and do particular task
example:
void set_Test_Status(Tests TestName, Status TestStatus)
{
switch(TestName)
{
case Tests::Test1:
{
switch(TestStatus)
{
case TestStatus::St1:
//Rest of Code
}
}
//Rest of Code
}
}
is it a good programming practice? or is there any alternative method or style of coding that i should be aware of? Thank you!
Edit:
Finally after trial and error, I did this. First i saw the maximum and minimum items in each enums, In my case TestName were 6 and TestStatus had 3. I created 3 functions setStatusRunning(Tests TestName), setStatusSelected(Tests TestName) and setStatusFinished(Tests TestName) and in set_Test_status, using switch(TestName) i check which function should be called and then called the appropriate functions. The reason i had to make set_Test_Status in the first place was to make easy for other classes, since i made set_Test_Status public and the other 3 as private.
It is truly a matter of opinion as having nested switch statements is valid c++ code. Some may not have problems with it while others may argue that it can be confusing.
My advice would be on the lines of this; if the code blocks within the case statements are short such as 1-2 lines and they are fairly easy to read and follow, then there should be nothing wrong with it. However, if the code is quite cumbersome and the nested switch statements spans well over 50 to 100+ lines then I would suggest refining your code and make functions out of them.
Examples:
// should be okay
unsigned int outerSwitch = someValue();
unsigned int innerSwitch = someOtherValue();
switch ( outerSwitch ) {
case 1: {
switch ( innerSwitch ) {
case 1 : {
// 1 or 2 lines okay;
}
case 2 : {
// 1 or 2 lines okay;
}
case 3 : {
// 1 or 2 lines okay;
}
default : {
}
} // inner switch when outer switch case = 1
}
case 2: {
// Same as case 1
}
case 3: {
// Same as case 1
}
default: {
}
} // outer switch
But as you have seen above with just 3 cases to the outer and inner; it gets very long very quickly and I haven't even expanded them all. So this can be frowned upon.
You can have a single switch as others have suggested that calls a specific function to that switch then within that function it has its own switch statement like this:
unsigned int someFuncA( unsigned int someVal ) {
switch ( someVal ) {
case 1 : {
// do this
// return that;
}
case 2: {
// ... etc.
}
} // switch
}
unsigned int someFuncB( int someVal ) {
// similar to someFuncA();
}
unsigned int someFuncC( int someVal ) {
// similar to someFuncA();
}
unsigned int switchValue = someValue();
unsigned int innerValue = someOtherFunction();
unsigned int temp = 0;
switch( switchValue ) {
case 1 : {
temp = someFuncA( innerValue );
// either return temp, break, continue, or fall through
}
case 2 : {
temp = someFuncB( innerValue );
// same as above
case 3 : {
temp = someFuncC( innerValue );
// same as above
}
default : {
// default stuff here
}
} // switch
Comparing the two you will see that the 2nd version is easier to read and less cumbersome than the 1st. Yes the first version is valid legal C++ code, but is frowned upon because of how messy it can easily and quickly get. So where ever you can; turn that code into a function that is designed to do just that one thing.
EDIT
Another possibility is to design specific functions to do a task and as you said that your function takes 2 different enumeration values, you can look up the concept of functions that are designed to take bit flags. You will see this kind of code quite a bit in windows programming as well as OpenGL.
Another option is this: consider that fact you have an outer control switch, and inner control switch. Even if you have multiple cases, each case is independent with a specific unique ID. The same can be said for the inner switch cases. Knowing this you can create an associative mapping of all the statements in a combined matter using std::multimap<unsigned, unsigned> testCases and with this lookup table you can have it in a single statement with independent function calls to each map entry. cppreference : std::multimap
Your map might look like this:
testCases[1][1];
testCases[1][2];
testCases[1][3];
testCases[2][1];
testCases[2][2];
testCases[2][3];
testCases[3][1];
testCases[3][2];
testCases[3][3];
Where each index of the map is the logic or calculation you want to perform.
It can be quite confusing for someone reading the code-- indentation helps, but it can still be difficult to follow where the case and switch statements start and end. Most IDEs have support for finding a matching brace, but finding a matching break isn't generally a thing, so it can be difficult to even see where a case statement ends. (And technically case doesn't define scope whereas braces do, so it doesn't even have an end.)
If you get misaligned braces or accidentally mismatch where they should be, you can have odd things happen. Languages like Ada try to prevent that with strongly typed English-language specifiers.
If you are doing a lot of sub-switches, I would put them into another function and call it with the information it needs, then you could do a switch statement inside the method which is more modular, separate scope and clear what is going on.
A good practice to keep code concise is to do only one thing in a function. Using a switch already is a smell that your function is going to do different things. It all depend of your specific case.
One thing to look at is: is it coherent to manage all these cases in one class. Should you have one class per possibility, with an interface forcing to implement a function, instead of doing all the possibilities in a switch case.
In case you want to keep the switch, a good practice would be to not put code in it other than the switch. Each case just calls a function. This will already make stuff more readable.
Finally, are you using all the cases? If no, you code could be more clear by just implementing the pairs of values that you need:
if(TestName == Tests::Test1 && TestStatus == TestStatus::St1)
{
doThing();
}
To summarize:
This might be a smell that your code needs to be split in more classes to have only one responsibility per class (too many if and/or too many switches ar a sign of that). If you are sure that you need a switch, keep it as simple and clear as possible

Function with a custom return type and the "false" return conditions?

I have a function that returns a custom class structure, but how should I handle the cases where I wish to inform the user that the function has failed, as in return false.
My function looks something like this:
Cell CSV::Find(std::string segment) {
Cell result;
// Search code here.
return result;
}
So when succesful, it returns the proper result, but how should I handle the case when it could fail?
I thought about adding a boolean method inside Cell to check what ever Cell.data is empty or not (Cell.IsEmpty()). But am I thinking this issue in a way too complicated way?
There are three general approaches:
Use exceptions. This is what's in Bathsheba's answer.
Return std::optional<Cell> (or some other type which may or may not hold an actual Cell).
Return bool, and add a Cell & parameter.
Which of these is best depends on how you intend this function to be used. If the primary use case is passing a valid segment, then by all means use exceptions.
If part of the design of this function is that it can be used to tell if a segment is valid, exceptions aren't appropriate, and my preferred choice would be std::optional<Cell>. This may not be available on your standard library implementation yet (it's a C++17 feature); if not, boost::optional<Cell> may be useful (as mentioned in Richard Hodges's answer).
In the comments, instead of std::optional<Cell>, user You suggested expected<Cell, error> (not standard C++, but proposed for a future standard, and implementable outside of the std namespace until then). This may be a good option to add some indication on why no Cell could be found for the segment parameter passed in, if there are multiple possible reasons.
The third option I include mainly for completeness. I do not recommend it. It's a popular and generally good pattern in other languages.
Is this function a query, which could validly not find the cell, or is it an imperative, where the cell is expected to be found?
If the former, return an optional (or nullable pointer to) the cell.
If the latter, throw an exception if not found.
Former:
boost::optional<Cell> CSV::Find(std::string segment) {
boost::optional<Cell> result;
// Search code here.
return result;
}
Latter:
as you have it.
And of course there is the c++17 variant-based approach:
#include <variant>
#include <string>
struct CellNotFound {};
struct Cell {};
using CellFindResult = std::variant<CellNotFound, Cell>;
CellFindResult Find(std::string segment) {
CellFindResult result { CellNotFound {} };
// Search code here.
return result;
}
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
void cellsAndStuff()
{
std::visit(overloaded
{
[&](CellNotFound)
{
// the not-found code
},
[&](Cell c)
{
// code on cell found
}
}, Find("foo"));
}
The C++ way of dealing with abject failures is to define an exception class of the form:
struct CSVException : std::exception{};
In your function you then throw one of those in the failure branch:
Cell CSV::Find(std::string segment) {
Cell result;
// Search code here.
if (fail) throw CSVException();
return result;
}
You then handle the fail case with a try catch block at the calling site.
If however the "fail" branch is normal behaviour (subjective indeed but only you can be the judge of normality), then do indeed imbue some kind of failure indicator inside Cell, or perhaps even change the return type to std::optional<Cell>.
If you can use C++17, another approach would be to use an std::optional type as your return value. That's a wrapper that may or may not contain a value. The caller can then check whether your function actually returned a value and handle the case where it didn't.
std::optional<Cell> CSV::Find(std::string segment) {
Cell result;
// Search code here.
return result;
}
void clientCode() {
auto cell = CSV::Find("foo");
if (cell)
// do stuff when found
else
// handle not found
}
A further option is using multiple return values:
std::pair<Cell, bool> CSV::Find(std::string segment) {
Cell result;
// Search code here.
return {result, found};
}
// ...
auto cell = CSV::Find("foo");
if (cell->second)
// do stuff with cell->first
The boolean flag says whether the requested Cell was found or not.
PROs
well known approach (e.g. std::map::insert);
quite direct: value and success indicator are return values of the function.
CONs
obscureness of first and second which requires to always remember the relative positions of values within the pairs. C++17 structured bindings / if statement with initializer partially resolve this issue:
if (auto [result, found] = CSV::Find("foo"); found)
// do stuff with `result`
possible loss of safety (the calling code has to check if there is a result value, before using it).
Details
Returning multiple values from functions in C++
C++ Error Handling - downside of using std::pair or std::tuple for returning error codes and function returns
For parsing, it is generally better to avoid std::string and instead use std::string_view; if C++17 is not available, minimally functional versions can be whipped up easily enough.
Furthermore, it is also important to track not only what was parsed but also the remainder.
There are two possibilities to track the remainder:
taking a mutable argument (by reference),
returning the remainder.
I personally prefer the latter, as in case of errors it guarantees that the caller has in its hands a unmodified value which is useful for error-reporting.
Then, you need to examine what potential errors can occur, and what recovery mechanisms you wish for. This will inform the design.
For example, if you wish to be able to parse ill-formed CSV documents, then it is reasonable that Cell be able to represent ill-formed CSV cells, in which case the interface is rather simple:
std::pair<Cell, std::string_view> consume_cell(std::string_view input) noexcept;
Where the function always advances and the Cell may contain either a proper cell, or an ill-formed one.
On the other hand, if you only wish to support well-formed CSV documents, then it is reasonable to signal errors via exceptions and that Cell only be able to hold actual cells:
std::pair<std::optional<Cell>, std::string_view> consume_cell(...);
And finally, you need to think about how to signal end of row conditions. It may a simple marker on Cell, though at this point I personally prefer to create an iterator as it presents a more natural interface since a row is a range of Cell.
The C++ interface for iterators is a bit clunky (as you need an "end", and the end is unknown before parsing), however I recommend sticking to it to be able to use the iterator with for loops. If you wish to depart from it, though, at least make it work easily with while, such as std::optional<Cell> cell; while ((cell = row.next())) { ... }.

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;
}