Use of constexpr function breaks compilation [solved]

I''m using C++11 constexpr functions for a while now in Arduino sketches (instead of macros) but recently came across what I think may be a bug in the IDE's parser.

Example compiling with IDE version 1.8.2:

// compiles if constexpr function is commented out
constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min) {
  return min * 60 * 1000;
};

enum SwitchState{
  TOGGLE_OFF,
  TOGGLE_ON,
  UNKNOWN,
} savedState = UNKNOWN;

void setup() {

}

void loop() {

}

void setCycle(SwitchState s) {
  // nothing to do here
}

I've not seen this before and was wondering if anyone else has any idea what's happening...

tried your code - slightly modified which just compiles

constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min)
{
  return min * 60 * 1000;
};

void setup() 
{
  Serial.begin(115200);
  Serial.println(__FILE__);
  Serial.println(MINUTES_TO_MILLIS(42));
}

void loop(){}

Used IDE 1.8.5

robtillaart:
tried your code - slightly modified which just compiles

constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min)

{
  return min * 60 * 1000;
};

void setup()
{
  Serial.begin(115200);
  Serial.println(FILE);
  Serial.println(MINUTES_TO_MILLIS(42));
}

void loop(){}




Used IDE 1.8.5

sure, removing the enum typed function it then compiles. constexpr is usable in C++11 (as you demonstrated)

I only came across this bug using the enum and enum type argument in a function call.

compiles in my xCode compiler, but not in Arduino IDE.

robtillaart: tried your code - slightly modified which just compiles

yeah, It works by adding a function prototype:

constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min) {
  return min * 60 * 1000;
};

enum SwitchState{
  TOGGLE_OFF,
  TOGGLE_ON,
  UNKNOWN,
} savedState = UNKNOWN;

void setCycle(SwitchState s);

void setup() {

}

void loop() {

}

void setCycle(SwitchState s) {
  // nothing to do here
}

I've come across this from time to time, using enums or structs as function parameters. It must be the way the .ino file is parsed when function prototypes are built.

Apparently the enum needs to be declared before the constexpr, makes it work too.

enum SwitchState {
  TOGGLE_OFF,
  TOGGLE_ON,
  UNKNOWN
} savedState = UNKNOWN;

constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min) { return min * 60 * 1000; };

void setup()
{
}

void loop()
{
}

void setCycle(SwitchState s)
{
  // nothing to do here
}