fc2ブログ

AIがもたらすプログラミングの未来

ずいぶん前に使っていたものの、かなりの間放置していたこのブログサイトですが、自分のメモ用にまた使ってみます。

最近は仕事が開発から少し離れたためにコード書く機会が少なくなってますが、本ブログのタイトルの”職業としてのプログラミング”というのを考えたときに、charGPTに代表される生成AIのインパクトはものすごいですよね。
ロジックをコード化するだけなら、無料のchatGPTでも、中級者以上のことをやってのけてくれる今、初心者でもプログラミング身に付けて高収入といったような眉唾というか詐欺まがいのビジネスと、そのレベルでプログラマとしてやっていこうとする開発者はほんとに厳しくなってくると思います。ローコード、ノーコードといっているレベルでは、ある意味プログラミング言語の形態が変わった程度で、そんな大きなインパクトは感じてなかったですが、それとは大きく違います。

じゃあ、AIによってプログラマは不要になるのかというと、不要になるというよりは必要なスキルの比重が大きくかわるのだろうなと思います。別に新しいことを言っているわけでもなく、世の中で言われている話ですが、どう作るかより、何をつくるかのところでの発想やアイデアに大きな付加価値がおかれるようになるイメージでしょうか。そのためには、細かいプログラミングロジックや、数学の知識などは今までもほど重要ではなくなるので、ある意味では、ソフトウェア開発のハードルはさがり、その門戸は広く開かれることになります。

そういう世界が来たときに、今のプログラマを生業としている人たち、あるいは、プログラマを目指そうとしている人たちはどうすべきなのでしょうか。よく言われるようにAIを使いこなすスキルを身につけるということなのでしょうが、そもそもそうなったときに、今までのスキルが生きないのであれば、そこに無理にこだわる必要もないし、ある意味、別の可能性をさぐっていく必要もあるのかもしれません。

いずれにしても、ソフトウェア開発がいろんな人に開かれる未来は、イノベーションが今まで以上に加速すると思います。それ自体は非常に楽しみですが、そんな時代の中で”職業としてのプログラミング”がどうなっていくのか、その中でどう自分の価値、自分が生み出す価値を作っていくべきなのかは、従来の概念にとらわれず、よくよく考えていきたいところです。

写真にEXIF(撮影日とGPS情報)をあとから追加する - exiftool

世界はいつも、決定的瞬間だ。
森山大道

以前AVCHDでとった動画や、BD/DVDレコーダでDVDにバックアップした動画をGoogleフォトにアップロードする方法書いたのですが、写真データのexifデータを編集する方法について、自分のメモもかねて残しておきます。

最近はスマホで写真をとることがおおいので、その場合は、GPS含めたEXIFデータが入ったJPEGが手元にあるので何の問題もなりのですが、以下のようなケースでは、写真の管理や検索のために、あとからEXIF情報を追加したい場合があります。
  • カメラにGPSがついてない
  • 子供の学校の写真等、印刷した写真として購入できるけどデータはもらえない
ということで、EXIFを一括編集、特に日付とGPS情報が編集できるツールを探しました。

家の環境がMacなので、EXIF編集ツール何かないかとググると、高機能なもので無料トライアルもできるものとしてはGraphicConverterというソフトがあたります。 有料ですが、とりあえずトライアルも可能です。実際、試してみると確かに高機能なのですが、複数写真のEXIFを一括編集したいという目的にはちょっとあいません。

EXIF編集だけなら、Photo Meta Editというツールが使えそうですが、有償なのでちょっと考えてしまいます。
結局たどり着いたのはexiftoolというperlで書かれたCUIツールです。先のGraphicConverterもEXIFの参照・修正にはこちらのツールを使っているようです。 CUIですが、一括編集するにはその方が融通も効くので結局便利です。使い方は以下を参考にさせて頂きました。
これで、EXIFもつけた状態でGoogleフォト等で管理できるようになりました。

【関連記事】
googleフォトアップロード用に動画ファイルの変更日を作成日にあわせる
DVDで保存していた撮影動画をGoogleフォトで管理

Androidではアイコンに未読数バッジがでない? - UIと特許

模倣するほうが楽かもしれない。でもそんなことをしても世界はよくならない。
スティーブ・ジョブズ

スマホをiPhoneからAndroidに買い替えた時に気づいたUIに関するメモ。

買い替え前はiPhone 5sを長らく使っていてそれほど不満もなかったのですが、そろそろ気分を変えるためにAndroidにまた戻そうかなと思ったのがその理由です。なので、特にこれがいいという機種もなかったのですが、休日にdocomoショップで物色した結果、買い替えたのがdocomoのLG V20 proです。他と比較してバッテリーの持ちはイマイチっぽいものの、スペック的にはかなり高く、大きさも丁度よかったのでこれに決めました。バッテリーの持ちは前評判通りですが、今のところは概ね満足しています。

iOSにあって、Androidに足りないもの・・・

iPhone 5sに変える前は、Androidを長らく使ってたので、違和感なく使えるかなと思ってたのですが、ひさびさにAndroidさわると違和感がかなりあります。特に、物理的なホームキーがないのがなんとも使いにくい。まぁ、慣れの問題だとは思うものの、すっかりiOSに慣れてしまっていたことに今更ながら気付かされました。まぁ、その辺はさわっているうちに、だんだん慣れてくるのですが、どうしても使いにくく感じてしまったのが、LINEや電話、メールの新着/未読のバッジ表示がないこと!アイコンの右肩にあるアイツです。
badge

iOSだと当たり前のように表示されていたバッジがないので、通知内容の確認をあとで見たい時や、気づいていない時の確認が大変不便になりました。なくなってはじめて気づくありがたみとはこの事です。

しかし、こんな便利なものが何故ないんだと不思議に思って、まわりのAndroidユーザーの人に聞くと「そういえば昔は出てた気もするけど、最近ないな」と。こういう話を聞くと疑われるのはAppleのUI特許。で、ちょっとググるとそれらしきものがQuoraにありました。
ここに書かれているAppleのUS特許USはこちら。 確かに、バッジ表示に関わる特許のようですね。他にもあるのかもしれませんが、少なくとも何らかの知財的な要因ではありそうです。

なお、AppleとAndroidを巡るUI特許に関しては、スクロールが終端であることをはねかえるアニメーションで示すいわゆるbounce back特許、ロック画面をスライド操作で解除するslide-to-unlock特許が有名ですね。これらの回避のために、Androidスマホのスクロール終端やロック解除は、それぞれいろんな亜流バリエーションが作られていて、なかなか楽しかったです。以下のSlideShare資料がまとめられていてわかりやすかったですね。

とはいえ、Androidでもアイコンバッジを使いたい

そうはいっても、やっぱりアイコンバッジ表示を使いたい。方法はないの?と思って調べるとありました。Nove Launcher Primeという有料のホームアプリを入れて、その拡張であるTeslaUnred for Nova Lancherを入れば、その一部としてバッジ表示ができるとのこと。
TeslaUnreadForNovaLancherPrime

さすが、Andorid。ホーム画面もカスタマイズできるというのはやっぱりすばらしい。なお、このNova launcher Primeは無料版もありますが、バッジ表示対応しているのは有料版のPrimeのみのようです。ちなみに、V20 Proの場合は、標準のHOMEはdocomo LIVE UXですが、バッジ表示がなくてもはるかに使いよくなります。まぁ、このあたりは好みの世界かもしれませんね。

Apple(iOS)とAndroidの違いというかせめぎあいを感じる一件でしたが、どちらかの世界だけにいるとなかなか見えにくいところなので、たまに機種変更するのも面白いですね。
(スマホそのものの使い勝手は犠牲にしたくはないですが。。。)

4756151515 黒船特許の正体-Apple、Amazon、Googleの知財戦略を読み解く- (OnDeck Books(Next Publishing)) 知財戦略のススメ コモディティ化する時代に競争優位を築く

ソフトウェアメトリクスは誰のもの?

偉人と凡人の別は一言にして尽くすべきのみ。かれは人生を簡単にする者なり。これは人生を複雑にする者なり。
高山樗牛

ソフトウェア開発の現場では、成果物やプロセスの評価、見積もりのために様々なメトリクスを収集します。メトリクスと一口でいっても、プロダクトメトリクスから、プロセスメトリクス、リソースメトリクスなど様々ありますが、主要なものでは、生産性を示す指標としてソースコード行数をかかった工数でわったKSTEP/人月のようなものや、その他にも、ソースコード中のコメントの割合を示すコメント率、欠陥数をソースコード規模で割った欠陥密度(バグ密度)などなど、その多くがソースコードのステップ数、行数がベースになっています。
こういったメトリクスメトリクスを測るということ自体は、プロダクトやプロセスを客観的に眺めるために有用ではあるのですが、その特性を理解しておかないと間違った指標として使われることがあります。

ソースコード行数という脆い足場

ソフトウェア開発の現場でよく使われるKSTEP/人月ですが、なんとなく高い方が良いと思われがちかもしれません。果たしてそうでしょうか?実装されたソースコードが同じであれば確かにその通りなのですが、差分開発なのか新規開発なのか、GUIアプリケーションなのか、デバイスドライバなのか、あるいはアルゴリズム実装なのかなど、その特性によって同じ難易度であってもソースコードの開発規模(新規コード or 修正コード)は大きく変わります。さらには、同じ機能実装であっても、プログラマのスキルによって、コードサイズは大きく変わります。例えば、優れたプログラマであれば数百行程度のロジックであっても、スキルの低いプログラマではその何倍もの可読性や効率の悪いコードを書くことがあります。これら両方が1ヶ月かかって開発したコードであったときに、後者の方が生産性が高いというのはありませんよね。つまり、ソースコード行数を基準値にしたメトリクスというのは、絶対的な指標としてはなかなか使いにくいパラメータです。特に、生産性の場合、優れたプログラマほど、少ないコード量を少ない期間でしあげることになるので、スキルの低いプログラマが冗長なコードを長時間かけて書いた時と同じような指標になってしまいます。欠陥密度(欠陥数/ソースコード行数)も同じような課題があります。

コメントは多い方がいいのか?

それでも、バグや開発工数は少ないに越したことはないとはいえますが、コメントとなるとそもそも多い方がいいのか少ない方がいいのかというところから意見が別れるところです。現場によっては、不要なコメントが山のように入っているコードがありますが、こういうコメントは害悪でしかありません。コメントないと分からないような実装になっているか、あるいは、無意味なコメントか。このあたりは随分前の投稿にも書きましたが、個人的には、基本的には極力書かない(書かずともわかる)というスタンスにすべきと思いますので、コメント率は少なめ(20%以下くらい)になるのが良いと思います。この辺の話はよく議論のタネになりますが、どちらの意見にも共通するのは、ソースコードを読む人が必要な情報が必要十分な形で伝わるようにするのが大事という点かと思います。

メトリクスをとっても意味はない?

ソースコード行数をはじめとして、ソフトウェアメトリクスというのはその基準値そのものがあいまいであったり、単純な量だけでは評価できないという性質をもっています。なので、異なる種類のプロジェクトを比べて、どっちが良いとか悪いとか、あるいは、絶対的な目標値を設定するということには使えません。この辺が正しく理解されず、間違った運用(いろんなプロジェクトを十把一絡げにして目標値を決めるとか、全く別のプロジェクトの成果をベースに見積もりをするとか)がされるのは非常に危険です。

では、全く約に立たないかというとそうでもありません。同じようなスキルのメンバーが同じようなソフトウェアを作るのであれば、実績としてのメトリクスを使った見積もりは有効でしょうし、メトリクスをベースに品質を評価(予測)することもできるでしょう。また、別々のプロジェクトが単純比較はできなくても、メトリクス値からプロジェクトの中で何が怒っているのかを予測することもできます。例えば、スキルの低いメンバーと高いメンバーで生産性(KSTEP/人月)がかわらないのであれば、スキルの低いメンバーのソースコードが冗長という可能性が高いのかもしれません。コメント率が著しく低い傾向があったら、いくつかファイルを見ることで、本当に優れたコードでコメントが最小限なのか、単にコメントも何もないわかりにくいコードなのかをチェックするきっかけになります。

このように、単純にメトリクスの数値を絶対的な指標として盲信するのではなく、その裏にある背景(コード品質や担当者のスキル)を把握するツールとして利用することで、メトリクスの価値が発揮されます。

4903729958 4873115655 4822282422

mallocの落とし穴 - 組み込みLinuxでのmemory overcommit

天災は忘れた頃にやって来る
寺田寅彦

組み込みLinuxにおけるメモリ確保のエラーハンドリングに関するお話。

Linuxにはmemory overcommit(オーバーコミット)と呼ばれる仕組みがあります。簡単にいうと、メモリ割り当ての段階では、仮想アドレス空間だけをわりあてて、実際に使われる段階で、実メモリを割り当てるというものです。メモリ割り当て時には、実メモリはまだ割り当てられないので、実際の物理メモリの容量以上のメモリ割当てが行われることを許されることになります。

実例を見た方が早いので、例えば以下の例。
#define BLK_NUM 100
#define BLK_SIZE (100 * 1000 * 1000) /* 100MB */

int
main(int argc, char* argv[])
{
  int i;
  char* blk[BLK_NUM];

  for (i = 0; i < BLK_NUM; i++) {
    blk[i] = malloc(BLK_SIZE);
    assert(blk[i] != NULL);
  }

  return 0;
}
mallocでヒープを100MBx1000 = 10GB取得していますが、これをコンパイルしたものを実メモリ128MBのLinuxで実行してもおそらくassert()にはひっかからず正常終了します。これはmallocの段階では、仮想メモリのみが割り当てられ、実メモリが割り当てられていないためです。つまり、アドレス空間を超えるような異常なmallocでもしない限り、mallocの戻り値は常に成功(NULL以外)で返ります。実際、malloc完了したところでプロセスのstatus値を見てみると、VSSは増えているものの、RSSは増えていないことが確認できると思います。(returnをwhile(1)やsleepにでもして、psやprocでみて見るとよくわかります)。

では、以下の分をmallocのループの下に加えるとどうなるでしょうか。
  for (i = 0; i < BLK_NUM; i++) {
    memset(blk[i], 0, BLK_SIZE);
  }
今後は、メモリが10GBもないようなシステムでは、実行途中に以下のようなログとともにプロセスが強制終了したと思います。
01:00:00 xxxxx kernel: Out of memory: Killed process 10000, UID 100, (xxx)
memsetによって書き込みが発生する段階で、実メモリが割当りあてられ、この時点でプロセスがkernelに強制的にkillされてしまいます)。いわゆるOOM-killer(out of memory killer)という仕組みで、カーネルがメモリを大量消費していると思しきプロセスを強制的にkillする仕組みです。教科書的な「mallocでは、戻り値見てメモリを取得できたか確認しましょう」というのはこの場合通用しないのです。さらに、困ったことに、必ずしも犯人とは限らないプロセスが殺される場合もあります。これだと、個別のユーザーアプリケーション側では対処のしようがありません。

そういうわけで、かなり不評なしくみでもあり、memory overcommitの仕組みについては、仕様バグだという言われようもよく見かけます。そういうことで、最近(というかkernel 2.6からなので結構前から)のLinuxには、overommitの挙動を変更する仕組みがあります。具体的には、sysctl、もしくは、直接proc/sysに値を書き込むことで設定を変更できます。以下、procのman pageから引用、
/proc/sys/vm/overcommit_memory
 このファイルにはカーネル仮想メモリーのアカウントモードが書かれている。 値は以下の通り:
  0: 発見的なオーバーコミット (heuristic overcommit) (これがデフォルトである)
  1: 常にオーバーコミットし、チェックしない。
  2: 常にチェックし、オーバーコミットしない。

/proc/sys/vm/overcommit_ratio (Linux 2.6.0 以降)
 この書き込み可能なファイルは、 オーバーコミットできるメモリーの割合をパーセントで定義する。 このファイルのデフォルト値は 50 である。 /proc/sys/vm/overcommit_memory の説明を参照。
上で、「犯人と思しきプロセス」がkillされるというのが、ここでいうheuristic overcommitというやつですね。どの閾値でoom-killerが呼ばれるかは、 以下の式になります。
CommitLimit = (total_RAM - total_huge_TLB) * overcommit_ratio / 100 + total_swap
組み込みでmallocでとったメモリを確実に確保したいというのであれば、overcommit_memory=2にしてovercommit_ratioを100に近い値にしておけば、基本的にはmallocでNULL以外がかえってくれば、そのメモリは使えるというこが一応保証されることにはなります。

では、組み込みの場合は、overcommit_memory=2を使うべきなんでしょうか?

残念ながらそうとは言い切れません。仮想メモリとして確保した分だけ、実メモリも消費する(実際割り当てられないとしても総和はこえないようコントロールされる)ということになると、以下のような場合に相当の実メモリが必要になります。
  • 各プロセス、スレッド毎のスタック用メモリ
    • 通常スレッドあたり2MB
    • 通常のスレッドならそこまでメモリは使わないのでovercommit=0なら必要量のpageのみが実メモリとして割り当てられるが、overcommit=2ならまるまる必要になる。
  • forkする際のfork元プロセスが使用しているメモリ
    • 通常、forkして時にはfork元プロセスのメモリ空間がコピーされるが、いわゆるcopy on writeという仕組みで、書き込みが行われない限りは、この段階では実際のメモリコピーは発生しない。
    • overcommit=2だと、その時点で実メモリの容量も予約されてしまう
    • 結果としては、fork(あるいは、中でfork実行するsystem関数など)が失敗することがある。

メモリ容量が少ない組み込みでは、こういう隠れた予約メモリがばかにならないので、結果としてovercommit=2で使うのはなかなか厳しいのではないかと。言い換えると、overcommit memoryという仕組みがあるおかげで、こういうケースにもうまく対応できているのだと考えられます。

じゃあ、一回メモリ不足はどうやってハンドリングしたらいいんだという話になりますが、基本的には組み込みなんだからメモリ使用量くらいちゃんと把握しましょうというのが基本ですが、エラー検出の方法としては、メモリ総量をwatchして不適切なプロセスがいればkillする、あるいは、リブートさせるという仕組みを自分でいれる方法になるのかと思います。ちなみに、oom-killerで中途半端にシステムを混乱させるくらいなら、kernel panicに落として、watchdogリセットにでももっていきたいということであれば、以下のproc設定(manpage引用)も検討候補になります。
/proc/sys/vm/panic_on_oom (Linux 2.6.18 以降)
 このファイルは、メモリー不足時にカーネルパニックを 起こすか起こさないかを制御する。
 このファイルに値 0 を設定すると、 カーネルの OOM-killer がならず者のプロセスを kill する。 普通は、OOM-killer がならず者のプロセスを kill することができ、 システムは何とか動き続けることができる。

 このファイルに値 1 を設定すると、 メモリー不足の状況が発生すると、カーネルは普通はパニックする。

memory overcommitにかぎらず、本当に必要なところまで処理を遅らせるという遅延処理は、パフォーマンスを最大化する上で非常に有用ですが、エラー処理が難しくなるので注意が必要ですね。

Linuxカーネル解析入門 (I・O BOOKS)Linuxカーネル Hacks ―パフォーマンス改善、開発効率向上、省電力化のためのテクニック UNIXという考え方―その設計思想と哲学

mbotでSTEM入門 - シャフトが壊れた時の修理方法

アトムは完全ではないぜ。なぜなら、悪い心を持たねぇからな。
手塚治虫 -『鉄腕アトム』

2020年、小学校でのプログラミング教育が必修化されることになり、「STEM教育」用の教材が増えてきました。STEMとは、"Science, Technology, Engineering and Mathematics" すなわち科学・技術・工学・数学の教育分野を総称する言葉で、これらを統合的に学ぶ機会を子どもたちに提供することで、次世代を担う人材に育てようという教育方針です。最近では、これに芸術(Airt)のAを加えてSTEAM教育という言葉も聞かれます。ニューヨーク市立大学教授のキャシー・デビッドソン氏がインタビューで語ったとされる「2011年度にアメリカの小学校に入学した子供たちの65%は、大学卒業時に今は存在していない職業に就くだろう」という予測も話題になりました。

さて、そんな中で種類も増えてきているSTEM教育用の教材ですが、やはり子供心をくすぐるのは自分でプログラミングできるロボットでしょう。子供向けのロボット教室も結構増えているようですが、最近はscratch(スクラッチ)というビジュアルプログラミング環境で、子供でもかんたんにプログラムが作れる環境が整っているので、キットさえ買えば自宅でも簡単にロボットプログラミングが始められます。

最初にどれを買うべきか

いろんなロボットが発売されていますが、最初の選択肢としてあがるのは以下あたりでしょうか。

LEGO midstorms

おそらく最も有名なのはLEGOのmindstormsでしょう。カスタム部品も抱負で、LEGOブランドの安心感もありますが、何分価格が高い。。大人も一緒に本格的にはじめたいというのならいいかもしれませんが、最初の子供用にはちょっと高いかな。

スタディーノではじめるうきうきロボットプログラミング

専用の解説書もあって、LEDチカチカから自動ドア、床ゆきお掃除ロボットと段階をおっていろんなものを作る楽しみがあります。これもなかなか楽しそうなので、次のmbotと迷いました。

Makeblock mBot

結局買ったのは、こちらのmbot距離センサ(超音波センサ)、ライントレースセンサ光センサブザーLEDと一通り入門に必要と思われるセンサが最初から搭載されており、bluetooth対応なので、付属のリモコンやPCあるいはスマホ、タブレットから操作までできます。これで1万円代中盤くらいなので、midstormと比べるとかなりお手頃です。プログラミング環境も、scratchベースのビジュアルプログラミング環境があるので、プログラミング経験のない小学生でもかんたんにはじめられます。ipad版ならPCもいらないのでさらにお手軽です (残念ながらiphone版はないのと、私の家のipad2はBLE(Bluetooth4.0)非対応なのでだめでしたが...新しいipadほしい..)。なお、mbotには、bluetooth版以外に赤外線版なるものもあるようですが、それだとリモートでプログラムの書き込み/デバッグができない(USBつながないといけない)ので、買うなら絶対bluetooth版がおすすめです。

私はサンワダイレクトさんから発売されているものを買ったのですが、詳しい説明がはいっていたので子供(小学校高学年)だけでかんたんに組み立てていました。プログラミングは、最初はさすがに少し説明しましたが、試行錯誤で距離センサーみてよけるものは結構手軽に作れてました。ビジュアルプログラミングなかなかあなどれないです。子供だけでできるように日本語の解説本(Makeblock公式 mBotで楽しむ レッツ! ロボットプログラミング)も購入しましたが、基本から順番に説明されていて、なかなかよかったです。

mBotの折れたシャフトの修理

なお、うちのmbotですが、完成してまだ電源をいれる前に、足で踏まれてシャフトがポッキリおれるという事故がありました。。修理部品をさがしてみたのですが、すぐには見つからず途方にくれそうになったのですが、そうえば、組立時にシャフトのあまりらしきものがあったのを思い出しました。「もしや、スペア部品?でも、何の説明もなかったけど・・・」と思って、もう少しぐぐってみると、以下の動画が見つかりました。
どうやら、シャフトは机からの落下等でよく折れるので、予備部品が最初からはいっていたようです。助かった。。
修理方法は動画の通りなのですが、モーターからキャップ外すのが結構固くて苦労しました。ドライバでひっかけて思い切ってやるしかないようです。

ということで、トラブルもありましたが、やっぱり目に見えて動くというのは、PC上に閉じたプログラミングとはまた全く違う楽しみがありますね。子供用と言いつつ、自分用にセンサ買い足したくなったきました ^^)

4865940847ロボットを動かそう! mBotで おもしろプログラミング
石井モルナ MAKO.
リックテレコム 2017-04-08

printfとtypedefの微妙な関係 - 無視されがち?なformt warning

型ができていない者が芝居をすると型なしになる。メチャクチャだ。
型がしっかりした奴がオリジナリティを押し出せば型破りになれる。どうだ、わかるか?
立川談志 - 『赤めだか』より

ひさびさにコーディングの話を書きたいと思います。組み込みの現場なんかで結構よく見かける話かと思いますが、以下のようなコードに対してでるwarningのお話です。

printfとtypdefの微妙な関係

ケースとしては、int等の組み込み型が環境依存なのを嫌って、typedefでint32_tやINT32という型におきかえることがあります。例えば以下のコード。
typedef long INT32;
int
main(int argc, char* argv[])
{
  INT32 val = 1;
  printf("val=%d\n", val);
  return 0;
}
さて、これをコンパイルすると、例えばgccなら以下のようなwarningがでます。(-Wallや-Wformatがある場合)
$ gcc -o test.c
test.c:9:22: warning: format specifies type 'int' but the argument has type
      'INT32' (aka 'long') [-Wformat]
  printf("val=%d\n", val);
-Werrorがついていればエラーになりますが、そうでない場合は、 実害なし、というか、別にあってるよね、くらいで無視されがちな気がしています。

実際のところ一般的な32bit処理系であれば、intとlongはどちらも符号付きの32bit整数型なので、 数値計算等で使っている範囲では全く同じなのですが、それでもwarningは出ます。なぜでしょうか?

INT32のようなtypedefを定義する理由は処理系依存の型を直接使わずに、 移植性を高めるために使われるものです。
(上の例なら、longが64bitになる64bitの処理系では、intへのtypedefに変えるなどする) 一方で、printfの%dは、そもそも処理系依存の型であるintを期待するものなので、 そこはintでなければ、処理系によっては不一致を起こすので、32bit系であろうと%dにはlongを渡す必要があるのです。

では、どうですればいいのでしょう?
上の例であれば、%dの代わりに%ld(signed long指定)を用いればwarningはなくなります。あるいは、引数側でintへのcastをしてやれば同じく問題はなくなります。
typedef long INT32;
int
main(int argc, char* argv[])
{
  INT32 val = 1;
  printf("val=%d\n", (int)val);
  return 0;
}
個人的には、printfのようなログ出力は処理系依存なので、引数の型の方にcastする上記やり方がスマートかと思います。 もちろんログなどではなくてファイルフォーマットにかかわるもので、移植時の型サイズ維持が重要なものはformat string側をかえるのが筋がいいものもあるとは思います。

「移植性をあげる」という目的で、処理系依存型を非依存型に変換するのはよく見かけるコードですが、一方で、非依存型から処理系依存型への変換というのは結構ないがしろにされがちです。strcmp等のstring系の関数でchar型を期待している関数を使う時も同じようなことがままあります。

なお、size_t, ssize_tについては、C99から専用のformat指定子zが定義されていますのでそれを使いましょう。(size_tから%zu、ssize_tなら%zd)

無視して良いwarning?

unsed-variablesとformatのwarningは無視されがちなwarningの2大巨頭ではないかと思います。どちらも大抵の場合は、確かに実害はないのですが、ごくまれにバグのものもあります。例えば以下のコード。
const char* name="taro";
printf("%d: name=%s\n", name, strlen(name)); 
引数順間違って%sに数値渡しているのでbuffer overrunをひきおこします。
ここで言いたいのは、「実害なし」という名目でwarningを残したり、 あえて、-Wno-formatのようにwarning抑制したりすることは、こういう本当にバグを埋もれさせかねないので、 基本的にはwarningは全て除去するというのは基本ポリシーとして実施すべきかと思います。

なお、デバッグ用にprintfを自作のマクロや関数でラップすることがありますが、 何もしないとprintfのformatチェックが機能しないことになり、 warning無視と同じくバグに気づくチャンスを逃すことになりかねません。 対策としては、例えばgccでは、独自定義マクロでもformatチェックするようにattributeしていることで コンパイラに指定する機構がありますので、あわせて活用することをおすすめします。
以下はgccの例です。
void debug_printf(const char* format, ...) __attribute__ ((format(printf, 1, 2)\
));

void debug_printf(const char* format, ...)
{
  va_list arg;
  va_start(arg, format);
  vprintf(format, arg);
  vfprintf(stderr, format, arg);
  va_end(arg);
}
上の例だと、__attribute__ formatという属性のを関数に付与することでformatチェックが入るようになります。引数の意味は、関数タイプ(この例だとprintf)、format文字列の位置(この例では1)、最初の引数の位置(この例では2)になっています。詳細は、以下gccのmanualが詳しいです。 ようするに、warningは正しく活用しましょうということですね。

なお、デバッグ出力用の可変個引数マクロやwarningの話は随分前にもとりあげていたので、よろしければご参考までに。

【関連記事】
可変個引数マクロを使う
warningに気を配る
使用しない仮引数

DVDで保存していた撮影動画をGoogleフォトで管理

忘れるにまかせるということが、結局最も美しく思い出すということなんだ。
川端康成 「散りぬるを」

前回に続いてmac環境でのGoogleフォトへの動画バックアップのTIPSを自分用メモもかねて紹介したいと思います。前回はAVCHD形式で撮った動画の保存についてでしたが、今回はDVDに保存した動画についてです。

さて、一口に「DVDで保存した動画」といってもいろいろな種類があります。PCにmp4形式のファイルをDVDにファイル保存したものもあれば、DVDやBlu-rayのレコーダでダビングしたものもあります。後者の場合、DVD-VideoやDVD-VR(Video Recording)といった形式で記録されることがほとんどだと思いますが、この場合、個々の動画が個別のファイルにはなっていないのでちょっと工夫が入ります。ここでは、多くのDVD/Blu-rayレコーダで採用されているDVD-VR形式で保存されたものについて説明したいと思います。

流れとしては、だいたい以下の手順になります。
  1. タイトル毎のファイルへの分割
  2. 撮影時刻の設定
  3. 拡張子変更
では順を追って説明します。

タイトル毎のファイルへの分割

Googleフォトはファイル単位で動画を管理するので、まずは撮影動画をファイル化する必要があります。このために以下のページで紹介されているdvd-vrというツールを利用します。 一応ツールのURLも。現時点ではv0.9.7でした。 このツールはコマンドラインベースのツールなのですが、実行バイナリではなくソースコードのみ公開されていますので、まずはビルドして実行ファイルを作成する必要があります。configureも必要ないので、適当なディレクトリで展開してmakeするだけでOKです。
$ tar zxvf dvd-vr-0.9.7.tar.gz 
$ cd dvd-vr-0.9.7
$ make
これで、dvd-vrという実行ファイルが作成されます。パスを通したい場合は、適切なフォルダに移動しましょう。

具体的なツールの使い方は上のURL参照頂ければいいかと思いますので、ここではポイントだけ説明します。基本的には、VR_MANGR.IFOファイルと、VR_MOVIE.VROファイルを指定してファイルを分割するだけです。
例として、タイトル確認 (パスが通っているところにdvd-vrがある前提で、DVD_VIDEO_RECORDERというボリューム名でマウントされているDVD内のタイトルを表示したいとした場合、コマンドとしては以下のようになります。
$ dvd-vr-0.9.7 /Volumes/DVD_VIDEO_RECORDER/DVD_RTAV/VR_MANGR.IFO
これでタイトルが確認できますので、次、ストリームファイルと分割後ファイルのprefixを指定してファイルを分割します。実際には既存ファイルを分割するのではなく、ファイルを区切りながらコピーするという動作になります。なお。分割後のファイルはコマンド実行したディレクトリ以下に作成されますので、あらかじめ分割後ファイルを入れたいフォルダに移動しておきましょう。
$ dvd-vr-0.9.7 /Volumes/DVD_VIDEO_RECORDER/DVD_RTAV/VR_MANGR.IFO /Volumes/DVD_VIDEO_RECORDER/DVD_RTAV/VR_MOVIE.VRO name=DVD
これで、DVD#001.vob, DVD#002.vob・・・というファイルが作成されます。

これで終了!と言いたいところですが、もう少し。
このままだと撮影日が本日になってしまいますので、これらに撮影日時情報を作成日及び変更日として記録します。
$ SetFile -d '09/24/2006 10:00:00' DVD#001.vob 
$ SetFile -m '09/24/2006 10:00:00' DVD#001.vob 
これでここのファイルへの分割というのは一端完了です。

拡張子の変更

上でできたvobファイルですが、残念ながらこのままだとGoogleフォトは****.vobをファイルとして見てくれません。vobの中身は基本的にはMPEGと同じでようなので、まとめてファイルをrenameします。
変更自体は以下のようなワンライナーで十分です。
for i in `ls *.vob`; do mv $i ${i%.vob}.mpg; done
ここで使っている部分一致の書き方は知らない方もいると思うので参考リンクあげておきますね。
これでDVD上の動画が全て.mpgファイルになったので、これらをアップロード対象ディレクトリに移動するなりすれば完了です。

DVDは保存やTVで見るには便利ですが、Googleフォトにいれると昔の動画もスマホで見れて楽しいですよ ^^)

B015XZLMKIパナソニック 1TB 2チューナー ブルーレイレコーダー 4Kアップコンバート対応 DIGA DMR-BRW1010
パナソニック 2015-10-16

PR

本のおすすめ

4873115655

4274065979

4822236862

4274068579

4822255131

B00SIM19YS


プロフィール

  • Author:proger
  • 組み込み関係で仕事してます

ブログ内検索