2017-01-11 2 views
3

次の例では、static_assertを使用して、fooがコンパイル時に決定されることを確認します。 static_assertが合格し、私はそれが実際にアクティブである間違った条件でチェックしました。これは、コンパイル時にfooがわかっていることを意味します。しかし、デバッガでコードをステップ実行すると、実行時にskip_first_wordも実行されることがわかります。コンパイル時および実行時に評価されるconst char * constexpr

// Skip the first word in p_str 
constexpr const char * skip_first_word(const char * p_str) { 
    return (*p_str == '\0') ? p_str : 
     (*p_str == ' ') ? p_str + 1 : 
     skip_first_word(p_str + 1); 
} 

// constexpr to calculate the length of a string 
constexpr size_t str_len(const char * p_str) { 
    return (*p_str == '\0') ? 0 : str_len(p_str + 1) + 1; 
} 

int main() 
{ 
    constexpr auto foo = skip_first_word("Hello, World!"); 
    constexpr auto foo_size = str_len(foo); 
    static_assert(foo_size == 6, "Wrong size"); 

    // This assert successfully fails 
    // static_assert(foo_size == 7, "Wrong size"); 

    // Prevent optimizations 
    for(auto ptr = foo; *ptr != '\0'; ++ptr) { 
     volatile auto sink = ptr; 
    } 
    volatile auto sink = &foo_size; 

    return 0; 
} 

ここでは何が起こっていますか?コンパイル時に計算されたfooを実行時に使用できないのはなぜですか?

編集:この動作は、Visual Studioの2015

+0

両方のケースで同じ最適化レベルを使用しましたが、それは正しいですか? –

+0

@ n.caillouはい、最適化の有無にかかわらず両方のケースを実行しました。 –

+0

@FrançoisAndrieux:VS2015の動作をカバーするために私の答えを更新しました –

答えて

5

gcc.godbolt.orgで観察されたが、あなたのコードが完全に-std=c++11 -O1のフラグを使用して、GCC 7打ち鳴らす3.9の両方でアウトに最適化されていることを示しています。

volatileの操作のコメントを外しても明らかにアセンブリ命令が生成されますが、skip_first_wordまたはstr_lenの命令は生成されません。


あなたは、Visual Studioに関する正しいです:CL 19 on gcc.beta.godbolt.orgを使用して、そのアセンブリがために生成されている例を示します

constexpr auto foo = skip_first_word("Hello, World!"); 
constexpr auto foo_size = str_len(foo); 

constexpr変数は、完全に計算することができる必要があるように、これは、コンパイラの実装不良のように思えますコンパイル時にさらに、変数はstatic_assertの内部で使用されており、で評価されることが保証されているのはです。これは、コンパイラが実行時のコンテキストで使用されることはありませんが、skip_first_wordstr_lenのアセンブリを不必要に生成していることを示唆しています。次のように手動でコードをインライン化

...

static_assert(str_len(skip_first_word("Hello, World!")) == 6, "Wrong size"); 
static_assert(str_len(skip_first_word("Hello, World!")) != 7, "Wrong size"); 

...produces no extra assembly

関連する問題