C++ Россия: бул кантип болду

Эгер оюндун башында дубалда С++ коду илинип турат десең, анда ал акырында бутуңа атып салышы мүмкүн.

Bjarne Stroustrup

31-октябрдан 1-ноябрга чейин Санкт-Петербургда C++ Russia Piter конференциясы болуп өттү - JUG Ru Group тарабынан уюштурулган Россиядагы масштабдуу программалоо конференцияларынын бири. Конок спикерлерге C++ Стандарттар комитетинин мүчөлөрү, CppCon баяндамачылары, O'Reilly китебинин авторлору жана LLVM, libc++ жана Boost сыяктуу долбоорлордун тейлөөчүлөрү кирет. Конференция өз тажрыйбасын тереңдетүүнү жана жандуу баарлашууда тажрыйба алмашууну каалаган тажрыйбалуу C++ иштеп чыгуучуларына багытталган. Студенттер, аспиранттар жана университеттин окутуучулары үчүн абдан жакшы арзандатуулар каралган.

Конференциянын Москвадагы чыгарылышына келерки жылдын апрелинде эле барууга болот, бирок бул арада биздин студенттер акыркы иш-чарада кандай кызыктуу нерселерди үйрөнүшкөнүн айтып беришет. 

C++ Россия: бул кантип болду

Сүрөт тартып конференция альбому

Биз жөнүндө

Бул кызматта Улуттук изилдөө университетинин Жогорку Экономика мектебинин - Санкт-Петербургдун эки студенти иштеген:

  • Лиза Василенко Колдонмо математика жана информатика программасынын алкагында программалоо тилдерин окуп жаткан 4-курстун студенти. С++ тили менен университетте биринчи курста таанышкандан кийин, өндүрүштө стажировкадан өтүп, аны менен иштөө тажрыйбасына ээ болдум. Жалпысынан программалоо тилдерине жана өзгөчө функционалдык программалоого болгон кызыгуу конференцияда баяндамаларды тандоодо өз изин калтырды.
  • Даня Смирнов «Программалоо жана маалыматтарды анализдөө» магистратурасынын 1-курсунун студенти. Мектепте окуп жүргөн кезимде С++ тилинде олимпиадалык маселелерди жазчумун, анан кандайдыр бир жол менен бул тил билим берүү иш-чараларында тынымсыз чыгып, акырында негизги жумушчу тил болуп калды. Мен билимимди өркүндөтүү жана жаңы мүмкүнчүлүктөрдү билүү үчүн конференцияга катышууну чечтим.

Бюллетенде факультеттин жетекчилиги биздин адистикке байланыштуу билим берүү иш-чаралары тууралуу маалымат менен көп бөлүшөт. Сентябрь айында биз C++ Россия тууралуу маалыматты көрүп, угуучу катары катталууну чечтик. Мындай конференцияларга катышуу биздин биринчи тажрыйбабыз.

Конференциянын структурасы

  • Отчеттор

Эки күндүн ичинде эксперттер көптөгөн актуалдуу темаларды камтыган 30 докладды окушту: колдонулуучу көйгөйлөрдү чечүү үчүн тил функцияларын гениалдуу пайдалануу, жаңы стандартка байланыштуу тил жаңыртуулары, C++ дизайнындагы компромисстер жана алардын кесепеттери менен иштөөдө сактык чаралары, мисалдар. кызыктуу долбоордун архитектурасы, ошондой эле тил инфраструктурасынын кээ бир майда-чүйдөсүнө чейин. Үч спектакль бир эле учурда болуп өттү, көбүнчө экөө орус тилинде жана бирөө англис тилинде.

  • Талкуу зоналары

Сөздөн кийин бардык берилбеген суроолор жана бүтпөгөн талкуулар маркердик такталар менен жабдылган баяндамачылар менен баарлашуу үчүн атайын бөлүнгөн жерлерге өткөрүлдү. Сүйлөшүүлөрдүн ортосундагы тыныгууну жагымдуу маек менен токтотуунун жакшы жолу.

  • Lightning Talks жана расмий эмес талкуулар

Эгерде сиз кыскача баяндама жасагыңыз келсе, анда кечки чагылган баяндамасына жазылып, конференциянын темасы боюнча каалаган нерсе жөнүндө сүйлөшүү үчүн беш мүнөт убакыт аласыз. Мисалы, C++ үчүн дезинфекциялоочу каражаттар менен тез таанышуу (айрымдар үчүн бул жаңы болгон) же угууга гана мүмкүн болгон, бирок көрүнбөгөн синус толкундарынын муунундагы ката жөнүндө окуя.

Дагы бир формат - "Жүрөктөн жүрөккө комитет" панелдик талкуусу. Сахнада стандартташтыруу комитетинин кээ бир мүчөлөрү, проектордо камин (расмий түрдө - чын жүрөктөн атмосфераны түзүү үчүн, бирок себеби "баары күйүп жаткандыктан" күлкүлүү көрүнөт), C++ стандарты жана жалпы көрүнүшү жөнүндө суроолор. , кызуу техникалык талкуулар жана holiwars жок. Көрсө, комитеттин курамында бир нерсеге толук ишенбеген же билбеген тирүү адамдар да бар экен.

Холивардын күйөрмандары үчүн үчүнчү окуя - BOF сессиясы "Go vs. C++". Биз Go сүйүүчүсүн, C++ сүйүүчүсүн алабыз, сессия башталганга чейин алар чогуу тема боюнча 100500 XNUMX слайд даярдашат (мисалы, C++ пакеттериндеги көйгөйлөр же Go'догу генериктердин жоктугу), андан кийин алар өз ара кызуу талкууга алышат жана угуучулар менен, ал эми көрүүчүлөр бир эле учурда эки көз карашты түшүнүүгө аракет кылат. Эгерде холивар контексттен тышкары башталса, модератор кийлигишип, тараптарды элдештирет. Бул формат көз карандылыкты жаратат: башталгандан бир нече саат өткөндөн кийин, слайддардын жарымы гана аткарылды. Аягын абдан тездетүү керек болчу.

  • Өнөктөш турат

Залдарда конференциянын өнөктөштөрү көрсөтүлдү – стенддерде алар учурдагы долбоорлор жөнүндө айтып беришти, стажировкадан өтүүнү жана жумушка орноштурууну сунушташты, викториналарды жана чакан сынактарды өткөрүштү, ошондой эле жагымдуу белектерди ойнотушту. Ошол эле учурда, кээ бир компаниялар, атүгүл, отчет угуу үчүн гана эмес, келгендер үчүн пайдалуу болушу мүмкүн болгон интервьюнун баштапкы этаптарынан өтүүнү сунушташкан.

Отчеттордун техникалык деталдары

Эки күн тең отчетторду уктук. Кээде параллелдүү отчеттордун ичинен бирөөсүн тандоо кыйынга турду – тыныгууларда алган билимибизди бөлүшүп, алмашууга макул болдук. Ошондо да көп нерсе четте калгандай. Бул жерде биз эң кызыктуу болгон кээ бир отчеттордун мазмуну жөнүндө сөз кылгыбыз келет

Компиляторду оптималдаштыруу призмасы аркылуу C++ тилиндеги өзгөчөлүктөр, Роман Русяев

C++ Россия: бул кантип болду
Слайддан тапшырмалары

Аталышынан көрүнүп тургандай, Роман мисал катары LLVMди колдонуу менен өзгөчөлүктөр менен иштөөнү караган. Ошол эле учурда, өз ишинде Clang колдонбогондор үчүн, отчет дагы эле кодду кантип оптималдаштырса болот деген түшүнүктү бере алат. Бул компиляторлорду жана тиешелүү стандарттык китепканаларды иштеп чыгуучулар бири-бири менен байланышып, көптөгөн ийгиликтүү чечимдер дал келиши мүмкүн.

Ошентип, өзгөчө кырдаалды чечүү үчүн сиз көп нерселерди кылышыңыз керек: иштетүү кодун (эгерде бар болсо) же учурдагы деңгээлдеги бош ресурстарды чакырып, стекти жогору айлантыңыз. Мунун баары компилятор чакырыктар үчүн кошумча инструкцияларды кошот деп алып келет. Ошондуктан, эгерде өзгөчөлүк иш жүзүндө көтөрүлбөсө, программа дагы эле керексиз аракеттерди жасай берет. Кошумча чыгымдарды кандайдыр бир жол менен азайтуу үчүн, LLVM өзгөчө кырдаалды иштетүү кодун кошуунун кереги жок болгон жагдайларды аныктоо үчүн бир нече эвристикага ээ же "кошумча" нускамалардын санын азайтууга болот.

Баяндамачы алардын он чактысын карап чыгып, алар программанын аткарылышын тездетүүгө жардам берген жагдайларды да, бул ыкмалар колдонулбаган жагдайларды да көрсөтөт.

Ошентип, Роман Русяев студенттерди өзгөчө кырдаалды камтыган кодду дайыма эле нөлдүк чыгым менен аткаруу мүмкүн эмес деген тыянакка алып келет жана төмөнкү кеңештерди берет:

  • китепканаларды иштеп чыгууда, негизинен, өзгөчөлүктөрдөн баш тартуу керек;
  • эгерде өзгөчөлүктөр дагы эле керек болсо, анда мүмкүн болушунча компилятор мүмкүн болушунча оптималдаштыруу үчүн noexcept (жана const) модификаторлорун бардык жерге кошуу керек.

Жалпысынан алганда, спикер өзгөчөлүктөр минималдуу түрдө колдонулса же таптакыр эле ташталат деген пикирди ырастады.

Баяндаманын слайддары төмөнкү шилтемеде жеткиликтүү: [“LLVM компилятор оптималдаштыруу объективинен C++ өзгөчөлүктөр”]

Генераторлор, корутиндер жана башка мээни ачуучу таттуулар, Ади Шавит

C++ Россия: бул кантип болду
Слайддан тапшырмалары

C++ 20 инновацияларына арналган бул конференциядагы көптөгөн баяндамалардын бири өзүнүн түстүү презентациясы менен гана эмес, коллекцияны иштетүү логикасы менен болгон көйгөйлөрдү так аныктоо менен да эсте каларлык болду (for цикл, кайра чалуулар).

Ади Шавит төмөнкүлөрдү баса белгилейт: азыркы учурда жеткиликтүү ыкмалар бүт коллекциядан өтүп, кандайдыр бир ички аралык абалга жетүүнү камсыз кылбайт (же алар кайра чалууларда, бирок көп сандагы жагымсыз терс таасирлер менен, мисалы, Callback Hell) . Итераторлор бар окшойт, бирок алар менен деле баары анчалык жылмакай эмес: жалпы кирүү жана чыгуу чекиттери жок (башталыш → аяктоо каршы rbegin → ренд ж. C++ 20 менен баштап, бул көйгөйлөр чечилди!

Биринчи вариант: диапазон. Итераторлорду ороп, биз итерациянын башталышы жана аягы үчүн жалпы интерфейске ээ болобуз, ошондой эле түзүү жөндөмүнө ээ болобуз. Мунун баары толук кандуу маалыматтарды иштетүү түтүктөрүн курууну жеңилдетет. Бирок баары ушунчалык жылмакай эмес: эсептөө логикасынын бир бөлүгү белгилүү бир итератордун ишке ашырылышынын ичинде жайгашкан, бул кодду түшүнүүнү жана оңдоону кыйындатат.

C++ Россия: бул кантип болду
Слайддан тапшырмалары

Ооба, бул учурда, C++20 кошумча корутиндерди (жүрүм-туруму Pythonдогу генераторлорго окшош функциялар): арадагы абалды сактоо менен учурдагы маанини кайтаруу менен аткарууну кийинкиге калтырса болот. Ошентип, биз маалыматтар менен көрүнгөндөй гана иштебестен, белгилүү бир корутиндин ичиндеги бардык логиканы камтыганга жетишебиз.

Бирок майдын ичинде чымын бар: азыркы учурда алар жарым-жартылай гана иштеп жаткан компиляторлор тарабынан колдоого алынган, ошондой эле биз каалагандай тыкан ишке ашырылган эмес: мисалы, корутиндерде маалымдамаларды жана убактылуу объекттерди колдонуунун кереги жок. Мындан тышкары, coroutines болушу мүмкүн болгон кээ бир чектөөлөр бар жана constexpr функциялары, конструкторлор/деструкторлор жана негизги бул тизмеге киргизилген эмес.

Ошентип, корутиндер маалыматтарды иштетүү логикасынын жөнөкөйлүгү менен маселелердин олуттуу бөлүгүн чечет, бирок алардын учурдагы ишке ашырылышы жакшыртууну талап кылат.

материалдар:

Яндекс.Таксиден C++ трюктары, Антон Полухин

Кесиптик ишмердүүлүгүмдө кээде мен жөн гана жардамчы нерселерди ишке ашырууга туура келет: кандайдыр бир китепкананын ички интерфейси менен API ортосундагы орогуч, журналды жазуу же талдоо. Бул учурда, адатта, эч кандай кошумча оптималдаштыруунун кереги жок. Бирок бул компоненттер RuNetтеги эң популярдуу кызматтарда колдонулсачы? Мындай кырдаалда бир саатына терабайттарды иштетүүгө туура келет! Андан кийин ар бир миллисекунд эсептелет жана ошондуктан ар кандай амалдарды жасоого туура келет - Антон Полухин алар жөнүндө айтып берди.

Балким, эң кызыктуу мисал көрсөткүчтөн ишке ашыруунун (pimpl) үлгүсүн ишке ашыруу болгон. 

#include <third_party/json.hpp> //PROBLEMS! 
struct Value { 
    Value() = default; 
    Value(Value&& other) = default; 
    Value& operator=(Value&& other) = default; 
    ~Value() = default; 

    std::size_t Size() const { return data_.size(); } 

private: 
    third_party::Json data_; 
};

Бул мисалда, биринчиден, мен тышкы китепканалардын баш файлдарынан арылгым келет - бул тезирээк компиляцияланат жана сиз өзүңүздү мүмкүн болгон аттардын конфликтинен жана башка ушул сыяктуу каталардан коргой аласыз. 

Макул, биз #include файлын .cpp файлына жылдырдык: бизге оролгон API, ошондой эле std::unique_ptr'дин алдыга декларациясы керек. Азыр бизде динамикалык бөлүштүрүү жана башка жагымсыз нерселер бар, мисалы, бир топ маалыматтарга чачырап кеткен маалыматтар жана кыскартылган кепилдиктер. std::aligned_storage мунун баарына жардам бере алат. 

struct Value { 
// ... 
private: 
    using JsonNative = third_party::Json; 
    const JsonNative* Ptr() const noexcept; 
    JsonNative* Ptr() noexcept; 

    constexpr std::size_t kImplSize = 32; 
    constexpr std::size_t kImplAlign = 8; 
    std::aligned_storage_t<kImplSize, kImplAlign> data_; 
};

Жалгыз көйгөй: биз ар бир оромонун өлчөмүн жана тегиздөөсүн көрсөтүшүбүз керек - келгиле, параметрлери менен пимпл шаблонубузду жасайлы, кандайдыр бир ыктыярдуу маанилерди колдонуп, деструкторго биз бардыгын туура деп тапкан чекти кошолу. : 

~FastPimpl() noexcept { 
    validate<sizeof(T), alignof(T)>(); 
    Ptr()->~T(); 
}

template <std::size_t ActualSize, std::size_t ActualAlignment>
static void validate() noexcept { 
    static_assert(
        Size == ActualSize, 
        "Size and sizeof(T) mismatch"
    ); 
    static_assert(
        Alignment == ActualAlignment, 
        "Alignment and alignof(T) mismatch"
    ); 
}

T деструкторду иштетүүдө мурунтан эле аныкталгандыктан, бул код туура талданат жана компиляция баскычында ката катары киргизилиши керек болгон талап кылынган өлчөмдөрдү жана тегиздөө маанилерин чыгарат. Ошентип, бир кошумча компиляциянын баасы менен биз оролгон класстардын динамикалык бөлүштүрүлүшүнөн кутулабыз, APIди ишке ашыруу менен .cpp файлында жашырабыз, ошондой эле процессор тарабынан кэштөө үчүн ылайыктуу дизайнга ээ болобуз.

Каттоо жана талдоо анчалык таасирдүү көрүнбөйт, ошондуктан бул кароодо сөз кылынбайт.

Баяндаманын слайддары төмөнкү шилтемеде жеткиликтүү: ["Таксиден C++ трюктары"]

Кодуңузду DRY сактоонун заманбап ыкмалары, Бьорн Фаллер

Бул баяндамасында Бьорн Фаллер кайталанма абалды текшерүүнүн стилистикалык кемчилиги менен күрөшүүнүн бир нече жолдорун көрсөтөт:

assert(a == IDLE || a == CONNECTED || a == DISCONNECTED);

Тааныш угулат? Акыркы стандарттарда киргизилген бир нече күчтүү C++ ыкмаларын колдонуу менен, сиз бир эле функцияны эч кандай өндүрүмдүүлүк жазасына тартпастан, көрктүү түрдө ишке ашыра аласыз. Салыштыруу:   

assert(a == any_of(IDLE, CONNECTED, DISCONNECTED));

Чектердин аныкталбаган санын иштетүү үчүн сиз дароо вариадик калыптарды жана бүктөлгөн туюнтмаларды колдонушуңуз керек. Келгиле, биз бир нече өзгөрмөлөрдүн энумдун state_type элементине теңдигин текшергибиз келет деп ойлойлу. Акылга келген биринчи нерсе, жардамчы функциясын жазуу: is_any_of:


enum state_type { IDLE, CONNECTED, DISCONNECTED };

template <typename ... Ts>
bool is_any_of(state_type s, const Ts& ... ts) { 
    return ((s == ts) || ...); 
}

Бул ортодогу натыйжа капалантат. Азырынча код дагы окула элек:

assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED)); 

Түрү эмес шаблон параметрлери кырдаалды бир аз жакшыртууга жардам берет. Алардын жардамы менен биз энумдун саналуу элементтерин шаблон параметрлеринин тизмесине өткөрүп беребиз: 

template <state_type ... states>
bool is_any_of(state_type t) { 
    return ((t == states) | ...); 
}
	
assert(is_any_of<IDLE, DISCONNECTING, DISCONNECTED>(state)); 

Автоматты типтүү эмес шаблон параметринде (C++17) колдонуу менен, мамиле жөн гана state_type элементтери менен эмес, ошондой эле типтүү эмес шаблон параметрлери катары колдонула турган примитивдүү типтер менен салыштырууга жалпылайт:


template <auto ... alternatives, typename T>
bool is_any_of(const T& t) {
    return ((t == alternatives) | ...);
}

Бул ырааттуу өркүндөтүүлөр аркылуу текшерүүлөр үчүн каалаган эркин синтаксиске жетишилет:


template <class ... Ts>
struct any_of : private std::tuple<Ts ...> { 
// поленимся и унаследуем конструкторы от tuple 
        using std::tuple<Ts ...>::tuple;
        template <typename T>
        bool operator ==(const T& t) const {
                return std::apply(
                        [&t](const auto& ... ts) {
                                return ((ts == t) || ...);
                        },
                        static_cast<const std::tuple<Ts ...>&>(*this));
        }
};

template <class ... Ts>
any_of(Ts ...) -> any_of<Ts ... >;
 
assert(any_of(IDLE, DISCONNECTING, DISCONNECTED) == state);

Бул мисалда, чегерүү көрсөтмөсү конструктор аргументтеринин түрлөрүн билген компиляторго структуралык шаблондун керектүү параметрлерин сунуштоо үчүн кызмат кылат. 

Андан ары - кызыктуураак. Бьорн натыйжадагы кодду == чегинен ашкан салыштыруу операторлору үчүн, анан ыктыярдуу операциялар үчүн кантип жалпылоону үйрөтөт. Жолдо no_unique_address атрибуту (C++20) жана lambda функцияларындагы шаблон параметрлери (C++20) сыяктуу функциялар колдонуу мисалдары менен түшүндүрүлөт. (Ооба, азыр лямбда синтаксисин эстеп калуу дагы оңой - булар бардык түрдөгү төрт ырааттуу кашаалар.) Функцияларды конструктор деталдары катары колдонгон акыркы чечим лямбданын эң жакшы салттарындагы тупле сөз туюнтмасын айтпаганда да менин жан дүйнөмдү жылытат. эсептөө.

Аягында, аны жылтыратууну унутпаңыз:

  • Ламбдалар бекер constexpr экенин унутпаңыз; 
  • Келгиле, кемчиликсиз багыттоону кошуп, ламбда жабылышындагы параметр пакетине карата анын жаман синтаксисин карап көрөлү;
  • Келгиле, компиляторго шарттуу noexcept менен оптималдаштыруу үчүн көбүрөөк мүмкүнчүлүктөрдү берели; 
  • Келгиле, ламбдалардын ачык кайтаруу маанилеринин аркасында калыптардагы түшүнүктүү каталарды чыгарууга кам көрөлү. Бул компиляторду шаблон функциясы чындыгында чакырылганга чейин дагы текшерүүлөрдү жүргүзүүгө мажбурлайт - типти текшерүү баскычында. 

Толук маалымат алуу үчүн, лекциянын материалдарын караңыз: 

Биздин таасирлер

C++ Россиядагы биринчи катышуубуз өзүнүн интенсивдүүлүгү менен эсте калды. Менде C++ Россия чын ыкластуу окуя катары таасир калтырды, мында машыгуу менен жандуу баарлашуунун ортосундагы чек ара дээрлик байкалбайт. Баяндамачылардын маанайынан баштап, иш-чаранын өнөктөштөрүнүн жарыштарына чейин кызуу талкуулар үчүн шарт түзөт. Докладдардан турган конференциянын мазмуну темалардын кеңири спектрин камтыйт, анын ичинде C++ инновациялары, ири долбоорлордун кейс изилдөөлөрү жана идеологиялык архитектуралык ойлор. Бирок иш-чаранын социалдык компонентине көңүл бурбоо адилетсиздик болуп калат, бул C++ тилине гана эмес, тилдик тоскоолдуктарды жеңүүгө жардам берет.

Конференциянын уюштуруучуларына мындай иш-чарага катышуу мүмкүнчүлүгү үчүн ыраазычылык билдиребиз!
Сиз C++ Россиянын өткөнү, азыркысы жана келечеги тууралуу уюштуруучулардын постун көргөн чыгарсыз JUG Ru блогунда.

Окуганыңыз үчүн рахмат жана окуяларды кайра баяндоо пайдалуу болду деп үмүттөнөбүз!

Source: www.habr.com

Комментарий кошуу