Я смотрел интервью с Хербом Саттером на канале 9, и он упомянул в конце видео, что синтаксис языка слева направо будет в его списке желаний для будущего стандарта C ++ (хотя он признает, что изменение C ++ таким образом в значительной степени сделал бы для совершенно другого зверя).
Помимо:
более понятным для людей, понятнее невооруженным глазом, например
//C syntax /*pointer to function taking a pointer to function(which takes 2 integers as arguments and returns an int), and an int as arguments and returning an int*/ int (*fp)(int (*ff)(int x, int y), int b) //Go analogous syntax which is left to write f func(func(int,int) int, int) int
легче анализировать (приводит к лучшей поддержке инструмента, как упомянуто в видео - например, рефакторинг кода)
какие еще преимущества есть у синтаксиса «слева направо» в языке программирования. Я знаю только о Pascal и Go, использующих такой синтаксис (и Go даже не идет полным ходом, как я понимаю из этого поста в блоге, из которого я взял также примеры). Было бы возможно иметь язык системного программирования такого рода синтаксиса?
источник
f :: (Int -> Int -> Int) -> Int -> Int
function strlen(s:String):int {...}
. Также напечатано лямбда-исчисление (отсюда и Хаскель).Ответы:
Основным преимуществом является то, что разбор проще и уникален. Обратите внимание, что после разбора строки компилятор будет знать, что это за тип, поэтому отныне определение типа не имеет значения.
Любую функцию, которая возвращает аргумент типа массива или указатель на функцию, в настоящее время трудно прочитать:
И было бы меньше шансов на недоразумение (как самый неприятный разбор ):
Использование аналогичного подхода для равномерной инициализации в C ++ 0x (т.е.
{}
для идентификации инициализации). Обратите внимание, что при подходе слева направо гораздо яснее, что мы определяем. Многие люди (я точно) были укушены в любой момент этой ошибкой синтаксического анализа в прошлом (более одного раза), и это не будет иметь место с синтаксисом слева направо.источник
new
операторамstruct
или семантике двух операторов семантикиclass
, что не применимо к C ++, поскольку в C ++ нет различий в типах значения / ссылкиКак мы сюда попали
Синтаксис C для объявления функциональных точек был предназначен для отражения использования. Рассмотрим обычное объявление функции следующим образом
<math.h>
:Чтобы иметь точечную переменную, вы можете присвоить ее типу безопасности, используя
вам нужно было бы объявить эту
fp
точечную переменную следующим образом:Так что все, что вам нужно сделать, это посмотреть, как вы будете использовать функцию, и заменить имя этой функции ссылкой на указатель, превращаясь
round
в*fp
. Тем не менее, вам нужен дополнительный набор паренов, который, как говорят некоторые, делает его немного беспорядочным.Возможно, это было проще в оригинальном C, который даже не имел сигнатуры функции, но давайте не будем возвращаться туда, хорошо?
Место, где это становится особенно неприятным, - выяснить, как объявить функцию, которая либо принимает в качестве аргумента, либо возвращает указатель на функцию, либо и то и другое.
Если у вас была функция:
Вы можете передать его функции сигнала (3) следующим образом:
или если вы хотите сохранить старый обработчик, то
что довольно легко. То, что довольно легко - ни красиво, ни легко - правильно делает декларации.
Ну, вы просто возвращаетесь к объявлению своей функции и меняете имя для ссылки на точку:
Поскольку вы не декларируете
gotsig
, вам может быть легче читать, если вы опустите:А может и нет. :(
За исключением того, что это недостаточно хорошо, потому что signal (3) также возвращает старый обработчик, как в:
Так что теперь вы должны выяснить, как объявить все это.
достаточно для переменной, которую вы собираетесь назначить. Обратите внимание, что вы на самом деле не заявляете
gotsig
здесь, толькоold_handler
. Так что этого действительно достаточно:Это приводит нас к правильному определению сигнала (3):
Typedefs на помощь
К этому времени, я думаю, все согласятся, что это беспорядок. Иногда лучше назвать свои абстракции; часто, действительно. При правильном
typedef
понимании это становится намного проще:Теперь ваша собственная переменная обработчика становится
и ваша декларация для сигнала (3) становится просто
что вдруг понятно. Избавление от * также избавляет от некоторых запутанных скобок (и они говорят, что парены всегда облегчают понимание - ха!). Ваше использование остается прежним:
но теперь у вас есть шанс понять заявления для
old_handler
,new_handler
и дажеsignal
когда вы впервые сталкиваетесь с ними или должны их написать.Вывод
Оказывается, очень немногие программисты на Си способны самостоятельно разрабатывать правильные декларации для этих вещей, не обращаясь к справочным материалам.
Я знаю, потому что у нас когда-то был этот вопрос на наших собеседованиях для людей, выполняющих работу с ядром и драйвером устройства. :) Конечно, мы потеряли много кандидатов, потому что они разбились и сгорели на доске. Но мы также избегали нанимать людей, которые утверждали, что имели предыдущий опыт работы в этой области, но на самом деле не могли выполнить работу.
Однако из-за этой широко распространенной трудности, вероятно, не только разумно, но и разумно иметь способ обойти все эти декларации, которые больше не требуют, чтобы вы были программистом с тройным альфа-уровнем, сидящим на три сигмы выше среднего, просто чтобы использовать это вроде комфортно.
источник
Я думаю, что вы несколько упустили момент, когда сосредоточились на битах слева направо.
Проблема C и C ++ заключается в ужасающей грамматике, которую они имеют, которую трудно читать (люди) и анализировать (инструменты).
Наличие более последовательной (или регулярной ) грамматики облегчает обе эти задачи. А более легкий анализ означает более простой инструмент: большинство современных инструментов не понимают C ++ правильно, даже самый последний плагин Eclipse, поскольку они стремились изобрести колесо ... и потерпели неудачу, и у них, вероятно, больше людей, чем в среднем проекте ОС.
Таким образом, вы, вероятно, прибили это, сосредоточившись на чтении и разборе ... и это большое дело :)
источник
gcc
?