mmurdoch/arduinounit

On AVR chipsets, flash string literals are incompatible with assert macro

wmacevoy opened this issue · 1 comments

TL;DR

On Arduino Uno, Mega and other boards that use the AVR chipset, direct flash literals do not compile
when used as the first or second argument of an assert:

test(flashCompileError) {
    assertEquals("test",F("test"),F("compare RAM and flash string."));
}

As a work-around, declare flash strings outside the assert:

test(flashCompileOk) {
    const __FlashStringHelper *fTest = F("test"); // *TWO* underbars...
    assertEquals("test",fTest,F("compare RAM and flash string."));
}

Notice this does not affect the optional message, which can use the F() macro.

Long Version

Flash string literals have been drastically rewritten in order to support string de-duplication in flash memory on the AVR (2.3.X-alpha). This represents a significant space savings on these memory limited platforms.

However, the new implementation is not compatible with the type discovery which the assert macros perform in order to use the correct comparison. This type discovery is not needed for the optional footnote message, and so this only applies to the first two arguments of any assert.

The work-around is to declare flash literals outside the macro before using them, as illustrated in the TL;DR section.

There are no good solutions. Even good solutions are not good, because the F() macro expands to a very large literal string in the assert which is wasting a lot of space (very ironic). I think this needs to be a feature.