Глобальное редактирование: извините, ребята, я весь загорелся и написал много ерунды. Просто старый чудак ругается.
Я хотел верить, что C пощадили, но, увы, с C11 его поставили на один уровень с C++. Очевидно, чтобы знать, что компилятор будет делать с побочными эффектами в выражениях, нужно теперь решить небольшую математическую загадку, связанную с частичным упорядочением кодовых последовательностей на основе "находится перед точкой синхронизации".
Мне посчастливилось спроектировать и внедрить несколько важных встроенных систем реального времени еще во времена K&R (включая контроллер электромобиля, который мог отправить людей врезаться в ближайшую стену, если двигатель не контролировался, 10-тонный промышленный робот, который мог бы раздавить людей в месиво, если бы ему не давали правильных команд, и системный уровень, который, хотя и безвредный, заставит несколько десятков процессоров высосать всю шину данных с менее чем 1% системной нагрузки).
Я могу быть слишком старым или глупым, чтобы понять разницу между undefined и unspecified, но я думаю, что у меня все еще есть довольно хорошее представление о том, что означают параллельное выполнение и доступ к данным. По моему, возможно, информированному мнению, эта одержимость парней из C++, а теперь и C с их любимыми языками, взявшими на себя проблемы синхронизации, является дорогостоящей несбыточной мечтой. Либо вы знаете, что такое параллельное выполнение, и вам не нужны никакие из этих штуковин, либо вы не знаете, и вы сделаете миру одолжение, не пытаясь с этим связываться.
Вся эта куча вызывающих слезы абстракций барьеров памяти просто связана с временным набором ограничений многопроцессорных систем кэширования, которые можно безопасно инкапсулировать в общие объекты синхронизации ОС, такие как, например, мьютексы и условные переменные C++. предложения.
Стоимость этой инкапсуляции — всего лишь минутное снижение производительности по сравнению с тем, чего можно достичь, используя детализированные конкретные инструкции ЦП, в некоторых случаях.
Ключевое слово volatile
(или #pragma dont-mess-with-that-variable
для всех I, как системный программист, будьте осторожны) было бы вполне достаточно, чтобы сказать компилятору прекратить переупорядочивать доступ к памяти. Оптимальный код можно легко создать с помощью прямых ассемблерных директив, чтобы дополнить низкоуровневый код драйвера и ОС специальными инструкциями для ЦП. Без глубоких знаний о том, как работает базовое оборудование (кэш-система или шинный интерфейс), вы все равно будете писать бесполезный, неэффективный или ошибочный код.
Небольшая корректировка ключевого слова volatile
, и Боб стал бы кем угодно, кроме самого заядлого программиста низкого уровня. Вместо этого обычная банда фанатов математики C++ устроила полевой день, разрабатывая очередную непонятную абстракцию, поддавшись своей типичной склонности разрабатывать решения в поисках несуществующих проблем и путая определение языка программирования со спецификациями компилятора.
Только на этот раз изменение потребовало также исказить фундаментальный аспект C, поскольку эти «барьеры» должны были быть созданы даже в низкоуровневом коде C для правильной работы. Это, среди прочего, привело к хаосу в определении выражений без каких-либо объяснений или оправданий.
В заключение, тот факт, что компилятор может создать непротиворечивый машинный код из этого абсурдного куска C, является лишь отдаленным следствием того, как разработчики C++ справлялись с потенциальными несоответствиями систем кэширования в конце 2000-х годов.
Это произвело фурор. ужасный беспорядок в одном фундаментальном аспекте C (определение выражений), так что подавляющее большинство программистов на C, которым наплевать на системы кэширования, и это правильно, теперь вынуждены полагаться на гуру, чтобы объяснить разницу между a = b() + c()
и a = b + c
.
Попытка угадать, что станет с этим злополучным массивом, в любом случае является чистой потерей времени и усилий. Независимо от того, что компилятор сделает из этого, этот код патологически неверен. Единственная ответственная вещь, которую нужно сделать с ним, — это отправить его в корзину.
Концептуально побочные эффекты всегда можно убрать из выражений, приложив тривиальное усилие явного разрешения модификации до или после вычисления в отдельном операторе. .
Такой дерьмовый код мог быть оправдан в 80-х, когда нельзя было ожидать, что компилятор что-то оптимизирует. Но теперь, когда компиляторы давно стали умнее большинства программистов, все, что осталось, — это кусок дерьмового кода.
Я также не понимаю важности этой неопределенной/неопределенной дискуссии. Либо вы можете положиться на то, что компилятор сгенерирует код с согласованным поведением, либо нет. Называете ли вы это неопределенным или неопределенным, кажется спорным вопросом.
По моему, возможно, информированному мнению, C уже достаточно опасен в своем состоянии K&R. Полезной эволюцией было бы добавление мер безопасности, основанных на здравом смысле. Например, используя этот расширенный инструмент анализа кода, спецификации заставляют компилятор реализовывать, по крайней мере, генерацию предупреждений о сумасшедшем коде, вместо того, чтобы молча генерировать код, потенциально ненадежный до крайности.
Но вместо этого ребята решили, например, , чтобы определить фиксированный порядок вычислений в C++17. Теперь каждого недоумка-программиста активно подстрекают намеренно добавлять побочные эффекты в его/ее код, купаясь в уверенности, что новые компиляторы охотно справятся с запутыванием детерминированным образом.
K&R был одним из истинных чудес компьютерного мира. За двадцать баксов вы получаете исчерпывающую спецификацию языка (я видел, как отдельные люди пишут полные компиляторы, используя только эту книгу), отличное справочное руководство (оглавление обычно укажет вам на пару страниц ответа на ваш вопрос). вопрос), и учебник, который научит вас использовать язык осмысленно. В комплекте с обоснованиями, примерами и мудрыми словами предупреждения о многочисленных способах, которыми вы можете злоупотреблять языком, чтобы делать очень, очень глупые вещи.
Уничтожение этого наследия ради такой малой выгоды кажется мне жестокой растратой. Но, опять же, я вполне мог не понять сути. Может быть, какая-нибудь добрая душа подскажет мне пример нового кода на C, в котором используются значительные преимущества этих побочных эффектов?
person
kuroi neko
schedule
15.01.2020
static
не меняет текущего. - person Bob__   schedule 13.01.2020clang
, чтобы этот фрагмент кода вызывал предупреждение IMHO. - person malat   schedule 14.01.2020update_three
на предмет присваиванияglobal_var
на тот случай, если это может привести к неопределенному поведению. Программист должен взять на себя некоторую ответственность! - person TonyK   schedule 15.01.2020