Какого типа `1.`?

1,00
р.
В такой программе на Си
double x = 1 x %= 1.
получаю сообщение об ошибке http://ideone.com/dDurEH
invalid operands to binary % (have 'double' and 'long double')
из которого следует, что выражение 1. имеет тип long double.
Тот же код, но на плюсах показывает просто double http://ideone.com/nd49YK:
invalid operands of types 'double' and 'double' to binary 'operator%'
Да и такая проверка на плюсах тоже за double http://ideone.com/HCw0GG:
auto x = 1.
cout << sizeof (double) << ' ' // 8 << sizeof (long double) << ' ' // 12 << sizeof x << ' ' // 8 << sizeof 1. << endl // 8 <br>Получается, С++ выводит тип double, а не long double.
Итак, это одни из различий Си и Си++ или же косяк компилятора? Какой правильный тип у константы 1. и зависит ли он от языка?

Ответ
Константа вида 1. имеет тип double как в C++, так и в 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.

Компилятор, используемый на ideone.com имеет версию 5.1.1 20150711. Так что может иметь смысл погонять её локально, если у кого есть возможность. Похожий компилятор на goodbolt (5.1) выдает ошибку с правильными типами:
error: invalid operands of types 'double' and 'double' to binary 'operator%' error: in evaluation of 'operator%=(double, double)'

Возможная причина кроется в значении FLT_EVAL_METHOD, которое задает точность вычислений для внутренних операций. Для ideone это значение равно 2, т.к. используется 32-битный компилятор:
For gcc, FLT_EVAL_METHOD == 2 is the default on 32 bit x86
Т.е. все вычисления с плавающей точкой опираются на тип long double.
Хотя, по правде говоря, это и не должно влиять на тип вещественной константы.
Как оказалось, изменить значение FLT_EVAL_METHOD с 0 на 2 на 64 bit компиляторе g++ можно путём добавления ключа -mfpmath=387:
#include #include
int main() { // 1 % 1. printf( "%d
", FLT_EVAL_METHOD) }
Результат:
2

В этом случае сообщение об ошибке для второго аргумента также выводит тип long double как и исходное на ideone (для 32 bit):
invalid operands to binary % (have 'int' and 'long double')

Для clang нужен другой ключ: -mno-sse. При этом диагностическое сообщение уже для обоих типов выводит double:
invalid operands to binary expression ('double' and 'double')

При этом первый, как мне кажется, должен всё же был остаться int.
Подводя итог, можно сказать, что оба компилятора в диагностических сообщениях имеют проблемы с выводом исходного типа операндов.