Comments 15
у вас кривой линтер и вы не умеете запускать его без компиляции всего. Язык-то то тут причем?
В язык затащили новую фичку. Но она оказалась малость недоделанной
Что недоделанного в самой фиче? Она работает как и обещалось, возможности объявлять что угодно в области видимости цикла нет, её и раньше не было.
Я бы сказал "схрена ли такое правило линтера", но и правило разумное: если вы никак не используете x
вне цикла, то что он вообще делает? Если это хитрое преобразование коллекции с аккумулятором, то правило линтера намекает вынести его в отдельную функцию (или воспользоваться std::transform
):
static void TransformData(std::vector<int>* data){
int x = 0;
for(int& elem : *data){
elem = x += elem;
}
}
(Если линтер и в этом случае считает код нарушением, то ИМХО лучше написать явное исключение, чем if(data->empty()) return;
)
Наконец, при 30-минутном билде может иметь смысл прогонять линтер локально, чтобы такие штуки не сваливались на голову сюрпризами?..
Сначала была одна крайность: C++0X рожали лет 10 и так и не сумели выпустить в 0X годах.
Затем другая крайность: по небольшому стандарту, но каждые 2 года.
Наверное следующая итерация будет "вменяемый баланс".
Но он решил, что стоит написать по-модному, выразительно и читабельно. К сожалению, он не учел, что прежде чем его код будут читать коллеги, то же самое попытается сделать проклятый линтер. В результате первый билд пошел прямо в мусорку - 30 минут коту под хвост.
А что, нельзя было прогнать линтер локально и до более долгосрочных этапов сборки?
Да, можно прогнать линтер локально на проектах уровня хелловорлд+, но даже с 10-ти летним аосп это не выйдет и я не знаю, как там прогнать линтер отдельно. И зачем тратить время на поиски этой информации?
По-моему с++ скатился где-то на std::chrono и полностью превратися в Г при появлении корутин, все их пишут, куча реализаций, прироста с CSP почти никакого, проекты, в итоге, становятся неподдерживаемыми.
Ещё мне нравилось работать с базовыми типами, сейчас развели целый зоопарк, умножим, на шаблоны, которые раздувают объектный код, в итоге всё это работает и разрабатывается медленно.
Даже ведущие компиляторы, уже начиная со стандарта 2017 (а по факту даже с 2011) не гарантируют полную совместимость со стандартом как по самому языку, так и по стандартной библиотеке.
Это моя реальность начиная с 1990-х годов, еще даже до принятия первого стандарта -- у каждого компилятора было свое подмножество (а в бородатых 90-х, порой, и нестандартное надмножество) C++.
Таков путь.
Прямое следствие того, что есть отдельно стандарт и есть несколько независимых вендоров компиляторов.
Если когда-нибудь все компиляторы кроме одного единственного помрут, ситуация и поменяется, может быть. Но пока этого не произошло, будет именно так.
Жить с этим можно. А страдают от такого, в основном, разработчики кросс-платформенных библиотек и кросс-платформенных приложений. Если же проект живет в рамках одной платформы и одного компилятора (а таких, как оказалось, немало), то и проблем особых нет.
переменную аннулировать, например выражением (void)x
(Void) не способен аннулировать свой операнд, ни один оператор приведения типа это не может. Это ничего не делающая операция, древний хак для обхода предупреждения компилятора о неиспользованной переменной.
Уверен в том, что С++ нужно прекратить развивать тем способом как это делается сейчас (добавлением новых фич с сохранением обратной совместимости со старыми). Нужно ввести версии языка, и в новой версии просто удалить всю ту фигню которую нагородили эволюционно, и добавить новые фичи вообще не оглядываясь на обратную совместимость, а думая лишь об их логичности, удобстве, красоте. Чтобы компилятор оличал исходники разных версий в одном проекте, в начале файла писать #pragma version. Если прагмы нет - значит "старая" (т.е. текущая) версия.
Звучит заманчиво, самому бы хотелось решения с помощью подобного варианта, но возникают вопросы. Допустим у нас компилятор с помощью опций или директив поддерживает старую и новую версию С++. Мы можем писать код полностью на новой версии или на старой версии - ура! Но если мы хотим поддерживать несколько версий одновременно, значит мы планируем какой-то постепенный переход. А как в этой ситуации делать interop ? ABI сломано, одни и те же конструкции теперь могут означать совсем разное. Через "С" ?
на первый взгляд звучит уверенно и вроде логично, но какой ценой ... что-то там, С++ не плохой по моим прикидкам
[[maybe_unused]]
добавили в C++17. Даже до этого, если нет согласия с линтером и есть достаточная уверенность, что он брешет, вариант с (void)
или любой другой подобной глушилкой был бы не так плох.
Собственно, я впринципе с точки зрения линтера не особо понимаю, в чём проблема, если переменная не использовалась в одной из веток — важнее же чтобы использовалась хотя бы в одной, разве нет?
"К слову, билд штука непростая, состоит из многих этапов и занимает примерно час+." Если следовать заголовку, то должно быть час++
Тейк про линтер непонятен, у вас clang daemon в ci или к иде не прикручен? Новые стандарты поддержаны неполно, но от этого не становятся бесполезными. Нишевого проходняка много, конечно, но концепты, корутины и модули это отлично, start lifetime as тоже супер, рефлексия вот подошла, всякого полно. А про то что язык большой это уже данность, его никто целиком не знает, дпже если делает вид что знает не верьте) P1787 тому докозательство.
Судя по всему, x
- это индекс элемента в коллекции. Поэтому вариант номер 6 - выразить это явным образом: использовать enumerate
из range-v3
или `boost::adaptors::indexed
из boost-range
+ structured bind.
Думай о секундах свысока — как бы говорит нам Modern C++