ゲームプログラマのエリートが世界に羽ばたく感動巨編!
スポンサーサイト

一定期間更新がないため広告を表示しています

【2013.06.29 Saturday 】 author : スポンサードリンク
| - | - | - |
cppcheck 日本語マニュアル

C/C++の静的解析ツール「Cppcheck」。

ナウでヤングでトレンドに敏感な開発者はコンパイラによるシンタックスチェック以外にもこういうツールを使うのがお洒落だという話を聞いた。


STLも解析してくれる静的解析ツールcppcheckを試す、と思ったら……(神様なんて信じない僕らのために)


僕もクールなギークの仲間入りがしたいので、早速うちの会社のプロジェクトのデイリービルドにcppcheckを組み込んだぜ!


マニュアルが英語しかなかったから翻訳しといたよ。
2〜3回査読したから、大きな意訳はないと思うけど間違ってたらごめんなさい。
これからcppcheckを使ってみようっていう人で英語が無理な人は使ってね☆

cppcheck日本語マニュアル 
  監訳:どすこい 翻訳:どすこい



お前の翻訳した日本語、意味がわかんねーぞって時は本家のマニュアルを読むんだ!

【2010.01.20 Wednesday 18:41】 author : どすこい
| 技術メモ | - | trackbacks(0) |
今更人に聞けないプログラマ用語読み方いろいろ

俺はこう読む!!!



git (ギット)
うっかりジットと読んじゃわないように。
バージョン管理ツール。国内ではSVNが主流のアレ。gitはCVSやSVNと違い、今流行りの分散型管理。
今、うちのプロジェクトではSVN使ってるけど、SVNはCで書いてある癖に遅すぎる!と上司が憤慨しているので、次のプロジェクトからはgit導入するかもしれない。そんなgit。


tortoise (トータス)
バージョン管理ツールsvnのクライアントのひとつ。マイナーだがTortoise CVSもある。
ってかTortoiseはsvn.exeをdll化してんじゃねーよ。シェルから svn update って書かせろ!


wiki (ウィキ)
wikipediaをウィキっていうやつは市ね。


radian (ラジアン)
ゲーム内のキャラクターの回転角度をデグリー角で扱ってると思って実はラジアンだったりすると悲しい結果になる。


lambda (ラムダ)
ラムダ式でおなじみのラムダ。Boost::lambdaのおかげでついにC++でも無名関数が使えるようになり、ホクホク。


regex (リジェックス)
こちらもboostライブラリから。C++に手軽に使える正規表現エンジンができてホクホク。


deque (デック)
STLコンテナ。double ended queueの略でデック。
デキューって読んじゃうとデグレードやデストラクタと同じ意味の「デ」みたいな印象に変わっちゃうので駄目。


επιστημη(エピステーメー)
「C++設計と進化」などの翻訳もしてるC++の有名人。
C++標準化委員会員。超有名人の割に読めない人が多い。


volatile (ボラティル)
C/C++のキーワードの中で使用頻度と知名度が多分一番低い。
いや・・・exportやregisterよりは高いか・・・。


enum (イーナム)
言わずと知れた列挙型。
エナムとか本気で言ってんの?
それともすごくネイティブに言ってんの?


Mul (ミュル)
掛け算の短い表記。multiplyの略なのでマルと読みたいキモチもある。
ベクトルにベクトルを足した値をスカラー倍する関数の定義が
Vec* AddMul( Vec* dest, Vec* src, Vec add, float s );
って感じに定義されている時に見かける表記。
AddMul をアッドマルと読むと切れが悪いのでアッドミュルと読む。


RTTI (アールティーティーアイ)
実行時型情報。コンパイラオプションでRTTIをONにしておかないとtypeinfoが使えない。
今の会社に入る面接でRTTIとC++の例外処理に関する知識が試されたのも良い思い出。
そのくせ、今のプロジェクトではRTTIは切ってある。なんでやねん!


引数 (ヒキスウ)
昔一緒に働いてた派遣が「いんすう」って言ってた。
教育を受けてないのかな?って思った。


reinterpret_cast<読み方>(リインタープリットキャスト)
C++標準のキャストの中で最強最低のキャスト。
dynamic_cast, static_cast, const_castとスラスラ書いた後、後一個なんだっけ・・・ってなる子。


false (フォルス)
あれだ、いわゆる !true だ。
たまにファルスって言う人を見かける。英語発音だと完全にフォルス。


SFINAE (スフィナエ)
C++でテンプレートのインスタンスの時に置き換え失敗を検出したらオーバーロードの候補から外すという言語仕様。「C++テンプレートテクニック」にも「EffectiveC++」にも「C++標準的コーディング技法」にも載ってるとても重要な概念。
中々声に出すこともないけど、あえて読むならスフィナエ!


Pimpl (ピーインプル)
ファイル依存を少なく保つプログラミングイディオムの一つ。
ポインタ経由でメンバ定義をソースファイル側に内包(インプリメント)するからPimpl。割と頻繁に使う。


Facade (ファサード)
GoFのデザパタの中で唯一読み辛い。


doxygen (ドキシジェン・ドクシジェン)
自動ドキュメント生成ツール。
ライブラリとかオープンソースプロジェクトによく使用される。昔導入してたけど、内容を知ってる前提のドキュメントしか生成しないので使うのをやめた。ソースの可読性も下がるし。ソース内で@paramとか見かけると大体doxygenのなごり。


stdio (スタンダードアイオー)
#include "stdio.h" スタジオヘッダーじゃないよ。


malloc (マロック)
mallocで確保した領域をdeleteした場合の動作は未定義。逆もまた然り。(キリッ


FFCCCC (ファイナルファンタジークリスタルクロニクルクリスタルベアラー)
最近メモリの未使用領域は0xFFCCで埋めるようにした。


sqrt (スクウェアルート)
平方根を計算してくれるC言語の標準関数。
ドラクエの呪文「スクルト」の語源。
・・・だと思う。


atan2(アタン(一拍空けて)ツー)
アークタンジェントを計算してくれるC言語の標準関数
キャラクターのXZ平面上の移動ベクトルからY軸回転角を求める時などに活躍する。


D3DXVECTOR3 (ディーサンディーエックスベクタースリー)
最初の3はサンと読み、最後の3はスリーと読んじゃう不思議。


A* (エースター)
主にゲームプログラムで使用する経路探索アルゴリズムの名前。
コンビニのレジのプログラムでA*アルゴリズムが使われてるとかは聞いたことがない。


GNU (グニュ)
やわらかいものを踏んだ時の擬音。
GCCはグニュシーコンパイラ、又はグニュコンパイラコレクション。どちらも正解。
GPLはグニュパブリックライセンス。GPLを見つけたらそっと離れるのが吉。


Delphi (デルファイ)
学生時代、読み方が分からずデルフィって読んでた。
デルファイの設計主任がマイクロソフトに引き抜かれて.NET frameworkを作った。もうデルファイから才能は去ったのだ・・という話が個人的にお気に入り。


eclipse (エクリプス)
ご存知java向けIDE。ただしプラグインでC++やpython開発もできる。
ハイライト表示、インテリセンス、リファクタリングなど主要な機能を揃えている。とくにハイライトが超強力。
最近はWiiのゲーム作ってるけど、ソースはほとんどエクリプスで書いてる。


Emacs (イーマックス)
プログラマ向けテキストエディタ。
これを使ってるプログラマは大抵能力が高い。


Sleipnir (スレイプニール)
あの一人ぼっちの共鳴の管理人も愛用しているタグブラウザ


Stirling (スターリン)
あの一人ぼっちの共鳴の管理人も愛用しているバイナリエディタ


Ajax (エージャックス)
アジャックスではありません。
アジャックスではありません。(大事な事なので2度言いました)


Erlang (アーラン)

昔、イーラーンって読んでたけどアーランが正解の関数型プログラミング言語。本も出てる。
意識しなくても並列化プログラムが書けるのがウリ。
(株)ピラミッドののプログラマも一押しのプログラミング言語。


Squirrel (スクワール)
スクイールと読みたいところだがスクワール。
C++と親和性の高いスクリプト言語。
スクエニがWiiウェア「小さな王様と約束の国ファイナルファンタジークリスタルクロニクル」で採用したことで一気にメジャーになった言語。
Luaより扱いやすいのに、なぜかLuaの本ばかりが出版される今日この頃。


Scala (スケーラ)
Javaの親戚。スカーラ説もあるけど、売られてる参考書にカタカナで思いっきりスケーラって書いてある。


C# (シーシャープ)
#の記号は♯(シャープ)じゃないという細かいウンチクが披露される言語。
声に出すときは「シーシャー」と、プを省略して言うのがデキるプログラマの証。


PNG (ピング)
画像ファイルフォーマットおよびその拡張子。ピーエヌジーでも通じる。通信用語っぽくピンっていうとまず一発では通じない。


BMP (ビーエムピー)
ビットマップ形式の画像の拡張子。人生で何度かこれをバンプって読まれた。天体観測でもしてろって思った。


gif (ジフ)
gitは"ギ"ットだけどgifは"ジ"フ。


_ (アンダーバー)
アンダースコア派との_熾烈な_争いが_絶えない


^ (アクサンシルコンフレックス)
この読み方は学生時代にならった。一番役に立った授業。
ビット演算ではXORの意味。


SIGGRAPH (シーグラフ)
映像の国際的な技術カンファレンス。オンラインで過去の論文集(英語)が読めるけど難しい。


UNIX (ユニックス)
ドラクエのパブリッシャーはエニックス。トイレのパブリッシャーはイナックス。
うちの会社はOS縛りが無いのでメインマシンでUNIX使ってる人もいる。


LaTex (ラテック)
ラテックスじゃない。でも開発者が「どう読んでもいいよ、レイテックスでもいい」と言っているとwikipediaに書いてあったので、これの読み方は無限にあるといえる。
wikipediaをウィキって略すやつは氏ね。


yacc (ヤック)
コンパイラコンパイラ。楽に構文解析エンジンが作れちゃうもの。
フルスクラッチで一つ一つ構文解析をしなくても、大方の機能はヤックが生成してくれるので、オリジナル言語をさくっと作りたい人にはおなじみ。
ただしコンパイラに関してはドラゴンブック読んでないやつは認めない。


opoona (オプーナ)

     |┃三        / ̄\
     |┃         |     |
     |┃          \_/
 ガラッ. |┃             |
     |┃  ノ//   ./ ̄ ̄ ̄ ̄ \
     |┃三    / ::\:::/::   \
     |┃     / <●>::::::<●>  \
     |┃    |     (__人__)     |  
     |┃三   \     ` ⌒´     /
     |┃三    / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ \








【2009.11.29 Sunday 20:02】 author : どすこい
| 技術メモ | - | trackbacks(0) |
ヌルい話

やぁ、こんにちは。どすこいです。

今日は普段偉そうにチラシの裏の日記を書いている僕が、実際はいかにヌルいか、その実態、恥ずかしい部分について書こうと思う。
今日の話は、この星のプログラマの中で、僕より能力が高い人たち、つまり上位5%に向けた話だ。
このブログを読んでくれている非プログラマの人には退屈な話になってしまうことをあらかじめ伝えておく。女子高生のキミ、専業主婦のキミ、あと僕のケータイにHTML形式のカワイイハート付きの絵文字を送りたいと思っているキミ、申し訳ないが、今日のエントリーに皆さんがクスっと笑う部分は無い。プログラマ向けなんだ。(ただしプログラマよりキミたちのほうが好きです、これからもよろしく)
あー、あと、プログラマの下95%に属する皆さん。
頑張ってついてくるように!


ちょっとこの関数を見て欲しい。
一応断っておくがC++言語で書かれている。


void func( int a );

void func( char* a );


この2つの関数の定義を、コンパイラは広い心で受け入れてくれる。
引数が違うから別の関数だと認識するのだ。

じゃあ早速呼んでみよう。


func( 0 );



どっちの関数が呼ばれるかな?
そう、正解、きみの考えは正しい。void func( int a )のほうが呼ばれる。
当たり前すぎてビビッたかい。

じゃあこういう呼び方をしたらどうなるだろう?


func( NULL );


これもvoid func( int a )のほうが呼ばれると思っちゃった人、いませんか?

正解です。おめでとう、勘にせよ、知っていたにせよ、貴方には力がある。
C++言語におけるNULLはキーワードではなく、単なるマクロ定義だ。
多くの実装系ではこんな風に書かれている。

#define NULL    0

その結果、引数をintで取るほうの関数が呼ばれる。
キモチ的にはchar*を受け取るほうの関数が呼ばれて欲しいのに、だ。
今、僕に文句を言おうとしている人がいるのも、僕は知っている。

俺の知ってる実装系ではNULLは

#define NULL ((void*)0)

だぞ!お前の世界だけが全てじゃないんだ!
と、言おうとしているね。何度も言うが僕は知ってるよ。
上記の実装系の場合はポインタにキャストしてあるので少なくともint型の関数が呼ばれることはない。ただしvoid*はchar*ではない。明示的にキャストしてやらなければ決してchar*の方の関数は呼ばれないんだ。((void*)0)という実装になっている時にNULLを使った関数呼び出しをすると、単に型が合わないとコンパイルエラーになる。

ただ、ひとつ確かなことがある。

昨日まで正常に動いていた貴方のスーパーエレガントアプリケーション(ゲームかもしれない)が、別の環境に移植した結果、急によく分からないエラーを吐き出して、貴方がその原因がNULLの定義の変化によるものだということに気づくのには、割と時間が掛かるということだ。人生は短い。


いまここに書いた話は、「だから注意しようね」なんていう警告がしたいんじゃない。
NULLはC++では(javaのような)キーワードじゃなくて、実装依存の定義でしかないよという、ただそれだけの話だ。



最近、僕はとあるライブラリのソースコードを読んでいた。
なにかまずいことをしているところを見つけてdisってやろうと思っていた。
そこでメンバ変数のポインタを初期化しているコードを見つけたんだ。
こんな感じ。


// **************************************
//  ラブレタークラスのコンストラクタだよ

LoveLetter::LoveLetter( std::string myName )
    : dear_( "どすこい" )
    , from_( myName )
    , stamp_(0)  // 切手は後で貼るからとりあえずヌルポインタ
   {
   適当にコンストラクタの処理...
}


実装詳細は重要じゃない。
どすこいにしか送れないラブレタークラスなんだ。
stamp_というメンバがポインタで初期化に0が与えられていることだけ見て欲しい。

以前、僕の友達が、「後輩がポインタも実体も何でもかんでも0で初期化する」と嘆いていて、僕はそれに対して、「ポインタを0で初期化するなんてとんでもない!NULLは厳密に言えば0じゃないからね((void)0)だし(キリッ」と言っていたのを思い出した。
お、このライブラリの作者も友達の後輩レベルかー(´ω`)と思った。




しかし、実際愚かだったのは僕だということが発覚。


調べた結果、C++においてポインタに0を代入するということは、必ずその型でのヌルポインタを示すという言語仕様だと分かった。
NULLで初期化すると実装依存のマクロなのでそれ(NULL)が-1かもしれない、つまり確実に0を代入するとは限らないのだ。なのでポインタだろうが数値だろうが、明示的に"0"を書くほうが適切なプラクティスといえる。つまり出来の悪いあの後輩の行いが正しく、偉そうにNULLは0とは意味が違うからNULLで初期化するべき(キリッ)と言っていた僕が間違っていたのだ・・・。


はずかしっ!俺、はずかしっ!


NULLと書くことでポインタを初期化していますよと一目で分かるのだが、NULLと書いてしまう以上は実装依存であることだけは受け入れなければならない。
その上でもNULLと明示的に書いたほうがいいだろう・・・とも思う。

そんなジレンマはこのようにすることで解消できる。


//
//  C++の技術応用NULL!
//
const class {
public:
    // あらゆる型のポインタに変換
    template<class T>
    operator T*() const{ return 0; } 

    // あらゆるメンバ型のポインタにも変換
    template<class C, class T>
    operator T C::*() const{ return 0; }

private:
    // アドレスを取ろうとしちゃだめ
    void operator&() const;
} NULL;


さあ、実装依存から抜け出したNULLという名前のポインタ初期化用の何かの誕生だ。
匿名クラスに0をT C::*型に変換するメンバテンプレートを実装したものだ。
この部分について、なにそれ意味わかんないと思った人、安心してほしい。
あなたはマイノリティではなく、同じような感想を持った95%の集合に属していて、そもそも冒頭に書いたようにこの記事はあなたに向けて書いていない。

EffectiveC++にこれに関する記述があるよ。
ただし、第3版じゃない、ひとつ前、改訂2版のほうだ。
25項「ポインタと数値型とにオーバーロードするのは避けよう」だ。
でも別に読まなくてもいい。僕と仕事をするわけじゃないからね。
第3版で削られた内容なので、ひょっとしたら重要じゃなかったのかもしれない。

とにかく、あの日の僕のように「NULLは0とは違うからNULLで初期化しなくちゃ駄目(キリッ)」といって恥ずかしい想いをする人が減るように、今日はこの話を書いた。

何か指摘があればトラックバックか、はてブでコメントしてくれれば読むかもしれないが、ただの情けない話なのでそっとしておいて欲しい。

【2009.11.05 Thursday 23:13】 author : どすこい
| 技術メモ | - | trackbacks(0) |
#は演算子でもある
人間だれしも、機嫌が良い日がある。
機嫌が悪い日もある。
プリプロセッサを使ってこうやって書きたい日もある。


// **********************************
// 型定義マクロ

#define MY_TYPEDEF( type, alias )     ¥
    #ifndef alias                     ¥
    typedef type alias;               ¥
    #endif // ifndef alias            ¥
    typedef type MY##alias;           ¥


// ==================================
// どのプラットフォームでも大体あるけど
// もし未定義だったらここで改めてエイリアス付けるよ
// ついでにオリジナルのエイリアスも付けるよ

MY_TYPEDEF( unsigned char, u8 )
MY_TYPEDEF( unsigned short, u16 )
MY_TYPEDEF( int, BOOL )
      :


ただしこれは叶わぬ夢。人の夢と書いて儚い。
C++プリプロセッサがdefineの多重展開を認めていないからこのコードはエラーになる。
コンパイラに渡された段階で展開された最初の #ifndef の # を #演算子として解釈することになる場合が多い。
そうなることも分かるが、コンパイラもっと頑張れと思う。



今、この記事を読んでC++におけるプリプロセッサマクロがいかに悪で、本来それらを使うべきではないのだという主張を僕に伝えようとメーラーを立ち上げた皆さん。
また、上記のエラーがいかに正当で、僕の主張がいかに無知なものか思い知らせてやろうとしている皆さん。
先に伝えておきたいことが2つある。とても重要なことだ。

まず1つ目は、あなたのその主張はあながち間違いでないことを僕は既に知っており、あなたがメールにコピペしてくれようとしている「EffectiveC++」や「C++設計と進化」の抜粋や、スラッシュドットの熱心なC++コミュニティのスレッドへのURLも、僕は既に何度も読んでいる。
続いて2つ目、僕は連絡先を公開していないので、いくらやっきになってメールの送り先アドレスをこのブログから探しても、答えは見つからないよ。
【2009.10.30 Friday 21:11】 author : どすこい
| 技術メモ | - | trackbacks(0) |
シャープな海
最近、仕事でC#の海を優雅に泳いでいる。

はるか昔、「Joel on Software」でおなじみのジョエルさんが.NET Frameworkに対して懐疑的な見方をしていて、ジョエル信奉者の僕もジョエルが言うならそうなんだと、盲目的に信じてきた部分があった。
でも、僕のまわりの同業他社の優秀な人材(残念ながら社内には高いレイヤーで技術トークをしてくれる人間はいない)がこぞってC#の素晴らしさを説いてくれたので、今の仕事で採用してみた。
そしたらあまりに素敵なもので、テンションの上がりが止まらなかった。

もうMFCとかいう時代遅れのフレームワーク使ってられねぇとおもた。
RADツールという意味では.NET Framework最強じゃね?
ガベコレとジェネリック型、素敵すぎじゃね?


そんな感じでハッピープログラミングな昨今だけど、まだちょっと勘をとりもどせてない部分があって・・・。ウィンドウベースのMDIアプリを作ってるんだけど、子フォームに権限を委譲しすぎる設計で作ってしまったため、ある子フォームのメンバを他の子フォームが参照したい時など、とってもまずい。他のフォームへの参照経由でアクセスするとか、まったくエレガントじゃない。
あくまでフォームはユーザーとのインターフェースでしかなく、データ構造は全てそれらを包括するものが一元管理するべきだった。

次から気をつけるべー。
【2007.11.14 Wednesday 11:19】 author : どすこい
| 技術メモ | - | trackbacks(0) |
積み上げてきた歴史
最近作った当たり判定プログラムの、よりいっそうの高速化を計るため、平方根計算をフルスクラッチしてみた。
DSのライブラリで提供されてるsqrtより高速になるはずだった。

ボロッボロに負けたけど。

基本テーブル参照で、隙間は線形補完するようにしてみたんだけど、それよりも早いライブラリの標準関数。心が折れた。専用の平方根演算器の強さに乾杯バー

【2007.03.07 Wednesday 17:16】 author : どすこい
| 技術メモ | - | trackbacks(0) |
アッパーコンパーチブル
VC++2005のインスコも無事完了して、とりあえず昔のソースコンパイルしてみて、IDEの操作になれるかな〜なんて感じで触ってみたのですが・・・

もうね、エラー出る出る。


#include
windows.h cannot be opened


とか目を疑うよ。何がキャンノットビーオープンドだよ(`△´)シネ!

評価版だからなのか時代が変わったからなのか知らないが、Win32Appを作るには Windows Platform SDK なるものが別途必要だと。
仕方ないからSDKダウンロードして、VCから参照用のパス通して、やっっとオーケーですよ(´ω`)めんどくせーぜ。たりーぜ。


で意気揚々とビルド!



もうね、エラー出る出る。




なんかね・・・

for ( int i = 0; i < 10; i++ ){
  ...
}

for ( i = 0; i < 10; i++ ){
  ...
}

変数 i は未定義です。みたいなことを言われまくるわけです。

i の生存期間が短くなっちょるとですよ・・・
for文の中のブロックのみとなっとるわけです(`△´)シネ!

じゃあ何か!内部解釈としては

{
 int i;
 for ( i = 0; i < 10 ; i++ ){
   ...
 }
}

かよ!かってにブロック切ってんじゃねーよ!
てゆーか、そもそも可読性の低くなるような場所に変数宣言してんじゃねーよ、当時の俺!!未来の俺がVCに怒られたじゃねーか(`△´)

ふん!

for ( int i = 0; i < 10; i++ )

の部分を全部修正して、さあいよいよ終わりです。

ビルド!




もうね、エラー出る出る。



よくわかんないエラーが出まくるわけです。
開いたことねーよそんなファイル!って思わず泣いちゃいたくようなSDKのファイルとかライブラリからエラーが出まくるわけです。
そんなtypedefは無い!だとか、もうそのオブジェクトは別dllで定義済みだとか、いっぱい出てくるわけです。


マイクロソフトよ。
(´ω`)好き勝手に深い部分をいぢるのはやめておくれよ・・・



グーグル先生に解決方法を聞きながらチクチクと直す。

そしてやっっっっっとエラーを全て取り除いて、古いソースもビルドできる環境になった。



ええ、昔の思い出が画面上で動いた時は嬉しかったですね 
                 __どすこいさん(会社員)



でもすぐ閉じて寝た。
【2006.05.20 Saturday 12:20】 author : どすこい
| 技術メモ | - | trackbacks(0) |
秀丸先生の教え
秀丸エディタ(以下、秀丸先生)のマクロの勉強を始めた。

いまさら始めた。
というのも、エディタの置換ダイアログで置換作業を行っていたら
厳しく叱咤されたからである。
その文字列をもう一度置換するようなことが想定できるならマクロ
を書きなさい。と。

「マクロを覚える時間があれば、置換が100回は出来ます」
思ったが、そんなことを口に出したら明日からデスクが無くなってしまう
ので「ハイ、わかりましたすぐに勉強します」と満面の新卒スマイル
で答えた。

そして仕事の合間に秀丸先生のヘルプを見ながらマクロの勉強をした。

右クリックで選択した範囲の行の先頭に//をつけて選択行を全て
コメントアウトする
というマクロを作った。

これは誇らしげに書いているが、実際にはC言語で言うところの
printf覚えましたレベルのことなので、実はとっても情けない。

明日からも仕事の合間に頑張ろうと思う。
【2005.10.11 Tuesday 22:50】 author : どすこい
| 技術メモ | - | trackbacks(0) |
無駄なコードの向こう側
昨日のコードの解説をリクエストされました。
こんな記事にはオールウェイズ無関心だと思っていたので嬉しい限りです。
仕事柄…(SOBLOG)
総さん、ありがとうございます。ありがとうございます。(´ω`*)

以下、とりあえず昨日のコード。

#define MODE_1  1
#define MODE_2  0
#define MASK   0xF0
#define SHIFT   4

{
  info &= ~MASK;        …

  if ( 0 ) {
    info |= MODE_1 << SHIFT;
  }
  else {
   info |= MODE_2 << SHIFT; …
  }
}


ここまで。


なぜのブレークポイントを通らないかというと、昨日の記事でもちょっと触れたとおり、そもそもこの行のオブジェクトコードが生成されないからブレークポイントも無かったことにされるんですね〜。(ムツゴロウさん風に)

では、なぜオブジェクトコードが生成されないのかをこのコードの流れを追いながら解説。

このコードは、ある変数の上位4ビットに任意のデータを埋め込む目的で書かれています。
定数:MASKがデータを埋め込みたい部分(上位4ビット)用のビット列です。このビット列(11110000)を反転させて(00001111)、変数と論理積をとることで、まずは上位4ビットをクリア。,旅圈

その後、埋め込みたいデータ(MODE_1,MODE_2)を4ビット左シフトして論理和をとることでデータ埋め込み完了。
まぁ、普通のビット操作でした。

これで何も問題無いはずなのですが△旅は違うんですね。

MODE_2の値は0なんですね〜。
0を何ビットシフトしたころで0なんですね〜。
つまり変数がどんな値であろうと論理和の対象が0である以上、演算結果は最初の変数の値となにも変わらないんですね〜。
演算するだけステップ数の無駄です。
つまりコンパイラ様にとっては格好のオプチマイズ対象なわけですね〜。
お〜よしよし(ムツゴロウさん再度光臨)


正直、コンパイラがここまで考えてコード生成してるなんて思いませんでした。経験不足、認識不足、実力不足、睡眠不足、栄養不足でした。
こんな無駄なコードに気づけない僕はコンパイラにブレークポイントを無視られるのがお似合いだな(´ω`)

でも、この無駄なコードは前後のコードの可読性を高める関係で今もひっそりと僕のソースに残ってたりします。

結論:
僕はコンパイラにオプチマイズされるようなコードを書くのが
お似合いだとおもた。(´ω`)おもたよ。


ち・な・み・にっ!
今回のコードをなんと解説してくださっている奇特な方がいらっしゃったので紹介しておきます。不真面目にムツゴロウさんの真似でしか解説できない僕は早々に死ねばいいのになって思いました。
旅人さん、ありがとうございます。
【2005.09.28 Wednesday 00:13】 author : どすこい
| 技術メモ | - | trackbacks(1) |
☆ 無断リンク歓迎 ☆