473,486 Members | 1,984 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Integer promotion, relational operators, and unequal integer ranks.

Hi all,

I had a question about the topics in the subject and posted to
comp.std.c, but feel it may also be appropriate here. Please excuse
this crosspost if it is in bad form.

I have a question about whether or not I am interpreting a nuance of
the standard correctly, and the implications of said nuance. The
sections in the C99 standard (and possibly older standards) that I will
reference are as follows (typed out hopefully to avoid people having to
flip through their own manuals; if you want to fast forward to the meat
of this post, skip down to "-------end reference-------" line):

-------begin reference-------
6.2.6.2p2 (specifically):

For signed integer types, the bits of the object representation shall
be divided into three groups: value bits, padding bits, and the sign
bit. There need not be any padding bits; there shall be exactly one
sign bit. Each bit that is a value bit shall have the same value as the
same bit in the object representation of the corresponding unsigned
type (if there are M value bits in the signed type and N in the
unsigned type, then M≤N)...

6.3.1.1p1:

Every integer type has an integer conversion rank defined as follows:

—No two signed integer types shall have the same rank, even if they
have the same representation.
—The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision.
—The rank of long long int shall be greater than the rank of long
int, which shall be greater than the rank of int, which shall be
greater than the rank of short int, which shall be greater than the
rank of signed char.
—The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type, if any.
—The rank of any standard integer type shall be greater than the rank
of any extended integer type with the same width.
—The rank of char shall equal the rank of signed char and unsigned
char.
—The rank of_Bool shall be less than the rank of all other standard
integer types.
—The rank of any enumerated type shall equal the rank of the
compatible integer type (see 6.7.2.2).
—The rank of any extended signed integer type relative to another
extended signed integer type with the same precision is
implementation-defined, but still subject to the other rules for
determining the integer conversion rank.
—For all integer types T1, T2, andT3, if T1 has greater rank than T2
and T2 has greater rank than T3, then T1 has greater rank than T3.

6.3.1.8p1 (specifically):

Otherwise, the integer promotions are performed on both operands. Then
the following rules are applied to the promoted operands:

If both operands have the same type, then no further conversion is
needed.

Otherwise, if both operands have signed integer types or both have
unsigned integer types, the operand with the type of lesser integer
conversion rank is converted to the type of the operand with greater
rank.

Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand, then the
operand with signed integer type is converted to the type of the
operand with unsigned
integer type.

Otherwise, if the type of the operand with signed integer type can
represent all of the values of the type of the operand with unsigned
integer type, then the operand with unsigned integer type is converted
to the type of the
operand with signed integer type.

Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.

6.5.8p3

If both of the operands have arithmetic type, the usual arithmetic
conversions are performed.
-------end reference-------

Alright, now for the background. While redoing some string libraries I
had created a while back, I ran across some interesting check code that
I had added and now feel may be subject to an oddity. We all know that
the return type of snprintf is int (I assume for historical reasons and
the fact that a negative is used to indicate failure) as opposed to a
size_t. In this library I had code that does the following check
(where n is a non negative return value from a prior snprintf call used
to determine the size of the required storage):

if ( n >= SIZE_MAX )
{
.... return error information indicating that the size required will not
appropriately fit into a size_t and thusly I can not call malloc...

}

The assumption was that there is nothing in the standard to my
knowledge that prohibits a size_t being typedef'd to an unsigned type
incapable of holding the full positive range of an int. I believe my
past assumption was that integer promotion would be performed in this
relational expression and that the expression would always work. I'm
now beginning to question the always work portion. If I'm reading the
above referenced sections correctly, it is completely possible for an
implementation to have the following setup:

size_t typedef'd to an unsigned type with lower rank than an int.
Following the above rules, if we assume that in this implementation
there is a corresponding signed type, then both the size_t and the
signed type would have equal rank. Let us call this rank R1. int and
unsigned int have equal and higher rank than R1, lets call this R2.
Let A be the precision of the size_t, B be the precision of the
corresponding size_t signed type, C be the precision of an unsigned
int, and D be the precision of an int.

According to the above mentioned rules then,

R2 R1
A >= B (Rank R1) [6.2.6.2p2]
C >= D (Rank R2) [6.2.6.2p2]
D >= B [6.3.1.1p1]

Therefor, there is no way to link A and C relationally. It is entirely
possible to have the size_t have greater precision than the unsigned
int, even though the unsigned int is higher ranked (seems counter
intuitive but if I'm correct, this is true). Therefor, in my original
comparison, if we're on an implementation where this is true, and where
an int can not sufficiently hold all the values of a size_t, than
according to 6.3.1.8p1, *both operands are converted to the unsigned
integer type corresponding to the type of the operand with signed
integer type*, in this case unsigned int. Therefor, the size_t
(SIZE_MAX) would get converted to a type incapable of holding that
value, and the value would wrap around to a smaller number and thus
possibly give incorrect results.

Can someone very familiar with the standards tell me if my assumption
is correct. I know I've written a book in this post and apologize, I
just find it difficult to explain without the elaboration. If it is
true, do their exist any ways to safely compare values of an unsigned
type in a lower rank to values of a signed type in a higher rank
without any possible "overflow" of the value in the converted type?

Any insight would be massively appreciated!

Thanks so much!

-Charlie

Jan 15 '07 #1
1 3755
ch**********@merck.com wrote:

You better recheck this, but
6.3.1.8p1 (specifically):

Otherwise, the integer promotions are performed on both operands. Then
the following rules are applied to the promoted operands:
which means that SIZE_MAX will be at least promoted to unsigned int.

Jan 15 '07 #2

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

Similar topics

27
3083
by: glen herrmannsfeldt | last post by:
The subject recently came up in comp.compilers, though I believe that I asked here before. If you use relational operators, other than == and !=, on pointers to different objects, is there any...
16
5097
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. ...
49
14854
by: raju | last post by:
hi can we compare two integers without using relational operators (== != < <= > >=) thanks rajesh s
21
4074
by: Frederick Gotham | last post by:
I set about trying to find a portable way to set the value of UCHAR_MAX. At first, I thought the following would work: #define UCHAR_MAX ~( (unsigned char)0 ) However, it didn't work for me....
4
1914
by: spibou | last post by:
On 6.3.1.1 of N1124 we read: If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. A few lines above that...
6
13798
by: sarathy | last post by:
Hi, What is integer promotion? How is it different from arithmetic conversion? Regards, Sarathy
232
13062
by: robert maas, see http://tinyurl.com/uh3t | last post by:
I'm working on examples of programming in several languages, all (except PHP) running under CGI so that I can show both the source files and the actually running of the examples online. The first...
14
2537
by: AliceB.Toklas | last post by:
In my Absolute Beginner's Guide to C book by Greg Perry where it is instruction how relational operators work it gives the following example: int i = 5; so the following statement is true: ...
26
2876
by: Pietro Cerutti | last post by:
Hi group, I always thought that applying a binary operator such as ==, !=, <= or well defined. Now, I'm passing a program through splint and it says: Dangerous equality comparison involving...
0
6964
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7123
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7175
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7319
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4864
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
4559
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3069
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1378
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
598
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.