c++ – What kind of `1.`?

Question:

In such a program on C

double x = 1;
x %= 1.;

I get the error http://ideone.com/dDurEH

invalid operands to binary% (have 'double' and 'long double' )

from which it follows that expression 1. is of type long double .

The same code, but on the pros shows just a double http://ideone.com/nd49YK :

invalid operands of types 'double' and 'double' to binary 'operator%'

And such a check on the pluses is also for double http://ideone.com/HCw0GG :

auto x = 1.;

cout 
<< sizeof (double) << ' '      // 8
<< sizeof (long double) << ' ' // 12
<< sizeof x << ' '             // 8
<< sizeof 1. << endl;          // 8

It turns out that C ++ infers the type double , not long double .

So, is this one of the differences between C and C ++ or a jamb of the compiler?
What is the correct type for constant 1. and is it language specific?

Answer:

A constant of the form 1. is of type double both C ++ and C.

  • C

    6.4.4.2/4: An unsuffixed floating constant has type double . If suffixed by the letter for F , it has type float . If suffixed by the letter l or L , it has type long double .

  • C ++

    2.14.4 / 1: The type of a floating literal is double unless explicitly specified by a suffix.

The compiler used at ideone.com is version 5.1.1 20150711 . So it might make sense to run it locally if anyone has the ability. A compiler similar to goodbolt (5.1) produces an error with the correct types :

error: invalid operands of types 'double' and 'double' to binary 'operator%'
error: in evaluation of 'operator%=(double, double)' 

A possible reason lies in the FLT_EVAL_METHOD value, which specifies the computational precision for internal operations. For ideone, this value is 2 , because a 32-bit compiler is used :

For gcc, FLT_EVAL_METHOD == 2 is the default on 32 bit x86

Those. all floating point calculations are based on the long double type.

Although, in truth, this should not affect the type of the real constant.

As it turned out, the value of FLT_EVAL_METHOD can be FLT_EVAL_METHOD from 0 to 2 to 64 bit in the g ++ compiler by adding the -mfpmath=387 switch:

#include <stdio.h>
#include <float.h>

int main()
{
    // 1 % 1.;
    printf( "%d\n", FLT_EVAL_METHOD);
}

Result:

2

In this case, the error message for the second argument also outputs the type long double as the original one on ideone (for 32 bit):

invalid operands to binary % (have 'int' and 'long double')

Clang needs a different switch: -mno-sse . In this case, the diagnostic message for both types displays double :

invalid operands to binary expression ('double' and 'double')

In this case, the first, as it seems to me, should still have remained int .

Summing up, we can say that both compilers in diagnostic messages have problems with inference of the original type of the operands.

Scroll to Top