Weird compiler?

Hi, I have made a chronometer, but there is two weird things.
The first is that I need to put an instruction before another else I will get an error (the other function placed in other position work).

void menuChangeEvent(MenuChangeEvent changed){ 
  delay(0); 
  menuPrint(changed.to.getName());
}

delay(0) is the function added, else the compiler give error on menuPrint.

The second is totally weird, on the function

void doClearT(){
  while (digitalRead(pinButton2)==HIGH) delay(10);//wait until select is realeased
  lcd.setCursor(0,1);
  lcd.print("CAN+ACT per eseguire");
  while ((digitalRead(pinButton1)==LOW)&&!((digitalRead(pinButton2)==HIGH)&&(digitalRead(pinButton3)==HIGH)));
  if ((digitalRead(pinButton2)==HIGH)&&(digitalRead(pinButton3)==HIGH)){
    timesCount=0;
    storage.time[0]=0; 
    lcd.setCursor(0,1);
    lcd.print("Tempi cancellati    ");
  }
  while (digitalRead(pinButton1)==LOW) delay(10);//select to exit
}

if I comment the rows with "lcd." the serial port function, else the serial port does not initialize and the software hung of first Serial.println().
I have used in many other parts of the program "lcd." but only that function cause the error on serial port.

The program begin with

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

It hungs on print of "Test" and no feedback on serial monitor.

What happens?

JJ

The first is that I need to put an instruction before another else I will get an error (the other function placed in other position work).

You'll need to show the compiler output to get any help.

Calling delay() with a value of 0 is not a good idea.

It hungs on print of "Test" and no feedback on serial monitor.

What happens?

99.9% chance that you have run out of memory.

PaulS:
You'll need to show the compiler output to get any help.

Calling delay() with a value of 0 is not a good idea.

The compiler give a nosense error. delay(0) make compiling ok, and program work. Any instruction is ok before "menuPrint". If menuPrint is the first it give error (I don't write error now cause I can't try at this time).

It hungs on print of "Test" and no feedback on serial monitor.

What happens?

99.9% chance that you have run out of memory.
[/quote]
Out of memory at second line of code?
If I do a check with Serial.available() any following Serial.println("") will be simply ignored.
If I remove the lcd.
in that function the serial out is ok, all program work with serial output and lcd working.

JJ

if I comment the rows with "lcd." the serial port function, else the serial port does not initialize and the software hung of first Serial.println().

When you comment out some of the lcd print statements, the amount of SRAM is reduced. At some point, you reduce the SRAM requirements down to what is actually available.

Out of memory at second line of code?

A simple sketch, containing a setup() function and a loop() function that do nothing, gets converted to a cpp file, and a main() function is added, along with a call to init(). So, no, the code is not failing at the second line of the sketch. Much has happened long before the second instruction in setup is executed.

When a function call is made, like the one to Serial.println(), space is allocated on the stack for the return code and the location in the stack frame to return to, and all function arguments are pushed onto the stack. Guess where the stack lives. Yep, SRAM. Of which you don't have a lot, and are using (most likely) every last bit you have (and then some). So, when the stack grows beyond what there is room for, the Arduino crashes.

JumpingJack:
Hi, I have made a chronometer, but there is two weird things.
The first is that I need to put an instruction before another else I will get an error (the other function placed in other position work).

...

PaulS:
You'll need to show the compiler output to get any help.

...

JumpingJack:
The compiler give a nosense error.

Ah, no, not enough information. You asked for help with an error. You need to post the error, and/or preferably the whole sketch so we can reproduce the error.

Thank you for help. The problem for hung on first Serial.print is a ram problem, how run out cause the use of many lcd.print and Serial.print. I think is the write implementation that is not good with constant strings. I have to find a solution.

The second problem is that

void menuChangeEvent(MenuChangeEvent changed){
  delay(1);
  menuPrint(changed.to.getName());
}

is compiled ok but

void menuChangeEvent(MenuChangeEvent changed){
  menuPrint(changed.to.getName());
}

give this error

PhotoChrono.cpp: In function 'void menuChangeEvent(MenuChangeEvent)':
PhotoChrono:256: error: unable to find a register to spill in class 'POINTER_REGS'
PhotoChrono:256: error: this is the insn:
(insn 8 7 9 2 PhotoChrono.cpp:274 (set (reg:HI 24 r24)
(mem/s/f:HI (subreg:HI (reg/v:SI 24 r24 [orig:41 changed ] [41]) 2) [3 .name+0 S2 A8])) 8 {*movhi} (expr_list:REG_DEAD (reg/v:SI 24 r24 [orig:41 changed ] [41])
(nil)))
PhotoChrono.cpp:277: confused by earlier errors, bailing out

... confused by earlier errors ...

It's not the only one!

... unable to find a register to spill in class 'POINTER_REGS'

Unusual.

You are passing by value, try passing by reference:

void menuChangeEvent(MenuChangeEvent & changed){
  menuPrint(changed.to.getName());
}

Update after a test

this code give the error

void menuChangeEvent(MenuChangeEvent changed){
  menuPrint(changed.to.getName());
}

void menuPrint(const char* s){
  lcd.clear();
  lcd.print(s);
}

this code is compiled successfully

void menuChangeEvent(MenuChangeEvent changed){
  menuPrint(changed.to.getName());
}

void menuPrint(const char* s){
  lcd.clear();
//  lcd.print(s);
}

There is a bug in LiquidCrystal? It's the same bug that cause apparently memory related problem with Serial.print() run time? At this point is compiler time?
I'm using LiquidCrystal unmodified.

JJ

So you decided to not follow my suggestion of passing by reference?

Passing by reference don't give errors, like add an instruction before menuPrint or change menuPrint but it don't tell me how to prevent any furter problem. This program need a lot of functions, I want to solve the cause not to do a trick any time it happens. If the problem is write I think change the write method may be the solution.
Thanks

JJ

Our (those who answer many questions) experience is that the fragment of code "where the error occurs" only shows the symptom occurring, not the cause of the error, which is in the lines of code your partial understanding of the problem has choosen not to forward.

So for a speedy help I really think you should send us the whole program (no need to include the libraries if you have used unmodified public ones) Instead of cut-n-paste it, you can choose to ZIP it and attach it (Use the "Additional options" link at the bottom of the text entry field). The compiler output window you can cut-n-paste into a text file and include in the zip.

The "weird compiler" has worked fine for thousands of users and probably milliions of sketches. Maybe, just maybe, the fault is in your code?

Memory overrun issues have strange unexpceted restarts and hangs as their primary symptom. The root cause of overrun is too many "string"-constants or too large an array. Some of these can be solved by using the PROGMEM feature. Libraries have their own memory usage (sometimes documented).

There is a small memory usage report program, but its output is of little use if you have totally exhausted the SRAM

JumpingJack:
This program need a lot of functions, I want to solve the cause not to do a trick any time it happens. If the problem is write I think change the write method may be the solution.

You might want to try being a bit more co-operative here. It took two posts to get the exact error message from you. Your initial post mentioned a "weird error" but you didn't actually post the error until reply #5. Then it took another few posts before you reported that my suggestion worked.

Now as to why the "trick" worked ...

You are passing "MenuChangeEvent changed" by value to the function menuChangeEvent (hmm, slightly confusing names there). You haven't shown us what the declaration for MenuChangeEvent is , hopefully it won't take another 10 posts to find out.

Now when passing by value, the compiler has to make a copy of the entire structure - for all we know it is quite large. This is certainly going to consume some of your stack space to do. If you pass by reference instead (using the & symbol) it only has to push the address of the structure, not the whole thing.

The error message you got, which you disclosed after some prodding, was "unable to find a register to spill in class 'POINTER_REGS'". This suggests to me that (while possibly a compiler bug) that the compiler has run out of some resource, like it doesn't have enough registers free, on this small chip, to do what you, the programmer, are asking it to do.

Passing a structure by reference is something done a lot, as it is similar "under the hood" to passing a pointer. It is a low-cost action. Passing a structure by value is a high-cost event, depending on the size of the structure.

I found, for example, a reference to the general problem here:

One answer there says:

A lot of C programming is for embedded systems, where memory is at a premium, and stack sizes may be measured in KB or even Bytes... If you're passing or returning structs by value, copies of those structs will get placed on the stack, potentially causing the situation that this site is named after...

And in case you don't get the reference, the site is named "Stack Overflow".

So, my suggestion wasn't a trick. It solved your problem, and it also saves stack space (and time), something in short supply.

If you are planning to write a lot of functions, consider passing the structure you are using by reference (make it a const reference if you don't want it changed) rather than by value. I hope that helps.

Nick excuse me for reply, I have appreciated so much your solution, I know that pass by reference is light for compiler and this work, MenuChangeEvent is a big structure so passing by value is not a good idea.
But the thing that I don't understand is why if an instruction is present before menuPrint() the problem does not happens. What do the compiler?

JJ

Adding an extra function called changed the work the compiler had to do, and thus (for some unknown reason) made it able to cope.