Почему "0f" не рассматривается как литерал с плавающей запятой в С++?

Почему не 0f рассматривается как литерал с плавающей запятой в С++?

#include <iostream>

using namespace std;

int main(){
  cout << 0f << endl;

  return 0;
}

Компиляция приведенного выше дает мне

C2509 (синтаксическая ошибка: "плохой суффикс на номер" )

используя VS2008.

Ответы

Ответ 1

Если была явная заявленная причина для этого проектного решения, это было бы в документе C99 "Обоснование" (С++ скопировал все это дословно из C, не переосмыслив его). Но нет. Это все, что говорится о суффиксе "f":

§6.4.4.2 Плавающие константы

В соответствии с существующей практикой константа с плавающей запятой определяется как имеющая введите double. Поскольку C89 допускает выражения, содержащие только операнды floatдля выполнения в float арифметике, а не double, метод желательно выражать явные константы float. Тип long doubleвызывает аналогичные проблемы.

Добавлены суффиксы F и L для передачи информации типа с помощью плавающие константы, как и суффикс L, для длинных целых чисел. По умолчанию тип плавающих констант остается двойным для совместимости с предшествующей практикой. В качестве суффиксов также допускаются нижний регистр F и L.

Однако есть определенная причина. Обратите внимание на формулировку: "добавлены суффиксы для передачи информации типа с плавающими константами". Авторы стандарта думали о числовых константах, поскольку уже были однозначно либо целыми, либо с плавающей точкой к моменту поступления в суффикс. Суффикс предназначен только для дополнительной специфичности внутри категории, он не может переворачивать число из одной категории в другую. Это подкрепляется фактической грамматикой (C99 §6.4.4), которая сначала определяет числовые константы как целые константы или плавающие константы, а затем определяет отдельные классы суффиксов для каждого.

Ответ 2

Предполагая, что грамматика, используемая С++ для констант с плавающей запятой, такая же, как для C (что, я думаю, верно), мы имеем:

Определения некоторых ярлыков, взятых из ANSI C grammar

D      [0-9]
L      [a-zA-Z_]
H      [a-fA-F0-9]
E      [Ee][+-]?{D}+
FS     (f|F|l|L)
IS     (u|U|l|L)*

Теперь f или f, которые вы видите в конце плавающих точек, определены в FS выше.

Теперь давайте рассмотрим грамматику для распознавания действительных констант с плавающей запятой:

{D}+{E}{FS}?        
{D}*"."{D}+({E})?{FS}?  
{D}+"."{D}*({E})?{FS}?  

Теперь, если вы видите внимательно, нет правила, которое бы идентифицировало 0f.

Используя правило 1, мы можем иметь 0e0f

Используя правило 2, мы можем иметь .0f или 0.0f

Используя правило 3, мы можем иметь 0.f или 0.0f

Что на самом деле происходит в вашем случае: 0 of 0f будет потребляться лексическим анализатором как целочисленная константа D, а f будет использоваться как токен FS. Теперь, когда синтаксический анализ видит a D, за которым следует FS, для которого нет соответствующего правила, оно выплевывает ошибку:

error: invalid suffix "f" on integer constant

Ответ 3

Потому что 0 - целочисленная константа.

edit: сообщение об ошибке, данное codepad.org(предположим g++), может быть немного легче понять. msgstr "ошибка: недопустимый суффикс" f "для целочисленной константы". "0.f" будет работать, потому что 0. (или 0.0, то же самое) является десятичной константой, и просить десятичную константу быть float имеет больше смысла, чем просить целочисленную константу быть float:)

Ответ 4

Потому что вам нужно 0.0f.

Ответ 5

Здесь "потому что" для вас: если константа int с суффиксом f была автоматически преобразована в float, тогда 0x0f будет неоднозначным.

Ответ 6

Это не обязательно единственная причина, но суффикс l или l может быть применен к целочисленному литералу или к литералу с плавающей запятой. 42L имеет тип long int; 42.0L имеет тип long double.

Числовой литерал с суффиксом l должен быть неоднозначным, чтобы определить, является ли оно целым или плавающим. Разрешить суффикс F сам по себе, чтобы определить тип литерала, будет непоследовательным и потенциально запутанным. Это также затруднит добавление новых суффиксов в будущих версиях языка.