Команда C++-программистов — @starik-2005, @PyLounge, @markwatney, @dmitrmax и @rssdev10 — собрала 8 экспертных вопросов по C++. Давайте посмотрим, что их вопросам сможет противопоставить команда хабрачитателей.
Осторожно, в комментариях будут спойлеры. Там от лица C++-команды выступят @rotor и @PyLounge: они объяснят, если в вопросах будет что-то непонятно.
P.S. Если хотите поучаствовать в создании будущих квизов, пишите редактору: тг, Хабр.
Команда C++-программистов — @starik-2005, @PyLounge, @markwatney, @dmitrmax и @rssdev10 — собрала 8 экспертных вопросов по C++. Давайте посмотрим, что их вопросам сможет противопоставить команда хабрачитателей.
Осторожно, в комментариях будут спойлеры. Там от лица C++-команды выступят @rotor и @PyLounge: они объяснят, если в вопросах будет что-то непонятно.
P.S. Если хотите поучаствовать в создании будущих квизов, пишите редактору: тг, Хабр.
Комментарии (48)
Kelbon
12.08.2022 14:18-1Был бы очень хороший тест если были бы хорошие вопросы и хорошие варианты ответов, а так не хорошее, хорошо?
kuzhukin
12.08.2022 14:29+19Вопрос про интерфейсы странный. Да, в языке нет ключевых слов для определения интерфейса и для его реализации. Но язык позволяет определять интерфейсы в виде абстрактных классов и реализовывать их в дочерних в любом количестве.
screwer
12.08.2022 16:06+3Тоже споткнулся, пытаясь угадать, что по-мнению авторов больше похоже на правду.
amphasis
12.08.2022 14:31+1Единственное, что поставило в тупик — вопрос с массивом char и cout... Но, я никогда не писал на C++ ¯\_(ツ)_/¯
fshp
14.08.2022 22:21+1К тому же там "верный" ответ неверный без деталей.
Если бы оператор был бы не определен для char без каких-либо ньюансов, то код просто не скомпилировался бы. Но из-за неявного приведения к int все работает. А этот ответ считается неверным.
egor_nullptr
12.08.2022 14:36Уважаемая редакция, указанная на скриншоте ссылка ведёт на страницу с ошибкой 404
crackedmind
12.08.2022 14:39+7В 7 вопросе для С++17 будет другой ответ.
n0r3p1y
12.08.2022 18:42+2ну, вообще нет. ответ на этот вопрос всё тот же. в С++17 по большей части коснулись побочных эффектов при вызове функции, но сами же вычисления параметров до сих пор остаются indeterminately-sequenced.
Alex_Crack
12.08.2022 14:47Не очень-то и каверзные вопросы.
Пишу на С++ без малого всего год, а получилось ответить верно на 7 из 8.
А вообще из-за того, что в стандарте не прописано строго, как должны быть реализованы некоторые вещи, то и возникают потом "каверзные" ситуации.
Lazerate
12.08.2022 14:47+1А вы уверены, что составители теста знали С++? Или они застряли где-то в прошлых стандартах, и то не до конца изучив их? Например вопрос про порядок вызова функций имел бы другой ответ в С++17. Последний вопрос бредовый, ибо ладно, допустим, что не запрещено действительно Может быть уб... Но и разрешено тоже, в общем-то, т.к. уб ещё никто не запрещал – это просто поведение, на которое стандарт не налагает никаких требований. Что значит запрещено вообще, ill-formed? С volatile бред, конечно. Нет, абсолютно, совершенно нет, значение слова volatile не отключение компиляторных оптимизаций. Потрудитесь перед составлением теста убедиться в собственной экспертизе.
crackedmind
12.08.2022 16:12+2По поводу volatile давайте заглянем в стандарт https://eel.is/c++draft/dcl.type.cv#6
[Note 5:
volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.
Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object.
Lazerate
12.08.2022 20:48+2Спасибо за подтверждение моего тезиса. Наверно, теперь всем очевидно, что да, volatile указывает компилятору на то, что следует избежать оптимизаций, но это не предназначение, а _потому что_ "because the value of the object might be changed by means undetectable by an implementation". Как можно заметить, выключение ряда оптимизаций является следствием. Т.е. волатайл обозначает переменную, которая может быть изменена извне. Он не выключает абсолютно все оптимизации, это и не является целью. Если бы компиляторщики нашли способ агрессивно оптимизировать даже в случае изменений извне, они бы это сделали. В тесте же единственное предназначение волатайла для отключения оптимизаций. Смешно.
Не учитывая того факта, что это ненормативная часть стандарта, Note. Что-то вроде разъяснений, которые не дают никаких гарантий.
Kelbon
12.08.2022 21:13И тут написано что это Note, по стандарту volatile значит, что для переменной отсутствует гарантия. А эффекты с оптимизациями это следствие отсутствия гарантии. Стандарт ничего про оптимизацию не знает и не должен знать(за исключением гарантированных EBO/ NRVO/RVO)
Apoheliy
12.08.2022 15:21+4Вопрос про static_cast / dinamic_cast лучше как нибудь уточнить. При таком задании (не сказано про отсутствие любых virtual-ов) может быть и так и так. Иногда рекомендуют в общем случае использовать dynamic типа оверхед небольшой, но явно надёжнее.
Вопрос про интерфейсы тоже лучше переформулировать. ключевого слова нет, но концептуально это всё делается штатными средствами.
kozlyuk
12.08.2022 17:22+1Плюс там не сказано, что наследование не виртуальное и наследник прямой, а то и
static_cast
может быть запрещен:If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed.
ReadOnlySadUser
12.08.2022 16:11+28/8, за исключением того, что я на последний вопрос намеренно ответил "запретим потом" шутки ради.
Правда вопросы не особо-то сложные.
Tujh
12.08.2022 18:16+7Ответ про volatile не корректен. Это ключевое слово указывает компилятору, что данную переменную следует читать непосредственно из источника (появилось для непосредственного чтения данных из портов ввода-вывода в чистом Си).
a volatile object is one whose value might change spontaneously. That is, when you declare an object to be volatile, you're telling the compiler that the object might change state even though no statements in the program appear to change it
Как следствие этого требования компилятор отключает кеширование значения в регистрах и кешах процессора, которые действительно являются оптимизацией, поэтому отключение оптимизации для volatile переменных - это побочный эффект, а не основное предназначение, тем более в те времена, когда вводилось это слово оптимизирующих компиляторов не сушествовало, равно как и языка С++, между прочим, это легаси из чистого Си.Вопрос про приведение указателя базового к наследнику через static_cast...можно конено, но за такое надо руки отрывать.
ReadOnlySadUser
12.08.2022 18:56-11.
Открываем стандарт
volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object
Т.е. вот прям в стандарте написано, что для начала volatile - это подсказка компилятору, что вот тут оптимизировать никак нельзя, а уже потом, возможно, для каких-то архитектур, это будет означать специальные инструкции для чтения/записи, учитывающие кэш-процессора и пр.
2.
Можно и отрывать, конечно, но не так уж много выбора при компиляции с
-fno-rtti
Lazerate
12.08.2022 21:00+3Просто чтобы вы понимали, то, что написано в Note, не значит, что стандарт говорит, что компилятор обязан не оптимизировать. Note – это разъясняющая, ненормативная часть стандарта, которая не даёт никаких гарантий. Их, конечно, пишут, чтобы дать дополнительное объяснение и обычно они соответствуют реальности... Хотя, например, есть ноуты, в которых написано, что разыменование nullptr это UB, хотя сам стандарт этого не доказывает.
В любом случае вы выделяете почему-то совершенно неверные части разъяснения. Вы должны были выделить "because the value of the object might be changed by means undetectable by an implementation". Это причина. Это то, что обозначает волатайл. То, что компилятор не оптимизирует агрессивно, хотя _всё равно_ оптимизирует, лишь следствие, т.к. если бы он слишком агрессивно оптимизировал, наблюдаемое поведение программы могло бы отличаться от написанного, что запрещено. Я надеюсь вы умеете отличать причину от следствия?
ReadOnlySadUser
12.08.2022 21:12-1Так вопрос и не задаётся в стиле "в чем причина") Вопрос "что даёт использование volatile". И в стандарте чётко расписано к чему приведет использование volatile
Lazerate
12.08.2022 21:19Note – не является нормативной частью стандарта. Это не является гарантией, note не обязывает компилятор это выполнять. Правильным ответом было бы "указывает компилятору, что значение данной переменной может неожиданно измениться извне..." К этому можно было бы добавить "... вследствие чего агрессивные оптимизации обычно отключены для переменных с этим квалификатором".
По сути всё, что говорит стандарт на тему волатайла, это именно эта часть: https://eel.is/c++draft/dcl.type.cv#5
Note ниже просто дополнительное объяснение, помощь в трактовании. Но никак не точное значение, гарантия или обязательство для имплементации.
Если интересует где можно понять, почему Note не даёт никаких гарантий, то рекомендую посмотреть вот этот документ, часть 8.2: https://www.google.com/url?sa=t&source=web&rct=j&url=https://ec.europa.eu/eurostat/cros/system/files/ISO%2520reference%2520definitions%2520-%2520%2520guide%25202%2520-%25202004%2520-%2520rev.doc&ved=2ahUKEwjc2rHU9MH5AhVUCBAIHdL5CNkQFnoECCUQAQ&usg=AOvVaw2nLbbk204oJGuKGPgGyuGR
Kelbon
12.08.2022 21:23-1а в соседнем вопросе ФОРМАЛЬНО ИНТЕРФЕЙСОВ НЕТ В С++ считается верным ответом, очень последовательно и логично(НЕТ)
0xd34df00d
12.08.2022 21:13+3У меня есть некоторое впечатление, что компилятор, компилирующий
volatile int n = ... int nn = n; if (nn != 1) { *static_cast<int*>(nullptr) = 42; } int m = nn;
в код, эквивалентный
int m = 1;
и отсутствие всяких чтений из
n
, вполне себе соответствует стандарту, даже если считать вашуnote
нормативным текстом.Олсо, сам тест я тоже не нашёл. Видимо, не прошёл.
ReadOnlySadUser
12.08.2022 21:20Я не согласен. Даже с учётом UB под условием, компилятор сгенерировать код по чтению из
n
хотя бы вm
0xd34df00d
12.08.2022 21:23+1Обратите внимание, что я специально один раз читаю из
n
вnn
, и потом результат чтения изnn
присваиваю вm
.ReadOnlySadUser
12.08.2022 21:46Да, и я о том же. В if-ветке к нас UB, так что компилятор может её выкинуть полностью, но это вообще не значит, что чтение из n вернёт единицу. Это разные события в мире С++. Компилятор обязан сгенерировать код чтения из volatile, но не обязан генерировать UB ветку кода.
0xd34df00d
12.08.2022 22:58+2В if-ветке к нас UB, так что компилятор может её выкинуть полностью, но это вообще не значит, что чтение из n вернёт единицу.
Это значит, что в
nn
будет единица. Там не может не быть единицы, потому что иначе в программе было бы UB, а его не бывает.
RedWolf
13.08.2022 17:41Нужно обладать богатой фантазией, чтобы назвать эти вопросы каверзными. Половина из них вообще на общее развитие, независимо от языка. Я вот на с++ 20 лет не писал, но на 6 из 8 ответил
da-nie
13.08.2022 19:59+1Да где вы этот тест все берёте-то? :O Я не вижу ссылки. И я в этом не одинок (см. выше вопрос).
VedyNN
13.08.2022 20:55+1Касательно интерфейсов все скользко так как само слово часто фигурирует в том же стандарте при описание работы пространства имен и доступа к методам внутри структур, там не стесняются писать слово интерфейс ))
Вопросы интересные, но на вкус "блюстителей стандартов", слабовато будет.
Есть куча запарных тем на подумать, те же лямбды, и куча мест с неопределенным поведением (неожидаемым) в новых стандартах.
da-nie
15.08.2022 05:29+1Так. И всё-таки, я бы хотел увидеть, где тут этот тест.
Вот что показывает последний FireFox.
Ссылки на тест тут просто нет.
ryo_oh_ki
15.08.2022 06:47+15/8
Может ли класс в С++ реализовывать сразу несколько интерфейсов?
Составитель вопросов не знает, что интерфейсом в С++ называют чистый абстрактный класс. Отдельного ключевого слова не требуется. Мало класса? Есть шаблоны.
Akuma
Но вы не видели C++ уже 15 лет и то все ограничилось парой тестовых программ.
В целом "экспертность" вопросов вызывает сомнения. В том смысле, что зная другие языки, догадаться более-менее можно. Во многих вопросах "второй загаданный вариант" обычно оказывался верным. Можно было и посложнее :)