論理値の型について – プログラミング – Home

通知
すべてクリア

[解決済] 論理値の型について

固定ページ 1 / 2

紅'
 紅'
(@紅')
ゲスト
結合: 17年前
投稿: 48
Topic starter  

VC での論理値(BOOL/bool)の型について教えてください。

これまで私は VC&MFC でプログラムを書く事が多く、論理値 = BOOL型 と考えていました。
もちろん bool 型も知っていたのですがあまり使わず、「同じようなもの」と括っていまし
た。

が、先ほど思いついて、以下の事柄を VC6.0 & ダイアログベースのプログラムを作成して試し
てみました。

bool a;
BOOL b;

a = b; // ( 1) コンパイル時に警告が出る
a = ( 1 == 1 ); // ( 2) 警告は出ない
b = ( 1 == 1 ); // ( 3) 警告は出ない
sizeof( a ); // ( 4) = 1
sizeof( b ); // ( 5) = 4
sizeof( 1 == 1 ); // ( 6) = 4
sizeof( 1 != 1 );     // ( 7) = 4
sizeof( ( 1 == 1 ) ); // ( 8) = 4
sizeof( !( 1 == 1 ) ); // ( 9) = 1
sizeof( !!( 1 == 1 ) ); // (10) = 1

上記の (8) までは判るとして、(6) ~ (8) までと (9)、(10) とが異なるのは
それが仕様であり当然の事と理解して良いのでしょうか。

感覚的には (6) 以降はすべて論理値であるはずなので、BOOL か bool の違いはあっても
同じ型だと認識していて、疑った事がありませんでした。(汗
VC の場合、! 演算子の戻り値が bool であり、他の論理式の型は BOOL との認識は正しいで
しょうか。

一応、検索を掛けて調べたところ、以下のような記述がみられました。

・論理値としては bool を用いるべき
・BOOL(もしくは型不明) から bool への変換は !!(論理値) が便利

ものすごく基本的な事柄でお恥ずかしい限りなのですが、ご教示いただければ幸いです。


引用未解決
トピックタグ
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

正直なところ知らない。
BOOLは言語で決められたものじゃなくてboolがなかった頃から存在したものなので
俺はBOOLをboolと同じものとは思わない。intと同じものと思っている。
個人的な感想だけどboolに変換することってあまりないから
!!を便利とは感じてなかったりする。
boolが出来るまで0か0以外だったし今でもそれは残っているし
あえてboolを使うことあまりないな。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> VC の場合、! 演算子の戻り値が bool であり、他の論理式の型は BOOL との認識は正
しいで
> しょうか。

正しくありません。

#include <windows.h>
#include <iostream>
#include <string>
#include <typeinfo>

int main ()
{
bool a = false;
BOOL b = FALSE;

std::cout << ( 4) << typeid( a ).name() << std::endl;
std::cout << ( 5) << typeid( b ).name() << std::endl;
std::cout << ( 6) << typeid( 1 == 1 ).name() << std::endl;
std::cout << ( 7) << typeid( 1 != 1 ).name() << std::endl;
std::cout << ( 8) << typeid( ( 1 == 1 ) ).name() << std::endl;
std::cout << ( 9) << typeid( !( 1 == 1 ) ).name() << std::endl;
std::cout << (10) << typeid( !!( 1 == 1 ) ).name() << std::endl;

return 0;
}
をいくつかのバージョンで実行してみました。
Visual Studio 6.0
( 4) bool
( 5) int
( 6) long
( 7) long
( 8) long
( 9) bool
(10) bool

Visual Studio.NET / Visual Studio.NET 2003 / Visual Studio 2005 / Visual C++
2008 Express Edition
( 4) bool
( 5) int
( 6) bool
( 7) bool
( 8) bool
( 9) bool
(10) bool
と,バージョンによって結果が別れました。
VC++ 6.0はなぜかlongとして認識していますが,これはBOOL,つまりはintではないの
で,別の認識になっています。
# 不思議な結果です。

どちらにしても,VS2002からはちゃんと修正されているので,VC++ 6.0が特殊だと思った
方がよいでしょう。


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

BOOLはintのtypedefであり、Win32API(つまりはC)やそれをラップしたMFC等で論理値が必
要な場合にBOOLを使います

VCとしてではなく、C++として考えた場合にはBOOLは使いません(言語仕様にもないです
し)

// ※ <windows.h>をインクルードしない
int main()
{
BOOL b; // エラー!BOOLなんてありません
return 0;
}

BOOL(int)からboolへは暗黙の変換があるので!!を使う必要はないはずです
(警告は出ますが)

if文もboolへの暗黙の変換があるので当然BOOLも使えます

BOOL b;
if (b)
...

if (!b)
...


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

既に出ているように、BOOL は C/C++ の言語規格にはなく、VC++ や Windows SDK が独自
に定義した型で、int の別名です。
ただし、中身が int だからといって int として扱うべきではなく、中身が 0 と それ以
外しかない真偽値として扱うべきです。
「0 とそれ以外しかない」って当たり前じゃないか、と思われるかもしれませんが、重要
なのは、値が2パターンしかないということです。1 も 2 も 2147483647 も真という同
じ値です。
とは言うものの、GetMessage みたいな腐った関数もあるわけですがorz

ちなみに、DDK には BOOLEAN という型があります。こいつは char の別名です。


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

BOOLからboolへの変換はこうすればいいような気もします

BOOL b;
bool a = b == TRUE;


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

> bool a = b == TRUE;
これはまずいのでは?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

BOOL b;
bool a = (b != FALSE);

なんだけど、bool への変換規則は
「0ならfalse / 0以外はみんなtrue」
だから

BOOL b;
bool a = b;

でいぃんじゃないかと。


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

申し訳ないです。逆でした。

×
>bool a = b == TRUE;


>bool a = (b != FALSE);

以下は正しいですが、VCだと警告がでます
bool a = b; // 警告:intを論理値trueかfalseに強制的に変換します


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> 以下は正しいですが、VCだと警告がでます
> bool a = b; // 警告:intを論理値trueかfalseに強制的に変換します

warning-level-3以上で文句言ってきますねぃ。
bool a = (b!=0); が妥当/無難かなー


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

bool a = bool( b);
で済ませてます(vv;)。ゼロ/非ゼロに分かれるようです。


返信引用
紅'
 紅'
(@紅')
ゲスト
結合: 17年前
投稿: 48
Topic starter  

みなさま、ご返信をありがとうございました。

まとめるとこんな感じでしょうか。

・共に真偽値(「論理値」から改めます)を示すはずの == と ! で
 型が違うのは VC6 の方言。2002 以降は bool に統一されている。
・BOOL は windows.h に定義されている古い?型。
 C/C++ で標準なのは bool 。BOOL は標準には存在しない。
・BOOL -> bool の変換には以下のような方法がある。
 - !!(真偽値)
 - ( (真偽値) != FALSE )
 - ( (真偽値) != 0 )
 - bool( (真偽値) )

以上からすると、移植性などを考え特に必要ない場合には BOOL ではなくて
bool を使う方が安全な気がします‥‥が。windows.h を使用する環境と
そうでない環境とで共用するライブラリ?で真偽値の型が混在してしまうと
言うのも抵抗がある‥‥。
( 私は BOOL を戻り値の型にする関数をよく書いてました orz )

YuO さんが試してくださった型チェックで VC6 の == などが long だったのには
どう反応して良いのやら。windows.h がない環境でやったらどうなるのかと
コンソールアプリで sizeof( 1 == 1 ) を試したら 4 バイトだったのに、やはり
BOOL がなかったのにはちょっと笑いましたが。long だったんですね。

あと、BOOL -> bool には、気づいた後は少し冗長ですが以下のように書いてました。

 - ( (真偽値) ? true : false )

たったこれだけの事でもいろいろな表現があって面白いですね。

本題からははずれますが、頂いたご意見の中にあった、
「真偽値は 0 とそれ以外」という原則について、実際に他人のコードをみると
これを無視した書き方が結構みられます。「(真偽値) == true」とか。

私は怖くてそういう書き方は出来ないのですが、やはり気をつけようと思います。
自分以外、ほとんど全員が先の例のような書き方をするので、正直ちょっと
自信がなくなってました。

と、言うわけで取りあえず 解決 とさせて頂きます。
ありがとうございました。

>とは言うものの、GetMessage みたいな腐った関数もあるわけですがorz

そうなんですよね...


返信引用
紅'
 紅'
(@紅')
ゲスト
結合: 17年前
投稿: 48
Topic starter  

ごめんなさい。
またチェックを入れるのを忘れてました。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> ・BOOL は windows.h に定義されている古い?型。
>  C/C++ で標準なのは bool 。BOOL は標準には存在しない。

Cで真偽値を扱うために広く使われているtypedefがBOOL。
Cにboolは存在しない。

と、思っているのだけど。規格とか今すぐに調べられません。
どなたか、フォロー or 駄目出しをお願いできません?


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> Cで真偽値を扱うために広く使われているtypedefがBOOL。
> Cにboolは存在しない。

Cでは_Bool型があります。
で,<stdbool.h>をインクルードすると,
bool, true, false, __bool_true_false_are_defined
の各マクロを定義します。

ただし,各種論理演算の結果はCにおいては_Bool型ではなくint型です。
さらに,これらはC99の新規要素なので,VC++ではまだ対応していないはずです。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました