473,375 Members | 1,299 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,375 software developers and data experts.

int to unsigned int conversions

Hi,
This was asked on our school newsgroup by a friend of mine.
He gave the following code and said that it did not print out
the elements of the array. He asked for an explanation for this
behaviour. I whittled this down a bit but I am unable to pin it
to a reference from the standard which I would like to have given
when explaining it.
Ok here goes.

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

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main(void)
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
/* TOTAL_ELEMENTS is actually getting evaluated to an unsigned
int. Since sizeof returns size_t which is unsigned int.
I assume that this is the problem since the problem was reproduced
if I used this line instead:
for(d=-1;d <= ((unsigned int)7-2);d++)

This for some reason is either implementation defined behaviour
or undefined behaviour since I got two separate outputs from two
compilers.. one being Turbo C and one the VC compiler.
In one case it is not printing out any element of the array
since the LHS is forcing itself up into unsigned int ...
In the other case the unsigned int is coverted into an int, thus
there are no problems.
*/

printf("%d\n",array[d+1]);

return EXIT_SUCCESS;
}
Would like to hear your comments regarding the above explanation.
Regards,
Anupam
Nov 13 '05 #1
4 12391
Anupam wrote:

Hi,
This was asked on our school newsgroup by a friend of mine.
He gave the following code and said that it did not print out
the elements of the array. He asked for an explanation for this
behaviour. I whittled this down a bit but I am unable to pin it
to a reference from the standard which I would like to have given
when explaining it.
Ok here goes.

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

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main(void)
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
/* TOTAL_ELEMENTS is actually getting evaluated to an unsigned
int. Since sizeof returns size_t which is unsigned int.
I assume that this is the problem since the problem was reproduced
if I used this line instead:
for(d=-1;d <= ((unsigned int)7-2);d++)

This for some reason is either implementation defined behaviour
or undefined behaviour since I got two separate outputs from two
compilers.. one being Turbo C and one the VC compiler.
In one case it is not printing out any element of the array
since the LHS is forcing itself up into unsigned int ...
In the other case the unsigned int is coverted into an int, thus
there are no problems.
*/

printf("%d\n",array[d+1]);

return EXIT_SUCCESS;
}
Would like to hear your comments regarding the above explanation.


for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
should not print unless you have a situation where
size_t gets converted to int, because that's the only way
that -1 can be less than or equal to (size_t)5.
If size_t is unsigned short and unsigned short
has fewer value bits than int does, it should work.

If -1 is converted to an unsigned type,
then it is converted to the greatest value
that the unsigned type is capable of representing.

for(d=-1;d <= ((unsigned int)7-2);d++)
should not print at all.

for(d=-1;d <= (int)(TOTAL_ELEMENTS-2);d++)
should print the array.

--
pete
Nov 13 '05 #2
On 3 Dec 2003 03:33:42 -0800
an**************@persistent.co.in (Anupam) wrote:
Hi,
This was asked on our school newsgroup by a friend of mine.
He gave the following code and said that it did not print out
the elements of the array. He asked for an explanation for this
behaviour. I whittled this down a bit but I am unable to pin it
to a reference from the standard which I would like to have given
when explaining it.
Ok here goes.

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

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main(void)
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
/* TOTAL_ELEMENTS is actually getting evaluated to an unsigned
int. Since sizeof returns size_t which is unsigned int.
Is that true of both compilers you were trying? It is only required to
be an unsigned integer type so it could be unsigned long.

However, a more normal (and more reliable) way to do this loop is

for (d=0; d<TOTAL_ELEMENTS; d++)

to make certain that the above works for the maximum possible size of
array you would have to declare d as being of type size_t.
I assume that this is the problem since the problem was reproduced
if I used this line instead:
for(d=-1;d <= ((unsigned int)7-2);d++)

This for some reason is either implementation defined behaviour
or undefined behaviour since I got two separate outputs from two
Implementation defined.
compilers.. one being Turbo C and one the VC compiler.
In one case it is not printing out any element of the array
since the LHS is forcing itself up into unsigned int ...
In the other case the unsigned int is coverted into an int, thus
there are no problems.
*/

printf("%d\n",array[d+1]);

return EXIT_SUCCESS;
}
Would like to hear your comments regarding the above explanation.
Regards,


You are on the right lines, however the exact promotions applied depend
on how the implementation has chosen to define size_t, which on old DOS
and Windows compilers may depend on the options used.

If size_t is unsigned short and an int can represent all values of
unsigned short then it will be promoted to int. This may be the case if
you select the small memory model and an option that gives you 32 bit
ints.

Basically, your friend should not write his loops like that.

Look up "Arithmetic Conversions", "Integral Promotion" and "Integral
Conversion" for the full gory details
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #3
In <aa*************************@posting.google.com> an**************@persistent.co.in (Anupam) writes:
#include <stdio.h>
#include <stdlib.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main(void)
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
/* TOTAL_ELEMENTS is actually getting evaluated to an unsigned
int. Since sizeof returns size_t which is unsigned int.
It's an unspecified usigned integer type.
I assume that this is the problem since the problem was reproduced
if I used this line instead:
for(d=-1;d <= ((unsigned int)7-2);d++)

This for some reason is either implementation defined behaviour
or undefined behaviour since I got two separate outputs from two
compilers.. one being Turbo C and one the VC compiler.
Except for the pathological case when size_t is unsigned char or unsigned
short, the behaviour is well defined: d is converted to size_t (an
unsigned integer type) before the comparison.
In one case it is not printing out any element of the array
since the LHS is forcing itself up into unsigned int ...
This is the correct behaviour. When converting -1 to an unsigned type,
the result is the maximum value representable by theat type.
In the other case the unsigned int is coverted into an int, thus
there are no problems.


That compiler is broken. Neither Turbo C nor VC have a size_t that is
subject to the integral promotions, therefore there is no way a size_t
expression will be converted to int by the usual arithmetic conversions.

The general rule is that if you mix signed and unsigned integers in the
same expression, the signed integers must be non-negative in order to get
what you intuitively expect. Fix your loop to the idiomatic

for (d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d\n", array[d]);

and everything will work just fine.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #4
In article <aa*************************@posting.google.com> ,
an**************@persistent.co.in (Anupam) wrote:
#include <stdio.h>
#include <stdlib.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main(void)
{
int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
/* TOTAL_ELEMENTS is actually getting evaluated to an unsigned
int. Since sizeof returns size_t which is unsigned int.
I assume that this is the problem since the problem was reproduced
if I used this line instead:
for(d=-1;d <= ((unsigned int)7-2);d++)

This for some reason is either implementation defined behaviour
or undefined behaviour since I got two separate outputs from two
compilers.. one being Turbo C and one the VC compiler.
In one case it is not printing out any element of the array
since the LHS is forcing itself up into unsigned int ...
In the other case the unsigned int is coverted into an int, thus
there are no problems.
*/

printf("%d\n",array[d+1]);

return EXIT_SUCCESS;
}
Would like to hear your comments regarding the above explanation.
Regards,
Anupam


It gives you the right idea, just very slightly inaccurate. size_t can
be any unsigned type, not just unsigned int. But the important thing is
that depending on the implementation, d may be converted to an unsigned
type and therefore the loop will not print anything. Shows that you have
to be very careful mixing signed and unsigned operands.
Nov 13 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: MiniDisc_2k2 | last post by:
Okay, here's a question about the standard. What does it say about unsigned/signed mismatches in a comparison statement: char a = 3; unsigned char b = 255; if (a<b) Now what's the real...
8
by: Rade | last post by:
Following a discussion on another thread here... I have tried to understand what is actually standardized in C++ regarding the representing of integers (signed and unsigned) and their conversions....
10
by: Vijay Kumar R Zanvar | last post by:
Hi clc, Please elaborate the warning: F:\Vijay\C> type unsigned2.c #include <stdio.h> #include <stdlib.h> int
12
by: Peter Ammon | last post by:
When I add an unsigned long long and an int, what type do each of the values get promoted to before the addition is performed? What is the type of the resulting expression? What occurs if the...
16
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
3
by: Joe Van Dyk | last post by:
What bad things could happen if I compare signed and unsigned integers? (is that even valid C?) Thanks, Joe
4
by: techie | last post by:
I have defined a number of unsigned integer types as follows: typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedfe long long uint64; Is it...
7
by: somenath | last post by:
Hi All, I am trying to undestand "Type Conversions" from K&R book.I am not able to understand the bellow mentioned text "Conversion rules are more complicated when unsigned operands are...
8
by: Steven | last post by:
Hello, everyone! I find a version of strcpy(), I don't know why it return the unsigned char value. Can I change it into return *s1-*s2? int strcmp(const char *s1, const char *s2) { while...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.