2

Just a few hours ago, the following question came up: Variable cannot appear in a constant-expression

Luckily for the OP, the answer provided did solve his problem, but I cannot reproduce the solution.

I've attempted to simplify the code even more and I am now stuck with the following:

#include <bitset>

int main ()
{
   const size_t length_1 = static_cast<const size_t>(1.0f);
   std::bitset<length_1> bits_1;
   const size_t length_2 = static_cast<const size_t>(1.0f / 1.0f);
   std::bitset<length_2> bits_2;
}

If compiled with -pedantic, the first example is accepted by the compiler, but the one with a division (but obviously same number) is rejected with the message "length_2 cannot appear in a constant-expression".

Without -pedantic as well as with -pedantic -std=c++0x it's accepted without any further warning.

This is the full output of g++ -v (I apologize for german, but I'm sure you get the right information anyway):

Es werden eingebaute Spezifikationen verwendet.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
Ziel: i686-linux-gnu
Konfiguriert mit: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread-Modell: posix
gcc-Version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

What's the reason for this behaviour? I guess it's 1.0f beeing recognized as some special constant and therefore changing the behaviour of static_cast?

Community
  • 1
  • 1
stefan
  • 10,215
  • 4
  • 49
  • 90
  • please feel free to suggest a better title than "weirdness", I'm kind of sleepy right now โ€“ stefan Aug 19 '12 at 23:49
  • I think I've found a possible answer for this mess here: http://www.velocityreviews.com/forums/t674562-floating-point-literal-cannot-appear-in-a-constant-expression.html "The motivation was not to require cross-compilers to implement the floating point arithmetic of the target machine." but I'll let someone who knows more about this provide an answer. The fact that it works in VS2010 kind of makes sense, since it doesn't support cross-compilations. โ€“ Mihai Todor Aug 19 '12 at 23:59
  • Also, the magic combination `-pedantic -std=c++0x` doesn't do the trick for me and I have no idea why. Given the citation above, I would expect it to reject my code even without `-pedantic`... Anyway, I'll just compile without `-pedantic` and that's that. โ€“ Mihai Todor Aug 20 '12 at 00:01

1 Answers1

2

The answer is in ยง5.19.

C++03 allows only arithmetic constant expressions which meet the requirements for an integral constant expression: "Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types."

So while it seems reasonable to treat 1.0f/1.0f as 1 it's nevertheless beyond the standard. To avoid "floating point arithmetic of the target machine" sounds like a good explanation to me. GCC 4.7 requires libgmp, libmpfr, and libmpc to make this work.

C++11 imposes no such restrictions. But the accuracy is still implementation defined. Implementations are only "encouraged" to provide consistent results for compile-time and run-time evaluation.

rtlgrmpf
  • 431
  • 2
  • 6