Kui nÀidate nÀidendi alguses, et seinal on kood C++ jaoks, siis peab see kindlasti lÔpus teile jalga laskma.
Bjarne Stroustrup
31. oktoobrist kuni 1. novembrini toimus Peterburis C++ Russia Piter konverents â ĂŒks suurimaid programmeerimiskonverentse Venemaal, mille korraldas JUG Ru Group. KĂŒlalislektorite seas on C++ standardimise komitee liikmed, CppCon'i ettekandjad, O'Reilly vĂ€ljaande autorid ja ka selliste projektide hooldajad nagu LLVM, libc++ ja Boost. Konverents on suunatud kogenud C++ arendajatele, kes soovivad sĂŒvendada oma ekspertiisi ja vahetada kogemusi elavas suhtluses. ĂliĂ”pilastele, doktorantidele ja ĂŒlikoolide Ă”ppejĂ”ududele on pakutavad vĂ€ga head allahindlused.
Moskva konverentsi vĂ€ljaannet saab kĂŒlastada juba jĂ€rgmise aasta aprillis, kuid meie ĂŒliĂ”pilased rÀÀgivad, millest huvitavast nad eelmisel ĂŒritusel teada said.Â

Fotod
Meist
Selle postituse eest vastutasid kaks HSE ĂŒliĂ”pilast â Peterburist:
- Lisa Vasilenko on 4. kursuse bakalaureuseĂŒliĂ”pilane, kes Ă”pib programmeerimiskeelte suunda âRakendusmatemaatika ja informaatikaâ programmis. Tutvudes C++ keelega ĂŒlikooli esimesel kursusel, omandas ta hiljem selle kasutamise kogemuse praktikal töötades. Kirg programmeerimiskeelte, eriti funktsionaalse programmeerimise vastu on mĂ”jutanud ka tema valikuid konverentsidel esitlemiseks.
- Danya Smirnov on 1. aasta magistrant programmeerimise ja andmeanalĂŒĂŒsi erialal. Juba koolis lahendas ta C++ keeles olĂŒmpiaadiĂŒlesandeid, ja edaspidi seisis see keel pidevalt tema Ă”pingutes, kuni sellest sai tema peamine tööriist. Ta otsustas konverentsist osa vĂ”tta, et oma teadmisi tĂ€iendada ja tutvuda uute vĂ”imalustega.
Fakulteedi uudiskirjas jagatakse tihti teavet haridusĂŒrituste kohta, mis on seotud meie erialaga. Septembris nĂ€gime C++ Russia kohta teavet ja otsustasime registreeruda kuulajateks. See on meie esimene kogemus sarnastes konverentsides osalemiseks.
Konverentsi struktuur
Ettekanded
Kahe pĂ€eva jooksul lugesid eksperdid ette 30 ettekannet, kajastades palju pĂ”letavaid teemasid: keele funktsioonide nutikad rakendused praktiliste ĂŒlesannete lahendamiseks, tulevased keeuudised seoses uue standardiga, C++ disaini kompromissid ja ettevaatusabinĂ”ud nende tagajĂ€rgedega tegelemiseks, huvitava projekt arhitektuuri nĂ€ited ning mĂ”ned keele infrastruktuuri sisemised detailid. Samal ajal toimusid 3 ettekannet, enamasti kaks vene keeles ja ĂŒks inglise keeles.
Arutelualad
Esitluse jĂ€rel kanti kĂ”ik vastamata kĂŒsimused ja lĂ”petamata arutelud spetsiaalsetesse suhtlusaladele esinejatega, mis olid varustatud markeritahvlitega. Hea viis veeta paus ettekannete vahel meeldivas vestluses.
VĂ€lgatusettekanded ja mitteformaalsed arutelud
Kui soovid teha lĂŒhikese ettekande, saad registreeruda markerite tahvlil Ă”htusele Lightning Talk'ile ja saad viie minuti jooksul rÀÀkida kĂ”igest, mis seondub konverentsi teemaga. NĂ€iteks kiire sissejuhatus C++ sanitizersâitesse (mille kohta oli paljudele uut) vĂ”i lugu sinusoidi genereerimise veast, mille saab vaid kuulda, aga mitte nĂ€ha.
Teine formaat on paneeldiskussioon âKomiteega hingede ĂŒleâ. Lavale tulevad mĂ”ned standardimise komitee liikmed, projektoril on kamin (ametlikult - hingelise Ă”hkkonna loomiseks, kuid pĂ”hjus âsest KĂIK ON TULESâ tundub huvitavam), kĂŒsimused on standardi ja C++ ĂŒldise visiooni kohta, ilma Ă€gedate tehniliste arutelute ja konfliktideta. Selgus, et komitees on ka elavaid inimesi, kes ei pruugi mĂ”nedes asjades olla tĂ€ielikult kindlad vĂ”i midagi mitte teada.
Arutelu fĂ€nnide seas kestis kolmas ĂŒritus â BOF-seminar "Go versus C++". VĂ”tame Go armastaja ja C++ armastaja, enne sessiooni algust valmistavad nad koos 100500 slaidi teema ĂŒle (nt C++ paketeerimise probleemid vĂ”i Go generikate puudumine), seejĂ€rel arutavad nad elavalt ĂŒksteisega ja publikuga, samal ajal kui publik pĂŒĂŒab mĂ”ista kahte seisukohta. Kui arutelu muutub ebaoluliseks, sekkub moderaator ja lepitab pooled. See formaat venib: mitu tundi pĂ€rast algust oli lĂ€bida vaid pool slaididest. LĂ”ppu tuli tĂ”siselt kiirendada.
Partnerite stendid
KĂ€iguteedes olid esindatud konverentsi partnerid â stendidel rÀÀgiti kĂ€imasolevatest projektidest, pakuti praktikakohti ja tööleasumise vĂ”imalusi, korraldati viktoriine ja vĂ€ikeseid vĂ”istlusi ning loosi anti meeldivaid auhindu. Samuti pakkusid mĂ”ned ettevĂ”tted vĂ”imalust lĂ€bida esimesed vestlusetapid, mis vĂ”ib olla kasulik neile, kes tulid mitte ainult ettekandeid kuulama.
Ettekannete tehnilised ĂŒksikasjad
Kuulasime ettekandeid kogu pĂ€eva. MĂ”nikord oli raske valida ĂŒhte ettekannet samal ajal toimuvate seast â leppisime kokku, et jagame vahel oma teadmisi. Ja isegi nii tundub, et palju jĂ€i puudu. Siin tahaksime rÀÀkida mĂ”nest ettekandest, mis tundusid meile kĂ”ige huvitavamad.
C++ erandid kompilaatori optimeerimise vaatenurgast, Roman Rusajev

Slide
Nagu pealkirjast selgelt nÀha, kÀsitles Roman exceptionide töötlemist LLVM nÀitel. Samas vÔib see ettekande anda mÔningast arusaamist ka neile, kes ei kasuta oma töös Clang'i, kuidas kood vÔiks potentsiaalselt olla optimeeritud. See on nii, sest kompilaatiorite ja vastavate standardraamatukogude arendajad suhtlevad omavahel ja paljusid hÀid lahendusi vÔivad kasutada erinevad meeskonnad.
Seega, erandi kĂ€sitlemiseks on vaja teha mitmeid toiminguid: kutsuda vĂ€lja töötlemiskood (kui see on olemas) vĂ”i vabastada ressursid kĂ€imasolevas tasemes ja kerida stekki ĂŒlespoole. KĂ”ik see viib selleni, et potentsiaalselt erandeid tekitavate kĂ”nede jaoks lisab kompilaator tĂ€iendavaid instruktsioone. Seega, kui erand ei toimu, hakkab programm ikkagi tĂ€itma tarbetuid toiminguid. Ăhenduse kulude vĂ€hendamiseks on LLVM-is mitmeid heuristilisi meetodeid, et mÀÀrata olukordi, kus erandite töötlemise koodi ei ole vaja lisada vĂ”i mille puhul vĂ”ib vĂ€hendada âĂŒlemÀÀrasteâ instruktsioonide arvu.
Ettekandja uurib umbes kĂŒmmet neist ning nĂ€itab, kuidas situatsioonid, kus need aitavad programmi tĂ€itmist kiirendada, ning neid, kus need meetodid ei ole rakendatavad.
Seega toob Roman Russaiev kuulajate ette jÀrelduse, et kood, mis sisaldab töötlemist eranditega, ei pruugi alati olla teostatav nullkulusid kandva operatsioonina ning annab jÀrgmised nÀpunÀited:
- teeksite raamatukogude arendamisel pÔhimÔtteliselt loobuda eranditest;
- kui erandid on siiski vajalikud, siis tuleks vÔimaluse korral igal pool lisada modifikaatoreid noexcept (ja const), et kompilator saaks vÔimalikult palju optimeerida.
KokkuvĂ”ttes kinnitas ettekandja arvamust, et erandeid tuleks kasutada vĂ”imalikult vĂ€he vĂ”i neist ĂŒldse loobuda.
Ettekande slaidid on saadaval lingil:
Generators, coroutines ja muud aju avardavad meeldimised, Adi Shavit

Slide
Ăks paljusid konverentsi ettekandeid, mis kĂ€sitlevad C++20 uuendusi, jÀÀb meelde mitte ainult vĂ€rvikalt kujundatud esituse, vaid ka selge probleemide mÀÀratlemise tĂ”ttu kogu kollektsioonide töötlemise loogikas (for tsĂŒkkel, tagasiside-d).
Adi Shavit toob vĂ€lja jĂ€rgmised: praegu kasutatavad meetodid lĂ€bivad kogu kogumi ning ei pruugi anda juurdepÀÀsu teatud sisemisele vaheolekule (vĂ”i annavad seda callback-ide kaudu, kuid koos paljude ebameeldivate kĂ”rvalmĂ”judega, nagu Callback Hell). Tundub, et iteratoore on olemas, kuid ka nendega ei ole kĂ”ik nii sujuv: pole ĂŒldisi sisse- ja vĂ€ljapÀÀsukohasid (begin â end versus rbegin â rend jne), ebaselge on, kui palju me ĂŒldse iteratsiooni peame? Alates C++20 lahendatakse need probleemid!
Esimene variant: ranges. Iteraatorite kohal oleva ĂŒmbriku abil saame ĂŒldise liidese iteratsiooni alguse ja lĂ”pu jaoks, samuti vĂ”imaluse kompositsiooniks. KĂ”ik see vĂ”imaldab kergesti ehitada tĂ€islahendusega andmetöötluse torujuhtmeid. Kuid mitte kĂ”ik ei ole nii sujuv: osa arvutuste loogikast vĂ”ib paikneda konkreetse iteratori rakenduses, mis vĂ”ib muuta koodi mĂ”istmise ja silumise keerulisemaks.

Slide
Noh, selleks on C++20-sse lisatud korutiinid (funktsioonid, mille kĂ€itumine sarnaneb Pythonis kasutatavatele generaatoritele): tĂ€itmine saab olla edasi lĂŒkatud, tagastades mĂ”ningase praeguse vÀÀrtuse ja sĂ€ilitades samal ajal vaheoleku. Nii saavutame mitte ainult andmetega töötamise nende saabumisel, vaid ka kogu loogika kapseldamise konkreetse korutiini sisse.
Kuid on ka negatiivne kĂŒlg: praegu toetavad neid vaid osaliselt olemasolevad kompilaatorid ja need on teostatud mitte nii hoolikalt, nagu sooviks: nĂ€iteks ei tasu korutiinides kasutada viiteid ja ajutisi objekte. Pluss, on mĂ”ned piirangud, mis vĂ”ivad olla korutiinid, ja constexpr-funktsioonid, konstruktorid/destruktorid ning ka main ei kuulu sellesse nimekirja.
Seega lahendavad korutiinid mÀrkimisvÀÀrse osa andmete töötlemise loogika lihtsustamise probleemidest, kuid nende praegused teostused vajavad tÀiendavat tööd.
Materjalid:
- C++ Russia slaidid â
C++ trikid Yandex.Taxis, Anton Poluhhin
Oma professionaalses tegevuses peab vahel tegelema puhtalt abifunktsioonidega: rakendama mingi teegi sisemise liidese ja API vahel, logimist vĂ”i parsimist. Sel juhul ei ole tavaliselt vajalik mingisugune tĂ€iendav optimeerimine. Aga mis siis, kui neid komponente kasutatakse mĂ”nedes populaarseimates teenustes Ruunetis? Sellises olukorras tuleb töödelda terabaitide kaupa logisid tunnis! Siis on iga millisekund oluline ja seetĂ”ttu tuleb kasutada erinevaid nippe â just neist rÀÀkis Anton Poluhin.
VĂ”ib-olla oli kĂ”ige huvitavam nĂ€ide pointer-to-implementation (pimpl) mustri rakendamine.Â
#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_;Â
};Selles nĂ€ites tahaks esialgu vabaneda vĂ€liste raamatukogude pealkirjafailidest â see kiirendab kompileerimist ja samuti kaitseb vĂ”imalike nimede konfliktide ja teiste sarnaste vigade eest.Â
HĂ€sti, viisime #include cpp-faili: vajalik on edasine dekleerimine ĂŒmbritsetud API-st ning std::unique_ptr. NĂŒĂŒd on meil dĂŒnaamilised allokatsioonid ja muud ebameeldivad asjad, nagu laiali hajutatud andmed pĂ”hjas ja vĂ€henenud garantii. KĂ”ik selle jaoks vĂ”ib aidata 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 data_;Â
};Ainus probleem: iga ĂŒmbriku jaoks tuleb mÀÀrata suurus ja joondamine â teeme meie pimpl mallina parameetritega , kasutame mĂ”ningate suvaliste vÀÀrtuste jaoks ja lisame destruktorisse kontrolli, et kĂ”ik oleks Ă”igesti Ă€ra arvatud:Â
~FastPimpl() noexcept {Â
validate();Â
Ptr()->~T();Â
}
template
static void validate() noexcept {Â
static_assert(
Size == ActualSize,Â
"Suurus ja sizeof(T) ei ĂŒhti"
);Â
static_assert(
Alignment == ActualAlignment,Â
"Joondamine ja alignof(T) ei ĂŒhti"
);Â
}Kuna T on destruktori töötlemisel juba mÀÀratletud, töötab see kood Ă”igesti ja kompilatsioonietapis kuvab vajalikud suuruse ja joondamise vÀÀrtused, mis tuleb kirjutada. Nii saame ĂŒhe tĂ€iendava kompileerimise hinnaga vabaneda juurdehindlusest pakendatud klasside dĂŒnaamilise eraldamise eest, peidame API .cpp-faili rakendusse ning saame protsessorile paremini vahemĂ€lu sobiva struktuuri.
Logimine ja analĂŒĂŒs tundusid vĂ€hem muljetavaldavad, seega ei mainita neid selles ĂŒlevaates.
Ettekande slaidid on saadaval lingil:
Kaasaegsed tehnikad oma koodi kuivana hoidmiseks, Björn Fahller
Selles ettekandes nÀitab Björn Fahller mitmeid erinevaid viise, kuidas vÔidelda selliste stilistiliste puudustega nagu korduvate tingimuste kontrollimine:
assert(a == IDLE || a == CONNECTED || a == DISCONNECTED);Kas see on tuttav? Kasutades mitmeid vĂ”imsaid C++ tehnikaid, mis on ilmunud hiljutistes standardites, saab sama funktsionaalsuse elegantsetel viisidel rakendada ilma igasuguste jĂ”udluskadudeta. VĂ”rdle:  Â
assert(a == any_of(IDLE, CONNECTED, DISCONNECTED));Ebakindla arvu kontrollide haldamiseks tahaksime kasutada variadic templates ja fold expressions. Oletame, et soovime vĂ”rrelda mitme muutuja vĂ”rdsust enumâi state_type elemendiga. Esimene asi, mis pĂ€he tuleb â kirjutada abifunktsioon 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) || ...);Â
}
Selline vahepealne tulemus on pettumust valmistav. Kood ei muutu senimaani loetavamaks:
assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED)); Non-type mallikparameetrite abil on vĂ”imalik veidi olukorda parandada. Nende abil edastame enum'ist loetletud elemendid malliparameetrite nimekirja:Â
template
bool is_any_of(state_type t) {
return ((t == states) | ...);
}
assert(is_any_of(state)); C++17 versioonis auto kasutamisega mitte-tĂŒĂŒpilise malliparameetri (non-type template parameter) kasutamine laiendab lĂ€henemist nii, et saame vĂ”rrelda mitte ainult state_type elemente, vaid ka primitiivsete tĂŒĂŒpidega, mida saab kasutada mitte-tĂŒĂŒpiliste malliparameetrite jaoks:
template
bool is_any_of(const T& t) {
return ((t == alternatives) | ...);
}Nende jĂ€rjestikuste paranduste kaudu saavutatakse soovitud sujuv sĂŒntaks kontrollide jaoks:
template
struct any_of : private std::tuple {
// oleme laisad ja pÀrime tuple'ist konstruktorid
using std::tuple::tuple;
template
bool operator ==(const T& t) const {
return std::apply(
[&t](const auto& ... ts) {
return ((ts == t) || ...);
},
static_cast<const std::tuple&>(*this));
}
};
template
any_of(Ts ...) -> any_of;
assert(any_of(IDLE, DISCONNECTING, DISCONNECTED) == state);
Selles nĂ€ites on deduktioonijuhend mĂ”eldud kompilaatori jaoks soovitud malliparameetrite struktuuri nĂ€itamiseks, teades konstruktorite argumentide tĂŒĂŒpe.Â
Edasi â on huvitavam. Björn Ă”petab kokku vĂ”tma tekkinud koodi vĂ”rreldes teiste vĂ”rdlusoperaatoritega peale ==, ja seejĂ€rel ka erinevate operatsioonidega. Samuti tutvustatakse nĂ€ite kaudu selliseid omadusi nagu no_unique_address atribuut (C++20) ja malliparameetrid lambda-funktsioonides (C++20). (Jah, nĂŒĂŒd on lambda sĂŒntaks veel lihtsam meelde jĂ€tta â see on neli jĂ€rjestikust sulgude paari kĂ”ikidest sortidest.) LĂ”pplahendus, mis kasutab funktsioone kui ehitusdetailideks, rÔÔmustab mind tĂ”eliselt, rÀÀkimata tupelise vĂ€ljendi kasutamisest lambda-arvutuse parimate traditsioonide jĂ€rgi.
LÔpus ei unusta me ilustamisega tegeleda:
- Kordame, et lambdad on - constexpr tasuta;Â
- Lisame perfect forwardingâi ja vaatame selle koledat sĂŒntaksit seoses parameter packâiga lambda sulgudes;
- Anname kompilaatorile rohkem vĂ”imalusi optimeerimiseks conditional noexceptâi abil;Â
- Mugime selgeid tagastavaid vÀÀrtusi lambdade abil, et parandada vigade arusaadavust mallides. See sunnib kompilaatorit tegema rohkem kontrollimisi enne mallifunktsiooni vĂ€ljakutset - tĂŒĂŒbi kontrollimise etapis.Â
Lisainformatsiooni saamiseks pöörduge loengumaterjalide poole:Â
- Ettekande slaidid:
Meie muljed
Meie esimene osalemine C++ Russia jÀÀb meelde oma sisukuse poolest. C++ Russia jĂ€tab mulje sĂŒdamlikust ĂŒritusest, kus Ă”ppe ja elava suhtluse piir on peaaegu tajumatu. KĂ”ik, alates ettekandjate meeleolust kuni ĂŒrituse partnerite korraldatud konkurssideni, kutsub esile elavaid arutelusid. Konverentsi sisu, mis koosneb ettekannetest, katab ĂŒsna laia teemaspektrit, sealhulgas C++ uuendusi, praktilisi nĂ€iteid suurematest projektidest ja ideoloogilisi arhitektuurilisi kaalutlusi. Kuid oleks ebaĂ”iglane unustada ĂŒrituse sotsiaalset aspekti, mis aitab ĂŒletada keelebarjÀÀre mitte ainult C++ osas.
TĂ€name konverentsi korraldajaid sellise sĂŒndmuse korraldamise vĂ”imaluse eest!
Korraldajate postitus mineviku, oleviku ja tuleviku kohta C++ Russia oli nÀhtav .
AitĂ€h lugemise eest, loodame, et meie sĂŒndmuste kokkuvĂ”te on olnud kasulik!
Allikas: habr.com
