Подтвердить что ты не робот

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

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

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

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

const int y = 100000000;

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

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

Во всяком случае, лучшим решением будет космический символ:

const int z = 1 000 000;

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

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

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

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


& dagger; Это непонятно, потому что все эти языки в тексте поддерживают понятие "разломать" запятую другое атомное предложение, с периодом, действующим для "прекращения" предложение — для меня, по крайней мере, это довольно похоже на запятую "разломать" интегральную часть числа и период, "завершающий" его готовность к дробному входу.

4b9b3361

Ответ 1

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

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

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

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

const int x = 0x123 a;

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

Из wiki у нас есть хороший пример:

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 question, в котором говорится:

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

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

Ответ 4

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

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

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

0 x 1 a B 2 3

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

Ответ 5

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

Ответ 6

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);

Ответ 7

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

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