ab.com コミュニティ

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

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




新しいトピックを投稿する  トピックへ返信する  [ 4 件の記事 ] 
作成者 メッセージ
 記事の件名: アラインメント指定
投稿記事Posted: 2006年4月01日(土) 00:37 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
このコードでは16と出力されます。
コード:
#strict
#prompt

Type Align(8) S1
	x As DWord
	y As DWord
End Type

Print SizeOf (S1)
しかしそれと同等と私が思った次のVC++のコードでは8が出力されます。
コード:
#include <iostream>
#include <windows.h>

__declspec(align(8)) struct S1
{
	DWORD x;
	DWORD y;
};

int main()
{
	std::cout << sizeof (S1) << std::endl;
}
色々と試してみると,次のコードでは16と出力されました。
コード:
#include <iostream>
#include <windows.h>

struct S1
{
	__declspec(align(8)) DWORD x;
	__declspec(align(8)) DWORD y;
};

int main()
{
	std::cout << sizeof (S1) << std::endl;
}
つまりアラインメントの対象が構造体全体であるか,個々のメンバであるかの違いのようです。

私はABのTypeに指定するAlignは構造体全体に対するアラインメントの指定であるべきだと思います。
つまり最初のABのコードは前者のVC++のコードに対応するようにするということです。

そもそもWinAPIで使われる構造体の中には8バイトアラインメントが指定されているものがあります。
そのような構造体をABに持ってくるとき,試しにType Align(8)としてみたことからこのことに気づきました。

VC++ではalign(8)と指定されているのに,ABでは付けるとエラーになるので省くということは,
どうも違和感を感じさせます。それが前者の意味にしてほしいと言う理由ですね。


通報する
ページトップ
投稿記事Posted: 2006年4月01日(土) 13:24 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
お住まい: 高知
この件につきましては、私のコラム執筆にあたり、山本様とメールで
いくつかやりとりがありましたので、回答させて頂きます。

まず、ActiveBasicのアライメントについて抜粋
引用:
VC++のアライメントの初期値は8byte、
VB、BC++のアライメントは4byteなんですが
ABって何Byteなんでしょうか?
引用:
アラインメントに初期値はありません。

この説明は、非常に重要なポイントなので、よく理解してください。

そもそも、アラインメントとは、構造体の先頭を0としたときに、メンバ変数の
データサイズでそのオフセットが割り切れない場合に、発生するものです。パ
ディングを挿入して、そのメンバのデータサイズで割り切れるようにする働きが
あるんですね。
簡単にいうと「ActiveBasicはそもそもアライメントと呼ばれる概念が希薄で
APIで使用される構造体が問題なく動くように自動的に調節する。」ってことだそうです。

つまり、イグトランス様が試された
コード:
Type Align(8) S1
    x As DWord
    y As DWord
End Type
というコードはそもそもAlign(8)を付けなくてもActiveBasicでは問題なく
動くと言うことです。


結局Alignとは何なのか?ってことについて抜粋
引用:
構造体のアラインメントについては、コンパイラによって互換性が薄いようで
す。CPUの処理速度に関係してくる内容なので、ターゲットマシンやOSによって
仕様が異なるという意味では納得はできますが、、、作っているこちらもややこ
しい限りですf(^^

・自動調節(デフォルト)
・互換性を重視するため、1バイトまたは2バイトでアラインメントをとる

これら以外に関しては、必要なケースを見たことがありませんので、4~16バイ
トアラインメントに関して、何か問題が生じるようであれば、VCのものと比較し
ながらサポートを行おうと思います。
という返答を頂いております。
私も、最初は混乱しましたので、意見としてはイグトランス様に賛成です。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2006年4月04日(火) 23:54 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
最初にAlign(8)と付けてみたのはWin64への移植性が心配になったからです。
幸いにもx86系のCPUもアラインメントの扱いがなっていなくても動いてしまいますが,だからこそ心配になったのです。

そもそもNバイトにアラインメント(境界調整)するということは,
メモリアドレスがNの倍数になる位置に配置するということのはずです。

それで気づいたのですが,これは0と出力されなくてはいけないはずなのですが,そうではありませんでした。
(私がコンパイルすると4が出力されました。)
コード:
#strict
#prompt

Type Align(8) S1
    x As DWord
    y As DWord
End Type

Dim dw As DWord
Dim s1 As S1

Dim address As ULONG_PTR

Print (VarPtr(s1) As ULONG_PTR) Mod 8
そしてこれと(メンバの配置以外は)ほぼ等価なはずのVC++のコードです。
コード:
#include <iostream>
#include <windows.h>

__declspec(align(8)) struct S1
{
	DWORD x;
	DWORD y;
};

int main()
{
	using namespace std;
	DWORD dw;
	S1 s1;

	cout << reinterpret_cast<ULONG_PTR>(&s1) % 8 << endl;
	return 0;
}


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2006年4月05日(水) 00:47 
オフライン
Site Admin

登録日時: 2005年5月30日(月) 15:08
記事: 535
アラインメント、一番頭が痛くなる問題ですね。アプリが強制終了して、原因を突き詰めたらデータの境界ラインが8の倍数になってなかったとか…。64ビットコンパイラの製作場面では、しょっちゅう遭遇していました。


では本題。

引用:
私はABのTypeに指定するAlignは構造体全体に対するアラインメントの指定であるべきだと思います。
つまり最初のABのコードは前者のVC++のコードに対応するようにするということです。

そもそもWinAPIで使われる構造体の中には8バイトアラインメントが指定されているものがあります。
そのような構造体をABに持ってくるとき,試しにType Align(8)としてみたことからこのことに気づきました。

VC++ではalign(8)と指定されているのに,ABでは付けるとエラーになるので省くということは,
どうも違和感を感じさせます。それが前者の意味にしてほしいと言う理由ですね。
指定したアラインメント値よりも小さなデータ型が存在するとき、現状のABの仕様ではムリヤリにアラインメントをとっているのが現状です。

私のほうでも、VC++での動作の違いを確認できました。移植のことを考えると、あわせたほうが無難ですね。アラインメント誤差によるバグは一番やっかいなものであるのはご承知のとおりですので、改善しようと思います。

引用:
最初にAlign(8)と付けてみたのはWin64への移植性が心配になったからです。
幸いにもx86系のCPUもアラインメントの扱いがなっていなくても動いてしまいますが,だからこそ心配になったのです。

そもそもNバイトにアラインメント(境界調整)するということは,
メモリアドレスがNの倍数になる位置に配置するということのはずです。

それで気づいたのですが,これは0と出力されなくてはいけないはずなのですが,そうではありませんでした。
(私がコンパイルすると4が出力されました。)
鋭いポイントをつかれますねf(^^

確かに、Win64では、8バイト区切りのデータ配置を機械語が要求してきます(違反すると、強制終了になります)。よって、Win64の環境下では、各変数の先頭アドレスは8で割り切れる数値となっています。これは、Win32の環境とは異なる点です。

このように、現状の64ビット版ActiveBasicでは8バイト境界ラインを意識した仕様になっておりますので、ご安心ください。


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

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


オンラインデータ

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


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

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