warning - comparing a signed value to an unsinged value

D

Dan Pop

In said:
What do you think is the best way to handle a compiler warning about
comparing an unsigned value to a signed value? Cast to silence it?
Disable that warning altogether? Or just live with it?

I prefer not to enable this warning. It never revealed a real bug in my
code and I'd never use a cast for the sole reason of silencing a warning.

Dan
 
P

pete

Kevin said:
Why is everyone answering by
suggesting there's something wrong with the code?

The warning suggests that a better choice of types may be available.
I understand that that isn't the case.
 
S

Sheldon Simms

Changing the type is not an option. As I told pete, 'SomeFunc' is
actually sscanf() with a %n format specifier.

The value is non-negative, but the interface requires an int. This is
beyond my control. If you want to file a defect report suggesting that
the %n format specifier for the *scanf functions should expect a size_t
instead of an int, be my guest. While you're at it, I believe there are
a few other standard library functions that use ints where size_t would
probably be more appropriate.

Maybe I should have been more clear in my post. I intended for you to
assume the types were dissimilar for some good reason and could not be
easily changed to similar types.

Yes, in your defect report be sure to include a note stating that Dennis
Ritchie (or whoever defined it) is an idiot for defining *scanf() the
way he did.

I feel I owe you an apology Kevin! It really was stupid of me to
attempt to answer your question by considering the different possibilites.
I should have realized right away that you are an expert. After all,
novices and inexperienced programmers hardly ever post anything in
comp.lang.c, and even if they did, I should have been able to recognize
your expertise by clairvoyantly reading your aura. I promise it will
never happen again. Please forgive me.

-Sheldon
 
K

Kevin Goodsell

Sheldon said:
I feel I owe you an apology Kevin! It really was stupid of me to
attempt to answer your question by considering the different possibilites.
I should have realized right away that you are an expert. After all,
novices and inexperienced programmers hardly ever post anything in
comp.lang.c, and even if they did, I should have been able to recognize
your expertise by clairvoyantly reading your aura. I promise it will
never happen again. Please forgive me.

Sorry, I was feeling a bit frustrated with the replies I was getting. I
probably should have been more clear in my first message, and I
definitely should not have been as harsh in my replies as I was. I've
actually spent quite a bit of time here (though not lately), and getting
the "newbie treatment" irritated me, but it's probably my own fault for
not being clear enough. Again, I apologize.

-Kevin
 
C

CBFalconer

Kevin said:
.... snip ...

It just so happens that in the specific case that prompted the question,
I was comparing the result of a strlen() call to an int that was used as
the destination variable for a sscanf %n format specifier. If you can
suggest a way to persuade sscanf to use size_t instead of int for %n, or
a way to persuade strlen() to return int, then I suppose your answer
would be useful.

I asked a pretty simple question. Why is everyone answering by
suggesting there's something wrong with the code? Let me clarify: I have
two variables that need to be compared. Assume the types are dictated
by something beyond my control. One is a signed type and one is an
unsigned type. I know the comparison is safe because the signed variable
is non-negative. But the compiler warns about it. I was seeking opinions
on how to handle this. Changing the types is not an option.

IIRC you did not originally specify that the integer was known to
be positive. In this case you can obviously cast it to unsigned
without worries, and be done with it. The usage deserves a
comment, just in case someone somewhere passes in a negative value
in future. For example, the scanf might fail, and thus never set
the integer value, which thus needs initializing or other
avoidance.
 
C

CBFalconer

Kevin said:
CBFalconer said:
No, one should understand the data one is working with, and
program accordingly.

And I do understand the data. But the problem persists.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
/* in the real program, buffer will be filled at run-time */
char buffer[] = " 0324 ";
long value;
int converted_items, scanned_chars = 0;

converted_items = sscanf(buffer, "%li %n", &value, &scanned_chars);

/* check if conversion failed: */
if (converted_items < 1 ||
(scanned_chars != 0 && scanned_chars < strlen(buffer)) )
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

Unless I'm missing something, this code is perfectly fine. It should
convert the value from buffer to a long, allowing octal and hex
representations, and fail if the format is incorrect in any way. But the
comparison 'scanned_chars < strlen(buffer)' still causes a warning. The
question I am posing is, what do you consider the best way to handle a
situation like this?

I think the code is redundant. If sscanf ever scans past a '\0'
you have major problems with your library, so the strlen call is
pointless. I would write:

if (1 == sscanf(buffer, "%li%n", &value, &scanned_chars)) {
return EXIT_SUCCESS;
}
else {
return EXIT_FAILURE;
}

Note that I removed the space after %li. If you want to ensure a
terminating space you can also test:

if (' ' == buffer[scanned_chars]) ....
 
K

Kevin Goodsell

CBFalconer said:
I think the code is redundant. If sscanf ever scans past a '\0'
you have major problems with your library, so the strlen call is
pointless. I would write:

if (1 == sscanf(buffer, "%li%n", &value, &scanned_chars)) {
return EXIT_SUCCESS;
}
else {
return EXIT_FAILURE;
}

Note that I removed the space after %li. If you want to ensure a
terminating space you can also test:

if (' ' == buffer[scanned_chars]) ....

I believe you have misunderstood the intent of the code. The strlen()
call was to ensure that *all* characters were scanned (in other words,
that the buffer contained a valid integer and nothing else, except
possibly trailing or leading white space).

I'd like to go into more detail, but I have to run. It this is unclear,
I'll clarify later.

-Kevin
 
R

Rudolf

if (1 == sscanf(buffer, "%li%n", &value, &scanned_chars)) {
return EXIT_SUCCESS;
}
else {
return EXIT_FAILURE;
}


My question is off-topic from the original question, I'm curious if I'm
not understanding what sscanf returns. My documentation for the scanf
family says that the return value is "the number of input items
assigned." If that's the case, then the above code will return failure
if the sscanf gets a value for both "value" and "scanned_chars" since in
that case sscanf will return 2 and not 1.

Am I missing something?
 
J

Jeremy Yallop

Rudolf said:
My question is off-topic from the original question, I'm curious if I'm
not understanding what sscanf returns. My documentation for the scanf
family says that the return value is "the number of input items
assigned." If that's the case, then the above code will return failure
if the sscanf gets a value for both "value" and "scanned_chars" since in
that case sscanf will return 2 and not 1.

Am I missing something?

You're missing that %n is an exception: it's not counted as one of the
"input items assigned".

Jeremy.
 
I

Irrwahn Grausewitz

Rudolf said:
My question is off-topic from the original question, I'm curious if I'm
not understanding what sscanf returns. My documentation for the scanf
family says that the return value is "the number of input items
assigned." If that's the case, then the above code will return failure
if the sscanf gets a value for both "value" and "scanned_chars" since in
that case sscanf will return 2 and not 1.

Am I missing something?

Yup. C99 7.19.6.2#12:

[...]
Execution of a %n directive does not increment the assignment count
returned at the completion of execution of the fscanf function.
[...]

Regards
 
D

Dan Pop

My question is off-topic from the original question, I'm curious if I'm
not understanding what sscanf returns. My documentation for the scanf
family says that the return value is "the number of input items
assigned." If that's the case, then the above code will return failure
if the sscanf gets a value for both "value" and "scanned_chars" since in
that case sscanf will return 2 and not 1.

Am I missing something?

Either your documentation is incredibly poor, or you didn't read it
carefully enough. What does it say about %n ?

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top