SlideShare a Scribd company logo
1 of 32
Download to read offline
組み込みでこそ
C++を使う100の理由
Aiming 大阪社内勉強会
2012-06-11 @kikairoya
喋ること
•   C滅びろ
•   C滅びろ
•   C滅びろ
•   C滅びろ
•   C滅びろ
「Cを使う必然性」の幻想
•   C++使うと遅くなるしCでいいよ
•   …同じならCでよくね?
•   いや例外とかでかいじゃん
•   templateとかよくわかんないし
C++使うと遅くなるしCでいいよ
• そうでもない
• 同じことを実現しようとすれば、ほぼ正確に同じだけ
  の命令数が必要
   – Cで書いてもC++で書いても生成コードサイズは
     大して変わらない(RTTIと例外テーブルは除く)
• 20年前の昔なら兎も角、21世紀も10年過ぎた現在
  ではJavaですらCより速い場合がある
「C++遅い」の主要因
• 無意味な仮想関数
   – dynamic polymorphismを使わないなら要らない
• newの乱発
   – Cと同じように単にスタックに配置すればいい
• SjLj例外ハンドリング
   – Dw2例外ハンドリングを使うか、OFFにする
おまけ:Javaのパフォーマンス
• http://blog.cfelde.com/2010/06/c-vs-java-
  performance/ とか
     g++ 4.3
        vs
  Sun Java HotSpot VM, version 1.6.0_20
…同じならCでよくね?
• んなこたない
• C++でしか出来ないことはあるけれど、Cでしか出来
  ないことはほとんど無い
   – C99の複合リテラル・名前付き初期化くらい
   – どちらもC++で似たような機能は実現可能
   – C89に限定すれば事実上「全く」無いと言える
いや例外とかでかいじゃん
• そげなことない
• 不要ならOFFにすればいいだけ
• RTTIも同様
• 例外飛ばしてたらリアルタイム性守れない場
  合があるので、その場合はOFF
• 例外無くてもデストラクタは正しく走るので、リ
  ソース管理も安全安心
templateとかよくわかんないし
• 面倒な部分はライブラリ側に全部隠せます
• エラーコードは確かに量多いですが…
  実行時に不思議な挙動をするか
  コンパイル時に説教されるか
  どっちがいいですか?
• コンパイル通した時点でデバッグ終了が理想
  – 現実は厳しいけれど、コンパイラが見つけ
    てくれるエラーの量はCとは段違い
便利で危険なprintf
• printfって便利だけど危ないよね…
• sizeof(int)==2の環境だと特に問題が顕在化
  しやすい
• それC++なら型安全に出来るよ
• ntfmtとか
• cprintfとか
printfの罠
• たとえばこんなコード

extern int g_value_for_something;

void logger() {
  printf("value:%d¥n",
   g_value_for_something);
}
printfの罠
• 「intが16ビットですぐ溢れるからlongにしよう」

extern long g_value_for_something;

void logger() {
  printf("value:%d¥n",
   g_value_for_something);
}
printfの罠
• 「intが16ビットですぐ溢れるからlongにしよう」

extern long g_value_for_something;

void logger() {
        !!!フォーマット指定子を変え忘れた!!!
  printf("value:%d¥n",
   g_value_for_something);
}
constexprなprintfなら
• 変え忘れたらコンパイルエラーにできます
extern long g_value_for_something;

void logger() {
  cprintf("value:%d¥n",
   g_value_for_something);
}
   FORMAT_ERROR_format_specifier_d_takes_int_but_
   given<T>::fail() [with T = long int]
void *パレード
• Cで汎用コンテナやアルゴリズム作ろうとする
  と、void *の山になりますよね…
• ライブラリで閉じていればまだいいけど、ユー
  ザコードでvoid *からキャストする必要がある
• それC++なら型安全に出来るよ
• STLとか
ビットフィールドの恐怖
• 組み込みでも一番低いレイヤではハードウェ
  アレジスタを叩く必要がある
• Cだとよくビットフィールド使うけれど…
• GCCでは間違ったアドレスにアクセスすること
  がある!
ビットフィールドの恐怖
• こんなありふれたコードから…

volatile struct {
      volatile unsigned int a: 8;
      volatile unsigned int b: 4;
} bitfield;

int main() {
   bitfield.a = 1;
}
ビットフィールドの恐怖
• こんな恐ろしいコードが!!!



  movl   $1, bitfield+3(%rip)
  ↑ (bitfield+3)番地に32ビットで書き込み
ビットフィールドの恐怖
• 組み込みでも一番低いレイヤではハードウェアレジ
  スタを叩く必要がある
• Cだとよくビットフィールド使うけれど…
• GCCでは間違ったアドレスにアクセスすることがあ
  る!(注: BTSにパッチ投稿済)
  – ベンダコンパイラでもコンパイルオプション一つで
    ビットオーダーが変わることがある
• それC++なら安全でポータブルに出来るよ
ビットフィールドの克服
• こんなコードを用意しておけば…

struct addr_t { size_t addr; };
template <typename T, int H, int L = H>
struct ioaccess_bit {
 template <int = bitsizeof(H)-1, int = H>
 struct gen_mask {
  static constexpr T value = (~static_cast<T>(0)<<H+1) ^ (~static_cast<T>(0)<<L);
 };
 template <int h>
 struct gen_mask<h, h> { static constexpr T value = ~(~static_cast<T>(0) << L); };
 constexpr ioaccess_bit(addr_t addr): addr(addr.addr) { }
 size_t addr;
// continue
ビットフィールドの克服
• こんなコードを用意しておけば…

// continued
 size_t addr;
 static constexpr T mask = gen_mask<>::value;
 constexpr T omit_bits(T x) { return x & ~mask; }
 constexpr T extract_bits(T x) { return (x & mask) >> L; }
 constexpr T shift_bits(T x) { return (x << L) & mask; }
 volatile T *get_addr() const { return reinterpret_cast<volatile T *>(addr); }
 operator T() const { return extract_bits(*get_addr()); }
 ioaccess_bit operator =(T v) const {
     T tmp = *get_addr(); *get_addr() = omit_bits(tmp) | shift_bits(v); return *this;
 }
};
ビットフィールドの克服
• こんな定義で…
struct { struct reg_t { struct can_mb_id_t {
   struct bit_t {
    static constexpr size_t base = 0x00090200;
    size_t offset;

        ioaccess_bit<uint32_t, 31> IDE = addr_t{base+offset};
        ioaccess_bit<uint32_t, 30> RTR = addr_t{base+offset};
        ioaccess_bit<uint32_t, 28, 18> SID = addr_t{base+offset};
        ioaccess_bit<uint32_t, 17, 0> EID = addr_t{base+offset};
    bit_t(size_t off): offset(off) { }
   } BIT;
 } ID; };
 reg_t operator[] (size_t n) { return reg_t{{{n}}}; }
} MB;
ビットフィールドの克服
• こんなコードが書けます。

int n = MB[0].ID.BIT.SID;
MB[0].ID.BIT.EID = 12;
assert(MB[1].ID.BIT.IDE == 1);
割り込みマスク
•   割り込みを一時的にマスクしたいこと、有りますよね
•   sti()/cli()でいいんだけど、もしネストされてたら…?
•   というかcli()とか呼ぶの忘れますよね
•   それC++なら自動化できるよ
単純な例
struct lock_interrupt {
  lock_interrupt() : masked(get_imask_ccr()) {
    set_imask_ccr(1);
  }
  ~lock_interrupt() {
    set_imask_ccr(masked);
  }
  bool masked;
};

// in some function...
  lock_interrupt lk;
  // do critical action, let's forget unmask interrupt flag!
}
醜い固定小数点演算
• Cで実数演算する場合は…
   – double/floatを使う
   – 整数を自前でシフトして使う
   – 固定小数点演算ライブラリを作る
• 固定小数点を使う場合、演算子使えなくて大変です
  よね…
• それC++ならスマートに出来るよ
美しい固定小数点演算
fixed calc_1(             void calc_1(
  fixed v,                 fixed *result,
  fixed u                  fixed *pv,
){                         fixed *pu
  v *= 1.5f;              ){
  return v + calc_2(u);    fixed tmp;
}                          fixed_from_float(&tmp, 1.5f);
                           fixed_mul(pv, pu, &tmp);
                              calc_2(&tmp, pu);
                              fixed_plus(result, pv, &tmp);
                          }
美しい固定小数点演算
• 演算子オーバーロードは用法・容量を守って
  正しく使いましょう。
まずは簡単なところから
• たとえC++の機能を使っていなくても、拡張子は.cpp
  にしましょう
• マクロで定数やインライン関数を書くのはやめて、
  static constやinlineを使いましょう
• テンプレートを「書く」のは慣れてからで十分
• 千里の道も一歩から
  C++マスターもBetter Cから
おしまい
• Let's C++!!!

More Related Content

What's hot

20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
増田 亨
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
 

What's hot (20)

C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
 
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門1076: CUDAデバッグ・プロファイリング入門
1076: CUDAデバッグ・プロファイリング入門
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
Map
MapMap
Map
 

Similar to 組み込みでこそC++を使う10の理由

C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
digitalghost
 

Similar to 組み込みでこそC++を使う10の理由 (20)

競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
マーク&スイープ勉強会
マーク&スイープ勉強会マーク&スイープ勉強会
マーク&スイープ勉強会
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
C++ tips4 cv修飾編
C++ tips4 cv修飾編C++ tips4 cv修飾編
C++ tips4 cv修飾編
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Hupc 1
Hupc 1Hupc 1
Hupc 1
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語る
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
C++11のつかいかた
C++11のつかいかたC++11のつかいかた
C++11のつかいかた
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 

Recently uploaded

Recently uploaded (12)

Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 

組み込みでこそC++を使う10の理由