Showing posts with label Labels. Show all posts
Showing posts with label Labels. Show all posts

Wednesday, 2 February 2011

Consequences of Ignoring Compiler Warnings

Though this is a fictional program that I have picked up from here, I have seen similar problems in real life.

Lets say my program (below) was expected to return this


but instead returned:

Program as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

class
Bclass
{

public
:
Bclass() {}
virtual
void func()
{

cout<<"In Bclass::func()"<<endl;
}
};


class
Dclass : public Bclass
{

public
:
Dclass() {}
virtual
void func()
{

cout<<"In Dclass::func()"<<endl;
Bclass:func();
}
};


int
main()
{

Dclass d;
d.func();
//...
return 0;
}



The clue of the problem was given by the compiler that generated the following warning:

main.cpp(23) : warning C4102: 'Bclass' : unreferenced label

pointing to the line

Bclass:func();

The problem lies in the fact that due to a single : rather than :: the line above is being treated as label and since its an unreferenced label it goes back to the start of the same function.

You can read the complete discussion here. Make sure to check the warnings the next time your program behaves unexpectedly.

Wednesday, 9 June 2010

Simulating 'break all' in C++

Sometimes your program is inside multiple loops when it meets a certain criteria and all you want to do is to break out from all the loops. Some programming languages allow 'break all' statements while most of them dont.

In Java there is a nice little feature of using a label on the outermost loop and then you can say inside 'break label' to break from the outermost loop. This is shown in the example below



String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
for(Object2 object2: object1){
//I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
//Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
//Compare with valueFromObj2 to decide either to break all the foreach loop
if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
break OUTERMOST;
}
}//fourth loop ends here
}//third loop ends here
}//second loop ends here
}//first loop ends here



The important thing to remember is this is not available in C++.

Another way of doing 'break all' is to have a 'flag' in each of the loop as well like:

while ( condition && !flag)

Then inside the nth loop set the flag to true and break. All the the loops will exit. This is a good approach and is widely used.

I prefer using another approach using the goto statement. A lot of C++ people hate goto and think its pure evil but I dont think its always that bad. Also see this. Example as follows:





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example of simulating break all in C++
#include<iostream>

using namespace
std;

int
main()
{


cout << "Entering the nested loop" << endl;
for
(int loop1 = 0; loop1 < 4; loop1++)
{

cout<<"Loop1 : " << loop1 << endl;
for
(int loop2 = 0; loop2 < 4; loop2++)
{

cout<<"Loop2 : " << loop2 << endl;
for
(int loop3 = 0; loop3 < 4; loop3++)
{

cout<<"Loop3 : " << loop3 << endl;
if
(loop3 == 3 && loop2 == 2 && loop1 == 1)
{

goto
SOMELABEL;
}
}
}
}

SOMELABEL:
cout << "Exiting the nested loop" << endl;

return
0;
}







The output is as follows: