libc ++ std :: istringstream不会引发异常.漏洞? [英] libc++ std::istringstream doesn't thrown exceptions. Bug?

查看:167
本文介绍了libc ++ std :: istringstream不会引发异常.漏洞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在配置了std::istringstream以设置failbit时引发异常后,libc ++没有发生任何异常(这是在Linux下使用libc ++ rt编译并由libcxxrt支持).我想这是libc ++或libcxxrt中的错误:

After configuring a std::istringstream to throw exceptions when failbit is set I get no exceptions happening with libc++ (this is under linux with libc++ compiled with support from libcxxrt). I suppose this is a bug in libc++ or libcxxrt:

#include <iostream>
#include <sstream>

template<typename T> std::istream &getvalue(std::istream &is, T &value, const T &default_value = T())
{
    std::stringstream ss;
    std::string s;
    std::getline(is, s, ',');
    ss << s;
    if((ss >> value).fail())
        value = default_value;
    return is;
}

int main()
{
    std::string s = "123,456,789";
    std::istringstream is(s);
    unsigned n;

    try
    {
        is.exceptions(std::ios::failbit | std::ios::eofbit);

        getvalue(is, n);
        std::cout << n << std::endl;

        getvalue(is, n);
        std::cout << n << std::endl;

        // Disable EOF exception on last bit
        is.exceptions(std::ios::failbit);

        getvalue(is, n);
        std::cout << n << std::endl;

        // Force Fail reading after EOF
        getvalue(is, n);
        std::cout << n << std::endl;
    }
    catch(std::ios::failure &fail)
    {
        std::cout << "Fail" << std::endl;
    }
}

libstdc ++的输出:

output for libstdc++:

123
456
789
Fail

libc ++/libcxxrt输出:

libc++/libcxxrt output:

123
456
789
0

编辑

也在OS X上进行了测试.

EDIT

Also tested on OS X.

提交的错误: http://llvm.org/bugs/show_bug.cgi?id = 15949

推荐答案

libc ++响应27.7.2.1 [istream]/p4,它描述了unsignedbasic_istream解析operator>>:

libc++ is responding to 27.7.2.1 [istream]/p4 which describes the basic_istream parse operator>> for unsigned:

如果这些被调用函数之一引发异常,则除非 明确指出,否则,输入函数会将badbit设置为错误 状态.如果在exceptions()中打开badbit,则输入函数重新抛出 没有完成其动作的异常,否则不会 抛出任何东西并继续进行,就好像被调用函数返回了一个 故障指示.

If one of these called functions throws an exception, then unless explicitly noted otherwise, the input function sets badbit in error state. If badbit is on in exceptions(), the input function rethrows the exception without completing its actions, otherwise it does not throw anything and proceeds as if the called function had returned a failure indication.

如果:

is.exceptions(std::ios::failbit | std::ios::badbit);

然后获得所需的行为.

123
456
789
Fail

更新

chico在下面的评论中正确地指出,他希望getline(is, s, ',')会抛出,而不是unsigned提取器.

chico rightly pointed out in the comments below that he expected getline(is, s, ',') to throw, not the unsigned extractor.

查看21.4.8.9 [string.io]/p7,它描述了此getline:

Looking at 21.4.8.9 [string.io]/p7 which describes this getline:

效果:表现为未格式化的输入函数(27.7.2.3),除了 它不会影响后续对的调用返回的值 basic_istream<> :: gcount().构造哨兵对象后,如果 哨兵转换为true,调用str.erase()然后提取 来自is的字符,并通过调用将它们附加到str str.append(1,c)直到出现以下任何一种情况:...

Effects: Behaves as an unformatted input function (27.7.2.3), except that it does not affect the value returned by subsequent calls to basic_istream<>::gcount(). After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c) until any of the following occurs: ...

所以问题变成了:

未格式化的输入函数的行为如何?

How does an unformatted input function behave?

27.7.2.3 [istream.unformatted]/p1说:

27.7.2.3 [istream.unformatted]/p1 says:

每个未格式化的输入函数都通过构造一个 带有默认参数noskipws的sendry类的对象(第二个) 说法正确.如果哨兵对象返回true,则转换为 类型为bool的值,该函数将努力获取所请求的 输入.否则,如果哨兵构造函数通过抛出 异常,或者当哨兵对象返回false时,将其转换为 类型为bool的值,该函数将返回而不会尝试获取 任何输入.无论哪种情况,提取的字符数均设置为 0;未格式化的输入函数,其字符数组为非零 size作为参数还应存储一个空字符(使用charT()) 在数组的第一个位置. 如果在此期间引发异常 输入,然后在错误状态为 315 上打开ios :: badbit. (从basic_ios<> :: clear()引发的异常不会被捕获或 如果(exceptions()& badbit)!= 0,则异常为 .它还计算提取的字符数.如果不 引发异常,它通过将计数存储在成员中而结束 对象并返回指定的值.无论如何,哨兵 对象在离开未格式化的输入函数之前被销毁.

Each unformatted input function begins execution by constructing an object of class sentry with the default argument noskipws (second) argument true. If the sentry object returns true, when converted to a value of type bool, the function endeavors to obtain the requested input. Otherwise, if the sentry constructor exits by throwing an exception or if the sentry object returns false, when converted to a value of type bool, the function returns without attempting to obtain any input. In either case the number of extracted characters is set to 0; unformatted input functions taking a character array of non-zero size as an argument shall also store a null character (using charT()) in the first location of the array. If an exception is thrown during input then ios::badbit is turned on315 in *this’s error state. (Exceptions thrown from basic_ios<>::clear() are not caught or rethrown.) If (exceptions()&badbit) != 0 then the exception is rethrown. It also counts the number of characters extracted. If no exception has been thrown it ends by storing the count in a member object and returning the value specified. In any event the sentry object is destroyed before leaving the unformatted input function.

315)这样做不会导致ios :: failure抛出.

315) This is done without causing an ios::failure to be thrown.

(出于可读性考虑,我加了强调)

(emphasis added by me for readability purposes)

所以这再次表明,如果需要此解析操作中的异常,则必须在exceptions中设置badbit.

So this again appears to indicate that if an exception is desired from this parse operation, badbit has to be set in exceptions.

这篇关于libc ++ std :: istringstream不会引发异常.漏洞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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