Acceptable use of a label and 'goto'? [closed] - c++

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 7 years ago.
Improve this question
I am writing a tokenizer for a compiler. I have a while loop that loops over characters and then a switch that checks for certain conditions. I then need to exit both blocks to write the token:
Token token;
while (peekChar() != '\0')
{
switch (c = nextChar())
{
case '(':
token = Token(TOKEN_LEFT_PAREN, currentLine);
goto MakeToken;
// ... every other character, some with lots of logic
}
}
MakeToken:
// write the token
Is this an acceptable use of labels, or is there a better way? I have learnt to think of labels as just terrible practice, but surely there must be uses for them (or they wouldn't be implemented in the standard?). Thanks.

Generally, when we want to break several scopes at once, it means that we can make sub-functions; Something like:
bool HandleChar(char c)
{
switch (c)
{
case '(': {
Token token = Token(TOKEN_LEFT_PAREN, currentLine);
return true;
}
// ... every other character, some with lots of logic
}
}
And then:
while (peekChar() != '\0')
{
if (HandleChar(nextChar())) {
break;
}
}
// ...

You could implement the very same with break here, without needing to use goto.
The only time I found a only-slightly-revolting case of goto in C++ was in a complex state machine where developers took arduous care not to mess up local state.
Generally, a parser (or more specifically, a tokenizer) is the last place where I'd go for spaghetti coding -- if anything, this calls for using C++ in a more functional way.

I believe this is one of very few examples when goto is accepted however you could use a flag:
Token token;
bool flag = true;
while ((peekChar() != '\0') && flag)
{
switch (c = nextChar())
{
case '(':
token = Token(TOKEN_LEFT_PAREN, currentLine);
flag = false;
// ... every other character, some with lots of logic
}
}

Related

Declare int variable aux a.length = (); Or use o.length () in all loops? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I wonder which is faster: Say I'm working with some text (30 characters), which would be better? And with a lot of text which would be better?
1-
int tam = text.length();
for(int i=0;i<tam;i++)
{
//something here//
}
2-
for(int i=0;i<a.length();i++)
{
//something here//
}
and also comparing these two:
1-
for (int i = 0; i < b.length(); i++)
{
aux = a.find(b[i]);
if (aux == -1)
{
sucess = 0;
break;
}
else
{
a.erase(aux,1);
}
}
2-
for (int i = 0; i < b.length(); i++)
{
if (a.find(b[i]) == -1)
{
sucess = 0;
break;
}
else
{
a.erase(a.find(b[i]),1);
}
}
Both first are the better approach.
On the first example you are checking if i<a.length() is true on every cycle. That means that you are going to execute a.length() for every iteration. If the variable a is not changed, it is unnecessary and the better approach is to calculate before and use that value.
Note that if the variable a is changed inside, placing i<a.length() might be the correct approach. It depends on your problem.
On the second example it is the same basics. You avoid useless calculations because you won't need to calculate a.find(b[i]) again inside the else.
As a general rule of thumb, as computations get bigger, more complex, and more frequent you want to minimize your unnecessary calculations. This means that storing something that needs to be calculated in a variable may speed up the process.
In both of your examples, for extremely large numbers,
int scratch = big.length();
for(int i=0;i<scratch;i++){
//body//
}
is usually faster.
In the future, general questions like this tend to belong in something like the Code Review Stack Exchange.

How to avoid too much embedded if-else? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
like this:
if(...){
if(...){
}else{
...
}
}else if(...){
if(...){
}else{
...
}
}else{
...
}
in coding always meet with that situation, it looks so terrible. how to avoid it?
There's no general rule. but, two common cases are:
When a switch/case could help you reduce the amount of code.
When you should have designed your code with a state machine instead.
Depending on you needs and codes these might be a better solution.
Assumption: you want to call some function depending upon result checked inside if-else ladder.
if you have a come with some index calculated with values you are checking inside the if-else condition, then having static array of function pointers could benefit you lot if ladder is too big.
eg.
uint8_t x;
uint8_t y;
if(x == 1)
{
if (y == 1)
call11();
else if (y==2)
call12();
}
else if( x == 2)
{
if (y == 1)
call21();
else if (y==2)
call22();
.
.
.
}
else if(x ==3)
.
.
.
Above code could be replaced as below
typedef void (*FuncPtr)();
FunPtr array[65535];
//intialize at once with some function
void initFunArray()
{
array[1*256 + 1] = call11;
array[1*256 + 2] = call12;
....
array[2*256 + 1] = call21;
array[2*256 + 2] = call22;
....
array[3*256 + 1] = call31;
array[3*256 + 2] = call32;
....
// Others will be set to null as array is static
}
uint8_t x;
uint8_t y;
index = x*256 + y;
array[index](); // calling appropriate call.
Generally when I see code like that I tend to wince a little. The worst case was a single file, 22 thousand lines long and only three functions - that made me sob.
The fact that at the lowest level you have a series of conditions which generally means some sort of type is involved.
So your code will look a bit like:
If (...) {
OnTypeConditionOne(...);
Else if (...) {
OnTypeConditionTwo(...);
Else {
OnTypeConditionThree(...);
}
Obviously you pass through whatever variables are needed to perform the subclauses. You then do the same to those subclauses until you have lots of small files. It is important to name the files something logical otherwise you might get lost in similar sounding names.

In C++, if break; keyword not exist for Switch case block, both case "b" & default is executed [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
bool condition = true;
string input = "b";
switch (input)
{
case "b":
if (condition)
{
Console.WriteLine("B");
}
default:
Console.WriteLine("Default");
break;
}
C++:
B
Default
you missed a break after case,
bool condition = true;
string input = "a";
switch (input)
{
case "b":
if (condition)
{
Console.WriteLine("B");
}
break; // You missed break;
default:
Console.WriteLine("Default");
break;
}
C# does not allow to execute more than one case which is logically incorrect so prevented by C# compiler.

How to keep track of order in which switch case values are executed? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How can I keep track of the order in which switch case statements are executed?
For example:
while (some_boundary) {
switch (value) {
case a:
do something;
move to next value;
break;
case b:
do something;
move to next value;
break;
case c:
do something;
move to next value;
break;
}
}
I want to know if the switch was executed abc or bac or cab, etc.
Any idea ? Or will implementing via if/else make more sense ?
You can save a vector at every iteration with the value of the corresponding iteration:
std::vector<int> sequence;
while (some_boundary) {
int temp = computeValue(); // Or however you get your value.
sequence.push_back(temp);
switch (temp) {
case a:
//do something;
break;
case b:
//do something;
break;
case c:
//do something;
break;
}
}
Edit: This is assuming that value is set somewhere between the while and the switch, so you can save it in advance. Other option is to include the push_back instruction in every case, but is more "dirty". Preallocating the vector could save some computation time as well.
Edit2: code modified according the suggestions so that it is ensured that a new value will be computed.
If you just want to know (and not save the results) you could just output the value at each iteration. Try
cout << value << endl;
as the first line within the while loop.

c++ variable keeps resetting instead of incrementing? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
void RetailerOrder::addItem(Product* p)
{
bool space = false;
int counter = 0;
while ((space == false) && (counter < manifest.size()))
{
if (manifest[counter] == nullptr);
{
manifest[counter] = p;
space = true;
}
counter++;
}
if (space == false)
{
cout << "no space" << endl;
}
}
Why does the counter reset to zero with each pass through the while loop? If I use it as it is, only the last product that I enter gets stored in the array because i is always 1. Is there a way to let the counter increase.
if (manifest[counter] == nullptr); // << see here
{
manifest[counter] = p;
space = true;
}
That semi-colon at the end of your if statement means "if condition, do nothing".
Then the braced scope following that executes always.
It should instead be:
if (manifest[counter] == nullptr)
{
manifest[counter] = p;
space = true;
}
As an aside, I'm not a big fan of things like:
if (space == false) ...
since, if you name you boolean values intelligently, you can avoid the comparisons:
if (! foundSpace) ...
The intelligent naming means that the boolean variable itself should be readable, such as with foundSpace or haveFinished or userIsClinicallyInsane. Once it is, you don't need to compare it to boolean constants at all.
That greatly reduces the code size and avoids the reductio-ad-absurdum situation where you don't know when to stop comparing booleans to constants:
if ((((haveFinished == true) == true) != false) == true) ...
As a second aside, I value my vertical space greatly when looking at code and there are ways to simplify your code which make it shorter and, in my opinion, easier to understand.
Since you're only using space as a way to insert the item and exit the loop prematurely, you could use something like:
void RetailerOrder::addItem (Product* p) {
// Check every possible slot.
for (int i = 0; i < manifest.size(); i++) {
// If one free, use it and exit.
if (manifest[i] == nullptr) {
manifest[i] = p;
return;
}
}
// None were free, complain bitterly.
cout << "no space" << endl;
}
Still, that's a stylistic approach of mine and you should feel free to ignore it if you disagree.
The "multiple return points are bad" crowd may not like it but that's usually because they don't understand the reason why it's considered suspect, the inability to easily see the many code paths. With a function of this size, it's not really a issue.