libstdc++ 和 libc++ 之间的行为差异:bitset 上的运算符>>
Difference of behavior between libstdc++ and libc++: operator>> on bitset
考虑以下代码:
#include <bitset>
#include <sstream>
#include <iostream>
int main(int argc, char* argv[])
{
std::stringstream stream;
std::bitset<1> bitset(1);
std::cout<<"before = "<<bitset[0]<<std::endl;
stream<<"4";
stream>>bitset;
std::cout<<"after = "<<bitset[0]<<std::endl;
return 0;
}
在g++
下用libstdc++
编译,结果是:
> g++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty
before = 1
after = 1
在clang++
下用libc++
编译,结果是:
> clang++ -stdlib=libc++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty
before = 1
after = 0
哪一个是正确的?两者(因为未定义的行为)?海湾合作委员会?铿锵?
你应该检查是否
stream>>bitset;
成功。如果没有,则不能指望之后 bitset
的值。
#include <bitset>
#include <sstream>
#include <iostream>
int main(int argc, char* argv[])
{
std::stringstream stream;
std::bitset<1> bitset(1);
std::cout<<"before = "<<bitset[0]<<std::endl;
stream<<"4";
if ( stream>>bitset )
{
std::cout<<"after = "<<bitset[0]<<std::endl;
}
else
{
std::cout << "Failed to restore bitset from stream.\n";
}
return 0;
}
使用 g++ 4.9.3 的输出:
before = 1
Failed to restore bitset from stream.
根据我的理解,libc++ 就在这里,但它不是唯一正确的行为。
N4140 §20.6.4 [bitset.operators]
Effects: Extracts up to N characters from is. Stores these characters in a temporary object str of type basic_string<charT,
traits>
, then evaluates the expression x = bitset<N>(str)
.
Characters are extracted and stored until any of the following occurs:
- N characters have been extracted and stored;
- end-of-file occurs on the input sequence;
- the next input character is neither
is.widen(’0’)
nor is.widen(’1’)
(in which case the input character is not extracted).
If no characters are stored in str
, calls
is.setstate(ios_base::failbit)
(which may throw ios_base::failure
(27.5.5.4))
重要的是要注意 x = bitset<N>(str)
不是有条件的。如果 ios_base::failure
没有被抛出,那么这就是执行的表达式。 bitset<N>(""s)
(即空字符串)是 0
.
因此,根据我的理解,您的 bitset
应该归零或者应该抛出上述异常。
如果没有抛出异常,您可能需要测试操作是否成功(通过测试返回的流)。
考虑以下代码:
#include <bitset>
#include <sstream>
#include <iostream>
int main(int argc, char* argv[])
{
std::stringstream stream;
std::bitset<1> bitset(1);
std::cout<<"before = "<<bitset[0]<<std::endl;
stream<<"4";
stream>>bitset;
std::cout<<"after = "<<bitset[0]<<std::endl;
return 0;
}
在g++
下用libstdc++
编译,结果是:
> g++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty
before = 1
after = 1
在clang++
下用libc++
编译,结果是:
> clang++ -stdlib=libc++ bitset_empty.cpp -o bitset_empty
> ./bitset_empty
before = 1
after = 0
哪一个是正确的?两者(因为未定义的行为)?海湾合作委员会?铿锵?
你应该检查是否
stream>>bitset;
成功。如果没有,则不能指望之后 bitset
的值。
#include <bitset>
#include <sstream>
#include <iostream>
int main(int argc, char* argv[])
{
std::stringstream stream;
std::bitset<1> bitset(1);
std::cout<<"before = "<<bitset[0]<<std::endl;
stream<<"4";
if ( stream>>bitset )
{
std::cout<<"after = "<<bitset[0]<<std::endl;
}
else
{
std::cout << "Failed to restore bitset from stream.\n";
}
return 0;
}
使用 g++ 4.9.3 的输出:
before = 1
Failed to restore bitset from stream.
根据我的理解,libc++ 就在这里,但它不是唯一正确的行为。
N4140 §20.6.4 [bitset.operators]
Effects: Extracts up to N characters from is. Stores these characters in a temporary object str of type
basic_string<charT, traits>
, then evaluates the expressionx = bitset<N>(str)
. Characters are extracted and stored until any of the following occurs:
- N characters have been extracted and stored;
- end-of-file occurs on the input sequence;
- the next input character is neither
is.widen(’0’)
noris.widen(’1’)
(in which case the input character is not extracted).If no characters are stored in
str
, callsis.setstate(ios_base::failbit)
(which may throwios_base::failure
(27.5.5.4))
重要的是要注意 x = bitset<N>(str)
不是有条件的。如果 ios_base::failure
没有被抛出,那么这就是执行的表达式。 bitset<N>(""s)
(即空字符串)是 0
.
因此,根据我的理解,您的 bitset
应该归零或者应该抛出上述异常。
如果没有抛出异常,您可能需要测试操作是否成功(通过测试返回的流)。