Bug: Sketch uses X bytes (Y%) of program storage space. Maximum is 32,256 byte

While compiling the sketch (attached) I got this error:

Sketch uses 49,304 bytes (152%) of program storage space. Maximum is 32,256 bytes.
Global variables use 176 bytes (8%) of dynamic memory, leaving 1,872 bytes for local variables. Maximum is 2,048 bytes.
processing.app.debug.RunnerException: Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
at processing.app.debug.Compiler.size(Compiler.java:336)
at processing.app.debug.Compiler.build(Compiler.java:119)
at processing.app.Sketch.build(Sketch.java:1170)
at processing.app.Sketch.build(Sketch.java:1143)
at processing.app.Editor$BuildHandler.run(Editor.java:2016)
at java.lang.Thread.run(Thread.java:745)
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.

Sketch uses two library:
#include <Servo.h>
#include <Adafruit_NeoPixel.h>

oiOSoul.ino (21.1 KB)

Time for a bigger processor.
ATmega1284P, 128K flash, 16K sram, 32 IO. Dual hardware serial ports.
http://www.crossroadsfencing.com/BobuinoRev17/

But how come, the owner of this code used Arduino Uno board:

Clearly, something's amiss since the article code is about 19K and yours is over twice as much. Perhaps you should post your code.

Edit: I see you did post it...I'll take a look.

I can't compile the program on a ATMega2560 without removing lines 340-361. Removing those lines it compiles to over 43K. I'm not sure what the issue is, but the error message I'm getting is:

/cygdrive/c/Users/econjack/AppData/Local/Temp/ccU2j4EU.s: Assembler messages:
/cygdrive/c/Users/econjack/AppData/Local/Temp/ccU2j4EU.s:17121: Error: operand out of range: 64
Error compiling.

I've not seen that error before, but perhaps someone else knows what it is.

A quick look with "avr-nm -S --sort-size" and avr-objdump shows that the bulk of the code is in your modules (loop, sneeze, doseOff, etc), and an awful lot of it is manipulation, conversion, and math on floating point numbers (ever call to move3servos() does three int to float conversions, and you have a LOT of them.

I reduced sketch size by about 16k bytes by making the parameter passing to move3servo use ints, and doing the float conversion inside the subroutine. (that's not enough to make it fit, but it's pretty close.)

Passing large numbers of largish arguments to functions is not something that an AVR does very well. You could probably get a bunch more savings by passing move3servos a pointer to "positions", like:

position_t doseOff1 = {&servoLeg, centerLeg, &servoWaste, 1400, &servoHead, centerHead, 2.0};
 :
move3servos(&doseOff1);

And ... is it always servoLeg, servoWaste, servoHead? Save more space by assuming that and not passing them as arguments ("moveLegWasteHead(...)", even.)
You probably CAN get this functionality to fit in 32k on an Uno. But you would have a lot more breathing room and less "empty" effort using a bigger microcontroller (also, this is the sort of thing that would benefit from running on a 32bit ARM instead of an AVR. Probably.)

Solved: oiO project not compatible with with Arduino 1.6
Use instead: Arduino 1.0.6

Well, that's impressive.
The new compiler seems to be in-lining a bunch of the function calls inside loop, having incorrectly decided that they are "small" Adding "-fno-inline-small-functions" to the sketch compile reduces the .o from 44k to about 12k...

I think that qualifies as a compiler bug...

I reported it as a bug but they closed the issue with grounds:

1.6.3 uses an updated gcc with an updated avrlibc. Updates usually mean more functionality that sometimes lead to bigger programs. While I don't know the root cause of your particular issue, if I was you I would: 1) stick with 1.0.6 for that particular sketch only OR 2) optimize it so that it fits into the board OR 3) play with gcc optimizations flags and try to squeeze it (try switching from -Os to -O3)

yeah; it's not an arduino bug, it's an avr-gcc bug. Probably of the sort that they won't fix either ("we do that optimization based on an intermediate code representation of the program, it's not our fault that functions grow from "small" to "not small" when going from the intermediate form to actual machine code on the AVR." Grr.) I'll see if I can do some poking and prodding in places that might have more results. a 3x increase in size is not "somewhat bigger."

On the bright side, even with 1.6.3 as shipped, there are potential solutions. Adding "-fno-inline-small-functions" to the appropriate platforms.txt file will result in your sketch being about 2k smaller than it was with the 1.0.6 compiler (~17k) And this is a much easier change to make, compared to modifying the IDE source code (which is what you would have had to do to change compiler options in 1.0.x)

Looks like the original poster didn't link to the issue he posted on GitHub. Here it is:

Looks like Bill and I duplicated our efforts to analyze the problem and discover the inline heuristics issues, all because this same issue was posted in 2 different places, without any links on either to the other.

@flash_oh (aka "dubnikov" on Github) - I really wish people like you would at least link between your duplicated postings. You've caused valuable time to be wasted on duplicated effort by not taking that very simple step.

Yes, sorry for that.
Since they closed (now they reopen) this case.

It turns out that this isn't even an AVR-specific bug.

I've submitted 65740 – spectacularly bad inlinining decisions with -Os

(edited down to C for x86!)

BillW-MacOSX-2<10423> /sw/lib/gcc4.7/bin/gcc-fsf-4.7 -c -Os -w foo.ii -fno-inline-small-functions
BillW-MacOSX-2<10424> size foo.o
__TEXT  __DATA  __OBJC  others  dec     hex
8725    209     0       0       8934    22e6

BillW-MacOSX-2<10426> /sw/lib/gcc4.7/bin/gcc-fsf-4.7 -c -Os -w foo.ii 
BillW-MacOSX-2<10427> size foo.o
__TEXT  __DATA  __OBJC  others  dec     hex
29936   209     0       0       30145   75c1

westfw,

Federico Fissore (Arduino developer which maintaining and evolving the Arduino IDE) already updated to old similar bug: Bug 38629 - target-specific parameters for inline heuristics not defined for AVR
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38629

The bug he had linked/updated WAS arduino specific (and quite old.)
The current bug has been confirmed present in the (quite different) new compiler, and not avr-specific.