Почему символ пробела не был выбран для C ++ 14-значных разделителей?

Начиная с C ++ 14, благодаря n3781 (что само по себе не отвечает на этот вопрос) мы можем написать код, подобный следующему:

const int x = 1'234; // one thousand two hundred and thirty four

Цель состоит в том, чтобы улучшить код следующим образом:

const int y = 100000000;

и сделать его более читабельным.

Подчеркивание (_) символ уже был взят в C ++ 11 пользовательскими литералами и запятой (,) имеет проблемы с локализацией — многие европейские страны ставят в тупик использовать это как десятичный разделитель — и конфликтует с оператором запятой, хотя мне интересно, какой реальный код мог быть нарушен, например, допустив 1,234,567,

В любом случае, лучшим решением может быть космический символ:

const int z = 1 000 000;

Эти смежные числовые литеральные токены могут быть объединены препроцессором так же, как строковые литералы:

const char x[5] = "a" "bc" "d";

Вместо этого мы получаем апостроф ('), не используется ни одной системой записи, которую я знаю как разделитель цифр.

Есть ли причина, по которой апостроф был выбран вместо простого пробела?


Это сбивает с толку, потому что все эти языки в тексте поддерживают понятие запятой, «разрывающей» в другом атомарном предложении, с периодом, функционирующим для «завершения» предложения — для меня, по крайней мере, это весьма аналогично запятой «разбивая» неотъемлемую часть числа и периода «заканчивая» его готовым к дробному вводу.

55

Решение

Есть предыдущая статья, n3499, что говорит нам, что, хотя сам Бьярне предложил пробелы в качестве разделителей:

Хотя этот подход соответствует одному общему типографскому стилю, он страдает некоторыми проблемами совместимости.

  • Это не соответствует синтаксису для С.-номер, и минимально потребует расширения этого синтаксиса.
  • Что еще более важно, была бы некоторая синтаксическая неопределенность, когда шестнадцатеричная цифра в диапазоне [a-f] следует за пробелом. Препроцессор не будет знать, следует ли выполнять замену символов, начиная с пробела.
  • Это, вероятно, сделает инструменты редактирования, которые захватывают слова, менее надежными.

Я думаю, что следующий пример является основной отмеченной проблемой:

const int x = 0x123 a;

хотя, на мой взгляд, это обоснование довольно слабое. Я до сих пор не могу придумать пример из реальной жизни, чтобы сломать его.

Обоснование «инструментов редактирования» еще хуже, так как 1'234 в основном нарушает все подсветки синтаксиса, известные человечеству (например, которые использовались Markdown в самом вопросе выше!), и затрудняет реализацию обновленных версий указанных подсветчиков.

Тем не менее, к лучшему или худшему, именно это обоснование привело к принятию апострофов.

34

Другие решения

Очевидная причина не использования пробелов в том, что новая строка также
пробел, и этот C ++ обрабатывает все пробелы одинаково. И выкл
рука, я не знаю ни одного языка, который принимает произвольные пробелы
в качестве разделителя.

Предположительно, можно использовать Unicode 0xA0 (неразрывный пробел) — это
наиболее широко используемое решение при наборе текста. Я вижу две проблемы с
что, однако: во-первых, это не в базовом наборе символов, а во-вторых,
это не визуально отличительный; вы не можете видеть, что это не пространство
просто смотрю на текст в обычном редакторе.

Помимо этого, не так много вариантов. Вы не можете использовать запятую, так как
это уже законный токен (и что-то вроде 1,234 Сейчас
юридический C ++, со значением 234). И в контексте, где это может произойти
в юридическом кодексе, например a[1,234], Хотя я не могу себе представить, что реально
код на самом деле с помощью этого, есть основное правило, что ни одна легальная программа,
независимо от того, насколько абсурдно, следует молча менять семантику.

Подобные соображения означают, что _ не может быть использован либо; если есть
#define _234 * 2, затем a[1_234] будет молча менять значение
код.

Я не могу сказать, что я особенно доволен выбором ', но это
имеет преимущество использования в континентальной Европе, по крайней мере, в
некоторые виды текстов. (Кажется, я помню, что видел это по-немецки, для
Например, хотя в типичном бегущем тексте, немецкий, как и большинство других
языки, будет использовать точку или неразрывный пробел. Но возможно это было
Швейцарский немец.) Проблема с ' разбор; последовательность '1' является
уже законно, как есть '123', Так что-то вроде 1'234 может быть 1,
с последующим началом символьной константы; Я не уверен, как далеко вы
надо смотреть вперед, чтобы принять решение. Там нет последовательности юридических
C ++, в котором за интегральной константой может следовать символ
постоянный, так что нет проблем с нарушением юридического кода, но это означает,
это лексическое сканирование внезапно становится очень зависимым от контекста.

(Что касается вашего комментария: нет логики в выборе
десятичный или разделитель тысяч. Например, десятичный разделитель
конечно, не полная остановка. Это просто произвольные соглашения.)

16

От вики, у нас есть хороший пример:

auto floating_point_literal = 0.000'015'3;

Здесь у нас есть . оператор, а затем, если другой оператор будет встречаться, мои глаза будут ждать чего-то видимого, как запятая или что-то, а не пробел.

Таким образом, апостроф здесь намного лучше, чем пробел.

С пробелами это было бы

auto floating_point_literal = 0.000 015 3;

что не так хорошо, как в случае с апострофами.


В том же духе Ответ Альберта Реншоу, Я думаю, что апостроф более ясен, чем пространство, предлагаемое Гонками Легкости на Орбите.

type a = 1'000'000'000'000'000'544'445'555;
type a = 1 000 000 000 000 000 544 445 555;

Пробел используется для многих вещей, например, для конкатенации строк, которые упоминает OP, в отличие от апострофа, который в этом случае проясняет для кого-то, что используется для разделения цифр.

Когда строк кода становится много, я думаю, что это улучшит читабельность, но я сомневаюсь, что именно по этой причине они выбирают его.


О пробелах, возможно, стоит взглянуть на этот C вопрос, который говорит:

Язык не позволяет int i = 10 000; (целочисленный литерал — это один токен, промежуточный пробел разделяет его на два токена), но, как правило, затраты на выражение инициализатора в виде выражения, являющегося вычислением литералов, практически отсутствуют.

int i = 10 * 1000; /* ten thousand */

10

Это правда, я не вижу практического смысла:

if (a == 1 1 1 1 1) ...

поэтому цифры могут быть объединены без реальной двусмысленности
а как насчет шестнадцатеричного числа?

0 x 1 a B 2 3

Это невозможно сделать из опечатки (обычно мы должны увидеть ошибку)

8

Я полагаю, это потому, что при написании кода, если вы достигнете конца «строки» (ширины экрана), произойдет автоматический разрыв строки (или «перенос слов»). Это может привести к тому, что ваш int будет разделен пополам, одна половина будет на первой строке, вторая половина на второй … таким образом, все останется вместе в случае word-wrap,

5
float floating_point_literal = 0.0000153;   /* C, C++*/

auto floating_point_literal = 0.0000153;    // C++11

auto floating_point_literal = 0.000'015'3;  // C++14

Комментирование не повредит:

/*  0. 0000 1530 */
float floating_point_literal = 0.00001530;

Бинарные строки могут быть трудно разобрать:

long bytecode = 0b1111011010011001; /* gcc , clang */

long bytecode = 0b1111'0110'1001'1001;  //C++14
// 0b 1111 0110 1001 1001  would be better, really.
// It is how humans think.

Макрос для рассмотрения:

#define B(W,X,Y,Z)    (0b##W##X##Y##Z)
#define HEX(W,X,Y,Z)  (0x##W##X##Y##Z)
#define OCT(O)        (0##O)long z = B(1001, 1001, 1020, 1032 );

// result :  long z = (0b1001100110201032);

long h = OCT( 35);

// result :  long h  = (035); // 35_oct => 29_dec

long h = HEX( FF, A6, 3B, D0 );

// result :  long h  = (0xFFA6BD0);
1

Это связано с тем, как анализируется язык. Авторам компилятора было бы трудно переписать свои продукты для принятия литералов с разделителями.

Кроме того, я не думаю, что разделение цифр пробелами очень распространено. Что я видел, это всегда непробельные символы, даже в разных странах.

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector