C++ 有符号字符的位运算
如果平台的C++ 有符号字符的位运算,c++,C++,如果平台的char类型已签名且某些参数在负范围内(例如,char\u位匹配('\xf0','\xc0','\x20')),则以下代码是否依赖于未定义的行为 上下文 我问这个问题的原因是因为在带有-O3的GCC 8.1.0中,我看到一种行为只能由char\u位匹配('\xf0','\xc0','\x20')错误返回true引起。此代码的行为符合预期: static constexpr bool char_bitmatch(char c_in, char pos_in, char neg_in)
char
类型已签名且某些参数在负范围内(例如,char\u位匹配('\xf0','\xc0','\x20')
),则以下代码是否依赖于未定义的行为
上下文 我问这个问题的原因是因为在带有
-O3
的GCC 8.1.0中,我看到一种行为只能由char\u位匹配('\xf0','\xc0','\x20')
错误返回true
引起。此代码的行为符合预期:
static constexpr bool char_bitmatch(char c_in, char pos_in, char neg_in)
{
auto c = static_cast<unsigned char>(c_in);
auto pos = static_cast<unsigned char>(pos_in);
auto neg = static_cast<unsigned char>(neg_in);
return (c & pos) == pos
&& !(c & neg);
}
static constexpr bool char\u bitmatch(char c\u in,char pos\u in,char neg\u in)
{
自动c=静态c_-cast(c_-in);
自动位置=静态浇铸(位置输入);
自动负=静态投切(负投切);
退货(c&pos)=pos
&&!(c&neg);
}
根据我的理解,这不应该解决这个问题--&
在有符号字符
和无符号字符
之间应该是一样的
这让我得出了一些结论(但我不知道哪一个是正确的):
无符号字符
修复了未定义的行为有趣。我认为你认为
char\u bitmatch
返回true
的假设是,呃,错误的
当我运行此代码时:
#include "stdio.h"
static constexpr bool char_bitmatch(char c, char pos, char neg)
{
return (c & pos) == pos
&& !(c & neg);
}
int main (void)
{
constexpr bool b = char_bitmatch ('\xf0', '\xc0', '\x20');
printf ("%d\n", b);
}
我得到:
0
所以我认为问题出在代码的其他地方
我使用了与您相同的编译器-在运行它(可选编译器)
而且,
==pos
是多余的,不是吗?所以每次使用&
操作数都会升级--在这段代码中,它们变成int
。从带符号的char
升级到int
和unsigned char
升级到int
的行为完全不同。@BenVoigt看着代码,这会影响这里的结果吗?@Paul:我不这么认为,但这与问题的说法相反,即“&
在有符号的字符和无符号的字符之间应该是一样的。”@Ben好的,明白了。我发现你的评论很有教育意义(我从来没有停下来思考过),这让我想到了。==pos
如果测试是“所有pos
位都设置好了(并且没有任何neg
位设置好了”)。省略==pos
将导致“设置了任何pos
位…”规则。我在独立娱乐中也看到了这一点。这是一个棘手的问题,因为这个问题只发生在发布版本中,而添加打印语句等操作也会消除这个问题。我的假设只通过GDB得到了验证--length==2
@Ben啊是的,你说得对,我想了一点,对不起。显然,我每天早上都太早了,我经常自己使用这种结构。@Travis-Hmmm,那里有很多代码。足以使我的平板电脑崩溃,但我现在已经确信,char\u bitmatch
与签名字符一样工作,即使我个人不会这样编码,即使我看起来还没有完全清醒!
0