gcc c ++ 11限制用户定义的常量和模板参数包 [英] gcc c++11 limits for user defined constants and template parameter packs

查看:173
本文介绍了gcc c ++ 11限制用户定义的常量和模板参数包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在gcc 4.7.2中使用用户定义的常量,并遇到了一些我不太理解的大小限制因素。

I've been playing with user defined constants in gcc 4.7.2 and ran into some sort of size limiting factors which I do not quite understand.

是为定点十进制类型定义一个constexpr运算符。我想避免从双转换,而是在编译时使用可变参数模板解析尾数和指数。尾数解析证明有点棘手。

The idea was to define a constexpr operator "" for fixed point decimal type. I want to avoid casting from double but rather parse mantissa and exponent at compilation time using variadic templates. The mantissa parsing proved a bit tricky.

当我启用下面代码底部的3个禁用行中的任何一行时,gcc会陷入无限循环并挂在那里。我注意到相同的最大大小的浮点文字和显式实例化的可变参数模板,但稍大的整数文字大小。

When I enable any of the 3 disabled lines at the bottom of the code below, gcc falls into infinite loop and hangs there. I noticed the same max size for floating point literal and explicit instantiation of the variadic template but slightly larger size for integer literal.

我使用命令:g ++ -std = c + +11 -Wall -g -o literal_value literal_value.cpp

I used command: g++ -std=c++11 -Wall -g -o literal_value literal_value.cpp

使用-ftemplate-depth-128没有区别。

Using -ftemplate-depth-128 makes no difference.

#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中的错误还是我缺少

Is that a bug in gcc or am I missing something?

推荐答案

我必须说,你发现了一些不错的角落使编译器疯了:-)对我来说gcc 4.7.2和4.8在编译期间崩溃。但是cl(顶部版本)编译整个代码很好,但使用2.4GB RAM。问题似乎被连接到ternaty运算符'。'检查。如果你删除它,并在main()中注释实数测试,一切都编译得像一个爆炸。

I must say that you found some nice corner case that makes compilers crazy :-) For me gcc 4.7.2 and 4.8 crashed during compilation. However clang (top version) compiled whole code fine but was using 2.4GB RAM. The problem seems to be connected to ternaty operator for '.' check. If you remove it and comment real number tests in main() everything compiles fine like a blast.

因此回答你的问题,你可能不会错过任何东西,gcc和clang需要可能根据您的情况修改其实施。

So answering your question you probably do not miss anything and gcc and clang need to probably revise their implementaion based on your case.

这篇关于gcc c ++ 11限制用户定义的常量和模板参数包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆