Main Content

生成されたコードと MATLAB コードの外観の相違点

MATLAB® Coder™ は、動的に型指定された MATLAB コードを静的に型指定された C/C++ に変換し、最適化します。静的型付き言語では変数の型が明示的に宣言されている必要があり、これらの型はコンパイル時に決定されます。コード ジェネレーターによって特定の変更や最適化が実行されるため、生成されたコードで MATLAB のデータ型と機能を使用できます。コード生成でサポートされるデータ型と機能の詳細については、データ定義およびC/C++ コード生成でサポートされている MATLAB 言語機能を参照してください。

これらの変更や最適化が行われるため、生成されたコードの外観は MATLAB コードとは異なります。次のいずれかが原因で、生成されたコードは MATLAB コードと 1 対 1 の方法でマッピングされない可能性があります。

メモ

ソース コードによっては、これらのケースがここに示す内容とは少し異なる方法で発生する場合があります。

MATLAB 関数の C/C++ 関数へのマッピング

MATLAB Coder は、MATLAB コードからスタンドアロン C/C++ コードと MEX コードを生成します。MATLAB コード内の 1 つの関数が、生成されたコードで複数の関数に変換される場合があります。また、MATLAB コード内の 2 つ以上の関数が、生成されたコードで 1 つの関数本体になる場合もあります。この処理は関数のインライン化と呼ばれます。既定では、コード ジェネレーターは、内部のヒューリスティックな方法を使用して関数をインライン化するかどうかを判定します。詳細については、生成コードのパフォーマンスと可読性を微調整するためのインライン化の制御を参照してください。

関数出力の表現

MATLAB 関数の出力は、C の戻り値になる場合や参照渡しの入力になる場合があります。MATLAB コード内の 1 つのスカラー出力が、生成されたコードで戻り値として扱われます。

  • 関数 addOne には入力変数 x と出力変数 y があります。次の例では、x の型は double です。

    function y = addOne(x)
    y = x + 1;
    end

    このスニペットに対して生成されたコードは次のとおりです。

    double addOne(double x)
    {
      return x + 1.0;
    }

    関数 addOne への入力 x は、生成されたコードで値受け渡し変数として扱われます。MATLAB 関数の出力は、生成されたコード内の値で返されます。

  • 配列の場合、出力は参照によって渡されることがあります。次に示すコードの抜粋では、double 入力 x と配列出力 y を使用しています。

    function y = addMat(x)
    z = [1:100];
    y = z + x;
    end
    

    出力変数 y は、次に示す生成されたコードで参照渡し配列変数に変換されます。

    void addMat(double x, double y[100])
    {
      int i;
      for (i = 0; i < 100; i++) {
        y[i] = ((double)i + 1.0) + x;
      }
    }
  • 複数の出力変数をもつエントリポイント関数の場合、出力は生成されたコードで参照によって渡されることがあります。このコードの抜粋には、double の 2 つのスカラー出力 y および zdouble のスカラー入力 x があります。

    function [z,y] = splitOne(x)
    y = x + 1;
    z = x + 2;
    end
    

    出力変数 y および z は、生成されたコードで参照渡し変数に変換されます。

    void splitOne(double x, double *z, double *y)
    {
      *y = x + 1.0;
      *z = x + 2.0;
    }

生成されたコードでのエントリポイント関数による引数渡しの動作の詳細については、生成コードの展開を参照してください。

生成されたコードでの定数値の削除

コード内の定数値は、生成されたコードでは保持されない場合があります。これらの値は、生成されたコードを最適化するために削除されることがあります。定数畳み込みにより、MATLAB コードに存在していた可能性のある計算が削除され、代わりにその計算が結果に置き換えられます。詳細については、定数畳み込みを参照してください。

たとえば、以下のコードの抜粋について考えます。

function y = removeConst
x = ones(10);
y = x + 1;
end

コード ジェネレーターは、メモリを節約するために定数行列 x を削除し、定数値を結果として割り当てます。生成されたコードは以下のコードのように表示されます。

void removeConst(double y[100])
{
  int i;
  for (i = 0; i < 100; i++) {
    y[i] = 2.0;
  }
}

MATLAB コード内のエントリポイント関数以外の関数に対する未使用の入力または定数入力は、生成されたコードでは関数本体から削除されます。

コード ジェネレーターによる関数の特殊化では、関数を、入力型、サイズ、実数/複素数または値が関数の特定の呼び出し用にカスタマイズされる場合があるバージョンに変更できます。これは効率的な C コードを生成するために行われますが、コードが重複します。詳細については、特殊な関数またはクラスを参照してください。

行列要素へのアクセス

前の例で行列にアクセスするには、C/C++ の追加のコード行が必要です。1010 列の行列は、生成されたコードでは 100 個の double 要素の配列として表されます。配列要素にアクセスするには for ループを使用します。C/C++ では多くの行列演算がサポートされないため、コード ジェネレーターは行列と行列に対する演算を、配列とその配列にアクセスするための for ループなどのメソッドに変換します。

算術演算とその他の関数呼び出し

生成されたコードでは、MATLAB コード内の算術演算やその他の関数を実行するために標準 C ライブラリが使用される場合があります。サポートされている言語関数の一覧については、C/C++ コード生成でサポートされている MATLAB 言語機能を参照してください。

可変サイズの配列

コード生成では、配列は固定サイズまたは可変サイズになります。可変サイズの配列は、生成されたコードでは異なる形式で表示される場合があります。コード ジェネレーターで配列のサイズを確認できる場合は、固定サイズの配列のコードを生成できます。また、コード生成は上限のある固定サイズの配列に対しても有効です。場合によっては、動的に割り当てられた配列も生成されます。可変サイズの配列のコード生成を参照してください。

固定サイズの配列と可変サイズの配列のコード生成により、生成されたコードで次の変数宣言が得られる場合があります。

double x[10];        // Fixed-size array
double y_data[20];
int y_size[2];       // y_data and y_size denote an upper-bounded array
emxArrayReal_T *z;   // Dynamically allocated array

生成されたコード内のローカル変数

MATLAB コードに大量のメモリを占有するローカル変数が含まれている場合、生成されたコードでは、その変数はローカル変数、静的なローカル変数、または生成されたコード内のエントリポイント関数に渡される struct 内の変数として宣言される可能性があります。この変換を制御するには、生成されたコードに割り当てられるメモリを制御します。スタック領域使用量の制御を参照してください。

生成されたコード内の cell 配列

生成されたコードに cell 配列を実装するために、コード ジェネレーターはその配列を struct、静的な配列、または動的な配列に変換する可能性があります。詳細については、cell 配列のコード生成を参照してください。

初期化関数と終了関数

コード ジェネレーターは、初期化と終了の 2 つのハウスキーピング関数を作成する場合があります。これらの関数は、コード生成レポートの [生成されるコード] タブで確認できます。初期化関数は、生成される C/C++ エントリポイント関数が扱う状態を初期化します。終了関数は、割り当て済みのメモリを解放し、その他のクリーンアップ操作を実行します。詳細については、生成された初期化関数と終了関数の使用を参照してください。

関連するトピック