C++ cross initiialization error - c++

When compiling the following code it provides me with two errors; "jump to case label" and "crosses initialization of std::ofstream SaveLogin". I am currently using codeblocks with the gnu gcc compiler.
switch(choice) {
case 1:
// login
case 2:
// register
ofstream SaveLogin;
break;
case 3:
// reset password
;}
Thanks for viewing my question-EDIT: my question was flagged as a duplicate of another question but the question specified did not entirely conclude my problem. This post is specifically about my problem although I hope it can hope any other people who are having the same problem

The compiler is correct: C++ does not allow you to skip over a variable declaration in the same scope. goto is similarly restricted.
If you need SaveLogin for all cases then declare it above the switch. If you only need it for case 2 then use scope blocks:
case 2 /*not directly relevant but there's no need for the parentheses*/:
{
// register
ofstream SaveLogin; /*ToDo - more logic here unless it's contained
fully within construction and destruction*/
break;
}
case 3:

Here's a small change to the code that should illustrate the problem:
switch(choice) {
case 1:
// login
case 2:
// register
ofstream SaveLogin;
break;
case 3:
// reset password
SaveLogin << "whatever\n"; // added code
;}
That last line would be legal, because SaveLogin is in scope, but it would get executed only as part of case 3, which skips the initialization of SaveLogin. So the rule is that a jump (switch or goto) can't skip an initializer. One possibility, as #Bathsheba mentions, is to put the definition of SaveLogin above the case statement. Another possibility is to limit the scope of SaveLogin so that the jump doesn't bypass it:
case 2:
{
ofstream SaveLogin;
break;
}
case 3:
With the curly braces, SaveLogin is not in scope at case 3 and the problem has gone away.

Related

C++ switch empty default case [duplicate]

In the interest of future readers and my own sanity later, I like to make it absolutely clear that switch statements that do not have a default case (due to all cases being covered) or sequential if-elseif-else with a final else that should not do anything must not be omitted and a comment to that effect be included (see example).
However, whenever I include the default case in the switch statement and leave it empty I must put a semicolon inside the default case or a compiler error: " Line [Line of closing brace of switch statement]`missing ';' before '}'" occurs. WHY?!
EXAMPLE: GENERATES COMPILER ERROR
switch(direction) {
case MOVE_UP:
//...
break;
case MOVE_RIGHT:
//...
break;
case MOVE_DOWN:
//...
break;
case MOVE_LEFT:
//...
break;
default:
/* DO NOTHING */
}
EXAMPLE: DOES NOT GENERATE COMPILER ERROR
switch(direction) {
case MOVE_UP:
//...
break;
case MOVE_RIGHT:
//...
break;
case MOVE_DOWN:
//...
break;
case MOVE_LEFT:
//...
break;
default:
/* DO NOTHING */;
}
Because you need a statement for your default case. A semicolon is an empty-statement.
6.1/1 in C++03 gives the grammar for a labeled-statement:
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
C++11 is the same except you can have attributes before the label.
A zero-length sequence of tokens is not a statement in C++, hence default: on its own is not a labeled-statement.
That said, I don't know what the motivation was why the grammar for a labeled-statement doesn't allow default: statementopt. If it did then there would be a grammatical ambiguity if you wrote default : case 1: break;, whether case 1: break; is the statement belonging to default:, or whether default: has no statement of its own, but is immediately followed by one. There's still no doubt what it means, but maybe it was thought that it would mess up people's parsers.

C++ - can I create a member of another class and use it in a constructor? [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 4 years ago.
Improve this question
So I have two classes - one for a specific Player and one for a Team for players.
Player(string line){
string write;
stringstream line1(line);
int i = 0;
while (getline(line1, write, ';')){
switch (i) {
case 0:
name = write;
i++;
break;
case 1:
surname = write;
i++;
break;
case 2:
skills[0] = write;
i++;
break;
case 3:
skills[1] = write;
i++;
break;
case 4:
skills[2] = write;
i++;
break;
case 5:
skills[3] = write;
i++;
break;
case 6:
skills[4] = write;
i++;
break;
case 7:
age = stoi(write);
i++;
break;
case 8:
height = stoi(write);
break;
default:
break;
}
}
}
The Player class has a constructor that takes a string with all of parameters and sets them all. It works.
What I want to accomplish is be able to pass a file containing some lines (fstream type) to a constructor of Team class and make a team of Players specified in the file. This is what I tought of:
Team(fstream file){
string one;
while (getline(file, one))
Player asdf = (one);
addPlayer(asdf);
}
Use of undeclared identifier 'asdf' is all I get from this. Could someone guide me to the right approach?
To answer your question, yes it is possible to create an object in the CTOR and keep it around. Be aware that by doing this you are allocating memory, and this can cause your constructor to fail. Also, you are passing a local variable to the "AddPlayer" method, which might be a problem, depending on how that is implemented.
Without seeing more code, what you have posted looks valid.
Are both pieces of code in the same source file? Perhaps you need "#include Player.h" at the top of the file declaring the team.
EDIT: To answer the actual question; you can create an instance of another class within a constructor and then use it however you please. As a side note, member generally refers to variables and functions declared within a class.
The line:
Player asdf = (one);
Can be changed to:
Player asdf(one);
Also a word of caution, you are making a copy of adsf when you pass it to addPlayer(). That may well be appropriate. But you do have the option to employ move semantics if that is a better fit.

Can I use switch-case inside if condition?

I'm making a robot which can avoid an obstacle itself by moving randomly in another direction when it meets an obstacle. Can I use a switch case inside an if condition as a statement, like in the code below?
if(s1)
{
switch(randNumber)
{
case 0:
spincw();
break;
case 1:
spinccw();
break;
case 2:
up();
break;
case 3:
right();
break;
case 4:
back();
break;
}
}
I compiled this but it shows
error: a function-definition is not allowed here before '{' token
Yes you can call switch in if. you can not define a function inside another function. Can you please take a loot at function being defined correctly. Might be the problem is somewhere else. Can you please provide more detail.

Do I need a "Default" statement in this scenario?

Often in school, our lecturers will tell us to always include a Default statement at the end of a switch case statement. However, I have always been wondering is it necessary for ALL (or most) scenario?
Consider the following example in C++:
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
In the case above, I feel that it is impossible to have a case where it can be > 2 or < 0, so do I still need to include a Default statement?
There are similar questions in SO asking for the need of Default in switch-case. The replies given there stated that we should almost at anytime include a Default. But of all the cases I encountered personally, it just seems to be redundant since the Default can never be reached.
Edit: Also, in terms of defensive programming, does this scenario needs a Default statement?
And if I were to add a Default statement. It will only be a error-handling statement, am I right to say that?
Technically, no you don't, because you've covered all possible cases with your switch statement.
However, I always find it useful to include an assertion/exception in the default anyway. Consider the following scenario:
// V1.0.0: Initial version.
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
Later...
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
In this scenario, developer #2 updated the rand modulus, but didn't actually add the case to handle num == 4. Without the default, you're going to silently fail, and that could cause all kinds of badness that could be very hard to debug. A more maintainable solution might be:
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
default:
assert(false);
throw InvalidNumException("BUG: Method has not been specified for value of num");
}
When debugging, this would stop the debugger at the assert, and if (god forbid) the missing case makes it all the way to production, you'll get an exception thrown, rather than just running off and doing stuff that shouldn't happen.
EDIT:
I think including a catch-all is a good addition to a defensive programming style. It guarantees that you'll get a useful outcome if you miss a case statement (even if that useful outcome is to cause the program to crash).
EDIT 2:
As Andre Kostur mentioned in a comment to this answer, some compilers will emit warnings if you switch on an enum and forget to handle a case, which is a good reason to not include a default case for an enum switch statement. Refer to Phresnel's answer for more information about that.
its not necessary, but it is a good habit to include it, with a print. I always do something like print "This should NOT happen" in the default (or except) so I know there is something happening which I didnt expect to happen. Computers can sometimes do weird things, be prepared!
Strictly speaking, you do not. However, in larger projects it can help finding or avoiding bugs if you want to change your code later.
For example, imagine you want to add some cases/methods later. If you leave the switch as is, you might have to debug and see why the new method isn't called. On the other hand, throwing a kind of NotImplementedException there will directly lead you to the fact that you forgot to add a case.
Depending on the exact context, it can be a matter of style. What I do sometimes is the following.
Consider that you in some point of time you tweak
int num = rand()%3;
to
int num = rand()%4;
then your switch statement is not correct and complete anymore. For such cases, you could add the following:
default:
throw std::logic_error("Oh noes.");
std::logic_error is for errors by the programming team. Now if your team forgets to update the switch, it will (hopefully early) have an aborting program with a trace to hunt down for.
Downside of default
There is also a downside of including a default-clause. When you switch upon an enum ...
enum class Color {
Red, Green, Blue
};
....
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
};
... some compilers will warn you that not all cases are covered. To shut the compiler up, you can now do two things:
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
default: break;
};
Color c = ....;
switch(c) {
case Color::Red: break;
case Color::Green: break;
case Color::Blue: break;
};
You will realise that of those two alternatives, the latter might be more productive. However, this relies on compiler behaviour. You could still throw an exception in the default, but transform what would be a nice compile time error into a runtime error, of which many agree the former is preferable.
The best of two worlds (portable errors, with the bonus of compile time errors) could be achieved using early exit or structures where you can test afterwards if a case was hit:
Color c = ....;
switch(c) {
case Color::Red: return;
case Color::Green: return;
};
throw std::logic_error(...);
MYSQL mysql = {0};
switch(c) {
case Color::Red: mysql = red_database(); break;
case Color::Green: mysql = green_database(); break;
};
if (!mysql)
throw std::logic_error(...);
do I still need to include a default statement?
You don't need to, as long as the assumption about the possible range of num holds - which it will, as long as you don't change the code that calculates it.
You might want to, to validate that assumption in case it changes in future. That kind of defensive programming can be useful to catch broken assumptions quickly, before they cause major problems.
And if I were to add a Default statement. It will only be a error-handling statement, am I right to say that?
Yes. I'd throw a logic_error, or maybe just terminate the program, to indicate that a logical assumption is invalid.
So let's evolve your code a little bit, to something more realistic:
void processNumber(int maxNum) {
int num = rand()%maxNum;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
}
and here you need to make sure that it is in the set of allowed values [1, 2, 3]. You can check it in number of ways, but you need safeguards and check input carefully and raise errors, even if it is internal function.

create an object in switch-case

i use visual studi 2008. (c++)
in my switch case a wanted to create an object, but i doens't work.
is it right, that i can't create an object in a switch case?
if that's right,whats the best way to work around it,
a new method that's creates that object?
edit the code:
switch (causwahl){
case '1':
cAccount *oAccount = new cAccount (ID);
case '2' ....
I can't say for sure with such a vague question, but I'm guessing that you're doing something like this:
switch(foo)
{
case 1:
MyObject bar;
// ...
break;
case 2:
MyObject bar;
// ...
break;
}
This isn't allowed because each case statement has the same scope. You need to provide more scope if you want to use the same variable name:
switch(foo)
{
case 1:
{
MyObject bar;
// ...
break;
}
case 2:
{
MyObject bar;
// ...
break;
}
}
I suggest avoiding switch-case because of this and other problems. You can allow variable definitions by extra curly braces, but that looks messy and causes two levels of indentation. Other problems are that you can only use integer/enum values for cases, that the break statement cannot be used to break from a loop outside the switch. Forgetting to break is also a very common programming mistake that cannot be detected by the compiler (because it is still valid code) and it leads to hard to debug bugs.
Personally I only use switch-case with enum values, and even then never with a default label. This has the benefit of getting me a compile warning (from GCC) if not all possible values of the enum are handled.
There is nothing wrong with if-elses.
switch (choice)
{
case 1:
{
cout<<"\nBike object created********"<<endl;
Bike B1(2,4,50);
V=&B1;
V->Display_Details();
V->CallToll(persons);
break;
}
case 2:
{
cout<<"\n CAR object created********"<<endl;
Car C1(4,8,50);
V=&C1;
V->Display_Details();
V->CallToll(persons);
break;
}
default:
cout<<"You have entered an invalid choice...........Please Enter valid choice........"<<endl;
}