++ 4.9.2と5.3.1を生成++グラム上の集約初期の配列は、このコードはコンパイルに数秒かかり、52776バイトの実行ファイルを生成します。のstd :: G上の巨大なコード
#include <array>
#include <iostream>
int main()
{
constexpr std::size_t size = 4096;
struct S
{
float f;
S() : f(0.0f) {}
};
std::array<S, size> a = {}; // <-- note aggregate initialization
for (auto& e : a)
std::cerr << e.f;
return 0;
}
size
を増やすには、ように見えますコンパイル時間と実行可能なサイズを直線的に増やします。私はclang 3.5またはVisual C++ 2015でこの動作を再現することはできません。-Os
を使用すると違いはありません。
movl
命令生成、
a
の初期化が展開されていることが明らかになった点検
$ time g++ -O2 -std=c++11 test.cpp
real 0m4.178s
user 0m4.060s
sys 0m0.068s
:
main:
.LFB1313:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
subq $16384, %rsp
.cfi_def_cfa_offset 16400
movl $0x00000000, (%rsp)
movl $0x00000000, 4(%rsp)
movq %rsp, %rbx
movl $0x00000000, 8(%rsp)
movl $0x00000000, 12(%rsp)
movl $0x00000000, 16(%rsp)
[...skipping 4000 lines...]
movl $0x00000000, 16376(%rsp)
movl $0x00000000, 16380(%rsp)
T
が非自明なコンストラクタを有し、アレイが初期化されるときにのみ起こると{}
を使用してください。以下のいずれかを実行すると、g ++は単純なループを生成します。
S::S()
を削除します。S::S()
を削除し、クラス内でS::f
を初期化します。- 集約初期化(
= {}
)を削除します。 -O2
なしでコンパイルします。
私は最適化としてループをアンロールしていますが、これは非常に良いとは思いません。これをバグとして報告する前に、誰かがこれが期待される行動かどうかを確認できますか?
[編集:私はa new bugを開こうとしました。これは他のものとは一致しないようです。彼らは奇妙なコードジェネよりも長いコンパイル時間になりました。]
ワウ。 g ++は6.1でも同様です。コンパイラにクラッシュさせて、godboltに関するバグ報告を提出する:https://godbolt.org/g/Ae75GH – NathanOliver
@ NathanOliver Welp、それはちょっと確認する。ありがとう。 – isanae
gccのconstexpr配列の処理も疑わしいです。 constexpr std :: arrayを初期化するときも同様です。 = make_array(...)make_array()はconstexprです。 –