`if constexpr` does't compile with `avr-g++ -std=c++17`

128 Views Asked by At

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)
0

There are 0 best solutions below