Products > Programming

Array initialization in switch statement

(1/4) > >>

This is the weirdest bug I've ever encountered. I'm writing software for an Arduino Nano (Atmega328P) in the Arduino IDE. The problem lies in the following switch statement:

--- Code: ---switch (s[0]) {
   case 'D':
   case 'd':
     /* Irrelevant to this problem */
   case 'P':
   case 'p':
     byte dot_map[6] = {0, 2, 3, 4, 6, 7}; // <-- This line right here
     /* Stuff */
   case 'B':
   case 'b':
     /* Irrelevant to this problem */
   case 'F':
   case 'f':
     asm volatile ("nop");
     asm volatile ("nop");
     Serial.println("Incorrect command");
     asm volatile ("nop");
     asm volatile ("nop");

--- End code ---

The line I've marked, the declaration of the byte array, when that line is present none of the following case statement work. What's more, I've checked the output of the compiler with objdump and those cases aren't even present in the compiled program. Everything works fine when that declaration is done before the switch statement. Also, everything works when the code inside the case statement containing the line is in braces.

So, is it not allowed to declare arrays inside the case of a switch statement? Is there any other reason this would not work?


I do not know the Arduino language, but since it is derived from a mix of C and C++, I may guess the problem from the perspective of those languages. You have scoping problem in that line. Your dot_map array is in what scope? Imagine you read dot_map if s[0] is 'b': what will happen? It is not even initialized there.

tl;dr: never declare variables in switch statements, unless you explicitly introduce another scope for them.

I understand that, that is why the braces solve the issue. It's just very odd that the compiler decides to solve the issue by completely ignoring the following case statements without giving any warning or error. I was wondering if there's an underlying reason that I don't know about.

I agree, odd.    It doesn't compile with linux gcc.

Edit: but it does compile if you put ";" before "byte dot_map".   And it runs correctly.  dot_map is in scope in cases below where it is declared.  As one would expect if the switch were replaced with gotos.   Summary - just a pre-processor or compiler bug.

The keyword is "hoisting": declarations are moved to the top of whichever scope they are in.  It may be that it doesn't work with switch/case and the compiler starts reading garbage.  It should be an error in C (which does not perform hoisting..?).



[0] Message Index

[#] Next page

There was an error while thanking
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod