Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > condition true or false? -> (-1 < sizeof("test"))

Reply
Thread Tools

condition true or false? -> (-1 < sizeof("test"))

 
 
BartC
Guest
Posts: n/a
 
      05-17-2012
"Eric Sosman" <> wrote in message
news:jp2ps3$gnm$...
> On 5/17/2012 6:16 AM, BartC wrote:


>> which gives conflicting results. (Presumably an integer literal such as
>> "4"
>> is assumed to be signed? Having it as unsigned would be more intuitive,
>> as
>> it would be impossible for it to be negative.)


> The types of integer constants depend on their magnitude and
> on the notation used, as described in 6.4.4.1p5. The constant 4
> has type int, and is signed even though the value is positive.
> If you think it would be "more intuitive" for the 4 to be unsigned,
> please ponder `-8 / 4' and `-8 / 4u' and explain why having them
> be identical would be unsurprising.


If you're going to make integer literals be unsigned by default, then you
would probably also change mixed arithmetic to be signed and not unsigned.

--
Bartc

 
Reply With Quote
 
 
 
 
Andreas Perstinger
Guest
Posts: n/a
 
      05-17-2012
On 2012-05-17 14:00, BartC wrote:
> "Andreas Perstinger"<> wrote in message
> news:jp2nkq$36f$...
>> I think your problem is that in example 1 and 3 you print the signed
>> values (b and -2) with the %d format specifier but to see what's going

>
> Because they are signed!
>
>> on you have to use %u because they get converted to unsigned int before
>> the comparison is evaluated:
>>
>> printf("%u<%u = %d\n\n", a, b, a<b);

>
> This is the point. You're just demonstrating here *how* it manages to print
> the wrong result!
>
> But the fact is that b *is* signed, and needs to be displayed with %d. So in
> my original example, the 4 and -2 were printed correctly in each case.


I thought you were interested in the behaviour of the comparison,
weren't you? At least that was the problem of the OP.

Of course b as such is signed but in regard to the comparison with an
unsigned value it gets converted to unsigned int. Therefore I think
printing b as int just adds to the confusion.

> Also my gcc didn't give any warnings despite using -Wconversion.


$ cat test.c
#include <stdio.h>

int main(void)
{
unsigned int a=4;
signed int b=-2;

printf("%u<%d = %d\n\n", a, b, a<b);
printf("%d<%d = %d\n\n", 4, b, 4<b);
printf("%u<%d = %d\n\n", a, -2, a<-2);
printf("%d<%d = %d\n\n", 4, -2, 4<-2);

return 0;
}
$ gcc -o test -Wconversion test.c
$ gcc -o test -Wextra test.c
test.c: In function ‘main’:
test.c:8:37: warning: comparison between signed and unsigned integer
expressions
test.c:10:38: warning: comparison between signed and unsigned integer
expressions
$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2

Bye, Andreas

 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      05-17-2012
Eric Sosman <> writes:
>On 5/17/2012 6:16 AM, BartC wrote:
>>which gives conflicting results. (Presumably an integer literal such as "4"

>Well, "4" is not an integer literal, but that's a markup issue


That's why I write:

,,an int literal, such as »4«,`` and

,,a string literal, such as »"4"«,``

. I am giving classes for beginners. The "»«" quotes make sure that
my students will not type in these quotes into their C programs,
because they do not know how to enter them using their keyboards.
Moreover, these quotes cannot be confused for C string quote »""«.
Moreover, they are part of the widespread charset ISO-8859-1,
so it is justifiable to use the in Usenet posts tagged

Content-Type: text/plain; charset=ISO-8859-1

 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      05-17-2012
"Andreas Perstinger" <> wrote in message
news:jp2r2q$nh2$...
> On 2012-05-17 14:00, BartC wrote:


>> But the fact is that b *is* signed, and needs to be displayed with %d. So
>> in
>> my original example, the 4 and -2 were printed correctly in each case.


> Of course b as such is signed but in regard to the comparison with an
> unsigned value it gets converted to unsigned int. Therefore I think
> printing b as int just adds to the confusion.


Printing signed b as "%u" would probably itself have induced a comment, and
generated confusion of it's own.

>> Also my gcc didn't give any warnings despite using -Wconversion.


> $ gcc -o test -Wconversion test.c
> $ gcc -o test -Wextra test.c


OK, so there are even more warning levels beyond -Wall and -Wconversion.

>
> I thought you were interested in the behaviour of the comparison, weren't
> you? At least that was the problem of the OP.
>


(Regarding the OP's problem, the suggestion I made elsewhere, that mixed
arithmetic should be signed not unsigned, would have fixed it!

Well, except in the unlikely scenario that sizeof("test") was bigger than
2GB or so.)

--
Bartc

 
Reply With Quote
 
Tim Prince
Guest
Posts: n/a
 
      05-17-2012
On 5/17/2012 4:38 AM, Eric Sosman wrote:
> On 5/17/2012 4:40 AM, John Reye wrote:
>> Hello,
>>
>> please can someone explain why
>> (-1< sizeof("test"))
>> is false.

>
> Because of the "usual arithmetic conversions," 6.3.1.8.
> Most arithmetic operators require operands of the same type,
> so for differing types the UAC's operate to reconcile them
> before the operation is performed. In this case you have an
> int and a size_t, and the UAC's convert the int to size_t:
>
> if ( (size_t)-1 < sizeof("test") )
>
> Since size_t is an unsigned type, (size_t)-1 is the largest
> value the type can represent, and is a good deal greater
> than (size_t)5.
>
> Aside: I suppose that on a perverse implementation the
> outcome might be different. If (size_t)-1 is mathematically
> no greater than INT_MAX the conversion would go the other way.
> The size_t would convert to an int before the comparison and
> you'd have:
>
> if ( -1 < (int)sizeof("test") )
>
> I've never heard of an implementation where size_t is so
> narrow, and I'm not 100% sure it would be conforming -- but
> I'm not 100% sure it would be forbidden, either.
>


I've tried to work with an organization whose coding policies were
incompatible with size_t taking a wider data type than int. The
assignment probably was punishment for my background in Fortran, which
may still account for not fully understanding the possibilities you
describe.


--
Tim Prince
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      05-17-2012
On 05/17/2012 05:38 AM, Robert Wessel wrote:
....
> Somewhat simplified*, C's "usual arithmetic conversions" convert
> signed integers to unsigned when paired with an unsigned value for
> some operator.

....
> *an except exists when all possible values of the unsigned type can be
> represented in the signed type, but it doesn't apply here


The first part of the usual arithmetic conversions is to apply the
integer promotions, which means that if int can represent all values of
the unsigned type, it will be promoted to int (6.3.1.1p2). Your
assertion to the contrary notwithstanding, that can apply here: SIZE_MAX
< INT_MAX is possible, though rather unusual.

I believe that the exception you're referring to is the one that applies
after the integer promotions, and only if they don't convert the
unsigned value to 'int'. It applies only if the integer conversion rank
of the unsigned type is lower than the rank of the signed type. For
instance, if UINT_MAX < LLONG_MAX (which is pretty likely to be true,
but not a requirement), the expression -1LL < 5U will be evaluated using
long long, and will therefore be true.
--
James Kuyper
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      05-17-2012
On 05/17/2012 07:38 AM, Eric Sosman wrote:
....
> outcome might be different. If (size_t)-1 is mathematically
> no greater than INT_MAX the conversion would go the other way.
> The size_t would convert to an int before the comparison and
> you'd have:
>
> if ( -1 < (int)sizeof("test") )
>
> I've never heard of an implementation where size_t is so
> narrow, and I'm not 100% sure it would be conforming -- but
> I'm not 100% sure it would be forbidden, either.


Can you give a justification for your doubts about whether such an
implementation could be conforming?

The lower limit for SIZE_MAX is 65535, and there's no upper limit for
INT_MAX, so I don't see why an implementation where SIZE_MAX < INT_MAX
could not be fully conforming.
--
James Kuyper
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      05-17-2012
"BartC" <> writes:

> "Ben Bacarisse" <> wrote in message
> news:0.893910e519ad620c6915.20120517122826BST.87vc ...
>> "BartC" <> writes:

>
>>> (Presumably an integer literal such as "4"
>>> is assumed to be signed? Having it as unsigned would be more
>>> intuitive, as
>>> it would be impossible for it to be negative.)

>>
>> But that would turn x < 4 into an unsigned comparison. Worse, -1 would
>> always be unsigned (and large).

>
> 1 would be unsigned.
>
> -1, assuming constant folding by the compiler, would be equivalent to
> a signed integer literal of "-1".
>
> (If not, then it remains the negation of unsigned 1, performed at
> runtime. For this purpose, negating an unsigned value would need to be
> allowed, and I can't see a problem with that, except the usual
> overflow issues).


This discussion is confusing because it is not clear what changes you
are thinking of. Are you proposing that the operand of - not be subject
to integer promotion, or are you proposing to change how integer
promotion is defined?

What about x < 4 being an unsigned compression? Are proposing a change
to the definition of <, to the usual arithmetic conversions, or something
else?

If all you are saying that there is probably a language a bit like C in
which integer constants are all unsigned, and that such a language might
have fewer surprises for people learning it, then I am happy to agree.

--
Ben.
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      05-17-2012
"Ben Bacarisse" <> wrote in message
news:0.acebabc8187a84f5ab75.20120517153225BST.87pq ...
> "BartC" <> writes:
>> "Ben Bacarisse" <> wrote in message


> This discussion is confusing because it is not clear what changes you
> are thinking of. Are you proposing that the operand of - not be subject
> to integer promotion, or are you proposing to change how integer
> promotion is defined?


I hadn't planned to propose any changes! Just clarifying the signedness of
4, to make sense of my examples where the < was giving conflicting results
even though values being compared were apparently the same, yet there was no
warning given. (As it turns out, gcc needs -Wextra to give the warning.)

> What about x < 4 being an unsigned compression? Are proposing a change
> to the definition of <, to the usual arithmetic conversions, or something
> else?


If literals are unsigned, then yes, it would cause problems *because* of C
using unsigned modes for mixed arithmetic. So it would be a massive change
compared to, say, getting rid of trigraphs, which hardly anyone would
notice.

> If all you are saying that there is probably a language a bit like C in
> which integer constants are all unsigned, and that such a language might
> have fewer surprises for people learning it, then I am happy to agree.


(Actually I am working on such a language. There, I found things fell into
place better if literals were unsigned. Also it will use signed arithmetic
where operands are mixed, having briefly considered doing what C does.

That doesn't remove all problems, but I felt it was generally more useful.
And would have given the expected result in "-1<sizeof("test")", whether
size_t was signed or not.)

--
Bartc

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      05-17-2012
On 05/17/2012 06:16 AM, BartC wrote:
....
> However, -Wconversion doesn't give a warning in this example:
>
> unsigned int a=4;
> signed int b=-2;
>
> printf("%u<%d = %d\n\n", a, b, a<b);
> printf("%d<%d = %d\n\n", 4, b, 4<b);
> printf("%u<%d = %d\n\n", a, -2, a<-2);
> printf("%d<%d = %d\n\n", 4, -2, 4<-2);
>
> which gives conflicting results. (Presumably an integer literal such as "4"
> is assumed to be signed? Having it as unsigned would be more intuitive, as
> it would be impossible for it to be negative.)


Would you be less confused by the following:

printf("%u<%u = %d\n\n", a, (unsigned)b, a <b);
printf("%u<%u = %d\n\n", 4U, (unsigned)b, 4U<b);
printf("%u<%u = %d\n\n", a, (unsigned)-2, a <-2);
printf("%u<%u = %d\n\n", 4U, (unsigned)-2, 4U<-2);


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with while condition OR condition Bill W. Ruby 13 05-09-2011 09:42 PM
[False,True] and [True,True] --> [True, True]????? bdb112 Python 45 04-29-2009 02:35 AM
Loop until condition is true Remi Villatel Python 40 06-23-2005 07:21 PM
Condition outside loop or separate loop for different condition? - Java 12 06-15-2005 08:50 AM
Why is this condition true when it should be false ? Zenobia ASP .Net 0 07-08-2004 07:54 AM



Advertisments