CppUTestでBoostやSTLを利用する方法

主に自分用のメモとして。

CppUTestを、STLやBoost等、New演算子をオーバーライドして実装しているライブラリと併用するとき発生する問題と、その対策についてです。

経緯としては、こんな感じです。

CppUTestを使ったTDDを行なっている最中、boost::shared_ptrを使おうとしたところ、エラーが出てコンパイルが通らなくなりました。

ヘッダファイルをインクルードしただけで発生していたので、構文ミスでもない模様。

調べたところ、以下のスレッドにたどり着きました。

詳しい説明は以下。

Conflicts with operator new macros (STL!)

It is common for the memory leak detection macros to conflict with an overloaded operator new or with STL. This is because the macro replaces the call to operator new to a call to operator new with __FILE__, and __LINE__. If you overload operator new, it will replace your overloaded definition resulting in a compiler error. This is common when using Standard C++ library (STL).

CppUTestでは、標準でメモリリーク検出機能が動作するようになっているのですが、この機能を、new演算子をマクロとして再定義する形で実装しているようです。STLやBoostのライブラリでは、 new演算子をオーバーライドしているため、このマクロがコンフリクトしてしまうらしい。

解決方法としては、このマクロが定義される前に、対象となるヘッダをインクルードすること。

例えば、まず以下の様な、利用したいヘッダを読み込むヘッダを作り、

  • tests/PreIncludeFiles.h
#ifndef D_PRE_INCLUDE_FILES_H
#define D_PRE_INCLUDE_FILES_H

#include "boost/shared_ptr.hpp"

#endif

Makefileに、Includeするよう記述します。

CPPUTEST_CXXFLAGS += -include tests/PreIncludeFiles.h

gccのオプションは、CPPUTEST_CXXFLAGSCPPUTEST_WARNINGFLAGSCPPUTESTの標準オプション の順番で読まれるようなので、これで回避できる模様。

-include オプションなんて初めて知った。

ちなみに、メモリリーク機能を読み込む前に展開しているので、読み込んだ外部ライブラリのメモリリーク検出はできないようです。

2012年の振り返り

初めて早々、放置気味になっていました。

が、今年は、私にとって、いくつか新しいことに挑戦した年だったので、本当にギリギリなのですが、まとめておこうと思います。

主なトピック

  1. TDD for Embedded C 読書会に参加
  2. TDD in Actionに参加
  3. Interaction 2012を聴講

TDD for Embedded C 読書会に参加しました

初めて参加した、記念すべき勉強会。参加して感じたことなどは、以下の記事にまとめてあります。

私としては、組み込みソフトの開発はまだまだ色々出来るはず、と希望のようなものを得た勉強会でした。

TDD in Actionに参加しました

上記の読書会に参加して、TDDが分かった気になり、調子に乗って参加した、TDD BootCampの派生っぽい勉強会です。

内容としては、お題をペアプログラミングで黙々と実装しつつ、1時間おきに、メンターが前に出て、ライブTDDを行う、というものでした。

ペアプログラミングを初めて体験したのですが、初めての体験により緊張+ようやく慣れてきた程度のJava理解度のダブルラリアットで、なかなか悲惨な結果に。自分の未熟さを思い知りました。

一方で、TDDを最前線で実践されている方の考え方や、アプローチを知る機会となったのは良かったです。

特に、主宰の@kyon_mmさんと@pocketberserkerさんのライブコーディングでは、ドメインの定義やテスト設計から、コーディングに入るまでの流れを生で見せていただき、とても勉強になりました。

また、#なごやこわい を実際に体験し、衝撃を受けました。 #なごやこわい

Interaction 2012を聴講しました

とても記憶が遠いのですが、3/15〜3/17に行われた、Interaction 2012を聴講しました。

インタラクションは、ヒューマンインターフェース系のシンポジウムの一つで、その名前の通り、インタラクション研究の最大の祭典となっています。

特徴としては、デモを中心とした、ポスター形式のインタラクティブ発表がメインになっていることでしょう。あくまでも学会のシンポジウムであり、学術的な話が中心となりますが、作ったものを見せる、という意味で、雰囲気としては、Maker fairに近いと思います。

本当は、16,17と、有給を取って2日見るつもりだったのですが、運悪く仕事のピークと重なってしまい、叶わず。

結局、17日しか聴講できず、しかも、メインとなるは一般公開されていたため、一般参加とほぼ変わらない形になってしまい、参加費をひどく無駄にした気分なったのを覚えています(このシンポジウム、参加費がとても高い)

全体を通して、ヒューマンインターフェイスの世界では、プロダクトのコンセプトが大事になってきていると感じました。

Maker界隈のムーブメントもそうですが、あらゆるものが電子化される現在にあっては、物理的なプロダクトを作る上で、何故今更、物理的なモノとしての、専用のインターフェースに、グラウンドするする必要があるか、という問題を解決する必要が有るように感じました(それ、スマホ使ったWEBサービスで良いよね、に対する解答)

これは、最前衛のヒューマンインターフェース研究だけでなく、デジタル家電等の担い手であるメーカーも、必要に迫られている事だと思います。

ヒューマンインターフェース界隈は、そういう文脈で、とても参考になると思います。

Cygwinのコンソールから秀丸エディタを立ち上げる方法

本日格闘したネタについて、忘れないうちにメモしておきます。

Ubuntuを始めとして、Linuxデスクトップのディストリビューションが数多くあり、Unix互換機としてMacが支持される中、開発環境として、Windowsを選択する理由は限りなくなくなりつつあります。

今あえて開発環境として、Windowsを選択する理由は何か、と言えば、秀丸エディタの存在以外ないでしょう(なぜUbuntuやMacに秀丸エディタがないのだ…)。

というわけで、Cygwinのコマンドコンソールから、秀丸エディタを立ちあげて、愉快に開発を行うためのbashスクリプトを書きました。

コード例

以下bash関数を、.bash_profileに書き込めばOKです。 秀丸エディタのパスは、環境によって書き換えが必要です。

hidemaru()
{
	local options
	local path
	while [ -n "$2" ]
	do
		options+="$1 "
		shift
	done
	path=`cygpath -w "${1}"`

	/cygdrive/c/Program\ Files/Hidemaru/Hidemaru.exe $options $path &
}

ちょっとトリッキーなコードですが、要するに、最後の引数を、cygpathを使って、 CygwinのPATHからWindowsのPATHに変換しているだけです。 いろいろやってみた結果、これが一番シンプルにかけたと思っています。

使い方

基本的に、コマンドライン上での利用方法同様です。オプションなども使えるはずです。

 $ hidemaru オプション... ファイルパス

その他

同様にして、WindowsのGvimを、Cygwinから呼び出すこともできます。

wingvim()
{
	local options
	local path
	while [ -n "$2" ]
	do
		options+="$1 "
		shift
	done
	path=`cygpath -w "${1}"`

	/cygdrive/c/Program\ Files/vim/gvim.exe --remote-tab-silent $options $path &
}

既にGVIMが起動していた場合、タブとして起動するようにしています。

これで、Cygwin上でGitやらgccやらPythonやらを使いつつ、秀丸エディタと連携できます。

have fun programming.

Test-Driven Development for Embedded C 読書会に参加しました。

今年2月より始まった、Test-Driven Development for Embedded C(以下TDD for EC)の読書会が、今月始めに、めでたく最終回を迎えました。 全8回(うち1回は体調不良のため欠席)、10人前後のメンバーで、1年弱ほど続けてきました。

きっかけとモチベーション

読書会を知ったのは、Twitter上でした。フォローしていた方が呟かれていたのですが、TDD関連でその方を知り、フォローしたので、TDDについて追いかけていたことがきっかけでしょう。

TDDについて興味を持った理由はいくつかあります。

1. テスト自体への興味

私は、昨年2011年度卒として組み込み系プログラマになりました。プログラムの柔軟性や堅牢性については学生時代比較的意識していたのですが、テスト手法については、殆ど知識が なく、体系的な知識が欲しかったのです(これは現在進行形)

2. 開発スタイルへの疑問

実装して動かすまでのオーバーヘッドがかかりすぎることに悩んでいました。私が従事している開発は、基本的にモジュール単体での動作確認ができないため、他のモジュールと結合していない 部分の修正であっても、全モジュールをリンクしたプロダクトの状態で動作確認を行う必要があります。結果として、

  • ほんの一行変えただけでも、ビルドに5分以上かかる
  • ユースケースレベルの動作確認しか出来ない(単体動作用の仕組み一応はある)
  • コーディング中に誤りがあっても、原因を検出しにくい

等、開発環境としては厳しいことになっています。(私自身が、まず動かしてみて、修正していくというスタイルだったため尚更)

もっとテストしやすくて、もっと実装しやすくする方法があるはずだ、と、WEBを探し回っていたところ、出会ったのがTDDであり、『TDD for EC』でした。

書籍について

TDD for ECは、C言語を用いた組み込みソフトを、TDDによって開発するためのノウハウが記載されている本です。

Test-Driven Development for Embedded C (Pragmatic Programmers)

Test-Driven Development for Embedded C (Pragmatic Programmers)

内容としては、TDDの紹介から、利用するTestingフレームワークの紹介、C言語を用いた組み込み向けTDDの例、TDDで重要となる概念の説明(Test double, Mock等)と、TDDについて、網羅的に 説明しつつ、テストしやすい設計や、レガシーコードへの取り組みなど、TDDから一歩踏み込んだ内容になっています。 C言語に特化していますが、TDDの解説書としても、遜色ないと思われます(他の本を読み込んでいないのではっきりと断言できない)

導入部のコードの例が丁寧に書かれているのもTDD初心者にはありがたかったです。1ステップごとのコードが提示されているので、写経しながら、TDDのサイクルの感覚が分かりました。

また、私としては、Chapter 11. SOLID, Flexible, and Testable Designsで展開された、OOPの重要な概念であるSOLID原則を、PureなC言語で実装する方法がとても刺激的でした。 非オブジェクト指向言語であるC言語であっても、良い設計原則として、オブジェクト指向での原理原則が適用できるはずだと、これまで考えていたのですが、実際にどう適用するか、 私の中で回答がなかったのです。制約はあるものの、今回明快な回答が得られ、私の中の「良い設計」に対する認識が深まりました。

読書会に参加して得られたもの

本を読み得られたものは前節に書きましたので、読書会で副次的に得られたものについて書きます。

1. 社外のエンジニアと話ができた

読書会には、組み込みソフトを開発されているソフトエンジニアの方々が参加されました。

  • 職場の環境
  • 開発のスタイル
  • 最近の技術動向
  • 組み込み業界あるある

など、いろいろお話ができたのが良かったです。組み込み系の話は、WEB上では、あまり見聞きする機会がないので、とても興味深かったです。

同じ組み込みと言っても、開発の方法が一つではないし、環境も違うのですね(私の職場ほど旧態依然としているのは珍しいのか?)

2. 英文を読む習慣ができた

学生時代には、英語の論文などを読む機会もありましたが、就職してからは、殆ど英文を読む機会がありませんでした。今回、読書会に参加し、ある程度習慣化できたと思います。 今度久しぶりにTOEICでも受験してみようかと思います。

終わりに

私自身は、組み込み系ソフトと自動化テストは、本来相性が良いはずであると考えています。 組み込みソフトは、基本的にハードと仕様が変わらない限り、派生開発として、既存のソフトを利用します(場合によっては十年単位で)。
加えて、最近は出荷後も、ソフト改修やOSアップデートなどで、継続的に開発を行う必要があるケースも多く、自動化テストや、それを用いたCIなど 簡易に弊害確認が行える仕組みは本来とてもニーズがあるもののハズです。

ただ、現状、すでに動くソフトがあり、修正後の動作確認も人力で賄えるレベルであり、レガシーコードへの、自動化テストの導入には、かなりのコストが かかるため、主流にはなっていないようです。

ですが、組み込みソフトが大規模化し、メンテナンスの比重が高まっている(そしてメーカーに人力でのテストを行うための体力がなくなってきている)現在、 TDDを含めた、自動化テストのムーブメントは組み込み業界でも無視できないようになってきているのではないでしょうか。

ブログを始めました。

勉強会で知り合った方に勧められたので、ブログをはじめてみました。
以前、日記めいたことを、別の場所で公開していたことはあったのですが、 最後に書いたのはもう5年ほど前。隔世の感があります。 このはてなブログに関しても、あまりにも簡単に開設でき、驚いています。

タイトルのキャリングビークルとは、大学時代の恩師から教わった概念で、 "アイディアを載せるための乗り物"という意味です。 様々な仮説を検証するための、汎用的なプロトタイプというニュアンスが 近いでしょうか。私のいた研究室では様々なロボットを総称して、こう呼んでいました。

タイトルに見合うような、技術的な実践や、考えたことを記録していきたいと思います。