8

my code has 3 classes n_hexa,n_octa,n_bin. The code is here

switch(choice)
{
case 1: cin>>n; 
 n_hexa nx(n);
        break;
case 2: cin>>n; 
 n_octa no(n);
        break;
case 3: cin>>n;
 n_bin nb(n);
        break;
}

on compiling it gives a message "crosses initialisation of n_hexa" for line of n_octa

lovesh
  • 5,235
  • 9
  • 62
  • 93
  • welcome to stack overflow... please use the "code" formatting button on the toolbar (it looks like this: 101010") to format your code in the future. – Joel Spolsky Dec 09 '10 at 05:54
  • Related: http://stackoverflow.com/questions/2351936/create-an-object-in-switch-case http://stackoverflow.com/questions/449736/why-cant-variables-be-declared-in-a-switch-statement http://stackoverflow.com/questions/1231198/declaring-variables-inside-a-switch-statement http://stackoverflow.com/questions/2036819/compile-error-with-switch-expected-expression-before http://stackoverflow.com/questions/1115304/can-i-declare-variables-inside-an-objective-c-switch-statement http://stackoverflow.com/questions/4068909/odd-compiler-error-when-using-obj-c-objects-in-a-switch-statement – Adam Rosenfield Dec 09 '10 at 06:02

3 Answers3

12

If you want to have temporary objects inside a case, you'll need to scope them properly.

switch(choice)
{
    case 1:
    {
         cin>>n; 
         n_hexa nx(n);
         break;
    }
    case 2:
    {
         cin>>n; 
         n_octa no(n);
         break;
    }
    case 3:
    {
         cin>>n;
         n_bin nb(n);
         break;
    }
}
EboMike
  • 76,846
  • 14
  • 164
  • 167
  • wat do u mean by scope it properly – lovesh Dec 09 '10 at 05:57
  • @user535962: Introduce a new scope for each `case` by enclosing the code in braces, as EboMike has done here. – Fred Larson Dec 09 '10 at 05:58
  • See my code. The problem is that there could be a fall-through if you're omitting the break, so you'd end up in the next case. What's the lifetime of the object? If you explictly put curly braces around it, it's clear when the object will be created and when it will be destroyed. – EboMike Dec 09 '10 at 05:58
  • 1
    didn't occur to me he's after temporary objects.. :/ – Shadow The GPT Wizard Dec 09 '10 at 05:59
  • @eboMike: but y dis shud be an error? Can u explain wat cross initialisation is? I didnt omit d break – lovesh Dec 09 '10 at 07:26
  • You didn't, but it's simply not permitted. Check out some of the links Adam posted. Here's a good one: http://stackoverflow.com/questions/449736/why-cant-variables-be-declared-in-a-switch-statement – EboMike Dec 09 '10 at 07:29
  • @eboMike:thanks for d link. But dont u think putting it in a scope inside the case will also make the compiler generate the code? – lovesh Dec 09 '10 at 07:43
  • I changed my code and put braces around each object initialization in each case and it works. doesn't d compiler have 2 generate the code for each object now. i m confused – lovesh Dec 09 '10 at 08:05
  • I would hope the compiler generates code. That's what it's there for. I don't see what you're worried about? You have three different kinds of objects, and each one could be created/destroyed under certain circumstances. – EboMike Dec 09 '10 at 08:08
  • Well, @lovesh time to accept this answer - I also learned some new stuff from your question so thanks! :) – Shadow The GPT Wizard Dec 09 '10 at 08:19
  • i got my program working and thanks 4 dat. but i dont understand how putting braces around object instantiation in the case statements causes conditional compilation? what difference do the braces make? – lovesh Dec 09 '10 at 08:41
  • Braces determine the scope. An object will be deleted as soon as it's outside the scope and can no longer be accessed. Btw, hint, hint - as Shadow said, please consider accepting this answer. We'll both get rep points for that. – EboMike Dec 09 '10 at 09:46
2

Try declaring the variables above the switch command:

n_hexa nx;
n_octa no;
n_bin nb;
switch(choice) {
    case 1:
        cin>>n;
        nx(n);
        break;
...
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • That works too, although it would be somewhat wasteful if those classes have expensive constructors/destructors, or if they're big. Yeah, I saw your comment on my answer :) – EboMike Dec 09 '10 at 06:00
  • @EboMike: unless user535962 is specifically after some side effect of construction, or puts some extra statements before the break, this approach is still more useful than temporaries that disappear. Makes you want to see the surrouding context - there's probably a better way of writing the same functionality, but it's not clear what. – Tony Delroy Dec 09 '10 at 06:11
  • @Tony: I guess it's anyone's guess what the intent is :) The advantage of putting the variables into the cases is that the code is more contained, but it really depends on what the code is supposed to do. If the objects are used outside the switch, then The Wizard's approach is obviously the only way to go. – EboMike Dec 09 '10 at 07:02
  • @EboMike: yep I see your point and agree.. thanks for the vote of confidence. :) – Shadow The GPT Wizard Dec 09 '10 at 07:06
  • @Shadow Wizard:but dat wud mean i hav to instatiate 3 objects whereas in my original code i had to actually create just 1 object. thats an overhead – lovesh Dec 09 '10 at 07:07
  • @lovesh I'm not sure that only declaring them would instantiate them. My C/C++ skills are bit rusty by now though. @EboMike what do you say? – Shadow The GPT Wizard Dec 09 '10 at 07:10
  • @Ebo by the way, thought the first upvote was yours.. thanks anyway! :-P – Shadow The GPT Wizard Dec 09 '10 at 07:11
  • @Shadow Wizard: ya i m user535962 – lovesh Dec 09 '10 at 07:12
  • @Shadow Wizard: declaring dem wud call their default constructor and allocate memory 4 dem.It is dis overhead dat i m talking abt. – lovesh Dec 09 '10 at 07:18
  • Yes, Shadow's code would instantiate three objects on the stack, but if they don't have a constructor, they'd essentially be free. Even if the constructor is relatively trivial, it might get optimized out entirely. But if constructing/destruction them IS expensive, then don't do it that way. – EboMike Dec 09 '10 at 07:20
2

Ebomike's post has the answer to get rid of the errors. Now the reason is,

From Standard docs 6.7.3,

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps77) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has trivial type (3.9) and is declared without an initializer (8.5).

An example from the Standard docs itself,

void f()
{
// ...
goto lx; // ill-formed: jump into scope of a
// ...
ly:
X a = 1;
// ...
lx:
goto ly; // OK, jump implies destructor
// call for a followed by construction
// again immediately following label ly
}

In which the statement goto lx; is ill-formed because it is being jumped to the statement lx, where the scope of a is visible.

Also,

77)The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

So, this applies to switch as well.

And if braces {} are put in them, the scope is limited to the braces and you are free to declare within each case statement.

Hope that helps..

liaK
  • 11,422
  • 11
  • 48
  • 73