Why can't variables be declared in a switch statement?
Case
statements are only labels. This means the compiler will interpret this as a jump directly to the label. In C++, the problem here is one of scope. Your curly brackets define the scope as everything inside the switch
statement. This means that you are left with a scope where a jump will be performed further into the code skipping the initialization.
The correct way to handle this is to define a scope specific to that case
statement and define your variable within it:
switch (val)
{
case VAL:
{
// This will work
int newVal = 42;
break;
}
case ANOTHER_VAL:
...
break;
}
Can't declare variable in switch case [duplicate]
Opposite to C++, in C declarations are not statements and labels may precede only statements.
Placing a null statement after the label
case 4:;
you made that the label does not precede now a declaration.
Another approach is to use a compound statement after the label and to place the declaration inside the compound statement like
case 4:
{
int res = 1;
printf("%d",res);
break;
}
c++ Declaring a variable inside a switch statement
The reason why some variable declarations are not allowed in a switch
statement is: it is illegal for switch
-based control flow to jump over a variable initialisation.
In your case, I assume the type of commonData
has trivial initialisation (no constructor and no non-trivial members), so declaring it is perfectly fine, as would be declaring just int someInt;
. However, int someInt = 1;
is not allowed, since the initialisation would be skipped whenever mode
is not abc
.
I can't quite see what you'd get from declaring commonData
only once, except for saving some typing at the cost of obscuring the code ("where did commonData
come from?" when reading a case
block), which is never a good trade. So I would just use {}
inside each case
"block" and declare commonData
in each one which needs it. Or declare commonData
above the switch.
But if you really want the same commonData
to be shared by all case
s and yet local to the switch
block, you can fine-tune the scopes. Something like this:
switch(mode)
{
SomeType commonData;
case abc:
{
...
commonData = manager->getDataByIndex(this->Data.particularData);
int someInt = 1;
...
break;
}
case xyz:
...
commonData = manager->getDataByIndex(this->Data.particularData);
break;
default:
...
break;
}
or this:
switch(mode)
{
case abc:
SomeType commonData;
...
commonData = manager->getDataByIndex(this->Data.particularData);
{
int someInt = 1;
...
break;
}
case xyz:
...
commonData = manager->getDataByIndex(this->Data.particularData);
break;
default:
...
break;
}
But please, think of the next maintainer, and don't play such tricks.
The answer above assumes struct commonData;
is actually a "typo" in your code: literally, it would forward-declare a type, and not declare a variable. But that matches neither usage in the rest of your code, nor the text of your question, so I took the liberty of fixing this.
Why is declaring a variable in switch statement allowed? but not declaration + initialization?
The case label functions as a target of a goto
statement.
The C++ standard states in [stmt.dcl]/3
:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization.
So the below will fail:
case 'a':
int x = 4; //will fail
whereas the following will not fail:
case 'a':
int x; // this is ok
x = 4;
In response to the OP's edit:
In this particular case, just the declaration makes x
visible throughout the switch
statement as there are no braces {}
surrounding it.
So x
can be used in with the other case
s as well although the compiler will warn about using it uninitialized. Note that reading of an uninitialized variable is undefined behavior.
To answer the last part of your question:
Suppose the declaration with initialization was allowed it would mean that that particular value of x
(4 in this case) would have to be used in other case
s as well.
Then it would seem as if code for multiple cases was executed. So this is not allowed.
c++: why can we declare a variable in case of switch
There are actually 2 questions:
1. Why can I declare a variable after case
label?
It's because in C++ label has to be in form:
N3337 6.1/1
labeled-statement:
...
- attribute-specifier-seqopt
case
constant-expression
:statement
...
And in C++
declaration statement is also considered as statement (as opposed to C
):
N3337 6/1:
statement:
...
- declaration-statement
...
2. Why can I jump over variable declaration and then use it?
Because:
N3337 6.7/3
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A
program that jumps
(The transfer from the condition of a switch statement to a case label is considered a jump in this respect.)from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default
constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the
preceding types and is declared without an initializer (8.5).
Since k
is of scalar type, and is not initialized at point of declaration jumping over it's declaration is possible. This is semantically equivalent:
goto label;
int x;
label:
cout << x << endl;
However this wouldn't work if x
was initialized at point of declaration:
goto label;
int x = 58; //error, jumping over declaration with initialization
label:
cout << x << endl;
Why we can not define a variable twice in switch? [duplicate]
if the break statements are not used, Then we know that the following cases will be executed. So if you are permitted to declare in both cases that will cause a conflict. For example
switch(x) {
case 1:
int a = 1; // i have removed the break;
case 2:
int a = 2; // now what will happen here :)
break;
}
Declaration of a variable inside a swich case
The reason is that the lexical scope of both declarations is the entire switch body; all the cases share that scope.
That is, in terms of lexical scope, it's like writing
{
int a;
int a;
}
The solution is to enclose the declarations in another braced scope.
switch(whatever)
{
case 1:
{
int a;
break;
}
case 2:
{
int a;
break;
}
}
(Whether you put the break
inside or outside the braces is mostly a matter of taste. I prefer to include the entire case.)
This works for the same reason that this "switch-free" snippet works:
{
{
int a;
}
{
int a;
}
}
Related Topics
How to Read Unknown Number of Inputs
C++ Convert String to Hexadecimal and Vice Versa
What Is the Most Effective Way For Float and Double Comparison
What Is "Argument-Dependent Lookup" (Aka Adl, or "Koenig Lookup")
What Are the Barriers to Understanding Pointers and What Can Be Done to Overcome Them
Is There a Performance Difference Between I++ and ++I in C++
Thou Shalt Not Inherit from Std::Vector
How to Print a List of Elements Separated by Commas
Why Should the Implementation and the Declaration of a Template Class Be in the Same Header File
Carry Over Data Without Using for Loop
Undefined, Unspecified and Implementation-Defined Behavior
When and Why Will a Compiler Initialise Memory to 0Xcd, 0Xdd, etc. on Malloc/Free/New/Delete
What Are the Differences Between Struct and Class in C++
How to Initialize Private Static Members in C++