コンパイラエクスプローラーでの関数と関数テンプレート間の出力の比較

フランシス・カグラー

両方ともここで見ることができる階乗関数の単純なバージョンを実装しましたGCCトランクを使用しています。2つのソースファイルがあり、1つ目は関数バージョンで、2つ目はテンプレートバージョンです。各ソースファイルには、関連する出力を持つ2つのコンパイラが添付されています。各ソースファイルに接続されている2つのコンパイラの唯一の違いは、左側のコンパイラではコンパイラフラグまたは最適化がオンになっておらず、右側のバージョンでは-O3レベル3の最適化がオンに設定されていることです。

これが私の機能です:

// Function Version
int factorial(int n) {
    if (n == 0 || n == 1) return 1;
    if (n == 2) return 2;
    return (n * factorial(n-1));
}

// Template Version:
template<unsigned N>
static auto constexpr factorial_t() {
    return (N * factorial<N-1>());
}

template<>
auto constexpr factorial_t<0>() {
    return 1;
}
template<>
auto constexpr factorial_t<1>() {
    return 1;
}
template<>
auto constexpr factorial_t<2>() {
    return 2;
}

IDE Visual Studio 2017を使用してローカルPCにインストールしたものでこれらを実行すると、c++17期待される出力がから返されmain()、戻り値は両方の実装で正しいです。

これをCompilerExplorerに移植して、他のコンパイラとその最適化をテストし、生成されたアセンブリ命令を比較しました。これはかなり簡単なプロセスです。

これらの関数をそのように実行すると、次のようになります。

ソース#1

int main() {
    return factorial(6);
}

ソース#2

int main() {
    return factorial_t<6>();
}

コンパイラエクスプローラは、次の命令カウントを生成します。

  •          |   Assembly Instruction Count   |
    
  • Type     | Without O3 | With O3 Turned On |  
    
  • Function |     34     |       29          |
    
  • Template |     50     |        3          |
    

すべてが良いです。

4つのプログラム実行はすべて、値を返します208

今私の質問に:

ただし、レジスタの計算を行わずに、最初と3番目のコンパイラのアセンブリ内で直接明らかではありませんが、バージョンバージョンの-O3両方オンになっている2番目と最後のコンパイラでは、値のリターン呼び出しのレジスタに格納されます。なぜコンパイラExplorerが表示されます。代わりにfunctiontemplate720EAXmain()Program returned: 208720

アラン・バートルズ

mainを返すように定義されていintます。mainが返された、c ++ランタイムはstd::exitから返された値を使用して(または同等のコードを)呼び出しますmain

std::exitint終了コードも受け取ります。この終了コードがどのようにプロセス戻りコードに変換されるかは、実装によって定義されます。

Unixでは、プロセスの戻りコードは通常、単一の符号なしバイトであるため、-intに収まるように単純に切り捨てられます。0255

Windowsプロセスでは、戻りコードは32ビットの符号付き整数であるため、int渡されstd::exitは直接返されます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

テンプレート関数のインスタンス化でのコンパイラエラー

分類Dev

テンプレートクラスのstdスレッド呼び出しテンプレートメンバー関数:コンパイラエラー

分類Dev

テンプレートクラスでのテンプレート関数のオーバーロード

分類Dev

クラステンプレートと関数テンプレートの混合

分類Dev

関数テンプレートの引数の演繹(クラスと関数テンプレート)

分類Dev

コンストラクターとプロトタイプ内の関数

分類Dev

クラスと関数テンプレートの特殊化

分類Dev

テンプレート関数とクラスの混合

分類Dev

テンプレートクラスのフレンド関数とのリンクエラー

分類Dev

遅延保存プロパティで関数を使用するときのコンパイラエラー

分類Dev

C ++ gcc関数テンプレートのオーバーロードコンパイラの問題

分類Dev

テンプレートクラスメンバー関数間の循環依存

分類Dev

クラス内での(コンテナタイプ上での)テンプレート関数の宣言と、コンテナタイプ上でのテンプレートクラス外でのその定義-

分類Dev

コンストラクターとJavaスクリプトの別の関数間の共有ロジック

分類Dev

同数のテンプレートと関数のパラメーター

分類Dev

クラステンプレート内で定義されたフレンド関数。関数テンプレートの再定義エラー

分類Dev

テンプレートクラスの静的関数またはポインタへのスコープ解決

分類Dev

テンプレートクラス定義の下でのインライン関数の定義

分類Dev

JavaScriptでコンストラクター関数内のプロパティをフリーズする方法

分類Dev

テンプレートクラス内のテンプレート関数

分類Dev

テンプレートクラスの非テンプレート関数

分類Dev

Azure関数アプリのデプロイとリリースのパイプラインエラー

分類Dev

テンプレート関数によるテンプレートクラスのオーバーロード

分類Dev

constexprコンストラクターと関数でのリテラルクラスのコンパイルエラー(異なるvc、g ++)

分類Dev

関数内のスライスのコンテンツと容量をインプレースで変更する

分類Dev

テンプレートクラスのテンプレート可変個引数関数はコンパイルされません

分類Dev

Lambda関数のインラインコードプロパティにあるCloudFormationテンプレートの参照リソース

分類Dev

テンプレートクラスでのテンプレートメンバー関数の特殊化

分類Dev

テンプレートコンテナのconst関数のメンバー変数を変更するコンパイラエラー

Related 関連記事

  1. 1

    テンプレート関数のインスタンス化でのコンパイラエラー

  2. 2

    テンプレートクラスのstdスレッド呼び出しテンプレートメンバー関数:コンパイラエラー

  3. 3

    テンプレートクラスでのテンプレート関数のオーバーロード

  4. 4

    クラステンプレートと関数テンプレートの混合

  5. 5

    関数テンプレートの引数の演繹(クラスと関数テンプレート)

  6. 6

    コンストラクターとプロトタイプ内の関数

  7. 7

    クラスと関数テンプレートの特殊化

  8. 8

    テンプレート関数とクラスの混合

  9. 9

    テンプレートクラスのフレンド関数とのリンクエラー

  10. 10

    遅延保存プロパティで関数を使用するときのコンパイラエラー

  11. 11

    C ++ gcc関数テンプレートのオーバーロードコンパイラの問題

  12. 12

    テンプレートクラスメンバー関数間の循環依存

  13. 13

    クラス内での(コンテナタイプ上での)テンプレート関数の宣言と、コンテナタイプ上でのテンプレートクラス外でのその定義-

  14. 14

    コンストラクターとJavaスクリプトの別の関数間の共有ロジック

  15. 15

    同数のテンプレートと関数のパラメーター

  16. 16

    クラステンプレート内で定義されたフレンド関数。関数テンプレートの再定義エラー

  17. 17

    テンプレートクラスの静的関数またはポインタへのスコープ解決

  18. 18

    テンプレートクラス定義の下でのインライン関数の定義

  19. 19

    JavaScriptでコンストラクター関数内のプロパティをフリーズする方法

  20. 20

    テンプレートクラス内のテンプレート関数

  21. 21

    テンプレートクラスの非テンプレート関数

  22. 22

    Azure関数アプリのデプロイとリリースのパイプラインエラー

  23. 23

    テンプレート関数によるテンプレートクラスのオーバーロード

  24. 24

    constexprコンストラクターと関数でのリテラルクラスのコンパイルエラー(異なるvc、g ++)

  25. 25

    関数内のスライスのコンテンツと容量をインプレースで変更する

  26. 26

    テンプレートクラスのテンプレート可変個引数関数はコンパイルされません

  27. 27

    Lambda関数のインラインコードプロパティにあるCloudFormationテンプレートの参照リソース

  28. 28

    テンプレートクラスでのテンプレートメンバー関数の特殊化

  29. 29

    テンプレートコンテナのconst関数のメンバー変数を変更するコンパイラエラー

ホットタグ

アーカイブ