いつもお世話になります.忙しい中だとは思いますが質問よろしくお願いいたします.
まずRGBマクロ原文を以下に示させていただきます.
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
このマクロを自分はつぎのように解釈しました.
#define RGB(r,g,b) (
(COLORREF)(
(
(BYTE)(r)
| ( (WORD)( (BYTE)(g) )<<8 )
)
| (( (DWORD)(BYTE)(b) )<<16)
)
)
ここで,
BYTE = unsigned char : 1byte
DORD = unsigned short : 2byte
DWORD = unsigned long : 4byte
COLORREF = DWORD : 4byte
です.
したがって,これらを一つずつ構文解析して,
BYTE r, g, b;
( r | ((WORD)g) << 8 )
[g][g] [r][r] 16進表示
((DWORD)b) << 16
[0][0] [b][b] [0][0] [0][0]
((r | ((WORD)g) << 8 )) | (((DWORD)b) << 16)
[0][0] [b][b] [g][g] [r][r]
となっているのではないかと推測しました.
疑問なのは,
((DWORD)( (BYTE)g))
と
(DWORD)(BYTE)b
の違いです.この二つは異なるシンタックスの同じ動作だと解釈して上のようにイメージしたので,根本からして違うのならこの解釈は間違っていることになります.
この二つの違いは何なのでしょうか?
そしてこの解釈は正しいのでしょうか?
[追記:2015/4/16]
// macrosTest.h
#ifndef TESTER_MACROS_MACROTEST_H_
#define TESTER_MACROS_MACROTEST_H_
#ifndef WINDOWS
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef DWORD COLORREF;
#endif
// WinAPIにあるRGBマクロの動作確認
#ifndef WINGDI_H
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#endif
#define R_CASE1(r) (WORD)(BYTE)(r)
#define R_CASE2(r) (WORD)((BYTE)(r))
#define R_SHIFT(r) (WORD)(BYTE)r << 8
#define R_CASE1_SHIFT(r) (WORD)(BYTE)(r) << 8
#define R_CASE2_SHIFT(r) (WORD)((BYTE)(r)) << 8
#define TRGB(r,g,b) ((COLORREF)(((BYTE)(r)|(((WORD)(BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
// RGBマクロここまで
#endif
// main.cpp
#ifndef IOSTREAM
#include <iostream>
#endif
#include "macrosTester.h"
int main()
{
using namespace std;
char a{ 1 }, b{ 1 }; WORD w1{ 0 }, w2{ 0 }, w3{ 0 }; // 両方とも2^(1+8) = 512になることを期待したマクロ w1 = R_CASE1_SHIFT(a + b); cout << "R_CASE1 : r = " << w1 << ", type = " << typeid(w1).name() << endl; w2 = R_CASE2_SHIFT(a + b); cout << "R_CASE2 : r = " << w2 << ", type = " << typeid(w2).name() << endl; // 結果:期待通り // ではそもそも欠点のあるタイプでは? w3 = R_SHIFT(a + b); cout << "R_SHIFT : r = " << w3 << ", type = " << typeid(w3).name() << endl; // <<演算子の優先順位が~のエラーが出るものの512 // RGBマクロ本家のg部分のシフトを(DWORD)(BYTE)(g)に // 変更した場合との比較 char r{ 1 }, g{ 2 }; DWORD result1{ 0 }, result2{ 0 }; // 意地悪な式を代入 result1 = RGB(r+a, r%3/(g+a+b)*a+b, b+b); cout << "RGB = " << result1 << ", type = " << typeid(result1).name() << endl; result2 = TRGB(r+a, r%3/(g+a+b)*a+b, b+b); cout << "TRGB = " << result2 << ", type = " << typeid(result2).name() << endl; // 結果:どちらも同じ131330 return 0;
}
※少なくともvisual C++2013版では特に意味はないみたいです.
これがC++98や03になってくるとコンパイラの賢さとかでまた変わってくるかもしれませんが.
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/04/15 05:16