ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月29日(金) 02:28

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 13 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年8月04日(木) 00:38 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
型のキャストについて
引用:
コミュニティトピック : これはエラーを出したほうが良いと思います
http://www.discoversoft.net/forum/viewtopic.php?t=251

Discoversoft管理人日記 : ABのタイプキャスト問題
http://d.hatena.ne.jp/dai_optimistic/20050804
というこでして、現行AB4は型チェックが甘いんじゃないかというご指摘…。今後は複雑化するであろうコードを前提としていかなければならないので、最低限の言語仕様として、型のキャストを考えていく必要があります。


早速、型のキャストについての案件なのですが…



1. #strictディレクティブ
ソースコード中に"#strict"が存在すると、厳密な型チェックを行うようにします。指定されていない場合は、現在と同様、型チェックはプログラマーに任せられます。


2. キャストについて
CDbl、CSng、CLong、CDWord、CInteger、CShort、CByte、CCharなど、キャストの際に使うコンパイラ埋め込み型関数を追加します。しかし、この手法を採用するとある問題が出てきます。それは、オブジェクトポインタのキャストです。

C言語では、

RECT *pRect;
void *ptr;
pRect=(RECT *)ptr;

という記述ができますが、この案件のキャストは関数の形をしているため、オブジェクトポインタの型を明示できなくなります。となると、C言語のように、カッコで型名をくくるなどの対策が必要になりますが、そうすると更にC/C++の色が強くなってしまいそうです。それに加え、熟練したプログラマーであればC/C++風のキャストは便利なのですが、Basic言語としての取っ付き易さを考慮するとあまり気の進む仕様変更でもありません。

いっそのこと、すべてのポインタ変数はCPtrというキャスト関数で済ませてしまい、VoidPtr扱いにしてしまうか…。そうすると、またまた甘い型チェックということになってしまいそうです…。

こんな感じでキャストの方法が一番悩ましいところです。何かいい記述方法、ありませんでしょうか…?


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月04日(木) 08:42 
以下の2方法が考えられます。

1.CPtrの第二引数にポインタの型を指定

Dim pRect as *RECT
Dim ptr as VoidPtr
pRect=CPtr(ptr,RECT)

2.Castの第二引数に変換後の型を指定

Dim pRect as *RECT
Dim ptr as VoidPtr
pRect=Cast(ptr,*RECT)


通報する
ページトップ
   
投稿記事Posted: 2005年8月04日(木) 08:43 
オフライン

登録日時: 2005年5月31日(火) 20:14
記事: 203
お住まい: 兵庫県
> CDbl、CSng、CLong、CDWord、CInteger、CShort、CByte、CCharなど、キャストの際に使うコンパイラ埋め込み型関数を追加します。しかし、この手法を採用するとある問題が出てきます。それは、オブジェクトポインタのキャストです。
>
> C言語では、
>
> RECT *pRect;
> void *ptr;
> pRect=(RECT *)ptr;
>
> という記述ができますが、この案件のキャストは関数の形をしているため、オブジェクトポインタの型を明示できなくなります。となると、C言語のように、カッコで型名をくくるなどの対策が必要になりますが、そうすると更にC/C++の色が強くなってしまいそうです。それに加え、熟練したプログラマーであればC/C++風のキャストは便利なのですが、Basic言語としての取っ付き易さを考慮するとあまり気の進む仕様変更でもありません。

SizeOf関数で行われているように、引数に型名を取れるようにしてはどうでしょうか?
例えば pRect=Cast(ptr,*RECT) のような感じです。
または、Cast(ptr As *RECT) のようにするという手もあるかもしれません。
どちらにしても、少々強引な気がしないでもないですが…。

_________________
[hira]
http://hira.hopto.org/


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月04日(木) 09:38 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
もしCスタイルのキャストを採用するなら、それよりもC++/D形式のスタイルがいいのではないかと思います。
C++はstatic_cast<型>(式)などで、Dはcast(型)式という形です。
コード:
RECT *pRect1, *pRect2; 
void *ptr;
pRect1 = static_cast<RECT *>(ptr); /* C++ */
pRect2 = cast(RECT *)ptr; /* D */
ようするにCスタイルのキャストだけは勘弁してくれということです。あとからコードを見たときうっかり見過ごしてしまいそうなほどCスタイルキャストは目立ちません。
もちろんxsb007さんやhiraさんのCast関数の引数というのも悪くありません。
それどころか今1番いいんじゃないかと考えているのはhiraさんのAsです。私は括弧は要らなさそうに思うのでCast ptr As *RECTはどうかと思います。

ところでC#にはキャストの一種としてasがあり、構文は式 as 型でhiraさんの案に偶然ながら近いです。あちゃ、これでもいいような気もしてくる。
コード:
pRect = Cast(ptr As *RECT)
pRect = Cast ptr As *RECT
pRect = ptr As *RECT


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月04日(木) 11:04 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
"As 指定"、見過ごしていました。良さそうですね。

Dim a As *RECT
Dim base As *RECT
Dim i As Long
a=base As *RECT
a=(base As Long + i As Long) As *RECT

こういう記述もできそうです。これだったら、新しい仕様の使い勝手としてはかなりいいほうですね。有力候補として検討していこうと思います。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月04日(木) 22:26 
>"As 指定"、見過ごしていました。良さそうですね。

これならキャスト関数はコンパイラレベルでサポートしなくても、マクロ定義でできるから CastとC(型) 両方サポートするよりも簡単そうですね。

Const CByte(a) = ((a) As Byte)
Const CInt(a) = ((a) As Integer)
Const CLng(a) = ((a) As Long)
Const CDWord(a) = ((a) as DWord)
Const CSng(a) = ((a) as Single)
Const CDbl(a) = ((a) as Double)


通報する
ページトップ
   
投稿記事Posted: 2005年8月20日(土) 00:52 
型キャストの疑問はここでいいのかな…

さて、計算途中に型キャストを指定してもキャストされないのは仕様でしょうか?
コード:
#prompt
Dim A = &H7FFFFFFF As Long
Print Hex$((A As Word) - 1) '7FFFFFFE と表示されてしまう


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年8月20日(土) 01:15 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
引用:
型キャストの疑問はここでいいのかな…

さて、計算途中に型キャストを指定してもキャストされないのは仕様でしょうか?
コード:
#prompt
Dim A = &H7FFFFFFF As Long
Print Hex$((A As Word) - 1) '7FFFFFFE と表示されてしまう
ご報告ありがとうございます。16ビット整数値へのキャストを行ったときにデータの切り捨てが正常に行えないバグを確認できましたので、次回のバージョンアップで修正します。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月22日(月) 00:36 
たびたびすみません。
リテラル値を64bit整数型にキャストしたものを乗算しようとするとアクセス違反が起きます。
またキャストとは関係ないのですが、リテラル値同士の \ での除算が異常な値を返します。
ABver4.1beta1で確認しました。

(Codeで囲うと \ が / と表示されるようなのでべた書きで)
#prompt
Dim A = 356 As Word
Print Str$(356 \ 12) '2が表示される
Print Str$((A As QWord) * &HAAAAAAAB) '変数であれば問題なし
Print Str$((356 As DWord) * &HAAAAAAAB) '64bit整数型にキャストしなければ問題なし
Print Str$((356 As Int64) * &HAAAAAAAB) 'アクセス違反が起きる
Print Str$((356 As QWord) * &HAAAAAAAB) 'アクセス違反が起きる


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年8月22日(月) 02:30 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
引用:
リテラル値を64bit整数型にキャストしたものを乗算しようとするとアクセス違反が起きます。
またキャストとは関係ないのですが、リテラル値同士の \ での除算が異常な値を返します。
ABver4.1beta1で確認しました。

(Codeで囲うと \ が / と表示されるようなのでべた書きで)
#prompt
Dim A = 356 As Word
Print Str$(356 \ 12) '2が表示される
Print Str$((A As QWord) * &HAAAAAAAB) '変数であれば問題なし
Print Str$((356 As DWord) * &HAAAAAAAB) '64bit整数型にキャストしなければ問題なし
Print Str$((356 As Int64) * &HAAAAAAAB) 'アクセス違反が起きる
Print Str$((356 As QWord) * &HAAAAAAAB) 'アクセス違反が起きる
ご報告ありがとうございます。下記のバグを確認することができましたので、次回のバージョンアップで修正します。

・リテラル値同士の整数除算""が正常に行えないバグ
・64ビット整数値へのキャストをリテラル演算内で正常に行えないバグ


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2005年8月29日(月) 01:40 
キャストしたリテラル値を定数にしようとしても無効となるようです。
またキャスト関連とは違うバグですが、
#promptを指定したプログラムが最後にEnd命令語を呼び出さずに終了するとアクセス違反が起きます。
コード:
Const BYTE_MAX = (-1 As Byte)
#prompt
Print Str$(BYTE_MAX)


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年8月29日(月) 01:49 
環境を書き忘れました。
WinXp Home SP2
IE6 SP2
です。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年8月29日(月) 21:32 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
ご報告ありがとうございます。

Str$関数など、パラメータに浮動小数型を持つ場合に発生するようです。ようは、パラメータ引き渡し時にByte→Doubleの変換が正常に行われていないってことになります。

こちら、バグ扱いとなりますので、次回のバージョンアップで修正します。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 13 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[6人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean