how this works? is it or bug or not???

A

AliM

Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */
int main()
{
printf("%d",SIZE);
if(-1<=SIZE)
printf("1");
else printf("2");
}

It look like going to print 81 but it prints 82 anormally. When try:
printf("%d",-1<=SIZE);
It prints 0, How do you explain this?

Also I was using gcc 3.6.2

Thanks.
 
F

Fred

Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int))  /* this gets 8 perfectly */
int main()
{
   printf("%d",SIZE);
   if(-1<=SIZE)
       printf("1");
   else printf("2");
}

It look like going to print 81 but it prints 82 anormally. When try:>printf("%d",-1<=SIZE);

It prints 0, How do you explain this?

Also I was using gcc 3.6.2

Thanks

the result of sizeof() is a vlue of type size_t, which
on most implementations is an unsigned int or unsigned long.

So the -1 you compare it to is converted to an unsigned value,
which is some very large number.
 
E

Eric Sosman

AliM said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */
int main()
{
printf("%d",SIZE);
if(-1<=SIZE)
printf("1");
else printf("2");
}

It look like going to print 81 but it prints 82 anormally.

I have no idea where the "8" came from. The "2" is correct.
When try:
It prints 0, How do you explain this?

By referring to the rules of C.

Most two-operand operators can only do their job when their
operands have the same type. You cannot multiply a double by
an unsigned short, you cannot compare a long to a float, and so
on. You can *write* such an operator, but something happens
before the mixed-operand addition or comparison or whatever: The
operands are "promoted" to the same type, and then the operation
takes place between operands of that single type.

In your case, the written operands of the <= comparison
are an int (-1) and a size_t (SIZE). These are obviously not
the same type: int is signed and can be negative, while a size_t
is unsigned and can never be negative. So a conversion occurs,
and in this case the types are reconciled by promoting the int
to a size_t.[*] So the comparison that eventually occurs is
really (size_t)-1 <= SIZE.

So, what's the numerical value of (size_t)-1? Answer: it
is the greatest possible value a size_t can express -- which
is certainly greater than eight. Hence the result.

[*] On some "exotic" systems, SIZE might be promoted from
a size_t to an int. Such systems are theoretically possible,
but as far as I know nobody has ever seen one.
> Also I was using gcc 3.6.2

If you turn up your warning levels (I recommend -W -Wall),
gcc will warn you about this particular problem.
 
N

Nate Eldredge

Eric Sosman said:
AliM said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */
int main()
{
printf("%d",SIZE);
if(-1<=SIZE)
printf("1");
else printf("2");
}

It look like going to print 81 but it prints 82 anormally.

I have no idea where the "8" came from. The "2" is correct.

Er, from the first printf?
 
E

Eric Sosman

Nate said:
Eric Sosman said:
AliM said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */
int main()
{
printf("%d",SIZE);
if(-1<=SIZE)
printf("1");
else printf("2");
}
It look like going to print 81 but it prints 82 anormally.
I have no idea where the "8" came from. The "2" is correct.

Er, from the first printf?

(Harrumph.) "Young Nate so hasty is! The undefined
behavior in the first printf() he has overlooked, much as
Yodasosman the entire line has overlooked. The way of the
Jedi this is not!" (Harrumph, and thanks.)
 
B

Barry Schwarz

Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

%d requires the corresponding argument to be an int. Is yours?

What is the type of SIZE? What happens when you mix that type with a
negative int?
It look like going to print 81 but it prints 82 anormally. When try:
It prints 0, How do you explain this?

What happened to your if above happens here also.
 
E

Eric Sosman

Barry said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

How could the result be anything other than (size_t)8,
regardless of the specific system?
 
F

Flash Gordon

Barry said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

Am I going blind?
sizeof yields the size in bytes
ar is an array of 8 ints
therefore sizeof(ar) yields the same value as 8*sizeof(int)
8*sizeof(int)/sizeof(int) should yield 8 as far as I can see.

So what am I missing?

<snip>
 
B

Ben Bacarisse

Barry Schwarz said:
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

What system specific issue are you seeing?
 
B

Barry Schwarz

Barry said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

How could the result be anything other than (size_t)8,
regardless of the specific system?

Surely you realize that the expression 8 has type int. If the OP had
written your expression instead of his, I wouldn't have made the
comment. As it is, the #define does not produce an int though on some
systems it may produce an unsigned int. I expect on most it probably
produces an unsigned long.
 
B

Barry Schwarz

Barry said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

Am I going blind?
sizeof yields the size in bytes
ar is an array of 8 ints
therefore sizeof(ar) yields the same value as 8*sizeof(int)
8*sizeof(int)/sizeof(int) should yield 8 as far as I can see.

The fact the expression 8 has type int but the #define does not.
 
B

Barry Schwarz

Barry Schwarz said:
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

What system specific issue are you seeing?

typedef unsigned long size_t
 
C

CBFalconer

Eric said:
Barry said:
AliM said:
Last day I've seen a C code and I cant understand anything. It
prints invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

How could the result be anything other than (size_t)8,
regardless of the specific system?

You snipped Mr. Schwarz's accurate explanation of the error
(comparing a sizeof and a negative int).
 
B

Ben Bacarisse

Barry Schwarz said:
Barry Schwarz said:
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

What system specific issue are you seeing?

typedef unsigned long size_t

Too cryptic for me, but i see from replies that you object on the
grounds that 8 is of type int but the SIZE expression is not. True,
but then why say "system specific"? You complaint should have been
that the result is never 8 since int is signed on all systems just as
size_t is unsigned.

Even so I think that is setting too fine a distinction, even for
comp.lang.c. What next?

char s[] = "hello";
#define FIRST (s[0]) /* this is 'h' */

"No!, 'h' is an int but s[0] has type char!"
 
B

Barry Schwarz

Barry Schwarz said:
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

What system specific issue are you seeing?

typedef unsigned long size_t

Too cryptic for me, but i see from replies that you object on the
grounds that 8 is of type int but the SIZE expression is not. True,
but then why say "system specific"? You complaint should have been
that the result is never 8 since int is signed on all systems just as
size_t is unsigned.

Even so I think that is setting too fine a distinction, even for
comp.lang.c. What next?

char s[] = "hello";
#define FIRST (s[0]) /* this is 'h' */

"No!, 'h' is an int but s[0] has type char!"

If you use it in subsequent code where it makes a difference, such as
if (sizeof FIRST == sizeof 'h')
which is comparable to what the OP did, then it's a mandatory
distinction regardless of how fine.
 
I

Ioannis Vranos

AliM said:
Hi,
Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this
int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */
int main()
{
printf("%d",SIZE);
if(-1<=SIZE)
printf("1");
else printf("2");
}

It look like going to print 81 but it prints 82 anormally. When try:
printf("%d",-1<=SIZE);
It prints 0, How do you explain this?

Also I was using gcc 3.6.2


Your code corrected:


#include <stdio.h> /* Correction 1: Needed for printf() */
#include <stddef.h> /* It defines size_t type*/

int ar[8]= {1, 2, 3, 4, 5, 6, 7, 8};

const size_t SIZE= sizeof(ar)/sizeof(ar[0]); /* this gets 8 perfectly */

int main(void)
{
/* Correction 1: We must pass the expected argument
in a variadic function
*/
printf("%lu", (unsigned long)SIZE);


/* Correction 2: */
if(-1L <= (long)SIZE)
printf("1");

else
printf("2");

puts("");


return 0;
}
 
B

Ben Bacarisse

Barry Schwarz said:
Barry Schwarz said:
On Sat, 28 Mar 2009 13:34:27 +0000, Ben Bacarisse


Last day I've seen a C code and I cant understand anything. It prints
invalid result. The code was like this

int ar[8]={1,2,3,4,5,6,7,8};
#define SIZE (sizeof(ar)/sizeof(int)) /* this gets 8 perfectly */

Only for some system specific version of perfectly.

What system specific issue are you seeing?

typedef unsigned long size_t

Too cryptic for me, but i see from replies that you object on the
grounds that 8 is of type int but the SIZE expression is not. True,
but then why say "system specific"? You complaint should have been
that the result is never 8 since int is signed on all systems just as
size_t is unsigned.

Even so I think that is setting too fine a distinction, even for
comp.lang.c. What next?

char s[] = "hello";
#define FIRST (s[0]) /* this is 'h' */

"No!, 'h' is an int but s[0] has type char!"

If you use it in subsequent code where it makes a difference, such as
if (sizeof FIRST == sizeof 'h')
which is comparable to what the OP did, then it's a mandatory
distinction regardless of how fine.

Of course. I think you will be kept less busy if you limit yourself to
commenting on those uses rather than those deplorably lax comments.
 
I

Ioannis Vranos

Han said:
stdio.h defines size_t as well.


stdio.h is not mentioned defining size_t explicitly in the standard, although we can infer that it is defined
in it from the included functions.
 
E

Eric Sosman

Ioannis said:
stdio.h is not mentioned defining size_t explicitly in the standard,
although we can infer that it is defined in it from the included functions.

ISO/IEC 9899:1999 (E) says

7.19 Input/output <stdio.h>

7.19.1 Introduction

1 The header <stdio.h> declares three types, several
macros, and many functions for performing input and
output.

2 The types declared are size_t [...]
 

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,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top