2021.8.30 社内向け勉強会資料。 RustとC/C++のソースコードを実行し、比較する。
2021.8.30 Ѩ෦ߞೋRustೖֶࣜRustͷಛɺC/C++ͱͷҧ͍ΛͳΜͱͳ͘ཧղ͠Α͏
View Slide
ࣗݾհతͳͥRust͔?C/C++ͷ՝ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞/RustͷϞμϯ͞Λମݧ)RustͷࠐΈ։ൃͷద༻࣍2
■໊લɿѨ෦ɹߞೋ(͋ɹ͜͏͡)■ࠐΈιϑτΣΞ։ൃ19ɻɹCݴޠɺOSͳ͠(ϕΞϝλϧ)ͷ։ൃۀܦݧ͕΄ͱΜͲɻ■GitHub: https://github.com/grace2rikuɹࠓճͷϫʔΫͷιʔείʔυɿhttps://github.com/grace2riku/c_cpp_vs_rust/tree/masterࣗݾհ3
RustͷֶशՌΛͨ·ʹϥΠτχϯάτʔΫͳͲͰൃ৴͍ͯ͠·͢ɻྫ)Rustॳ৺ऀ͕ArduinoΛLνΧͯ͠Έͨhttps://speakerdeck.com/grace2riku/rustchu-xin-zhe-gaarduinowoltikasitemita-bb5de094-8ee0-48a6-af6e-a8ce7d430309ྫ)ArduinoͰϞʔλʔ੍ޚϩδοΫΛ࣮ͨ͠https://speakerdeck.com/grace2riku/arduinodemotazhi-yu-rozitukuwoshi-zhuang-sitahuaࣗݾհ4
ɾRustͬͯ͜ΜͳݴޠͳΜͩʔɺͱͳΜͱͳ͘Θ͔Δ͜ͱɻɹॳ৺ऀ͚ͷ༰Ͱ͢ɻɾC/C++ͱ3VTUͷҧ͍͕ͳΜͱͳ͘Θ͔Δ͜ͱɻɹ$$ܦݧऀ͕3VTUͷ҆શੑΛཧղ͢Δ͡ΊͷาͱͳΕخ͍͠Ͱ͢ɻత5
ɹ˙ࢿྉͷ͍ํɹޙͷϫʔΫͰ$$ͱ3VTUͷίʔυΛॻ͍࣮ͯߦ͠·͢ɻɹίʔυɺ࣮ߦ݁ՌΛ௨ͯ͠$$ɾ3VTUͷ͕ࣝΞοϓσʔτͰ͖Εخ͍͠ɻɹ$$ɾ3VTUͷίʔυΛ࣮ࡍʹखΛಈ͔࣮ͯ͠ߦɺ݁ՌΛ֬ೝ͢Δ͜ͱΛ͓קΊ͠·͢ɻɹίʔυͷ࣮ߦϒϥβͰಈ͘γϛϡϨʔγϣϯڥΛ͏ͷͰ։ൃڥͷ४උෆཁͰ͢ɻత6
ɾ҆શɾ҆৺ɻ⇛ଟػೳɺߴػೳɺෳࡶԽ͢ΔࠐΈػثͷཁٻ༷ʹC/C++Ͱཱ͔ͪ͑Δ͔ɻ࣌ʹ߹Θͤͨϓϩάϥϛϯάݴޠͷ࠾༻Λݕ౼͢ΔͷͲ͏͔ɻɾϞμϯ͔ͩΒɻͳͥRust͔?7
ɾCͷ͍͋·͍ͳݴޠ༷(ະఆٛಈ࡞)ɾϝϞϦཧɾC++͍͠ɾͦͷଞC/C++ͷ՝8
ɾCͷʲະఆٛಈ࡞ʳͱ?Cݴޠͷඪ४ن֨Ͱ͋ΔJIS X 3010ɿ2003(ISO/IEC 9899ɿ1999)ΑΓҾ༻ɻʲ3.4.3 ະఆٛͷಈ࡞ʢundefined behaviorʣ Մൖੑ͕ͳ͍ए͘͠ਖ਼͘͠ͳ͍ϓϩάϥϜߏཁૉΛ༻ͨ͠ͱ͖ͷಈ࡞ɼຢਖ਼͘͠ͳ͍σʔλΛ༻ͨ͠ͱ͖ͷಈ࡞Ͱ͋Γɼ͜ͷن͕֨ԿΒཁٻΛ՝͞ͳ͍ͷɻࢀߟ ະఆٛͷಈ࡞ʹରͯ͠ɼͦͷঢ়گΛແࢹͯ͠༧ଌෆՄೳͳ݁ՌΛฦͯ͠Α͍ɻ༁࣌ຢϓϩάϥϜ࣮ߦ࣌ʹɼจॻԽ͞Εͨɼڥʹಛ༗ͳํ๏Ͱॲཧͯ͠Α͍ʢஅϝοηʔδͷൃߦΛͬͯΘͳͯ͘Α͍ɻʣɻ͞ΒʹʢஅϝοηʔδΛग़ྗ͠ʣ༁ຢ࣮ߦΛதஅͯ͠Α͍ɻʳC/C++ͷ՝9
ɾCͷະఆٛಈ࡞ͳͲ͍͋·͍ͳಈ࡞Λ͢ΔίʔυΛRustͰ࣮ߦͯ͠Έ·͠ΐ͏ɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)10
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c, Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)11
ϫʔΫͷιʔείʔυ࣍ʹஔ͖·ͨ͠ɻhttps://github.com/grace2riku/c_cpp_vs_rust/tree/masterCode -> Download ZIPΛબɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)12
■ϫʔΫͷڥʹ͍ͭͯ●C/C++࣍ͷΞυϨεͷγϛϡϨʔλ(wandbox)Λ༻͠·͢ɻɹhttps://wandbox.org/●Rust࣍ͷΞυϨεͷγϛϡϨʔλ(Rust Playground)Λ༻͠·͢ɻɹhttps://play.rust-lang.org/ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)13
■ϫʔΫͷڥʹ͍ͭͯɹCͷઃఆ●Languagesɹ⇛C●gcc 11.1.0ΛબϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)14
■ϫʔΫͷڥʹ͍ͭͯɹCͷઃఆ●CͷόʔδϣϯʲC99ʳΛબ※C99બͷཧ༝ࣄͰ͍ͬͯΔϚΠίϯͷίϯύΠϥ͕C99४ڌͩͬͨͨΊɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)15
■ϫʔΫͷڥʹ͍ͭͯɹCͷઃఆᶃίʔυೖྗΤϦΞᶄίϯύΠϧɾίʔυ࣮ߦϘλϯᶅ࣮ߦ݁ՌදࣔΥʔχϯάɾίϯύΠϧΤϥʔ͕͋ΕදࣔɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)16ᶃᶄᶅ
■ϫʔΫͷڥʹ͍ͭͯɹRustͷઃఆ●σϑΥϧτ͔ΒઃఆมߋෆཁɻᶃίʔυೖྗΤϦΞᶄ࣮ߦ݁ՌදࣔΥʔχϯάɾίϯύΠϧΤϥʔ͕͋ΕදࣔɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)17ᶃᶄ
■ϫʔΫͷڥʹ͍ͭͯɹRustͷઃఆσϑΥϧτͷઃఆɾStable version: 1.54ɾEdition 2018ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)18
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c, C++*.cpp, Rust*.rs1. enum, switch: enum_switch.*ɹCͱRustͷίʔυΛൺֱɻɹenumܕͷൺֱɻCͷswitchɾRustͷmatchࣜͷൺֱɻ2. ଟଶ: polymorphism.*ɹC++ͱRustͷίʔυΛൺֱɻϫʔΫ(RustͷϞμϯ͞Λମݧ)19
1. enum, switch: enum_switch.*ɹenumܕͷൺֱɻCͷswitchɾRustͷmatchࣜͷൺֱɻ●ࢼͯ͠Έͯ΄͍͜͠ͱɾC:switchɾRust:matchจͷ݅Λͻͱͭআ࣮ͯ͠ߦɻɾprint_shape(Circle);ͷҾCircleΛ0(·ͨҙͷ)ʹมߋ࣮ͯ͠ߦɻϫʔΫ(RustͷϞμϯ͞Λମݧ)20
2. ଟଶ: polymorphism.*ɾC++ͱRustͰଟଶΛ࣮ɻιʔείʔυΛൺֱͯ͠Έ͍ͯͩ͘͞ɻɹɾΫϥεਤͱ؆୯ͳઆ໌Λ࣍ϖʔδʹهࡌɻϫʔΫ(RustͷϞμϯ͞Λମݧ)21
2. ଟଶ: polymorphism.*ɹɾଟଶͷઆ໌Ͱ͋Γͦ͏ͳαϯϓϧϓϩάϥϜΛɹC, RustͰͦΕͧΕ࣮ɻɾਤܗͱԁɾࡾ֯ܗɾਖ਼ํܗͷΫϥεɻɹShapeɿநΫϥεɹCircle, Triangle, Square: ShapeΛ۩Խͨ͠Ϋϥεɾprint_type(), calc_area(): ۩ԽΫϥεͰ࣮ߦ݁Ռ͕มΘΔɻϫʔΫ(RustͷϞμϯ͞Λମݧ)22ଟଶͷαϯϓϧίʔυͷΫϥεਤ
ੋඇɺ࣮ࡍʹखΛಈ͔ͯ͠ιʔείʔυΛγϛϡϨʔγϣϯͯ͠Έ͍ͯͩ͘͞ɻͦͯ͠C/C++ͱRustͷίʔυʹ͍ͭͯߟͯ͠ΈΔͱྑ͍ͱ͓͍·͢ɻ※ຊॻඌʹιʔείʔυͷ࣮ߦ݁ՌΛهࡌ͠·͢ɻγϛϡϨʔγϣϯ࣮ߦޙʹ֬ೝ͍͚ͨͩΕͱࢥ͍·͢ɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)23
͍͋·͍ͳίʔυ͕͋ͬͨͱ͖ɺίϯύΠϥʹΉ͜ͱɻɹ1. ίϯύΠϥΤϥʔʹͯ͠ཉ͍͠ɻɹ2. Υʔχϯάग़ͯ͠ཉ͍͠ɻɹ3. ͍͋·͍ͳίʔυΛ࣮ߦͨ͠Β࣮ߦ࣌Τϥʔʹͯ͠ཉ͍͠ɻɹ4. ͍͋·͍ͳίʔυΛ࣮ߦ͠ɺ͍͋·͍ͳಈ࡞Λߦ͏ɻ ⾨͜͜ʹࢸΔલʹόάʹؾ͖͍ͮͨ͠!!!ɾιʔείʔυͷ࣮ߦલʹ͍͋·͍ͳίʔυʹؾ͖ͮɺमਖ਼͍ͨ͠ɻ࣮͠ߦ࣮ͯ͠ߦ࣌Τϥʔʹͯ͠ཉ͍͠ɻ͍͋·͍ͳίʔυ͕Έࠐ·Εؾ͔ͮͣɺϦϦʔε͞Εͯ͠·͏͜ͱ΄Ͳා͍͜ͱͳ͍ɻ։ൃऀ͕ίϯύΠϥʹΉ͜ͱ24
ɾଟ͘ͷຊɺϒϩάͰRustΛARM Cortex-MίΞͰಈ͔͢νϡʔτϦΞϧ͕ܝࡌ͞Ε͍ͯΔɻ࣮ػͰ֬ೝ͍ͨ͠߹ɺARMCortex-MͷλʔήοτϘʔυ͕ݸਓతʹ͓͢͢Ίɻɾ࣮ػͷલʹखܰʹࢼͯ͠Έ͍ͨ߹ɺQEMUͰࢼͯ͠ΈΔͷྑ͍͔͠ͳ͍ɻɾArduinoͰಈ͔ͨ͠ࣄྫ͋ΔɻRustͷࠐΈ։ൃͷద༻25
ɾॴ༗ݖγεςϜɿίϯύΠϧͰ͖ͨΒϝϞϦ҆શੑΛอূɻɾCargoɿϏϧυπʔϧɾύοέʔδϚωʔδϟɹςετɾυΩϡϝϯτɾͦͷଞଟ͘ͷػೳɻɾC FFIɿRust㱻Cͷ૬ޓݺͼग़͠Մೳɻ·ͩ·ͩ͋ΔΑɺRustͷັྗ———26
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻऴΘΓ27
ɹҎ߱ʹϫʔΫͷC/C++, RustͷιʔείʔυͷγϛϡϨʔγϣϯ࣮ߦ݁ՌΛهࡌ͠·͢ɻγϛϡϨʔγϣϯ࣮ߦ֬ೝޙʹݟΔ͜ͱΛ͓קΊ͠·͢ɻϫʔΫͷ࣮ߦ݁Ռ28
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs˒1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)29
˒1. ܕΦʔόʔϑϩʔ: val_overflow.*Cͷ߹⇛Cwarning, ࣮ߦՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)30
˒1. ܕΦʔόʔϑϩʔ: val_overflow.*Rustͷ߹⇛ίϯύΠϧΤϥʔ, ࣮ߦෆՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)31
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*˒2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)32
˒2. ະॳظԽมͷࢀর: uninitialized_val.*Cͷ߹⇛Cwarning, ࣮ߦՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)33
˒2. ະॳظԽมͷࢀর: uninitialized_val.*Rustͷ߹⇛ίϯύΠϧΤϥʔ, ࣮ߦෆՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)34
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*˒3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)35
˒3. θϩׂΓ: div_by_zero.*Cͷ߹⇛Cwarning, ࣮ߦՄೳ⇛ྫ֎ൃੜɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)36
˒3. θϩׂΓ: div_by_zero.*Rustͷ߹⇛ίϯύΠϧΤϥʔ, ࣮ߦෆՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)37
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*˒4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)38
˒4. ྻཁૉ֎ΞΫηε: array_index_err.*Cͷ߹⇛C࣮ߦՄೳɻྻཁૉ֎ΞΫηε͢ΔɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)39
˒4. ྻཁૉ֎ΞΫηε: array_index_err.*Rustͷ߹⇛࣮ߦՄೳɻ࣮ߦ࣌Τϥʔɻpanic!Λ࣮͑ߦ࣌Τϥʔ༰͕Θ͔ΔɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)40
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*˒5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)41
˒5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*Cͷ߹⇛Cwarningɻ࣮ߦՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)42
˒5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*Rustͷ߹⇛ίϯύΠϧΤϥʔ, ࣮ߦෆՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)43
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c,Rust*.rs1. ܕΦʔόʔϑϩʔ: val_overflow.*2. ະॳظԽมͷࢀর: uninitialized_val.*3. θϩׂΓ: div_by_zero.*4. ྻཁૉ֎ΞΫηε: array_index_err.*5. ϏοτγϑτΦʔόʔϑϩʔ: shift_overflow.*˒6. Ϗοτγϑτෛͷ: shift_negative.*ϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)44
˒6. Ϗοτγϑτෛͷ: shift_negative.*Cͷ߹⇛Cwarningɻ࣮ߦՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)45
˒6. Ϗοτγϑτෛͷ: shift_negative.*Rustͷ߹⇛ίϯύΠϧΤϥʔ, ࣮ߦෆՄೳɻϫʔΫ(Cͷ͍͋·͍ͳಈ࡞Λମݧ)46
ςʔϚͪ͜Βɹ˞ϑΝΠϧ֦ுࢠC*.c, C++*.cpp, Rust*.rs1. enum, switch: enum_switch.*ɹCͱRustͷίʔυΛൺֱɻɹenumܕͷൺֱɻCͷswitchɾRustͷmatchࣜͷൺֱɻ2. ଟଶ: polymorphism.*ɹC++ͱRustͷίʔυΛൺֱɻϫʔΫ(RustͷϞμϯ͞Λମݧ)47