SlideShare uma empresa Scribd logo
1 de 32
Baixar para ler 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++!!!

Mais conteúdo relacionado

Mais procurados

Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
 

Mais procurados (20)

すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
できる!並列・並行プログラミング
できる!並列・並行プログラミングできる!並列・並行プログラミング
できる!並列・並行プログラミング
 
.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
C#でわかる こわくないMonad
C#でわかる こわくないMonadC#でわかる こわくないMonad
C#でわかる こわくないMonad
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
 
C#で速度を極めるいろは
C#で速度を極めるいろはC#で速度を極めるいろは
C#で速度を極めるいろは
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
 

Semelhante a 組み込みでこそ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
 

Semelhante a 組み込みでこそ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からのメッセージをお読みください
 

Último

Último (7)

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 

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