Skip to content

Confusion caused by use of -fpermissive in AVR and megaAVR compilation recipes #10154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
allnick opened this issue May 6, 2020 · 5 comments
Labels
Component: Compilation Related to compilation of Arduino sketches Type: Bug

Comments

@allnick
Copy link

allnick commented May 6, 2020

Hi.
There is the problem.

=============================================================

void setup() {
 Serial.begin(9600);
 Serial.println("Start");
}

void loop() {
 char ch = Serial.read();
 switch(ch){
  case '1':
   Serial.println("Block 1 starts executing");
   // Some block 1
   break;
  case '2':
   Serial.println("Block 2 starts executing");
   byte b;
   b = 0; // It's OK.
   // Some block 2
   break;
  case '3':
   Serial.println("Block 3 starts executing");
   // Some block 3
   break;
  case '4':
   Serial.println("Block 4 starts executing");
   // Some block 4
   break;
 }
}

Sketch uses 1668 bytes (5%) of program storage space…
Global variables use 294 bytes (14%) of dynamic memory…

=============================================================

void setup() {
 Serial.begin(9600);
 Serial.println("Start");
}

void loop() {
 char ch = Serial.read();
 switch(ch){
  case '1':
   Serial.println("Block 1 starts executing");
   // Some block 1
   break;
  case '2':
   Serial.println("Block 2 starts executing");
   byte b = 0; // This causes the problem! All blocks below the 2nd are never executed !!!
            // However, the value of the local variable in the 2nd block remains correct!
   // Some block 2
   break;
  case '3':
   Serial.println("Block 3 starts executing");
   // Some block 3
   break;
  case '4':
   Serial.println("Block 4 starts executing");
   // Some block 4
   break;
 }
}

Sketch uses 1596 bytes (4%) of program storage space…
Global variables use 244 bytes (11%) of dynamic memory…

=============================================================

Note the noticeably smaller code size in the second case.
Moreover, this does not depend on the number of blocks below the second one!
It looks like the linker just doesn't include them in the final code!
Bye.

@per1234
Copy link
Collaborator

per1234 commented May 6, 2020

Related: arduino/ArduinoCore-avr#268

@per1234 per1234 added Component: Compilation Related to compilation of Arduino sketches Type: Bug labels May 6, 2020
@MHotchin
Copy link

This is not valid C++ code, and should result in a compiler error. The standard says this program is ill-formed, not just undefined behaviour.

This exact scenario is called out the in the language standard:
https://en.cppreference.com/w/cpp/language/switch

@per1234
Copy link
Collaborator

per1234 commented Jun 15, 2020

The reason it compiles is due to the use of the -fpermissive compiler option (which is why I referenced arduino/ArduinoCore-avr#268 above). If you try to compile this code for one of the platforms that doesn't use -fpermissive (e.g., Arduino SAMD Boards), it does fail.

I suppose we could close this as covered by arduino/ArduinoCore-avr#268. That is somewhat specific to the AVR platform, due to being in its repository, but I added a comment there noting that the same applies to the Arduino megaAVR Boards platform.

@MHotchin
Copy link

Is it possible to selectively re-enable errors that -fpermissive is hiding? Since it's producing results that are not helpful, allowing projects with this defect to compile is counter-productive - silently broken is much worse than in-your-face broken.

@allnick
Copy link
Author

allnick commented Jun 15, 2020

This is not valid C++ code, and should result in a compiler error. The standard says this program is ill-formed, not just undefined behaviour.

I agree.
The following code solves the problem:

void setup() {
 Serial.begin(250000);
 Serial.println("Start");
}

void loop() {
 char ch = Serial.read();
 switch(ch){
  case '1':
   Serial.println("Block 1 starts executing");
   // Some block 1
   break;
  case '2': {
   Serial.println("Block 2 starts executing");
   byte b = 0; // Now it's OK.
   // Some block 2
   break;
  }
  case '3':
   Serial.println("Block 3 starts executing");
   // Some block 3
   break;
  case '4':
   Serial.println("Block 4 starts executing");
   // Some block 4
   break;
 }
}

But in the previous example, there is no compilation error, there is an incorrectly assembled final code.

@per1234 per1234 changed the title The problem with the switch statement when declaring to initialize a local variable inside it. Confusion caused by use of -fpermissive in AVR and megaAVR compilation recipes Mar 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Compilation Related to compilation of Arduino sketches Type: Bug
Projects
None yet
Development

No branches or pull requests

3 participants