#pragma twice

KAB-studio > プログラミング > #pragma twice > 103 Version 6.03 別名に注意!

#pragma twice 103 Version 6.03 別名に注意!

前のページへ 表紙・目次へ 次のページへ

 Version 6.03
別名に注意!

この前はクラスのメンバ変数の話をしたんだよね
 . や -> でメンバ変数にアクセスしたら、その変数だけに注目すればい
い、ってことでした。今回は、型関係のエラーの続き
そうそう、関数の引数に渡すときとかよくあるんだけど
特に API はそうでしょ。意味不明な型が結構あるからね。たとえば 
WPARAM や LPARAM 
メッセージの時に出てきたのだね
 WPARAM は unsigned int で LPARAM は long 。これが実際にそうなって
るのは Windef.h ってファイル

typedef UINT WPARAM;
typedef LONG LPARAM;

 typedef って……あ、 Ver 5.08 ( No.073 ) でやったね。型に違う名前
付けるのだ
そう。ここでは UINT の新しい名前に WPARAM を、 LONG の新しい名前に
LPARAM を加えてます
……で、 UINT は?  LONG って?
それも同じファイルの上の方で typedef されてるから

typedef unsigned int        UINT;

あ、 LONG は別だね。 Wtypes.h だ

typedef long LONG;

結局 unsigned int と long だったってわけね
これをどう調べるかって言うのは
ファイルから検索、でしょ
そう。【編集】−【ファイルから検索】で検索。検索場所は、 API 関連
のファイルが置いてある MICROSOFT VISUAL STUDIO\VC98\Include で
そこには API のファイルしかないの?
 API と、ランタイムのヘッダーファイル。だから一緒にランタイムも調
べることになるかな
質問! 実際に調べると、 WPARAM とかで調べると一杯出てきちゃうんだ
けど
検索一覧をクリックしてから Ctrl + F で
あ、検索ダイアログが!
それで typedef を検索、とか
なるほど。もひとつ質問!  LONG で検索したら Wtypes.h だけじゃなく
て Winnt.h でも見つかったんだけど、どっち?
場合によって
ばあいによってぇ!?
そうなんだって、ホントに。この例はどっちも同じ long だからいいけ
ど、ものによってはファイルによって何の型か違うことがあるし
……それってつまり、 typedef char LONG ってことがあるかもしんない
ってこと? なにそれわけ分かんない!
まーまー。手っ取り早く、ホントは何の型か調べるときにはこういうふう
にしましょう

    WPARAM wParam;
    int *pi = wParam;


こうするとこういうコンパイルエラーが出ます

error C2440: 'initializing' : 
    'unsigned int' から 'int *' に変換することはできません。

これで wParam の型が unsigned int だって分かるわけ
うわ、コンパイルエラーで型調べるの!? そーゆーのっていいの?
もちろん。ちなみに int * は何でもいいんだけど、このエラーは〈 = で
右から左に代入できないとき〉に出るから
代入できない型にするんだ。ってことは調べたい型が int * っぽかったら
他のにした方がいいのね
ポインタ以外はポインタに、ポインタはポインタ以外に、ってとこかな
最後の質問!! なんでわざわざこーゆーしちめんどくさいことしてる
の?  WPARAM なんて書かずに直接 unsigned int って書けばいいじゃん
建前上は、あとで型を変えることができる、っていう理由から
建前上はぁ?
たとえば、 C++ 言語の規則が変わって〈 int がなくなった!〉って場合

そんなことになったら int で書いてる部分全部直さないと
でも UINT を使ってたら、 typedef unsigned int UINT を書き換えるだ
けで
全部いっぺんに変えられる!
そういう利点があるから。ただその分、必要ない部分を変えちゃったら
いっぱい問題が出てくるね……
それに、他の OS では使えないし
どゆこと?
 UINT なんかの型は Windows API だけのものだから。他の OS でプログ
ラム組むときには使えないから
ってことは、各 OS ごとにそーゆー API があるの?
そういうこと。ウィンドウズに絞ってある程度やっておけば、他のでもあ
る程度通用すると思うから安心して
はーい
それにも関連してるんだけど、 API は実はこの typedef の嵐だったりし
ます。たとえば

typedef int                 INT;

が Windef.h にあります
うわ、 int にも!
他によく出てくるのが DWORD とか WORD とか BYTE とか。こういうのは 
Wtypes.h にあるね
こーゆーのの型も調べなきゃいけないんだ
一度は直に見た方がいいよ。ま、簡単に言えば BYTE が unsigned char 
で WORD が unsigned short 。 DWORD は double WORD の略だから
 double 、倍…… short の倍は4バイトだから、 unsigned long なんだ
ね、 DWORD は
そういうこと。で、まとめると、こういうふうに型に違う名前を付けるの
が API のポリシーってこと
趣味悪そう……
同じようなので、ポインタでこういう typedef してるのもあります
知ってる!  LPCTSTR とかだよね
それだけじゃないよ。さっき言った DWORD のポインタ版 LPDWORD とか
……もしかして LPINT も?
あります。 Windef.h にね

typedef int near            *PINT;
typedef int far             *LPINT;

??? なんか謎。 near とか far とかって?
これはね、 Windows 3.1 って知ってる?
大昔のウィンドウズだよね
大昔……まーそういうことで。今はポインタのサイズは?
32ビット
だけど、大昔はそんなにコンピューターに余裕なかったから、小さいポイ
ンタと大きいポインタのふたつを用意してたんです
それが near と far なんだ。近くと遠く?
アドレスで考えるとそういうこと、ってことなんだろうね。で、 near は
小さいから普通に P 、 far は long サイズのポインタだから LP を付ける
わけ
そっか、今は全部大きいポインタだからどれも LP の付いてる方使ってる
んだ!
一応ね
一応?
上の方でこういうのあるでしょ

#define far
#define near

 #define って憶えてる?
 Ver 4.09 ( No.059 ) でやったね。あれ、でもあれは……
そう。たとえば

#define DEF_FLAG_OK 1   // 定数。

これだったら、 DEF_FLAG_OK を 1 に置き換える……って、そういえばこ
れって typedef みたいだね
そだね、 typedef は #define の機能を〈型の名前〉だけに機能するよう
にしたものって言えるかも
ほほう
で、 #define far は、 1 にあたる部分が何もない、つまり〈空白〉に
なってるわけだから
ってことは far や near は空白に置き換えられる?
そういうこと! つまり、これらの単語が出てきたら消されちゃうってこ

あ! だから PINT も LPINT も同じなんだ
だからどっちを使ってもいいんだけど、基本的には LP 付いてる方。もー
しかしたら、 Windows 3.1 に移植することがあって、そのときその方が楽
だから
絶対ないような気がするんだけど
それがある業界なんだよね……あ、あと最後に const について
引数に使う const って前にかなりしっかりやったよね
 Ver 4.12 ( No.062 ) だね。そこでもやったけど

      int のアドレスを       int * へ
      int のアドレスを const int * へ
const int のアドレスを const int * へ

はコンパイルエラーにならないけど

const int のアドレスを       int * へ

はコンパイルエラーになります
ようするに、書き換えちゃいけないのを書き換えるようにしちゃいけな
いってことだよね
そういうこと。これはさっき言った typedef のにも当てはまるからね
あ、そっか、 LPCTSTR と LPTSTR もこれなんだもんね
さて、型関係のエラーはこの辺……ってことにしといて
ぶーぶー、もっといっぱいあるよ確かー
〈コンパイルエラーは論外〉って言った手前なんだけど、コンパイルエ
ラーが起きるからには理由があるわけで、その理由を知らないと
教えてもらっても理解できない、ってことねー
そゆこと。その辺はこれから少しずつ教えてくから

/*
    Preview Next Story!
*/
教えてもらうまでは大変ね……
僕も昔はホント、色々失敗したけどね
そういうもん?
うまくいったけど理解できてないコードを ML に載せたり……
ありゃりゃ……
というわけで次回
< Version 6.04 あるのにない!! >
ねぇ、今教えてくれてるのにはそういうことないのぉ?
……ギクっ……
ツッコむとこでしょそこは……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。