In a method in a class I'm working on I have
template <typename T = int_fast16_t, uint8_t Bits = sizeof(T) * 8 - 2>
struct FixedPointFraction {
using value_type = T;
constexpr static uint8_t kFractionBits = Bits;
// ...
template <typename U, uint8_t UBits = sizeof(U) * 2 - 2>
FixedPointFraction<U, UBits> Convert() const {
using Target = FixedPointFraction<U, UBits>;
static constexpr int kShift = Target::kFractionBits - kFractionBits;
// Fails to compile `if constexpr` below:
if constexpr (kShift > 0) {
return Target(static_cast<U>(fraction_bits << kShift));
} else if (kShift < 0) {
return Target{fraction_bits >> kShift};
} else {
return Target{fraction_bits};
}
}
// ...
};
But compiling with avr-g++ (GCC) 5.4.0
fails with
avr-g++ -g -DF_CPU=3'333'333L -std=c++17 -DNDEBUG -fdata-sections \
-ffunction-sections -fno-exceptions -flto=auto -Wall -Os -Werror -Wextra \
-B build/atpack/gcc/dev/attiny3224 -isystem build/atpack/include \
-mmcu=attiny3224 -Wa,-ahlmns=build/timer.lst -c -o build/timer.o timer.cc
...
util.h: In member function ...:
util.h:105:8: error: expected ‘(’ before ‘constexpr’
if constexpr (kShift > 0) {
^
Is support for C++17 somehow incomplete, or am I doing something wrong?
avr-g++
invokes GCC version 5.4.0:
% avr-g++ -v
Using built-in specs.
Reading specs from /usr/lib/gcc/avr/5.4.0/device-specs/specs-avr2
COLLECT_GCC=avr-g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/5.4.0/lto-wrapper
Target: avr
Configured with: ../gcc/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=avr CFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' CPPFLAGS='-Wdate-time -D_FORTIFY_SOURCE=2' CXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' FCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' FFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' GCJFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong' LDFLAGS=-Wl,-z,relro OBJCFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat ' OBJCXXFLAGS='-g -O2 -fdebug-prefix-map=/build/gcc-avr-mRLtUO/gcc-avr-5.4.0+Atmel3.6.2=. -fstack-protector-strong -Wformat '
Thread model: single
gcc version 5.4.0 (GCC)