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


начиная с 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";

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

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


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

7 53

7 ответов:

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

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

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

const int x = 0x123 a;

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

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

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

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

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

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

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

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

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

С 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 вопрос, который говорит:

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

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

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

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

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

0 x 1 a B 2 3

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

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

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

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

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