C programming in 2011

T

Tim Rentsch

Francois Grieu said:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
foo();
can be rewritten as
if ((unsigned)j-1u>7u)
foo();

No, it can't.

Would you please illustrate by an example when that does not stand?
Stick to C99, please.

On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX. Of course an implementation is
allowed to know that and take it into account.
 
T

Tim Rentsch

James Kuyper said:
That's UINT_MAX, not INT_MAX. And it's true whether or not 'int' is a
2's complement type; the rule is simply easier to implement in 2's
complement.

Amusing that there were two levels of correction and
the result still isn't right.
 
K

Kleuskes & Moos

Francois Grieu said:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
    foo();
can be rewritten as
    if ((unsigned)j-1u>7u)
        foo();
No, it can't.
Would you please illustrate by an example when that does not stand?
Stick to C99, please.

On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX.  Of course an implementation is
allowed to know that and take it into account.

I've been scratching my head for a bit, reading the above. In any
numbersystem i can come up with it seems that UINT_MAX > INT_MAX, if
only because of the sign bit required in integers.

So please, which situation did you have in mind where UINT_MAX ==
INT_MAX? The only one i can think of is a very silly definition in one
of the standard headers, making me want to give strong advice not to
use that a compiler. God knows what other silliness is hidden in the
headers.
 
T

Tim Rentsch

Kleuskes & Moos said:
Francois Grieu said:
On 26/05/2011 16:21, Branimir Maksimovic wrote:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
foo();
can be rewritten as
if ((unsigned)j-1u>7u)
foo();
No, it can't.
Would you please illustrate by an example when that does not stand?
Stick to C99, please.

On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX. Of course an implementation is
allowed to know that and take it into account.

I've been scratching my head for a bit, reading the above. In any
numbersystem i can come up with it seems that UINT_MAX > INT_MAX, if
only because of the sign bit required in integers.

So please, which situation did you have in mind where UINT_MAX ==
INT_MAX? The only one i can think of is a very silly definition in one
of the standard headers, making me want to give strong advice not to
use that a compiler. God knows what other silliness is hidden in the
headers.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Please refer to section 6.2.6.2, paragraph 2.
 
K

Kleuskes & Moos

On 26/05/2011 16:21, Branimir Maksimovic wrote:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
    foo();
can be rewritten as
    if ((unsigned)j-1u>7u)
        foo();
No, it can't.
Would you please illustrate by an example when that does not stand?
Stick to C99, please.
On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX.  Of course an implementation is
allowed to know that and take it into account.
I've been scratching my head for a bit, reading the above. In any
numbersystem i can come up with it seems that UINT_MAX > INT_MAX, if
only because of the sign bit required in integers.
So please, which situation did you have in mind where UINT_MAX ==
INT_MAX? The only one i can think of is a very silly definition in one
of the standard headers, making me want to give strong advice not to
use that a compiler. God knows what other silliness is hidden in the
headers.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Please refer to section 6.2.6.2, paragraph 2.

Nice to know that you know where integers are defined in the standard,
but that does not really answer my question. Much in contrast, from
what i read, it seems to validate my view, so please expound.

The chapter you mention endorses (explicitly) ones- and twos
complement, both of which obey the relation defined above, both for
the simple reason the need a (explicitly defined and demanded in the
chapter you mention) sign-bit.
 
J

James Kuyper

The closest the standard comes to directly constraining UINT_MAX
relative to INT_MAX is in 6.2.5p9: "The range of nonnegative values of a
signed integer type is a subrange of the corresponding unsigned integer
type, ...". That corresponds to the constraint UINT_MAX >= INT_MAX; it
is not violated by UINT_MAX==INT_MAX.
Nice to know that you know where integers are defined in the standard,
but that does not really answer my question. Much in contrast, from
what i read, it seems to validate my view, so please expound.

The chapter you mention endorses (explicitly) ones- and twos
complement, ...

You've forgotten sign-and-magnitude, which is also explicitly permitted.

.... both of which obey the relation defined above, both for
the simple reason the need a (explicitly defined and demanded in the
chapter you mention) sign-bit.

Actually, the relevant issue is 6.2.6.2p1, which specifies that unsigned
types can have padding bits. In particular, the bit which serves as a
sign bit for the corresponding signed type could be a padding bit for
the unsigned type.
This does not apply to those unsigned types which are prohibited from
having padding bits: unsigned char and the exact-sized types from
<stdint.h>, but unsigned int is allowed to have padding bits.
 
A

Angel

Wrong.

On any large project, it's important that there's a single formatting
style used throughout the project. Otherwise, the next time that
someone edits the code using the correct style, you end up with noise in
the diffs which can make it hard to discern the substantive changes from
the formatting corrections.

Also, rigid adherence to a coding convention helps weed out people who
aren't team players at an early stage.

Mm, I suppose you have some valid points there. Thanks for pointing that
out to me, I never looked at it that way.
 
K

Kleuskes & Moos

The closest the standard comes to directly constraining UINT_MAX
relative to INT_MAX is in 6.2.5p9: "The range of nonnegative values of a
signed integer type is a subrange of the corresponding unsigned integer
type, ...". That corresponds to the constraint UINT_MAX >= INT_MAX; it
is not violated by UINT_MAX==INT_MAX.

True. But then there's "not violating a constraint" and there's sheer,
unadulterated sillyness of actually creating an implementation in
which UINT_MAX==INT_MAX, since you would be throwing away half the
range of the unsigned integer (and that goes in all three mandated
numbersystems).

So while it may not violate the standard, it _is_ silly, and i would
very much like to know which compiler meets UINT_MAX==INT_MAX. Just so
that i can avoid it.
You've forgotten sign-and-magnitude, which is also explicitly permitted.

Yes. I omitted that one. But that changes nothing.
... both of which obey the relation defined above, both for


Actually, the relevant issue is 6.2.6.2p1, which specifies that unsigned
types can have padding bits. In particular, the bit which serves as a
sign bit for the corresponding signed type could be a padding bit for
the unsigned type.

Hmmm... For the reason mentioned above, that would be silly and i
suspect the padding has more to do with varying register sizes, the
occasional need to stuff a short int into a 32 bit register and
aligning arrays on word-boundaries.
This does not apply to those unsigned types which are prohibited from
having padding bits: unsigned char and the exact-sized types from
<stdint.h>, but unsigned int is allowed to have padding bits.

True. And having these padding bits serves what purpose in your
opinion? IFAIK the standards guys do nothing without a proper
rationale.
 
J

James Kuyper

True. But then there's "not violating a constraint" and there's sheer,
unadulterated sillyness of actually creating an implementation in
which UINT_MAX==INT_MAX, since you would be throwing away half the
range of the unsigned integer (and that goes in all three mandated
numbersystems).

So while it may not violate the standard, it _is_ silly, and i would
very much like to know which compiler meets UINT_MAX==INT_MAX. Just so
that i can avoid it.

There have been implementations which used the floating point processor
to implement an integer type (probably 'long int'), essentially by using
only mantissa bits, leaving the exponent bits completely unused.
Compared with that, throwing away only half of the potentially
representable range seems pretty minor.

....
True. And having these padding bits serves what purpose in your
opinion? IFAIK the standards guys do nothing without a proper
rationale.

An obvious possibility is a platform with no hardware support for
unsigned integers - depending upon the precise details of it's
instruction set, it could be easiest to implement unsigned ints as
signed ints with a range restricted to non-negative values. However, I
claim no familiarity with any such system.

I gather that padding bits were allowed because not allowing them would
make creation of a conforming implementation of C more difficult on some
platforms. The wording that describes padding bits was probably more
general than was needed to address the specific platforms the committee
was aware of, but I'm sure they were also concerned about possible
future platforms, and did not desire to unnecessarily constrain the
implementability of C. While they may be obscure platforms, the general
attitude of the C committee seems to be that C should be implementable
almost everywhere, even obscure platforms.
 
K

Kleuskes & Moos

There have been implementations which used the floating point processor
to implement an integer type (probably 'long int'), essentially by using
only mantissa bits, leaving the exponent bits completely unused.
Compared with that, throwing away only half of the potentially
representable range seems pretty minor.

Providing an example of even greatr sillyness, does not prove throwing
away half the range to be any less silly than it was before.

An obvious possibility is a platform with no hardware support for
unsigned integers - depending upon the precise details of it's
instruction set, it could be easiest to implement unsigned ints as
signed ints with a range restricted to non-negative values. However, I
claim no familiarity with any such system.

Such a system would not be able to operate, since every relative jmp-
instruction involves the addition (or subtraction, which is basically
the same). So name that fabled platform.
I gather that padding bits were allowed because not allowing them would
make creation of a conforming implementation of C more difficult on some
platforms. The wording that describes padding bits was probably more
general than was needed to address the specific platforms the committee
was aware of, but I'm sure they were also concerned about possible
future platforms, and did not desire to unnecessarily constrain the
implementability of C. While they may be obscure platforms, the general
attitude of the C committee seems to be that C should be implementable
almost everywhere, even obscure platforms.

Not so obscure that unsigned integers are not supported, after all,
every physical and logical memory address is, basically, an unsigned
integer.

So, noting the absence of any argument otherwise, UINT_MAX==INT_MAX is
only possible theoretically, but the chances of actually running into
it are virtually nonexistent, that is, somewhere between "highly
unlikely" and "absolute zero". In practice UINT_MAX > INT_MAX, and i
dare you to show me an example to the contrary.
 
S

Seebs

Mm, I suppose you have some valid points there. Thanks for pointing that
out to me, I never looked at it that way.

The interesting part is that it still doesn't actually matter where the
braces are, just that they're consistent.

It's like which side of the road you drive on. It's not actually known
to be significant, but it helps immensely if everyone on a given road agrees.

-s
 
K

Keith Thompson

Kleuskes & Moos said:
The closest the standard comes to directly constraining UINT_MAX
relative to INT_MAX is in 6.2.5p9: "The range of nonnegative values of a
signed integer type is a subrange of the corresponding unsigned integer
type, ...". That corresponds to the constraint UINT_MAX >= INT_MAX; it
is not violated by UINT_MAX==INT_MAX.
True. But then there's "not violating a constraint" and there's sheer,
unadulterated sillyness of actually creating an implementation in
which UINT_MAX==INT_MAX, since you would be throwing away half the
range of the unsigned integer (and that goes in all three mandated
numbersystems).
So while it may not violate the standard, it _is_ silly, and i would
very much like to know which compiler meets UINT_MAX==INT_MAX. Just so
that i can avoid it.
[...]
An obvious possibility is a platform with no hardware support for
unsigned integers - depending upon the precise details of it's
instruction set, it could be easiest to implement unsigned ints as
signed ints with a range restricted to non-negative values. However, I
claim no familiarity with any such system.

Such a system would not be able to operate, since every relative jmp-
instruction involves the addition (or subtraction, which is basically
the same). So name that fabled platform.

How do you know what's involved in relative jump instructions on a
hypothetical system that might not even exist?
Not so obscure that unsigned integers are not supported, after all,
every physical and logical memory address is, basically, an unsigned
integer.

On some systems, yes. On the hypothetical system in question, it's
likely that physical and logical memory addresses are represented as
signed integers. For example, if it's a 32-bit system, addresses might
range from -2147483648 to +2147483647.
So, noting the absence of any argument otherwise, UINT_MAX==INT_MAX is
only possible theoretically, but the chances of actually running into
it are virtually nonexistent, that is, somewhere between "highly
unlikely" and "absolute zero". In practice UINT_MAX > INT_MAX, and i
dare you to show me an example to the contrary.

I do not claim that such an example exists, but it *could*. Perhaps it
could be a specialized system, not primarily designed with C in mind,
but intended to support an environment which has no need for unsigned
arithmetic (and no, address calculations don't *necessarily* require
unsigned integer arithmetic).

On such a system, it would make sense to have:
INT_MIN = -2147483648
INT_MAX = +2147483647
UINT_MAX = INT_MAX
and for unsigned int to have a single padding bit in place of
signed int's sign bit. And that would probably result in much more
efficient code than forcing unsigned int to have 32 value bits and
perform most unsigned operations in software. (Perhaps unsigned long
would be 32 bits wide, and be slower than unsigned int.)

The point is that C is designed to be implementable with reasonable
efficiency on a wide variety of systems.

There are more things in heaven and earth, Horatio, ...
 
K

Keith Thompson

Seebs said:
The interesting part is that it still doesn't actually matter where the
braces are, just that they're consistent.

It's like which side of the road you drive on. It's not actually known
to be significant, but it helps immensely if everyone on a given road agrees.

Indeed. I've worked under some code layout standards that I find
extremely ugly, but having parts of the code in my own preferred style
would be far worse.
 
J

J. J. Farrell

Kleuskes said:
...
So, noting the absence of any argument otherwise, UINT_MAX==INT_MAX is
only possible theoretically, but the chances of actually running into
it are virtually nonexistent, that is, somewhere between "highly
unlikely" and "absolute zero". In practice UINT_MAX > INT_MAX, and i
dare you to show me an example to the contrary.

Why on earth should he? Who ever claimed such an environment exists, or
isn't silly? It's legal in C for such an environment to exist, that's
all. If someone is choosing to write code which is portable to all
possible legal C implementations, they have to allow for it. If they
only need to make their code portable to all environments which there is
the slightest predictable possibility of ever coming across, they can
ignore it.
 
F

Francois Grieu

Francois Grieu said:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
foo();
can be rewritten as
if ((unsigned)j-1u>7u)
foo();

No, it can't.

Would you please illustrate by an example when that does not stand?
Stick to C99, please.

On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX.(..)

I agree that an implementation could have UINT_MAX == INT_MAX
(the example of using a floating point engine is fine).

But, assuming that, for what value of j would the above
rewriting become invalid? I do not find any.

Francois Grieu
 
F

Francois Grieu

I just wrote::
Francois Grieu said:
On 26/05/2011 16:21, Branimir Maksimovic wrote:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
foo();
can be rewritten as
if ((unsigned)j-1u>7u)
foo();

No, it can't.

Would you please illustrate by an example when that does not stand?
Stick to C99, please.

On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX.(..)

I agree that an implementation could have UINT_MAX == INT_MAX
(the example of using a floating point engine is fine).

But, assuming that, for what value of j would the above
rewriting become invalid? I do not find any.

Got it: j = -INT_MAX; I stand corrected.

Francois Grieu
 
K

Kleuskes & Moos

Kleuskes & Moos said:
On 05/31/2011 08:57 AM, Kleuskes & Moos wrote:
...
The closest the standard comes to directly constraining UINT_MAX
relative to INT_MAX is in 6.2.5p9: "The range of nonnegative valuesof a
signed integer type is a subrange of the corresponding unsigned integer
type, ...". That corresponds to the constraint UINT_MAX >= INT_MAX; it
is not violated by UINT_MAX==INT_MAX.
True. But then there's "not violating a constraint" and there's sheer,
unadulterated sillyness of actually creating an implementation in
which UINT_MAX==INT_MAX, since you would be throwing away half the
range of the unsigned integer (and that goes in all three mandated
numbersystems).
So while it may not violate the standard, it _is_ silly, and i would
very much like to know which compiler meets UINT_MAX==INT_MAX. Just so
that i can avoid it. [...]
An obvious possibility is a platform with no hardware support for
unsigned integers - depending upon the precise details of it's
instruction set, it could be easiest to implement unsigned ints as
signed ints with a range restricted to non-negative values. However, I
claim no familiarity with any such system.
Such a system would not be able to operate, since every relative jmp-
instruction involves the addition (or subtraction, which is basically
the same). So name that fabled platform.

How do you know what's involved in relative jump instructions on a
hypothetical system that might not even exist?

What other methods of doing relative jumps did you have in mind? Since
you think there's an alternative, it's up to you to name it.


On some systems, yes.  On the hypothetical system in question, it's
likely that physical and logical memory addresses are represented as
signed integers.  For example, if it's a 32-bit system, addresses might
range from -2147483648 to +2147483647.

Ah. Another hypothetical system that defies the laws of common
sense... Great, what advantages does your hypothetical system with
signed memory addresses have? More importantly, how does that jive
with the electronics of the address-bus of that hypothetical system?

Objections concerning some hypothetical system which uses signed
integers as memory addresses and do not support nsigned integers are
not quite taken seriously on my side of the NNTP-server. Why not
invent a hypothetical system which uses pink bunnies to address
memory?
I do not claim that such an example exists, but it *could*.

Yes. And the chip-select signal might be delivered by invisible pink
unicorns, the Carry Flag might be hoisted by Daffy Duck and interrupts
might be implemented by Yosemity Sam, firing his guns at the hootenest-
tootenest-shootenest programmable interrupt controller north, east,
south AAAAND west of the Pecos.

To me, the flurry of hypotheticals merely indicates that i was right,
but you don't like admitting it, so you're grasping at hypothetical
straws.
Perhaps it could be a specialized system, not primarily designed with C
in mind, but intended to support an environment which has no need for
unsigned arithmetic (and no, address calculations don't *necessarily*
require unsigned integer arithmetic).

Ok. So name a (non-hypothetical) example of adddresses not being
unsigned integers. I wager a case of Grolsch you won't be able to. Not
because it's not possible, just because it's unpractical.

Besides, a pattern of bits on the address bus, and this would be the
best objection you can make, can be interpreted as signed _or_
unsigned at the whim of whomsoever is interpreting it. It really makes
no difference, it's just a question of how you interpret them.

But, given the practicalities of hardware design, they are usually
interpreted as being unsigned, simply because it's more convenient.
On such a system, it would make sense to have:
    INT_MIN = -2147483648
    INT_MAX = +2147483647
    UINT_MAX = INT_MAX
and for unsigned int to have a single padding bit in place of
signed int's sign bit.  And that would probably result in much more
efficient code than forcing unsigned int to have 32 value bits and
perform most unsigned operations in software.  (Perhaps unsigned long
would be 32 bits wide, and be slower than unsigned int.)

Ok.

Let me pose two simple questions...

How does a CPU add 1 and 1 and arrive at the (correct) answer: 2?
How do signed and unsigned versions of this operation differ?

The question "why doesn't anyone design a computer that does not
support unsigned arithmatic" should be obvious, if you got the above
two questions right, and hypothetical, highly unpractical systems
should then be laid to rest.
The point is that C is designed to be implementable with reasonable
efficiency on a wide variety of systems.

True. But i doubt you'll find ANY that match the exotic, nay,
excentric hardware you describe. I still dare yoou to name a single
CPU that does not support unsigned integers, and i'm very confident
you won't find any.
There are more things in heaven and earth, Horatio, ...

True. But that's no argument.
 
W

Willem

Kleuskes & Moos wrote:
)> An obvious possibility is a platform with no hardware support for
)> unsigned integers - depending upon the precise details of it's
)> instruction set, it could be easiest to implement unsigned ints as
)> signed ints with a range restricted to non-negative values. However, I
)> claim no familiarity with any such system.
)
) Such a system would not be able to operate, since every relative jmp-
) instruction involves the addition (or subtraction, which is basically
) the same). So name that fabled platform.

What do relative jump instructions have to do with unsigned integers ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
T

Tim Rentsch

Kleuskes & Moos said:
Kleuskes & Moos said:
On 26/05/2011 16:21, Branimir Maksimovic wrote:
On 05/26/2011 04:04 PM, Francois Grieu wrote:
[3] some compilers know that, when j is an int,
if (j<1 || j>8)
foo();
can be rewritten as
if ((unsigned)j-1u>7u)
foo();
No, it can't.
Would you please illustrate by an example when that does not stand?
Stick to C99, please.
On most implementations it will work, but it can fail if
UINT_MAX == INT_MAX. Of course an implementation is
allowed to know that and take it into account.
I've been scratching my head for a bit, reading the above. In any
numbersystem i can come up with it seems that UINT_MAX > INT_MAX, if
only because of the sign bit required in integers.
So please, which situation did you have in mind where UINT_MAX ==
INT_MAX? The only one i can think of is a very silly definition in one
of the standard headers, making me want to give strong advice not to
use that a compiler. God knows what other silliness is hidden in the
headers.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Please refer to section 6.2.6.2, paragraph 2.

Nice to know that you know where integers are defined in the standard,
but that does not really answer my question. [snip elaboration]

I think it will if you take some time to re-read it
carefully. To help, all text after "If the sign bit is
zero," does not bear on the INT_MAX == UINT_MAX question.
 
I

Ike Naar

Ah. Another hypothetical system that defies the laws of common
sense... Great, what advantages does your hypothetical system with
signed memory addresses have? More importantly, how does that jive
with the electronics of the address-bus of that hypothetical system?

Objections concerning some hypothetical system which uses signed
integers as memory addresses and do not support nsigned integers are
not quite taken seriously on my side of the NNTP-server. Why not
invent a hypothetical system which uses pink bunnies to address
memory?

http://en.wikipedia.org/wiki/Burroughs_large_systems describres
a family of non-hypothetical systems that used sign-and magnitude
representation for integers (integers were simply floating-point
numbers with a zero exponent). These systems existed before the
C language became popular (Algol was their main high level language),
but UINT_MAX==INT_MAX would be a logical choice for a C implementation
on such a system.
 

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
474,093
Messages
2,570,610
Members
47,230
Latest member
RenaldoDut

Latest Threads

Top