Расчет полей структуры на этапе компиляции

Вот смотрите. Я оставил практически полностью Ваш код, но изменил функцию подсчёта длины (про неё позже).

Также я добавил макрос WITH_CALC (первая строка). Если указать там true, то компилируется Ваш вариант, а если false – то такая же структура но безо всяких вычислений с голимыми константами. Это было сделано для проверки. Теперь Вы можете скомпилировать c true и с false и сравнить размер кода и данных. Как видите, размеры идентичны. Это доказывает, что все вычисления были сделаны компилятором, а в код попали только готовые константы.

Теперь про функцию подсчёта длины.

  1. она не использует никакие поля структуры (и не может, т.к. Вы её вызываете до создания экземпляра). Значит, она просто просится быть static.
  2. Вы вызываете её в constexpr-конструкторе, значит она обязана быть constexpr
  3. В С++11 (а “искаропки” указан именно он) тело constexpr-функции обязано состоять из единственного оператора return, поэтому я переписал её соответствующим образом (кстати, я не проверял Ваш вариант на корректность, просто переписал один в один)

Собственно, всё. Смотрите, разбирайтесь

#define WITH_CALC true

#if WITH_CALC /////////////////////////////////////////////////////////////////////

struct SExample {
  // конструктор, рассчитываем на этапе компиляции
  constexpr SExample(const char* const str) : _str(str), _len_utf8(strlenUtf8(str)) {}

	// длина строки в UTF-8
	static constexpr size_t strlenUtf8(const char *ptr /* const s*/) {
		return ! * ptr ? 0 : ((((*ptr & 0xc0) != 0x80) ? 1 : 0) + strlenUtf8(ptr + 1));
	}

size_t length(void) const { return _len_utf8; }

protected:
	const char* const _str;
	const size_t _len_utf8;
};

SExample ex = SExample("Пример");

#else	 /////////////////////////////////////////////////////////////////////

struct SExample {
	size_t length(void) const { return _len_utf8; }

 	const char* const _str;
	const size_t _len_utf8;
};
SExample ex = (SExample) { "Привет", 6 };

#endif	 /////////////////////////////////////////////////////////////////////

void setup(void) {
	Serial.begin(115200);
	Serial.print(ex.length());
}

void loop(void) {}
2 лайка