3

Cでは、MSVCおよび/またはGCCを使用して、関数パラメータの配置を制御できますか?

例えば

int main()
{
  __declspec( align(64) ) unsigned long long int
    test = 5;
  my_function_call( test );
  return( EXIT_SUCCESS );
}

void my_function_call( unsigned long long int fc_test )
{
  return;
}

私が達成したいのは、fc_test が 64 バイトにアラインされていることです。

AFAICT、これは不可能ですが、確認/拒否が求められます.

4

2 に答える 2

3

my_function_call が呼び出されると、test のコピーが渡されます。テスト自体に合格したわけではないため、テストのアライメントは関係ありません。配置属性は、値ではなく、テスト オブジェクトのプロパティです。

引数は、プラットフォーム固有の方法で渡されます。通常、小さな引数はレジスタで渡されます。ほとんどのマシンでは、レジスタはメモリの一部ではない特別なハードウェアであるため、アドレスがなく、アライメントもありません。

引数が大きい場合、プラットフォームの仕様によって、引数がメモリに渡されることが指定されている場合があります。次に、test のコピーをメモリに配置し、そのアドレスを呼び出された関数に渡し、呼び出された関数がそのアドレスを使用してコピーを取得するのは、呼び出し元の関数の仕事です。コンパイラがその一時コピーの配置に何らかの影響を与える可能性はありますが、そうするコンパイラは知りません。

何らかの理由で、呼び出された関数にアラインされたアドレスを渡したい場合は、test の値を渡す代わりに、そのアドレスまたはコピーのアドレスを渡します (これもアラインメント属性として)。さらに、アラインされたアドレスを渡し、呼び出された関数にアラインされていることを認識させたい場合は、関数のパラメーターを、アラインメント属性を持つ型へのポインターとして宣言します。(これを行うための構文は、標準 C の一部ではないため、コンパイラによって異なります。そうする手段は、typedef を使用して型を定義し、typedef にアライメント属性を含めてから、関数パラメーターを宣言することだと思います。その型へのポインタになります。)

正当な理由なしに、オブジェクトの位置合わせを気にするべきではありません。

于 2012-07-15T12:06:07.603 に答える
-1

x64では、アライメントは16バイトです。

ARMでは、8バイトでの配置。

x86では、アライメントは4バイトです。スタック上の変数を値で、連続するダブルワードのコンペアアンドスワップを実行する関数に渡すと、位置がずれてセグメンテーション違反になる可能性があります。変数のアドレスを渡すか、ローカル変数を定義して引数のコピーを作成する必要があると思います。

MSVCでは制御できないように見えます。GCC、スタック変数定義のアラインメント修飾子(!)を尊重しているようです。

于 2012-07-15T15:27:31.827 に答える