C ++ Urusi: jinsi ilivyotokea

Ikiwa mwanzoni mwa mchezo unasema kuwa kuna msimbo wa C ++ unaoning'inia kwenye ukuta, basi mwisho ni lazima kukupiga risasi kwenye mguu.

Bjarne Stroustrup

Kuanzia Oktoba 31 hadi Novemba 1, mkutano wa C ++ Russia Piter ulifanyika St. Petersburg - moja ya mikutano mikubwa ya programu nchini Urusi, iliyoandaliwa na JUG Ru Group. Wazungumzaji walioalikwa ni pamoja na washiriki wa Kamati ya Viwango ya C++, wazungumzaji wa CppCon, waandishi wa vitabu vya O'Reilly, na wasimamizi wa miradi kama vile LLVM, libc++ na Boost. Mkutano huo unalenga watengenezaji wazoefu wa C++ ambao wanataka kuimarisha utaalamu wao na kubadilishana uzoefu katika mawasiliano ya moja kwa moja. Wanafunzi, wanafunzi waliohitimu na walimu wa vyuo vikuu wanapewa punguzo nzuri sana.

Toleo la Moscow la mkutano huo litapatikana kutembelewa mapema Aprili mwaka ujao, lakini kwa wakati huu wanafunzi wetu watakuambia ni mambo gani ya kupendeza waliyojifunza kwenye hafla ya mwisho. 

C ++ Urusi: jinsi ilivyotokea

Picha kutoka albamu ya mkutano

kuhusu sisi

Wanafunzi wawili kutoka Chuo Kikuu cha Kitaifa cha Utafiti wa Shule ya Juu ya Uchumi - St. Petersburg walifanya kazi kwenye chapisho hili:

  • Liza Vasilenko ni mwanafunzi wa mwaka wa 4 wa shahada ya kwanza anayesoma Lugha za Kuratibu kama sehemu ya Programu ya Hisabati Iliyotumika na Sayansi ya Kompyuta. Baada ya kufahamiana na lugha ya C++ katika mwaka wangu wa kwanza chuo kikuu, baadaye nilipata uzoefu wa kufanya kazi nayo kupitia mafunzo katika tasnia. Mapenzi yangu ya lugha za programu kwa ujumla na utendakazi wa programu haswa yaliacha alama yake juu ya uteuzi wa ripoti kwenye mkutano huo.
  • Danya Smirnov ni mwanafunzi wa mwaka wa 1 wa programu ya bwana "Programu na Uchambuzi wa Takwimu". Nikiwa bado shuleni, niliandika matatizo ya Olympiad katika C++, na kisha ikawa kwa namna fulani kwamba lugha ilikuja mara kwa mara katika shughuli za elimu na hatimaye ikawa lugha kuu ya kufanya kazi. Niliamua kushiriki katika mkutano huo ili kuboresha ujuzi wangu na pia kujifunza kuhusu fursa mpya.

Katika jarida, uongozi wa kitivo mara nyingi hushiriki habari kuhusu matukio ya kielimu yanayohusiana na taaluma yetu. Mnamo Septemba tuliona habari kuhusu C++ Urusi na tukaamua kujiandikisha kama wasikilizaji. Huu ni uzoefu wetu wa kwanza wa kushiriki katika mikutano kama hii.

Muundo wa mkutano

  • Ripoti

Kwa muda wa siku mbili, wataalam walisoma ripoti 30, zinazohusu mada nyingi moto: matumizi ya busara ya vipengele vya lugha ili kutatua matatizo yaliyotumika, sasisho za lugha zinazokuja kuhusiana na kiwango kipya, maelewano katika muundo wa C++ na tahadhari wakati wa kufanya kazi na matokeo yao, mifano. ya usanifu wa kuvutia wa mradi, pamoja na baadhi ya maelezo ya chini ya hood ya miundombinu ya lugha. Maonyesho matatu yalifanyika wakati huo huo, mara nyingi mbili kwa Kirusi na moja kwa Kiingereza.

  • Kanda za majadiliano

Baada ya hotuba, maswali yote ambayo hayajaulizwa na majadiliano ambayo hayajakamilika yalihamishiwa kwenye maeneo maalum yaliyotengwa kwa ajili ya mawasiliano na wasemaji, yenye vifaa vya alama. Njia nzuri ya kuwa mbali na mapumziko kati ya hotuba na mazungumzo ya kupendeza.

  • Mazungumzo ya umeme na mijadala isiyo rasmi

Ikiwa ungependa kutoa ripoti fupi, unaweza kujiandikisha kwenye ubao mweupe kwa Mazungumzo ya Umeme wa jioni na kupata dakika tano za muda wa kuzungumza kuhusu chochote kuhusu mada ya mkutano. Kwa mfano, utangulizi wa haraka wa visafishaji taka vya C++ (kwa wengine ulikuwa mpya) au hadithi kuhusu mdudu katika kizazi cha mawimbi ya sine ambayo inaweza kusikika tu, lakini isionekane.

Muundo mwingine ni mjadala wa paneli β€œKamati ya Moyo kwa Moyo.” Kwenye hatua ni baadhi ya wajumbe wa kamati ya viwango, kwenye projekta ni mahali pa moto (rasmi - kuunda mazingira ya dhati, lakini sababu "kwa sababu kila kitu kimewaka moto" kinaonekana kuwa cha kuchekesha), maswali juu ya kiwango na maono ya jumla ya C++ , bila majadiliano motomoto ya kiufundi na holiwars. Ilibadilika kuwa kamati hiyo pia ina watu walio hai ambao wanaweza kutokuwa na uhakika kabisa wa jambo fulani au hawajui kitu.

Kwa mashabiki wa holivars, tukio la tatu lilibaki kwenye kesi - kikao cha BOF "Go vs. C ++". Tunamchukua mpenzi wa Go, mpenzi wa C++, kabla ya kuanza kwa kipindi wao kwa pamoja hutayarisha slaidi 100500 kwenye mada (kama vile matatizo ya vifurushi katika C++ au ukosefu wa jenetiki katika Go), kisha wanakuwa na majadiliano ya kusisimua kati yao na na hadhira, na hadhira inajaribu kuelewa maoni mawili mara moja. Ikiwa holivar inaanza nje ya muktadha, msimamizi huingilia kati na kupatanisha wahusika. Muundo huu unalevya: saa kadhaa baada ya kuanza, ni nusu tu ya slaidi zilizokamilishwa. Mwisho ulipaswa kuharakishwa sana.

  • Mshirika anasimama

Washirika wa mkutano huo waliwakilishwa katika kumbi - kwenye viwanja walizungumza juu ya miradi ya sasa, walitoa mafunzo ya kazi na ajira, walifanya maswali na mashindano madogo, na pia walishinda zawadi nzuri. Wakati huo huo, kampuni zingine zilijitolea kupitia hatua za mwanzo za mahojiano, ambayo inaweza kuwa muhimu kwa wale waliokuja sio tu kusikiliza ripoti.

Maelezo ya kiufundi ya ripoti

Tulisikiliza ripoti siku zote mbili. Wakati fulani ilikuwa vigumu kuchagua ripoti moja kutoka kwa zile zinazolingana - tulikubali kugawanyika na kubadilishana ujuzi uliopatikana wakati wa mapumziko. Na hata hivyo, inaonekana kwamba mengi yameachwa. Hapa tungependa kuzungumza juu ya yaliyomo katika baadhi ya ripoti ambazo tulipata kuvutia zaidi

Isipokuwa katika C++ kupitia prism ya uboreshaji wa mkusanyaji, Roman Rusyaev

C ++ Urusi: jinsi ilivyotokea
Telezesha kutoka mawasilisho

Kama kichwa kinapendekeza, Roman aliangalia kufanya kazi isipokuwa kwa kutumia LLVM kama mfano. Wakati huo huo, kwa wale ambao hawatumii Clang katika kazi zao, ripoti bado inaweza kutoa wazo la jinsi msimbo unaweza kuboreshwa. Hii ni kwa sababu watengenezaji wa watunzi na maktaba za kawaida zinazolingana huwasiliana na suluhisho nyingi zilizofanikiwa zinaweza sanjari.

Kwa hivyo, ili kushughulikia ubaguzi, unahitaji kufanya mambo mengi: piga nambari ya ushughulikiaji (ikiwa ipo) au rasilimali za bure katika kiwango cha sasa na usonge safu juu zaidi. Yote hii inaongoza kwa ukweli kwamba mkusanyaji anaongeza maagizo ya ziada kwa simu ambazo zinaweza kutupa tofauti. Kwa hivyo, ikiwa ubaguzi haujainuliwa, programu bado itafanya vitendo visivyo vya lazima. Ili kupunguza kwa namna fulani juu ya kichwa, LLVM ina heuristics kadhaa za kubainisha hali ambapo msimbo wa ushughulikiaji wa ubaguzi hauhitaji kuongezwa au idadi ya maagizo "ya ziada" inaweza kupunguzwa.

Mzungumzaji huchunguza takriban dazeni kati yao na anaonyesha hali zote mbili ambapo husaidia kuharakisha utekelezaji wa programu, na zile ambazo njia hizi hazitumiki.

Kwa hivyo, Roman Rusyaev anaongoza wanafunzi kwenye hitimisho kwamba nambari iliyo na utunzaji wa ubaguzi haiwezi kutekelezwa kila wakati kwa sifuri, na inatoa ushauri ufuatao:

  • wakati wa kuunda maktaba, inafaa kuacha ubaguzi kwa kanuni;
  • ikiwa tofauti bado zinahitajika, basi wakati wowote inapowezekana inafaa kuongeza viboreshaji isipokuwa (na const) kila mahali ili mkusanyaji aweze kuboresha iwezekanavyo.

Kwa ujumla, mzungumzaji alithibitisha maoni kwamba ubaguzi hutumiwa vyema kwa kiwango cha chini au kuachwa kabisa.

Slaidi za ripoti zinapatikana kwenye kiungo kifuatacho: [β€œVighairi vya C++ kupitia lenzi ya uboreshaji wa mkusanyaji wa LLVM”]

Jenereta, coroutines na utamu mwingine unaofungua ubongo, Adi Shavit

C ++ Urusi: jinsi ilivyotokea
Telezesha kutoka mawasilisho

Mojawapo ya ripoti nyingi katika mkutano huu zilizotolewa kwa ubunifu katika C++20 haikukumbukwa sio tu kwa uwasilishaji wake wa rangi, lakini pia kwa utambulisho wake wazi wa shida zilizopo na mantiki ya usindikaji wa mkusanyiko (kwa kitanzi, kurudi nyuma).

Adi Shavit anaangazia yafuatayo: mbinu zinazopatikana kwa sasa hupitia mkusanyiko mzima na hazitoi ufikiaji wa hali ya kati ya ndani (au hufanya katika kesi ya upigaji simu, lakini kwa idadi kubwa ya athari mbaya, kama vile Kuzimu ya Kurudisha nyuma) . Inaweza kuonekana kuwa kuna warudiaji, lakini hata nao kila kitu sio laini sana: hakuna sehemu za kawaida za kuingia na kutoka (anza β†’ mwisho dhidi ya rbegin β†’ rend na kadhalika), haijulikani ni muda gani tutarudia? Kuanzia na C++20, matatizo haya yanatatuliwa!

Chaguo la kwanza: safu. Kwa kufunga viambata, tunapata kiolesura cha kawaida cha mwanzo na mwisho wa urudiaji, na pia tunapata uwezo wa kutunga. Yote hii hurahisisha kuunda mabomba kamili ya usindikaji wa data. Lakini si kila kitu ni laini sana: sehemu ya mantiki ya hesabu iko ndani ya utekelezaji wa iterator maalum, ambayo inaweza kuchanganya kanuni kuelewa na kutatua.

C ++ Urusi: jinsi ilivyotokea
Telezesha kutoka mawasilisho

Kweli, kwa kesi hii, C++20 iliongeza coroutines (kazi ambazo tabia yake ni sawa na jenereta kwenye Python): utekelezaji unaweza kuahirishwa kwa kurudisha thamani fulani ya sasa wakati wa kuhifadhi hali ya kati. Kwa hivyo, tunafanikiwa sio tu kufanya kazi na data kama inavyoonekana, lakini pia kujumuisha mantiki yote ndani ya utaratibu maalum.

Lakini kuna nzi kwenye marashi: kwa sasa wanaungwa mkono kwa sehemu tu na wakusanyaji waliopo, na pia hazitekelezwi kwa uzuri kama tungependa: kwa mfano, bado haifai kutumia marejeleo na vitu vya muda kwenye coroutines. Zaidi, kuna baadhi ya vikwazo juu ya kile kinachoweza kuwa coroutines, na kazi za constexpr, wajenzi / waharibifu, na kuu hazijumuishwa katika orodha hii.

Kwa hivyo, coroutines hutatua sehemu kubwa ya shida na unyenyekevu wa mantiki ya usindikaji wa data, lakini utekelezaji wao wa sasa unahitaji uboreshaji.

Vifaa:

Mbinu za C++ kutoka kwa Yandex.Taxi, Anton Polukhin

Katika shughuli zangu za kitaalam, wakati mwingine lazima nitekeleze vitu vya kusaidia tu: safu kati ya kiolesura cha ndani na API ya maktaba fulani, ukataji miti au uchanganuzi. Katika kesi hii, kwa kawaida hakuna haja ya uboreshaji wowote wa ziada. Lakini vipi ikiwa vipengele hivi vinatumiwa katika baadhi ya huduma maarufu zaidi kwenye RuNet? Katika hali kama hiyo, italazimika kusindika terabytes kwa saa ya magogo peke yako! Halafu kila millisecond inahesabu na kwa hivyo lazima ubadilishe hila kadhaa - Anton Polukhin alizungumza juu yao.

Labda mfano wa kuvutia zaidi ulikuwa utekelezaji wa muundo wa pointer-to-utekelezaji (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_; 
};

Katika mfano huu, kwanza nataka kuondokana na faili za kichwa za maktaba ya nje - hii itakusanya kwa kasi, na unaweza kujikinga na migogoro ya majina iwezekanavyo na makosa mengine sawa. 

Sawa, tulihamisha #include kwenye faili ya .cpp: tunahitaji tamko la mbele la API iliyofungwa, pamoja na std::unique_ptr. Sasa tuna mgao unaobadilika na mambo mengine yasiyopendeza kama vile data iliyosambazwa kwenye kundi la data na dhamana iliyopunguzwa. std::aligned_storage inaweza kusaidia na haya yote. 

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_; 
};

Shida pekee: unahitaji kutaja saizi na upatanishi kwa kila kanga - wacha tufanye kiolezo chetu cha pimpl na vigezo. , tumia maadili fulani ya kiholela na ongeza cheki kwa mharibifu kwamba tumepata kila kitu sawa: 

~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"
    ); 
}

Kwa kuwa T tayari imefafanuliwa wakati wa kusindika kiharibu, nambari hii itachanganuliwa kwa usahihi na katika hatua ya mkusanyiko itatoa saizi inayohitajika na maadili ya upatanishi ambayo yanahitaji kuingizwa kama makosa. Kwa hiyo, kwa gharama ya kukimbia moja ya ziada ya mkusanyiko, tunaondoa ugawaji wa nguvu wa madarasa yaliyofungwa, kujificha API katika faili ya .cpp na utekelezaji, na pia kupata muundo unaofaa zaidi kwa caching na processor.

Ukataji miti na uchanganuzi ulionekana kutokuvutia na kwa hivyo hautatajwa katika hakiki hii.

Slaidi za ripoti zinapatikana kwenye kiungo kifuatacho: ["Ujanja wa C++ kutoka kwa Teksi"]

Mbinu za kisasa za kuweka msimbo wako DRY, BjΓΆrn Fahller

Katika mazungumzo haya, BjΓΆrn Fahller anaonyesha njia kadhaa tofauti za kukabiliana na dosari ya kimtindo ya ukaguzi wa hali unaorudiwa:

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

Je, unasikika? Kwa kutumia mbinu kadhaa za nguvu za C++ zilizoletwa katika viwango vya hivi majuzi, unaweza kutekeleza kwa umaridadi utendakazi sawa bila adhabu yoyote ya utendakazi. Linganisha:   

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

Ili kushughulikia idadi isiyorekebishwa ya hundi, mara moja unahitaji kutumia violezo tofauti na misemo ya kukunja. Wacha tufikirie kuwa tunataka kuangalia usawa wa anuwai kadhaa kwa kipengee cha state_type cha enum. Jambo la kwanza linalokuja akilini ni kuandika kazi ya msaidizi ni_yoyote_ya:


enum state_type { IDLE, CONNECTED, DISCONNECTED };

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

Matokeo haya ya kati ni ya kukatisha tamaa. Kufikia sasa nambari hiyo haisomeki zaidi:

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

Vigezo vya template isiyo ya aina itasaidia kuboresha hali kidogo. Kwa msaada wao, tutahamisha vitu vinavyoweza kuhesabika vya enum kwenye orodha ya vigezo vya template: 

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

Kwa kutumia kiotomatiki katika kigezo cha kiolezo kisicho cha aina (C++17), mbinu hiyo inalinganisha tu na ulinganisho na vitu vya state_type, lakini pia na aina za primitive ambazo zinaweza kutumika kama vigezo vya kiolezo visivyo vya aina:


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

Kupitia maboresho haya mfululizo, sintaksia fasaha inayohitajika ya ukaguzi inafikiwa:


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);

Katika mfano huu, mwongozo wa kukata hutumikia kupendekeza vigezo vya template ya muundo unaohitajika kwa mkusanyaji, ambaye anajua aina za hoja za wajenzi. 

Zaidi - zaidi ya kuvutia. Bjorn hufundisha jinsi ya kujumlisha nambari inayotokana kwa waendeshaji kulinganisha zaidi ya ==, na kisha kwa shughuli za kiholela. Njiani, vipengele kama vile no_unique_address sifa (C++20) na vigezo vya kiolezo katika vitendaji vya lambda (C++20) vinafafanuliwa kwa kutumia mifano ya matumizi. (Ndio, sasa sintaksia ya lambda ni rahisi zaidi kukumbuka - hizi ni jozi nne mfululizo za mabano za kila aina.) Suluhisho la mwisho kwa kutumia vitendaji kama maelezo ya mjenzi hunipa joto roho yangu, bila kusahau usemi tuple katika mila bora ya lambda. hesabu.

Mwishowe, usisahau kuiboresha:

  • Kumbuka kwamba lambdas ni constexpr kwa bure; 
  • Hebu tuongeze usambazaji kamili na tuangalie syntax yake mbaya kuhusiana na pakiti ya parameter katika kufungwa kwa lambda;
  • Wacha tumpe mkusanyaji fursa zaidi za uboreshaji kwa masharti isipokuwa; 
  • Wacha tutunze pato la makosa inayoeleweka zaidi katika violezo kwa shukrani kwa maadili wazi ya kurudi kwa lambdas. Hii italazimisha mkusanyaji kufanya ukaguzi zaidi kabla ya kitendaji cha kiolezo kuitwa - katika hatua ya kuangalia aina. 

Kwa maelezo, tafadhali rejelea nyenzo za mihadhara: 

Maoni yetu

Ushiriki wetu wa kwanza katika C ++ Urusi ulikuwa wa kukumbukwa kwa ukali wake. Nilipata maoni ya C++ Russia kama tukio la dhati, ambapo mstari kati ya mafunzo na mawasiliano ya moja kwa moja hauonekani. Kila kitu, kutoka kwa hali ya wasemaji hadi mashindano kutoka kwa washirika wa hafla, inafaa kwa mijadala mikali. Maudhui ya mkutano huo, unaojumuisha ripoti, yanashughulikia mada mbalimbali ikiwa ni pamoja na ubunifu wa C++, mifano ya miradi mikubwa na masuala ya kiitikadi ya usanifu. Lakini itakuwa si haki kupuuza sehemu ya kijamii ya tukio hilo, ambayo husaidia kushinda vikwazo vya lugha kuhusiana na sio tu kwa C ++.

Tunawashukuru waandaaji wa mkutano huo kwa nafasi ya kushiriki katika hafla kama hiyo!
Huenda umeona chapisho la waandaaji kuhusu siku za nyuma, za sasa na zijazo za C++ Urusi kwenye blogu ya JUG Ru.

Asante kwa kusoma, na tunatumai kuwa kusimulia tena matukio kulisaidia!

Chanzo: mapenzi.com

Kuongeza maoni