Kui nÀidatakse nÀidendis, et seinal ripub C++ kood, peab see lÔpus kindlasti teile jalga tulistama.
Bjarne Stroustrup
31. oktoobrist 1. novembrini toimus Peterburis C++ Russia Piter konverents â ĂŒks suurimatest programmistide konverentsidest Venemaal, mida korraldab JUG Ru Group. Kutsutud esinejate seas on C++ standardimise komitee liikmed, CppCon'i ettekandjad, O'Reilly raamatute autorid, samuti LLVM, libc++ ja Boost projektide hooldajad. Konverents on suunatud kogenud C++ arendajatele, kes soovivad sĂŒvendada oma ekspertiisi ja vahetada kogemusi elavas suhtluses. ĂliĂ”pilastele, aspirantidele ja ĂŒlikoolide Ă”ppejĂ”ududele pakutakse vĂ€ga meeldivaid allahindlusi.
Moskva vĂ€ljaanne konverentsist on vĂ”imalik kĂŒlastada juba jĂ€rgmise aasta aprillis, kuid seni jagavad meie ĂŒliĂ”pilased, mida huvitavat nad möödunud ĂŒritusel Ă”ppisid.Â

Fotod konverentsi
Meist
Selle postituse kallal töötasid kaks HSE ĂŒliĂ”pilast â Peterburis:
- Lisa Vasilenko â neljanda kursuse bakalaureuseĂ”ppe ĂŒliĂ”pilane, kes uurib programmeerimiskeelte suunda rakendusmatemaatika ja informaatika programmi raames. Tutvudes C++ keelega ĂŒlikooli esimesel kursusel, omandas ta hiljem kogemusi sellega tööstuses praktikal. Huvi programmeerimiskeelte, sealhulgas funktsionaalse programmeerimise vastu mĂ”jutas tema konverentsil valitud ettekandeid.
- Danya Smirnov â esimese aasta magistrant programmide ja andmete analĂŒĂŒsi valdkonnas. Juba koolis lahendas ta C++ keeles olĂŒmpiaaditeemasid, ning edasi juhtus nii, et keel ilmnes pidevalt tema Ă”ppetegevuses ja muutus lĂ”puks peamiseks töökeeleks. Otsustas konverentsist osa vĂ”tta, et oma teadmisi tĂ€iendada ning uutest vĂ”imalustest teada saada.
Kursuse juhatus jagab sageli meie erialaga seotud haridusĂŒrituste teavet. Septembris nĂ€gime teavet C++ Russia kohta ja otsustasime registreeruda kuulajatena. See on meie esimene kogemus sarnastes konverentsides osalemiseks.
Konverentsi struktuur
Ettekanded
Kaks pĂ€eva kestnudĂŒritusel lugesid eksperdid 30 ettekannet, kajastades mitmeid kuumi teemasid: keele omaduste nutikad rakendused rakenduslike probleemide lahendamiseks, keele uued uuendused seoses uue standardiga, kompromissid C++ disainis ja ettevaatusabinĂ”ud nende tagajĂ€rgedega töötamisel, nĂ€ited huvitavatest projektide arhitektuuridest ning mĂ”ned keele infrastruktuuri tagakĂŒljed. Samal ajal toimusid kolm ettekannet, enamasti kaks vene keeles ja ĂŒks inglise keeles.
Arutelualad
Ettekannete jĂ€rel kanti kĂ”ik vastamata kĂŒsimused ja lĂ”petamata arutelud ĂŒle spetsiaalselt tĂ€histatud suhtlemisaladeks, varustatud markeritahvlitega. Hea vĂ”imalus veeta paus ettekannete vahel meeldivas vestluses.
Ăkilised ettekanded ja mitteformaalsed arutelud
Kui soovi tekkis teha lĂŒhike ettekande, sai registreeruda markeritahvlile Ă”htusele Ă€kilisele ettekandele, et rÀÀkida viis minutit ĂŒkskĂ”ik millest konverentsi teemal. NĂ€iteks kiire sissejuhatus C++ sanitiseerijatesse (mĂ”ne jaoks oli see uus) vĂ”i lugu veast sinusoidi genereerimisel, mida saab ainult kuulda, kuid mitte nĂ€ha.
Teine formaat â paneeldiskussioon âKomitee hingeelustâ. Lavale on kutsutud mĂ”ned standardimiskomitee liikmed, projektoris on kamin (ametlikult â hingesooja atmosfÀÀri loomiseks, kuid pĂ”hjus âsest KĂIK ON TULESâ tundub naljakam), kĂŒsimused on seotud standardiga ja C++ ĂŒldise visiooniga, ilma tormikate tehniliste arutelude ja vaidlusteta. Selgus, et komitees on ka elavad inimesed, kes vĂ”ivad mĂ”nes osas pole olla tĂ€iesti kindlad vĂ”i midagist teada.
Vaidluste armastajatele jĂ€i kolmas ĂŒritus â BOF-sessioon âGo C++ vastuâ. VĂ”tame Go armastaja, C++ armastaja, enne sessiooni teevad nad koos 100500 slaidi teemal (nĂ€iteks probleemid C++ paketihalduses vĂ”i geneerikute puudumine Go-s), seejĂ€rel vaidlustavad nad elavalt ĂŒksteisega ja publikuga, kes pĂŒĂŒab mĂ”ista kaht erinevat vaatenurka. Kui algab vaidlus, mis ei ole asjakohane, sekkub moderaator ja lepib pooled kokku. Selline formaat venib: paar tundi pĂ€rast algust oli lĂ€bitud vaid pool slaididest. LĂ”ppu tuli kiirustada.
Partnerite stendid
Konverentsi partnerite tutvustamiseks olid saalides vÀlja pandud stendid, kus rÀÀgiti praegustest projektidest, pakuti praktika- ja töövÔimalusi, korraldati viktoriine ja vÀikeseid vÔistlusi ning loositi meeldivaid auhindu. Samuti pakkusid mÔned ettevÔtted vÔimalust lÀbida esialgseid vestluse etappe, mis vÔib olla kasulik neile, kes tulid mitte ainult ettekandeid kuulama.
Tehnilised ĂŒksikasjad ettekannetest
Kuulasime ettekandeid mĂ”lemal pĂ€eval. MĂ”nikord oli raske valida ĂŒhte ettekannet paralleelselt toimuvate seast â leppisime kokku, et jaguneme ja vahetame saadud teadmisi pauside ajal. Ja isegi sedasi tundub, et palju on jÀÀnud tĂ€helepanuta. Siin soovime rÀÀkida mĂ”nede ettekannete sisust, mis tundusid meile kĂ”ige huvitavamad
Erandid C++-s kompilatsiooni optimeerimise kaudu, Roman Rusjaev

Slaidist
Nagu pealkirjast selgelt nÀhtub, kÀsitles Roman eranditega töötamist LLVM nÀitel. Selle samas kohtumises vÔib ettekanne siiski anda teavet ka neile, kes ei kasuta oma töös Clang'i, kuidas koodi potentsiaalselt optimeerida. See on nii, et kompilaatorite ja vastavate standardteekide arendajad suhtlevad omavahel ja paljud head lahendused vÔivad kattuda.
Nii et erandi töötlemiseks on vajalik teostada palju toiminguid: kutsuda esile töötluskood (kui see on olemas) vÔi vabastada ressursid praegusel tasemel ja tÔsta teed kÔrgemale. KÔik see viib selleni, et kompilaator lisab potentsiaalselt erandeid tekitavate kÔnede jaoks tÀiendavaid juhiseid. Seega, kui erand tegelikult ei juhtu, hakkab programm ikkagi sooritama tarbetuid toiminguid. Nende kulude vÀhendamiseks on LLVM-is mitu heuristikat, mis mÀÀravad olukordi, kus erandi töötlemise koodi lisamine ei ole vajalik vÔi saab vÀhendada
Ettekandja kĂ€sitleb umbes kĂŒmmet neist ja nĂ€itab, kuidas olukorrad, kus need aitavad kiirendada programmi tĂ€itmist, samuti neid, kus neid meetodeid ei saa rakendada.
Nii et Roman Rusjaev juhib kuulajad jÀreldusele, et kood, mis sisaldab eranditega töötamist, ei ole alati vÔimalik tÀita nullkuludega, ning annab jÀrgmised nÔuanded:
- Raamatukogude arendamisel tuleks pÔhimÔtteliselt loobuda eranditest;
- kui erandeid siiski on vaja, tuleks vÔimalusel igale poole lisada modifikaatoreid noexcept (ja const), et kompilaator saaks maksimaalselt optimeerida.
KokkuvÔttes kinnitas esineja arvamust, et erandeid on kÔige parem kasutada minimaalselt vÔi nendest tÀielikult loobuda.
KĂŒpsised esitlusmaterjalid on saadaval lingil:
Generaatorid, korutiinid ja muud ajude sammutamise magusused, Adi Shavit

Slaidist
Ăks paljusid konverentsi ettekandeid, mis kĂ€sitlevad C++20 uuendusi, jĂ€i meelde mitte ainult vĂ€rvikalt kujundatud esituse, vaid ka selge probleemide mÀÀratlemise poolest, mis on seotud kogumite töötlemise loogikaga (for-tsĂŒkkel, callback'id).
Adi Shavit toob vĂ€lja jĂ€rgmised: praegused meetodid lĂ€bivad kogu kogumi ja ei anna samas ligipÀÀsu mĂ”nele sisemisele ajutisele olekule (vĂ”i annavad selle callback'ide puhul, kuid suure arvu ebameeldivate kĂ”rvaltoimetega, nagu Callback Hell). Tundub, et iteratoore on olemas, kuid ka nendega ei ole kĂ”ik sujuv: puuduvad ĂŒhenduspunktid sisse- ja vĂ€ljapÀÀsu jaoks (begin â end vastupidiselt rbegin â rend jne), ebaselge on, kui kaua me ĂŒldse iteratsiooniga tegeleme? Alates C++20 lahendatakse need probleemid!
Esimene variant: ranges. Iteraatorite peale mĂ€hkimise abil saame ĂŒhise liidese iteratsiooni alguseks ja lĂ”puks ning ka koostamise vĂ”imaluse. KĂ”ik see vĂ”imaldab hĂ”lpsasti ehitada tĂ€ielikke andmete töötlemise konveiere. Kuid mitte kĂ”ik ei ole nii sujuv: osa arvutuste loogikast asub konkreetse iteratsiooni rakenduses, mis vĂ”ib muuta koodi arusaadavamaks ja silumiseks keerukamaks.

Slaidist
Mis puutub sellesse, siis on C++20-sse lisatud korutiinid (funktsioonid, mille kĂ€itumine sarnaneb generaatoritega Pythonis): tĂ€itmine saab edasi lĂŒkata, tagastades mĂ”ne praeguse vÀÀrtuse, sĂ€ilitades samal ajal ajutise oleku. Seega saavutame mitte ainult andmete töötlemise nende ilmumise ajal, vaid ka kapseldame kogu loogika konkreetse korutiini sisse.
Kuid on ka ĂŒks negatiivne aspekt: praegu toetavad neid vaid osaliselt olemasolevad kompilaatorid ja implementeerimine ei ole nii hoolikas, nagu sooviks. NĂ€iteks ei tohiks korutiinide puhul kasutada viiteid ja ajutisi objekte. Lisaks on teatud piirangud selle osas, mis vĂ”ib olla korutiinideks, ja constexpr-funktsioonid, konstruktorid/destuktorid ning main ei kuulu selle nimekirja.
Seega lahendavad korutiinid mÀrkimisvÀÀrse osa andmete töötlemise loogika lihtsuse probleemidest, kuid nende praegune rakendus vajab tÀiendavat arendust.
Materjalid:
- C++ Russia slaidid â
C++ nipp Yandex.Taksist, Anton Poluhin
Oma ametialases tegevuses tuleb vahel luua puhtalt abistavaid asju: vahekiht sisemise liidese ja mingi raamatukogu API vahel, logimine vĂ”i parsimine. Sel juhul ei ole tavaliselt vajalik mingisugune tĂ€iendav optimeerimine. Aga mis siis, kui neid komponente kasutatakse ĂŒhes populaarseimas teenuses Venemaal? Sellisel juhul tuleb hallata tera- ja terabaiti ĂŒksnes logide jaoks! Iga millisekund on tĂ€htis ja seepĂ€rast tuleb kasutada erinevaid nippe â just neist rÀÀkis Anton Poluhin.
VĂ”ib-olla oli kĂ”ige huvitavamaks nĂ€iteks rakendamine mustri pointer-to-implementation (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_;Â
};Antud nĂ€ite puhul sooviks kĂ”igepealt vabaneda vĂ€liste raamatukogude pealkirjadest â nii compileerimine lĂ€heb kiiremini ja saab end kaitsta vĂ”imalike nimestruktuuri konfliktide ja muu sarnase eest.Â
HĂ€sti, tĂ”stsime #include .cpp-faili: vajalik on forward-declaration ĂŒmberpööratud API-le, samuti std::unique_ptr. NĂŒĂŒd on meil dĂŒnaamilised allot; ja teised ebameeldivad asjad, nagu andmete laialijagamine kuhja ja garanteeritud vĂ€hendamine. KĂ”igele sellele aitab kaasa 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: peame iga vahepaketi jaoks mÀÀrama suuruse ja joondamise â muudame meie pimpl ĆĄablooniks parameetritega , kasutame mingite suvaliste vÀÀrtustega ja lisame destruktoris kontrolli, et oleksime kĂ”ik Ă”igesti mÀÀranud:Â
~FastPimpl() noexcept {Â
validate();Â
Ptr()->~T();Â
}
template
static void validate() noexcept {Â
static_assert(
Size == ActualSize,Â
"Size and sizeof(T) mismatch"
);Â
static_assert(
Alignment == ActualAlignment,Â
"Alignment and alignof(T) mismatch"
);Â
}Kuna T destruktorit töödeldakse, on T juba mÀÀratletud, seetĂ”ttu ilmnevad selle koodi kĂ€itamisel kompilatsiooni ajal Ă”iged suuruse ja joondamise vÀÀrtused. Nii saame ĂŒhe tĂ€iendava kompileerimisseansi hinnaga loobuda dĂŒnaamilisest mĂ€lu eraldamisest, peidame API .cpp-faili, kus implementatsioon asub, ja saavutame CPU poolt paremini vahetatava struktuuri.
Logimise ja parsimise tĂ”husus ei paistnud silma, mistĂ”ttu neid ei kĂ€sitleta selles ĂŒlevaates.
KĂŒpsised esitlusmaterjalid on saadaval lingil:
Modernsed tehnikad, et hoida teie kood kuivana, Björn Fahller
Selles ettekandes tutvustab Björn Fahller mitmeid erinevaid viise, kuidas vÔidelda selliste stiililiste puudustega nagu korduvad tingimuste kontrollid:
assert(a == IDLE || a == CONNECTED || a == DISCONNECTED);Kas see on tuttav? Kasutades mĂ”ningaid vĂ”imsaid C++ tehnikaid, mis on ilmunud hiljutistes standardites, saab sama funktsionaalsuse elegantsemalt teostada ilma jĂ”udluse kaotamiseta. VĂ”rrelge:  Â
assert(a == any_of(IDLE, CONNECTED, DISCONNECTED));Kuna töödelda tuleb muutumatut hulka kontrolle, tuleb kasutada variadic templates ja fold expressions. Eeldame, et soovime kontrollida 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
bool is_any_of(state_type s, const Ts& ... ts) {Â
return ((s == ts) || ...);Â
}
Selline vahepealne tulemus on pettumustvalmistav. Praegu ei muutu kood loetavamaks:
assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED));Â Natuke olukorda parandavad non-type template parameetrid. Nende abil viime enumâi elemendid malliparameetrite nimekirja:Â
template
bool is_any_of(state_type t) {Â
return ((t == states) | ...);Â
}
assert(is_any_of(state)); Kasutades autoât mitte-tĂŒĂŒbi malliparametris (C++17), laieneb lĂ€henemine mitte ainult state_type elementide, vaid ka primitiivsete tĂŒĂŒpide vĂ”rdlemisele, mida saab kasutada mitte-tĂŒĂŒbi malliparametritena:
template
bool is_any_of(const T& t) {
return ((t == alternatives) | ...);
}JĂ€rjestikeste tĂ€iustamise kaudu saavutatakse soovitud sujuv sĂŒntaks kontrollide jaoks:
template
struct any_of : private std::tuple {
// laisaksite ja pÀrime ehitajad tuple'ilt
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 teenib deduktsioonigraafik soovitud malliparameetrite struktuuri nĂ€itamiseks kompilaatorile, kes teab konstruktoriga argumentide tĂŒĂŒpe.Â
Edasi â huvitavam. Björn Ă”petab ĂŒldistama saadud koodi vĂ”rdlusoperaatorite jaoks lisaks ==, ja seejĂ€rel ka kĂ”ikvĂ”imalike operatsioonide jaoks. Samal ajal tutvustatakse nĂ€iteks no_unique_address atribuuti (C++20) ja malliparameetreid lambdafunktsioonides (C++20). (Jah, nĂŒĂŒd on lambda-sĂŒntaks veelgi lihtsam meelde jĂ€tta â need on neli jĂ€rjestikust paari sulu igasuguses vormis.) LĂ”plik lahendus funktsioonide kasutamisega nagu konstruktorite detailid soojendab tĂ”eliselt mu hinge, rÀÀkimata tĂŒpist tuple parimates lambda-arvutuse traditsioonides.
LÔpus Àrge unustage viimistleda:
- Tuletame meelde, et lambdad on constexpr tasuta;Â
- Lisame perfektse edasikandmise ja vaatame selle inetu sĂŒntaks esinduspaketi korral lambdasulgudes;
- Anname kompilaatorile rohkem vĂ”imalusi optimeerimiseks tingimusliku noexcept'i abil;Â
- Hoolitseme arusaadavamate vea teatiste eest mallide puhul tĂ€nu lambda-de selgetele tagastatavatele vÀÀrtustele. See paneb kompilaatori tegema rohkem kontrollimisi enne mallifunktsiooni tegelikku kutsumist â tĂŒĂŒpide kontrollimise etapis.Â
KĂŒsimuste korral pöörduge loengumaterjalide poole:Â
- Ettekande slaidid:
Meie muljed
Meie esimene osalemine C++ Russia jÀÀb meelde oma rikkalikkuse poolest. C++ Russia avaldas muljet alsuse ĂŒritusena, kus Ă”ppe ja elava suhtlemise vaheline piir on peaaegu mĂ€rkamatu. KĂ”ik, alates esinejate meelestatusest kuni ĂŒrituse partnerite vĂ”istlusteni, kutsub esile elavaid arutelusid. Konverentsi sisuline osa, mis koosneb ettekannetest, hĂ”lmab ĂŒsna laia teemapinda, sealhulgas C++ uuendusi, nĂ€iteid suurtest projektidest ja ideoloogilisi arhitektuurilisi arutlusi. Kuid oleks ebaaus tĂ€helepanu pööramata ka ĂŒrituse sotsiaalsele kĂŒljele, mis aitab ĂŒletada keelebarjÀÀre, mitte ainult C++ osas.
TĂ€name konverentsi korraldajaid sellisel ĂŒritusel osalemise vĂ”imaluse eest!
Korraldajate postitust möödunud, oleviku ja tuleviku C++ Russia kohta olete vÔinud nÀha .
AitĂ€h lugemise eest ja loodame, et meie sĂŒndmuste kokkuvĂ”te oli kasulik!
Allikas: habr.com
