Reputation: 27673
Does the following code rely on undefined behavior if the platform's char
type is signed and some of the parameters are in the negative range (for example, char_bitmatch('\xf0', '\xc0', '\x20')
)?
static constexpr bool char_bitmatch(char c, char pos, char neg)
{
return (c & pos) == pos
&& !(c & neg);
}
The reason I am asking this is because in GCC 8.1.0 with -O3
, I am seeing a behavior which can only be caused by char_bitmatch('\xf0', '\xc0', '\x20')
erroneously returning true
. This code behaves as expected:
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);
}
From my understanding, this should not have fixed the issue -- &
should work the same between signed char
and unsigned char
.
This leads me to a few conclusions (but I don't know which is correct):
unsigned char
fixes an undefined behavior.Upvotes: 4
Views: 1574
Reputation: 25408
Interesting. I think your assumption that char_bitmatch
is returning true
is, erm, false.
When I run this code:
#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);
}
I get:
0
So I think the problem lies elsewhere in your code.
I used the same compiler as you - run it at Wandbox (choice of compilers available).
Also, == pos
is redundant, no?
Upvotes: 1