Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Weird warning about data type range

1 view
Skip to first unread message

Digital Puer

unread,
Aug 29, 2009, 3:33:49 AM8/29/09
to
I am seeing this very weird warning about
data type range. I am using g++ 4.1.2 (but this
applies to gcc as well).

I have this program:

#include <cstdio>
main()
{
char c = 27;

if (c >= 110 &&
c <= 127)
{
printf("hi");
}
}


When I compile it with g++, I get the warning:
test_range.cpp:7: warning: comparison is always true due to limited
range of data type

Line 7 is the comparison "c <= 127". Ok fine, that will always
be true, but the entire if-expression may not be true since
there is && in the expression.

Can someone tell me how to shut off this warning?

Juha Nieminen

unread,
Aug 29, 2009, 7:18:37 AM8/29/09
to

It's not saying that the expression is always true. It's saying that
that comparison is always true and thus a nop.

Stuart Golodetz

unread,
Aug 29, 2009, 7:20:02 AM8/29/09
to

Note it doesn't say anything about the entire if condition, just about a
particular comparison (specifically the c <= 127 one). It would seem
that char is signed by default on your platform. To get rid of the
warning, just delete the second comparison, i.e. change to using:

if(c >= 110)

On a separate note, main is missing a return type in your code - ITYM
int main().

Regards,
Stu

SG

unread,
Aug 29, 2009, 7:35:45 AM8/29/09
to
On 29 Aug., 13:20, Stuart Golodetz <b...@blah.com> wrote:
>
> Note it doesn't say anything about the entire if condition, just about a
> particular comparison (specifically the c <= 127 one). It would seem
> that char is signed by default on your platform. To get rid of the
> warning, just delete the second comparison, i.e. change to using:
>
> if(c >= 110)

That's not really satisfactory if you want your code to be portable
and support CHAR_MAX>127 cases. I'm not really interested in whether
the compiler figured out that it can ignore the c<=127 test because
the standard doesn't guarantee CHAR_MAX to be 127. CHAR_MAX can be
larger.

I do appreciate warnings, though. A warning in cases like

unsigned foo = getfoo();
if (foo>=0) {
// ...
}

is totally fine because foo can never be negative regardless of the
implementation details.

Cheers!
SG

Stuart Golodetz

unread,
Aug 29, 2009, 8:12:58 AM8/29/09
to

True enough. I guess we'd need to know more about the intent of the code
to write a portable version in this instance though (e.g. I can easily
make it work just by changing char c to int c, but that's not really
answering the original question). My guess intent-wise here is "test
program", but I may be wrong :-)

Cheers,
Stu

Jonathan Lee

unread,
Aug 29, 2009, 10:14:33 AM8/29/09
to
On Aug 29, 3:33 am, Digital Puer <digital_p...@hotmail.com> wrote:
> Line 7 is the comparison "c <= 127". Ok fine, that will always
> be true, but the entire if-expression may not be true since
> there is && in the expression.

Why not just #include <climits> and wrap the second half in an #if?

if (c >= 110
#if (CHAR_MAX > 127)
&& c <= 127
#endif
) {
...
}

I know its not pretty but either the test stays (and the compiler
produces the warning), or the test is somehow removed.

--Jonathan

Paavo Helde

unread,
Aug 29, 2009, 12:39:15 PM8/29/09
to
Digital Puer <digita...@hotmail.com> kirjutas:

unsigned char c = 27;
...

--or--

if (c>=110 && static_cast<unsigned char>(c)<=127)) ...

Paavo


Digital Puer

unread,
Aug 29, 2009, 8:35:34 PM8/29/09
to
Thanks for everyone's help.

What I am really trying to do is to test if
characters in a std::string are alphanumeric
characters in the Latin-1 encoding. I have
the following:


#define IS_ALPHANUMERIC(x) ( \
((x) >= 48 && (x) <= 57 ) || \
((x) >= 65 && (x) <= 90 ) || \
((x) >= 97 && (x) <= 122) || \
((x) >= 192 && (x) <= 214) || \
((x) >= 216 && (x) <= 246) || \
((x) >= 248 && (x) <= 255) )

string s = getLatin1Text();
int len = s.size();
for (int i = 0; i < len; i++)
{
if (! IS_ALPHANUMERIC(s.at(i)))
{
...
}
}

When I compile that, the last check (x <= 255)
gives the same warning that I showed in my
original post:

warning: comparison is always true due to limited range of data type

I guess I will have to isolate away the last check
with a #IF statement.

Juha Nieminen

unread,
Aug 30, 2009, 3:12:08 AM8/30/09
to
Digital Puer wrote:
> #define IS_ALPHANUMERIC(x) ( \
> ((x) >= 48 && (x) <= 57 ) || \
> ((x) >= 65 && (x) <= 90 ) || \
> ((x) >= 97 && (x) <= 122) || \
> ((x) >= 192 && (x) <= 214) || \
> ((x) >= 216 && (x) <= 246) || \
> ((x) >= 248 && (x) <= 255) )
>
> string s = getLatin1Text();
> int len = s.size();
> for (int i = 0; i < len; i++)
> {
> if (! IS_ALPHANUMERIC(s.at(i)))
> {
> ...
> }
> }

I don't think that's doing what you want it to do.

A std::string contains chars, which are usually signed in most
systems. Values outside the ASCII range will thus have *negative*
values. When you do eg. a "x >= 248" what will happen is that x, which
is a signed char, will first be promoted to an int, and then compared to
248. Since 248 is larger than 127, the comparison will always yield false.

And btw, this is a great example where using a preprocessor macro
instead of an inline function is a *bad* idea. With the macro you will
be silently calling "s.at(i)" 12 times per call, rather than just once.
(Might not be so relevant if it was "s[i]", but with "s.at(i)" 11 of the
boundary checks will be completely useless.)

What you need is an inline function which takes a char as parameter,
then internally casts it to unsigned char, and then compares it to
unsigned char literals.

Jonathan Lee

unread,
Aug 30, 2009, 12:18:18 PM8/30/09
to
On Aug 29, 8:35 pm, Digital Puer <digital_p...@hotmail.com> wrote:
> What I am really trying to do is to test if
> characters in a std::string are alphanumeric
> characters in the Latin-1 encoding. I have
> the following:

I think <locale> offers isalnum() to do just that. I haven't used it
before, but the way I understand it you can create the appropriate
locale and then the library does it for you. Ex.,

#include <locale>
#include <string.

// Not sure on the constructor argument here...
std::locale latin1("en_US.ISO8859-1");
std::string s;

...

for (size_t i = 0; i < s.length(); ++i) {
if (std::isalnum(s[i], latin1)) { ... }
}

Anyone know more?

--Jonathan

Jerry Coffin

unread,
Aug 30, 2009, 2:27:35 PM8/30/09
to
In article <ad7ec9cc-6e85-4d12-8ebf-6072d20e2617
@z4g2000prh.googlegroups.com>, digita...@hotmail.com says...

>
> Thanks for everyone's help.
>
> What I am really trying to do is to test if
> characters in a std::string are alphanumeric
> characters in the Latin-1 encoding. I have
> the following:
>
>
> #define IS_ALPHANUMERIC(x) ( \
> ((x) >= 48 && (x) <= 57 ) || \
> ((x) >= 65 && (x) <= 90 ) || \
> ((x) >= 97 && (x) <= 122) || \
> ((x) >= 192 && (x) <= 214) || \
> ((x) >= 216 && (x) <= 246) || \
> ((x) >= 248 && (x) <= 255) )
>
> string s = getLatin1Text();
> int len = s.size();
> for (int i = 0; i < len; i++)
> {
> if (! IS_ALPHANUMERIC(s.at(i)))
> {
> ...
> }
> }

If I had to do this, I think I'd use something like this:

#include <climits>
#include <vector>
#include <algorithm>

struct alphanumeric_table {
std::vector<bool> table;
public:
#define elements(r) (sizeof(r)/sizeof(r[0]))

alphanumeric_table() : table(UCHAR_MAX+2, false) {
static const int ranges[] = {
48, 57,
65, 90,
97, 122,
192, 214,
216, 246,
248, 255
};


for (int i=0; i<elements(ranges); i+=2)
std::fill(table.begin()+ranges[i]+1,
table.begin()+ranges[i+1]+2,
true);
}

bool operator[](int n) { return table[unsigned char(n+1)]; }
} alpha_table;

inline bool is_alphanumeric(int n) {
return alpha_table[n];
}

This assumes that EOF is -1. Technically this isn't required (any
negative value is allowed) but it's extremely common -- to the point
that I'm not sure I've ever seen or heard of it actually having any
other value. In any case, the reason for the "+1"in most places is to
get a range from 0 through the maximum, so we can use it directly as
an index into the vector.

--
Later,
Jerry.

Digital Puer

unread,
Aug 30, 2009, 6:31:53 PM8/30/09
to
On Aug 30, 11:27 am, Jerry Coffin <jerryvcof...@yahoo.com> wrote:
> In article <ad7ec9cc-6e85-4d12-8ebf-6072d20e2617
> @z4g2000prh.googlegroups.com>, digital_p...@hotmail.com says...

Thanks. This is great. A self-contained class like
this is much better than my #define macro. It's also
faster since the lookup is immediate rather than
through a bunch of if-in-range statements.


0 new messages