LINUX.ORG.RU

Вести с полей стандартизации C++: C++20 design is complete (Kona, 2019-02)

 


4

4

На Reddit-е появился большой пост с описанием того, что вошло в C++20 в результате очередного заседания комитета. На этой встрече в С++20 включили:

Modules!

Coroutines!

static, thread_local, and lambda capture for structured bindings.

std::polymorphic_allocator<>.

std::midpoint and std::lerp.

std::execution::unseq execution policy.

std::ssize() free function that returns a signed size.

std::span usability enhancements.

Precalculated hash values in lookup.

На следующей встрече в июне 2019-го будут рассматриваться к включению в C++20 следующие предложения (принципиально они уже одобрены, но до сих пор не были включены из-за незавершености формальных спецификаций):

Expansion statements.

The C++20 synchronization library.

std::format.

constexpr std::vector.

Allow constexpr allocation, but disallow allocations that are not deleted at compile time.

constexpr std::type_info::operator==.

New conceptification of iterators.

Monadic operations for std::optional.

std::source_location.

std::flatmap.

std::flatset.

std::ostream_joiner.

Stack trace library.

std::byteswap.

constinit.

Deprecating some uses of volatile.

Implicit creation of objects for low-level object manipulation.

using enum.

Ну и до кучи указывается, что еще было добавлено в C++20 ранее:

Concepts.

Contracts.

Ranges.

operator<=>.

A lot more constexpr features: consteval functions, std::is_constant_evaluated, constexpr union, constexpr try and catch, constexpr dynamic_cast and typeid.

Feature test macros.

std::span.

Synchronized output.

std::atomic_ref.

За подробностями лучше сходить на Reddit, там много поясняющего текста. Так же можно почитать отчет Херба Саттера.

★★★★★

Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от anonymous

Модули разве не ускорят компиляцию, когда будет подключаться что-то легковесное, вместо бомбически-огромных хедеров, нанизанных на километровую шашлычную палку

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Маленький модуль и такой же заголовок будет компилироваться примерно одинаково (в среднем модули на 15% быстрее, их не надо парсить и они бинарная база с ленивой загрузкой, зато теперь бинарный файл модуля для своей библиотеки нужно генерировать из набора типа заголовков и делается это однопоточно, т.е. если в проекте библиотеки и exe'шник, то сначала нужно для библиотеки сгенерировать модуль в один поток, а потом компилировать exe'шник).

Ну а свои сказки типа «мы переписали проект с 50-ти летней историей на технологию XXX, выкинули все легаси, улучшили архитектуру, получили ускорение, значит XXX рулит,» - оставь зеленым студентам с синдромом утенка.

Модули это способ вводить имена в область видимости единицы трансляции (функции, типы, пространства имен). И ничего более (изначально, вроде, хотели реализовать в модулях заголовки+бинарные библиотеки+флаги компилятора, но, вроде, отказались). Раньше это делалось препроцессором, теперь это часть языка. Принципиально ничего не поменялось.

Появилась возможность делать имена видимыми только для модуля, раньше для этого перед символом ставили «_». Но если разработчик использует такие символы из чужой библиотеки в своем коде (не для unit тестов), то надо ему объяснить, что он влез в детали реализации и следующая версия библиотеки поломает его код.

Стала чуть быстрее сборка, но только чуть.

За счет того, что реализация стала на уровне языка, то исправили косяк MS, когда они объявили min/max макросами и #include <windows.h> заменяло все последующие вхождения min/max на содержимое макроса. Но почему бы MS самим свой косяк не починить.

Ну и еще что-то так же по мелочи. В целом, модули вещь полезная, но это как переход на новое поколение процессора Intel (стало быстрее на 5%, добавили пару инструкций, сделали возможность загрузки аргументов AVX по выравниванию 16 байт, а не 32, переработали предсказатель переходов - быстрее не стало, но повод для анонса появился). В общем, от constexpr vector пользы больше, чем от модулей.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

вместо бомбически-огромных хедеров

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

Вопросы на понимание:

  • сколько парсятся такие заголовки?
  • сколько будут обрабатываться модули, предоставляющие ту же информацию?
  • как узнать, сколько времени компиляции работает препроцессор?
  • можно ли вообще узнать эту информацию?

Любители страшилок про огромные хедеры не только не сообщают такую информацию, но и не факт, что знают где ее взять и можно ли это вообще сделать...

А уж сравнения от гугла в стиле «мы переписали на модули самую древнюю часть кода с самым забористым легаси (а иначе зачем переписывать код, если он и так хорош), заодно поправили архитектуру и у нас все стало собираться в 4 раза быстрее (и работать тоже) - какие модули замечательные» - это для любителей поболтать.

anonymous
()
Ответ на: комментарий от anonymous

Но почему бы MS самим свой косяк не починить.

Примерно потому, почему не отказаться от пропихивания всяких secure boot.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Пытаюсь понять, содержат ли нововведения со времен С++98 что-то такое убийственно

Зависит от того, что именно ты готов назвать убийственным.

лаконичность

auto, лямбды, вариадики и т.д. и т.п.

эффективность

move semantics в первую очередь.

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Кстати, что юзаешь вместо unique_ptr? Свои велосипеды, библиотечное что-то или (надеюсь нет) руками без RAII?

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Ну может ты там живёшь в каком-то легаси. Если же ты реально пишешь, ценишь своё время, хочешь добиться простоты и надёжности, то в каждый попытке написать хоть что-то на С++98 - ты бы бежал от него сразу и быстро.

Писать на крестах как на крестах до 17-20х крество попросту невозможно. Ты лишь пишешь на си с классами, либо страдаешь. Раз ты не страдаешь - ты пишешь на первом.

rustforever
()
Ответ на: комментарий от I-Love-Microsoft

Модули разве не ускорят компиляцию

Это говно.

когда будет подключаться что-то легковесное

Это наследие того самого твоего любимого С++98.

вместо бомбически-огромных хедеров, нанизанных на километровую шашлычную палку

Всё будет аналогично.

Модули - это базворд для хомячков. Я вон виду соседнюю тему «какой язык может работать без системы сборки?» - один единственный - С/С++. Раздельная компиляция и прочая херня - всё это говно убогое.

Нужно развивать инкременталку и -fwhole-program. Всё остальное - говно убогое.

rustforever
()
Ответ на: комментарий от anonymous

В общем, от constexpr vector пользы больше, чем от модулей.

Это такое же говно от ламерков. Такая же полумера и такая же убогая.

Но это типичная ситуация для крестов - вместо решения проблем мы вычисраем тонны убогих костылей. Зачем нам нормальный constexpr в котором без проблем пилится хоть constexpr vsё - мы будем костылять 10раз одно и тоже.

По поводу модулей - это не работает даже так, как ты описал - т.к. я языке не появляется возможностей условной компиляции, то никаким образом препроцессор ты не заменишь.

rustforever
()
Ответ на: комментарий от rustforever

Приятно узнать мнение человека, который каждый абзац начинает с фразы «Это говно». Сразу чувствуется глубина понимания вопроса. А также мощь и величие писавшего.

anonymous
()
Ответ на: комментарий от anonymous

Ну так оно и есть. Если человек называет что-то говно, то он уверен в том, что может это тезис защитить. Если же человек трепло, которое боится всего и вся, то да - он будет маняврировать, боясь кидаться тезисами, т.к. кто угодно может прийти и показать ему, что он неправ. Именно поэтому балаболы всегда боятся конкретики.

rustforever
()
Ответ на: комментарий от I-Love-Microsoft

не использование чего драматически снижает лаконичность и эффективность моего кода.

Всё.

#include <cstdio>
#include <vector>
#include <cstdint>
#include <string>
#include <array>
#include <tuple>

struct alignas(64)/*и тут*/ A {
  A() = default;
  A(const A &) = delete;//ты будешь писать говно
  
  const size_t x = 10, y = 20;//и тут
  size_t xy = x * y;//и тут
  static inline const size_t n = 123;//ты будешь писать говно
  size_t m[n] = {};//и тут
};

template<typename T, size_t n = 64> constexpr bool is_aligned = !(alignof(T) % n);

using namespace std::literals;

constexpr auto gen() {
  std::array<char, 255> arr{};
  for(size_t i = 0; auto & x: arr) x = i++;
  return arr;
}

constexpr auto tbl = gen();

static_assert(tbl[10] == 10);

constexpr auto add = [](const auto & a, const auto & b) {return a + b;};
static_assert(add(10, 20) == 30);

auto inc = [it = 0ul]() mutable {return it++;};

void f(size_t x = 1023)  {}


int main() {
  fprintf(stderr, "%lu, %lu\n", inc(), inc());
  std::vector v{10, 20, 30};
  std::tuple t{10, "20"sv, 30.};
  
  static_assert(is_aligned<A>);
  auto str = ""sv;
  static_assert(std::is_same_v<decltype(str), std::string_view>);
  asm(R"(
    //я
    //пишу
    //как
    //человек
  )");
  
}

Это такие, базовые вещи - без которых ты не напишешь ни грамма лаконичного и эффективного кода на С++. Про какую-нибудь попсу типа вариадиков, move, stdlib и прочую херню - я даже не упоминаю.

К тому же прошло уже дохрена времени и попросту «что было» уже не вспомнишь.

Стоит ли мне одуматься и немедленно занюхивать все новые фичи стандартов.

Ответ очевиден.

rustforever
()
Ответ на: комментарий от htower_

Очередное трепло, которое было мною помножена на ноль в соседней теме. Но это трепло прибежало сюда, с горящей жопой, что-то кукарекать, в надежде найти поддержи у таких же убогих.

rustforever
()
Ответ на: комментарий от rustforever

Дурачок, это ведь ты бегаешь с полными шароварами по C/C++ темам и кукарекаешь всем про то, что они «трепло», «обосрались», «ламерки» и «хомячки». У тебя же явно проблемы с головой :)

htower_ ★★
()
Ответ на: комментарий от htower_

Бездарность, я иду туда, куда хочу и множу там подобное тебе трепло. Далее, когда подобное тебе трепло помножено - оно понимаешь, что они никто и ничто и начинает бегать везде и всюду, с рожей в говне, кукарекая «ааа, там царь - кукареку».

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

rustforever
()
Ответ на: комментарий от rustforever

Бгг. У тебя какая-то нездоровая фиксация на теме фекалий - ты, случаем, не копорофил? Так часто и много писать про говно - это надо его сильно любить :)

htower_ ★★
()
Ответ на: комментарий от I-Love-Microsoft

rustforever — это очередная инкарнация Царя. Если вам это о чем-то говорит.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Ну иногда же надо порадовать население :) Чувак или тот самый Царь (т.е. явно нездоров) или слишком жЫрный тролль.

htower_ ★★
()
Ответ на: комментарий от dave

То есть, в C++17 ты не можешь передать аргумент типа void. А из-за этого ломаются привычные приемы ФП.

Покажи обычный приём в Haskell по передаче в функцию Void

anonymous
()
Ответ на: комментарий от anonymous

Покажи обычный приём в Haskell по передаче в функцию Void

Легко.

- Пример 1 без объяснений.

main :: IO ()

- Пример 2 с небольшими объяснениями.

makeMeFeelGood :: IO ()
makeMeFeelGood = putStrLn "Be happy!"

main :: IO ()
main = 
  do makeMeFeelGood
     putStrLn "See you!"

- Пример 3 с подробными объяснениями.

makeMeFeelGood :: IO ()
makeMeFeelGood = putStrLn "Be happy!"

main :: IO ()
main = 
  makeMeFeelGood >>= \() ->
  putStrLn "See you!"
dave ★★★★★
()
Ответ на: комментарий от dave

Покажи обычный приём в Haskell по передаче в функцию Void

Легко.
- Пример

Кажись, здесь путаница с каррированием, что в принципе не умеет c++, но умеет хаскелл (говорят, был человек - Хаскелл Карри). Костыли c++ не могут решить проблему каррирования, нужна поддержка самим языком.

anonymous
()
Ответ на: комментарий от anonymous

Нет, это не каррирование. В C++ эта штука была бы полезной для вычисления std::future<void> и для его метода then. А в haskell практически все серьезное программирование использует передачу void по значению (тип называется в haskell как "()"). Это, вообще, у меня одна из лакмусовых бумажек, по которым я определяю насколько язык близок к ФП.

dave ★★★★★
()
Ответ на: комментарий от dave

тип называется в haskell как "()"

Это пустой tuple. Можно заменить пустым классом. В с++ его нет, скорее всего, из-за явного оверхеда (миниальный размер объекта - 1 байт).

anonymous
()
Ответ на: комментарий от anonymous

Это совсем не то. В C++ тип называется void по историческим причинам, но по сути плюсовый void - это хаскельный (). В С++11 можно даже вернуть из функции результат другой функции, которая вернет void. То есть, void можно возвращать из функции, но комитетчики почему-то не пошли дальше и не стали разрешать передавать void как аргумент в функцию. Я с этим столкнулся как-то в C++17, и мне это не понравилось.

dave ★★★★★
()
Ответ на: комментарий от dave

void - это хаскельный ()

Нет. () - это пустой tuple. Которого нет с++. И вообще, в с++ нет tuple, а есть костыль.

anonymous
()
Ответ на: комментарий от dave

В С++11 можно даже вернуть из функции результат другой функции, которая вернет void.

Это было можно и в C++98: https://wandbox.org/permlink/snkFPSjlZ1DjfcZq

Ну и это не возврат. Это частный случай.

не стали разрешать передавать void как аргумент в функцию

Нельзя передать то, чего нет.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от dave

Ты обосрался, но тебе уже сказали.

можно даже вернуть из функции результат другой функции

Ламерок, кто тебе такую херню сказал? Может просто ты обосрался? return может принимать «ничего». return; void f(); не имеет возврата. таким образом return f(); эквивалентно return;

но комитетчики почему-то не пошли дальше и не стали разрешать передавать void как аргумент в функцию.

Просто они не такие тупые ламерки.

rustforever
()
Ответ на: комментарий от eao197

Нельзя передать то, чего нет.

Вот и комитетчики так думают. Поэтому все взоры прогрессивной общественности сейчас обращены на Rust, а не на C++.

dave ★★★★★
()
Ответ на: комментарий от anonymous

Нет. () - это пустой tuple. Которого нет с++. И вообще, в с++ нет tuple, а есть костыль.

И пустой tuple тоже. Так спокойнее анониму?

dave ★★★★★
()
Ответ на: комментарий от dave

Вот и комитетчики так думают.

Логично думают, в общем-то. А то ведь можно дойти и до:

void f(void a, void b, void c) {...}

сейчас обращены на Rust

А в Rust-е есть void, который можно передавать аргументом?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

Конечно, есть в rust. Пишется тоже как (), он же пустой tuple. Его можно передать как аргумент. А вот в F# называется уже unit. Да, тоже можно передать аргументом в функцию. А вот в scala небольшой бардак с этим.

Отсутствие результата - это, вообще-то, bottom. Просто зависон, когда код попадает в условный вечный цикл, и не может завершится.

dave ★★★★★
()
Последнее исправление: dave (всего исправлений: 2)
Ответ на: комментарий от dave

Конечно, есть в rust. Пишется тоже как (), он же пустой tuple.

Пустой tuple — это не void. Но тут я не первый вам об этом говорю.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

Ох, устанешь тут от вас. Ну, возьмите F# тогда, буквоеды вы такие, программисты, одним словом. Там уже не пустой tuple, а прямо так и называется «unit». Сути-то это не меняет. Значение у типа unit, кстати, там пишется "()". Да, можно передать аргументом в функцию. Это прямой аналог void из C#, но в F# есть хаки для передачи unit из монад, потому что в том C#, что я использовал, тоже void не был полноценным типом в .NET подобно С++.

dave ★★★★★
()
Ответ на: комментарий от dave

И пустой tuple тоже. Так спокойнее анониму?

Что ты хочешь? Чтобы в очередном патче с++ стал ФП-языком, где очень многое завязано на tuple'ы (множество с бинарной операцией с единичным элементом)? Могу огорчить, с++ не построен на стройной теоретической базе, это просто сборник правил.

anonymous
()
Ответ на: комментарий от dave

И пустой tuple тоже. Так спокойнее анониму?

Ну, и, ламерок?

using Void = std::tuple<>;

Void ya_jru_govno(Void a, Void b, Void c) {
  return {};
};

Void res = ya_jru_govno({}, {}, {});

Почему я за ламерков должен тебя множить на ноль? Ты без перед тем как нести ахинею - в школу бы сходил.

rustforever
()
Ответ на: комментарий от dave

О боже, откуда ты такой гений мамкин вылез. Я просто поражаюсь всей невероятности той ахиней, что ты несёшь. ТЫ мало того, что обосрался(но ладно, тут адепты тебя на помножили на ноль), дак ещё и врёшь и подменяешь понятия. Тебе сообщили(причём те самые адепты) о том, что void в сишке и воид в твоих маня-фантазиях разные вещи, и в твоём недоязычке для колхозников нету воида, а есть нелепая херня. Запомни это.

rustforever
()
Ответ на: комментарий от anonymous

Что ты хочешь?

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

    /// A functional-style replacement for the `void` type.
    struct unit_t {
        unit_t() = default;
    };

Но я уже понял, что мои идеи, скорее всего, восприняты не будут в среде программистов С++. Слишком они чужеродны и непонятны.

dave ★★★★★
()
Ответ на: комментарий от dave

Не знаю архитектуру объектов Haskell, но скорее всего в нем можно возвратить void и при этом компилятор знает, что void имеет ссылку на объект определенного типа. В C++ все не так. При использовании void мы должны явно указать тип объекта на который он указывает.

PS: Просьба сильно не пинать.

anonymous
()
Ответ на: комментарий от dave

В среде C++ программистов такой широкой разлет... Начиная от откровенного неприятия современного C++, как в случае с Iron_Bug, до портированного из Хаскелля функционального хардкора, как в случае c GraninAS — и это только на LOR-е.

Так что я бы не стал сильно бояться. Если есть идеи, которыми можно поделиться, поделитесь, плз. Кому-то может быть интересно.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от dave

/// A functional-style replacement for the `void` type.

Я тебя читаю, и мне кажется, что ты ни ФП не понимаешь, ни С++. Если бы понимал, таких проблем бы не было. Спишу на стресс и волнение.

anonymous
()
Ответ на: комментарий от dave

Ну дак что, ты на это отвечать будешь:

using Void = std::tuple<>;

Void ya_jru_govno(Void a, Void b, Void c) {
  return {};
};

Void res = ya_jru_govno({}, {}, {});

Оказалось, что для последнего пришлось изобрести велосипед (остальное вроде как вполне можно аккуратно и симпатично записать на C++17 через шаблоны):

Это нихрена не замена пустому таплу, замену тебе дали.

unit_t() = default;

Зачем?

Но я уже понял, что мои идеи, скорее всего, восприняты не будут в среде программистов С++. Слишком они чужеродны и непонятны.

У тебя нет идей - есть какие-то глупые попытки что-то утверждать, о чём-то рассуждать, но в теме нихрена не понимать.

anonymous
()
Ответ на: комментарий от eao197

В среде C++ программистов такой широкой разлет... Начиная от откровенного неприятия современного C++, как в случае с Iron_Bug, до портированного из Хаскелля функционального хардкора, как в случае c GraninAS — и это только на LOR-е.

Так что я бы не стал сильно бояться. Если есть идеи, которыми можно поделиться, поделитесь, плз. Кому-то может быть интересно.

Да я тут вижу в треде, что разношерстные, начиная вечно регистрирующимися тетрархами и заканчивая какими-то непонятными «специалистами-самовыдвиженцами» по ФП.

Идея есть, и она даже работает на растишке и на хаскеле, но оба языка довольно нишевые, а тут хочется получить больший охват аудитории, да и у C++ есть определенные преимущества для моей прикладной области. Если в C++ ввели std::future, то в принципе, ничего особенного нового я не добавлю. Все в рамках уже используемых решений.

dave ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Модули разве не ускорят компиляцию, когда будет подключаться что-то легковесное, вместо бомбически-огромных хедеров, нанизанных на километровую шашлычную палку

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

KennyMinigun ★★★★★
()
Ответ на: комментарий от dave

Ну так поделитесь. Неадекватов (не в медицинском/социальном смысле) бояться — на LOR не ходить :)

eao197 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.