私は gcc 4.7.2 でユーザー定義の定数をいじっていて、よくわからない何らかのサイズ制限要因に遭遇しました。
アイデアは、固定小数点 10 進数型の constexpr 演算子 "" を定義することでした。double からのキャストを避けたいのですが、可変個引数テンプレートを使用して、コンパイル時に仮数と指数を解析します。仮数部の解析は少しトリッキーでした。
以下のコードの下部にある 3 つの無効な行のいずれかを有効にすると、gcc が無限ループに陥り、そこでハングします。浮動小数点リテラルと可変個引数テンプレートの明示的なインスタンス化の最大サイズは同じですが、整数リテラルのサイズはわずかに大きいことに気付きました。
コマンドを使用しました: g++ -std=c++11 -Wall -g -oliteral_valueliteral_value.cpp
-ftemplate-depth-128 を使用しても違いはありません。
#include <iostream>
#include <cstdint>
typedef std::uint64_t value_type;
template<value_type Temp, char... List> struct literal_parser;
template<value_type Temp, char Head, char... List>
struct literal_parser<Temp, Head, List...>
{
static const value_type value = Head == '.' ?
literal_parser<Temp, List...>::value :
literal_parser<Temp * 10 + Head - '0', List...>::value;
};
template<value_type Temp, char Last>
struct literal_parser<Temp, Last>
{
static const value_type value = Last == '.' ?
Temp : Temp * 10 + Last - '0';
};
template<char... List>
inline constexpr value_type operator"" _value() noexcept
{
return literal_parser<0U, List...>::value;
}
int main()
{
std::cout << "value 1: " << 123456789012345678_value << std::endl;
std::cout << "value 2: " << 1.23456789012345_value << std::endl;
std::cout << "value 3: " << literal_parser<0U, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5'>::value << std::endl;
#if 0
std::cout << "value 4: " << 1234567890123456789_value << std::endl;
std::cout << "value 5: " << 1.234567890123456_value << std::endl;
std::cout << "value 6: " << literal_parser<0U, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6'>::value << std::endl;
#endif
}
それはgccのバグですか、それとも何か不足していますか?