Почему C не предлагает синтаксически прозрачные ссылки, как C ++ и Java? - PullRequest
3 голосов
/ 28 июня 2019

Я пытался узнать больше об исторической причине [s] для передачи по значению в C. Существует сообщение о переполнении стека, которое затрагивает эту тему в связи с C ++. Тем не менее, я заинтересован в C. Я представляю себе, когда это решение было принято, можно было бы сделать то, что мы сейчас называем «передать по ссылке». Тем не менее, это был не выбор. Есть ли проблемы с оптимизацией, многопоточностью и т. Д., Которые входят в игру?

Я пытался это Google, но нигде не получил. Передача по значению дает некоторые гарантии в отношении того, что переменная не изменяется под капотом. Это единственная причина? Я полагаю, что в то время концепция «копирования толстого объекта» не была большой проблемой, и передача по значению приводила к небольшим накладным расходам. Таким образом, это могло бы считаться правильным выбором. Есть ли что-то еще в этом решении?

Ответы [ 5 ]

13 голосов
/ 28 июня 2019

По словам Кернигана и Ричи в Язык программирования Си , 1978, пункт 1.8 «Аргументы - вызов по значению», стр. 24:

Call по стоимости является активом, но не обязательством. Обычно это приводит к более компактным программам с меньшим количеством посторонних переменных, поскольку аргументы могут рассматриваться как удобно инициализированные локальные переменные в вызываемой подпрограмме. Например,…

… При необходимости можно организовать функцию модификации переменной в вызывающей подпрограмме. Вызывающий должен предоставить адрес переменной, которую нужно установить (технически указатель на переменную),…

7 голосов
/ 28 июня 2019
  1. Передача по значению часто происходит быстрее, чем передача по ссылке и разыменование указателя каждый раз, когда вы хотите использовать аргумент.Поскольку структуры не были частью раннего C, а затем требовалось передать их в качестве указателя, это не было большой проблемой.

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

  3. На старых компьютерах требовался микрооптимизированный код для более быстрой работы, поскольку сами процессоры были не оченьбыстро.

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

Все этовместе, вероятно, сводится к тому, что C использует передачу по значению.

4 голосов
/ 28 июня 2019

C всегда стремился быть хорошо работающим и «близким к металлу», и передача примитивов (целых чисел / указателей / чисел с плавающей точкой) по ссылкам просто неоптимальна (у первобытного C не было структур, и когда он их получализначально они были довольно ограничены, и вы не могли передать их по значению или вернуть их.)

Передача по ссылке обязательно включает в себя передачу (неявно разыменованный) указатель, и если вы собираетесь передать указатель,Вы также можете передать значение напрямую и избавить вызываемого от необходимости извлечения цели указателя.

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

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

1 голос
/ 30 июня 2019

C всегда был предназначен для (а) быть ближе к машине и (б) дать вам основные механизмы, с которыми вы могли бы делать более сложные вещи, если хотите. Я думаю, что выбор передачи по значению является правильным по обоим критериям.

C дает вам пропуск по значению, но если вам нужен эффект передачи по ссылке, вы можете легко сделать это с помощью &. (С другой стороны, если язык дал вам пропуск по ссылке, и вы хотели смоделировать передачу по значению, вы бы немного застряли.)

Использование передачи по значению также обходит все головоломки с передачей по ссылке, как пресловутое (предполагаемое) поведение в Фортране, где, если вы вызвали f(5), а затем f изменили его аргумент, вы в конечном итоге изменили все остальные 5 в программе.

1 голос
/ 30 июня 2019

По моему мнению, основной причиной реализации языка с такой низкой сложностью были среды, поддерживаемые в древние времена при разработке языка Си.Лучшим компьютером, доступным в 1976 году для работы с Unix (v5, v6, v7?), Был pdp-11, представляющий собой компьютер с 64 КБ (в прошлом вы могли разделить инструкции и данные в двух разных сегментах, чтобы удвоить виртуальное адресное пространство)виртуальные адреса.

Необходимость запуска компилятора C только с 64 КБ виртуального пространства делает pcc (портативный компилятор C, компилятор из at & t unix для pdp-11 / unix) для наложения текстового сегмента, чтобы позволитьместо для всего кода.

И наконец, подумайте, что эти программисты должны были написать весь этот код с ed(1) на печатном телетайпе !!!!(без плоских 40-дюймовых экранов с полноэкранным редактором с символами 100x180, цветным синтаксисом или аналогичными эффектами)

...