Mais conteúdo relacionado
Semelhante a 組み込みでこそC++を使う10の理由 (20)
組み込みでこそC++を使う10の理由
- 2. 喋ること
• C滅びろ
• C滅びろ
• C滅びろ
• C滅びろ
• C滅びろ
- 3. 「Cを使う必然性」の幻想
• C++使うと遅くなるしCでいいよ
• …同じならCでよくね?
• いや例外とかでかいじゃん
• templateとかよくわかんないし
- 5. 「C++遅い」の主要因
• 無意味な仮想関数
– dynamic polymorphismを使わないなら要らない
• newの乱発
– Cと同じように単にスタックに配置すればいい
• SjLj例外ハンドリング
– Dw2例外ハンドリングを使うか、OFFにする
- 21. ビットフィールドの恐怖
• 組み込みでも一番低いレイヤではハードウェアレジ
スタを叩く必要がある
• Cだとよくビットフィールド使うけれど…
• GCCでは間違ったアドレスにアクセスすることがあ
る!(注: BTSにパッチ投稿済)
– ベンダコンパイラでもコンパイルオプション一つで
ビットオーダーが変わることがある
• それC++なら安全でポータブルに出来るよ
- 22. ビットフィールドの克服
• こんなコードを用意しておけば…
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
- 23. ビットフィールドの克服
• こんなコードを用意しておけば…
// 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;
}
};
- 24. ビットフィールドの克服
• こんな定義で…
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;
- 26. 割り込みマスク
• 割り込みを一時的にマスクしたいこと、有りますよね
• sti()/cli()でいいんだけど、もしネストされてたら…?
• というかcli()とか呼ぶの忘れますよね
• それC++なら自動化できるよ
- 27. 単純な例
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!
}
- 28. 醜い固定小数点演算
• Cで実数演算する場合は…
– double/floatを使う
– 整数を自前でシフトして使う
– 固定小数点演算ライブラリを作る
• 固定小数点を使う場合、演算子使えなくて大変です
よね…
• それC++ならスマートに出来るよ
- 29. 美しい固定小数点演算
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);
}