Address of an array = address of its 1st element: undecidable question?

C

candide

Hi,


I try to find out what exactly means "an array and its address are the
same" or "have the same value".
Everybody seems to agree that they doesn't share the same type, of course.

For enlighting the discussion, here some more or less contradictory
quotes from clc and comp.std.c regarding this question :


-------------------------------- 8<
-------------------------------------------
> I'm not aware of any definition (or even description) of the C language
> that said that taking theaddressof anarraywas equivalent to taking
> theaddressof the first member of thearray. Certainly there were
> compilers that worked that way, but there were also many compilers that
> considered it an error and didn't allow it at all.
>

-------------------------------------------------------------------------------

> >(...) The address of an array IS the address of
> >it's first element.
>
> The standard doesn't say so explicitly although a conforming implementation
> doesn't really have much choice in the matter. (void *)&s and (void *)&s[0]
> pretty much have to generate thesameaddress or else standard library
> functions like fread() would have problems.
-------------------------------------------------------------------------------

> > OK, but what IS the address of an array? If we consider that in most
> > contexts an array name "a" is converted to &a[0], then the closest thing I
> > can imagine that would be anarray addressis the address of a cell that
> > holds &a[0]. Seems like that is just creating an unnecessary level of
> > indirection. I'd be interested in an example where this would be
useful.
>
> In the usual implementation the bit value of &a[0] and &a will be the
> same,
> but the type is different (ptr to int, ptr to array of int).
> If you add 1 to them you will get different answers.
-------------------------------------------------------------------------------

> Don't be fooled by the fact that the above works. It just so happens that
> myarray and &myarray are both expressions that yield the same pointer. But the
> two pointers have a different type.

-------------------------------------------------------------------------------


> &array is a perfectly legitimate expression; it yields the address of
> the array, which is distict from the address of itsfirstelement.
> They have the "same value" in some sense, but they're of different
> types.

-------------------------------------------------------------------------------

> [...] The address of an array is the same as
> the address of its first element just as the address of a struct is the
> same as the address of its first member (the addresses are the same but
> the types are different)
-------------------------------------------------------------------------------

> Paul Seale wrote:
>
>
> What's theaddressof a struct? Theaddressof a struct is "the same
> as" theaddressof its first member, but they have different types.
> Likewise, theaddressof anarrayis "the same as" theaddressof its
> first element, but they have different types. (By "the same as", I
> mean that they compare equal if you convert them both to (void *)).
--------------------------------- >8
 
P

Peter Nilsson

Richard Heathfield said:
candide said:
I try to find out what exactly means "an array and
its address are the same"

They aren't. An array is an array. An address is a
pointer value. These are not the same thing. If you
mean that &array and &array[0] are the same,
they aren't. They have different types.
or "have the same value".

If you try to take the value of an array, what you
actually get is the value of a pointer to the first
member of the array. That doesn't mean that an array
is the same as a pointer. If you mean that &array
and &array[0] have the same value, they don't. They
have different types.

What about (void *) &array == (void *) &array[0]?
And therefore they cannot have the same value.

So 1 is _not_ the same value as 1u?

Can you then tell me what the standard means when
it says...

"The range of nonnegative values of a signed
integer type is a subrange of the corresponding
unsigned integer type, and the representation
of the same value in each type is the same."
^^^^^^^^^^

Either 'same value' is independant of type, or
above line makes no sense. Which is it?
 
B

Ben Bacarisse

candide said:
I try to find out what exactly means "an array and its address are the
same" or "have the same value".

These two statements are very different. The first one is just wrong
and I am pretty sure you did not mean to suggest that. There is no
object in C that is the same as its address.

The second one simply depends on a term that is not well-defined.

Most people consider the type to be an important part of the notion of
value, so two things of different type are not likely to be considered
the same. They may compare equal (0 == 0.0 in C) but that is not the
same. (In other languages one type can be included in another so two
values may be exactly the same even in they have different types but
that is not really the way C types work.)

Of course, people can be lax with words. I may say, off hand, that 0
and 0.0 have the same value and that is a perfectly defensible
statement but only if you know the ways in which they differ. It is
equally valid to say that they are *not* the same value. What matters
is not the answer to an ill defined question but a full understanding
of arrays, pointers, and their relationships.
Everybody seems to agree that they doesn't share the same type, of
course.

Good. That is indisputable.
For enlighting the discussion, here some more or less contradictory
quotes from clc and comp.std.c regarding this question :

-------------------------------- 8<

This one is taken out of context. IIRC LJ was taking about historical
C compilers before the construct of taking the address of an array had
been defined by the language standard.
(...) The address of an array IS the address of
it's first element.

The standard doesn't say so explicitly although a conforming implementation
doesn't really have much choice in the matter. (void *)&s and (void *)&s[0]
pretty much have to generate thesameaddress or else standard library
functions like fread() would have problems.

OK, I have no problem with that. The way in which the values are "the
same" is made explicit -- they compare equal when converted to void*.
Paul said:
OK, but what IS the address of an array? If we consider that in most
contexts an array name "a" is converted to &a[0], then the closest thing I
can imagine that would be anarray addressis the address of a cell that
holds &a[0]. Seems like that is just creating an unnecessary level of
indirection. I'd be interested in an example where this would be
useful.

In the usual implementation the bit value of &a[0] and &a will be the
same,
but the type is different (ptr to int, ptr to array of int).
If you add 1 to them you will get different answers.

OK. Again, I see no problem. Note the DR is careful to say "the bit
value". He does not really care about the bits, he wants a phrase
that means "the value when you have thrown away or ignored the type".
Bit value is a good way to suggest that.

Again, no contradiction. KK is explicit that the pointers have
different types so he must be using "the same" to mean "the same
except for the type". If KK had just said "... yield the same
pointer" and stopped there, someone would have come in to clarify the
matter. The term "the same" is just too vague to left unqualified.

KT prefers to emphasise the difference and puts "the same" in quotes to
show that it is vague and need qualification. No contradiction that
I can see.
[...] The address of an array is the same as
the address of its first element just as the address of a struct is the
same as the address of its first member (the addresses are the same but
the types are different)

More of the same. The problem is entirely due to how the writer like
to view the phrase "the same". LJ obviously prefers to emphasise the
similarity but he, too, is careful to point out the difference.

Again, another careful writer putting the matter quite clearly in my
view. The "scare quotes" draw attention to the problem phrase but
both the similarities and the differences are made explicit.
So what ? Is the question undecidable ?

If you include the notion of type in that of value, then the answer is
"no". If you don't then the answer can be a qualified "yes". The
qualification is made very clear by most of the quotes ("the bit
values are the same", "they compare equal when converted to void *")
but even when it is glossed over, there is no contradiction.

My personal preference is to be strict about the types so I would say
that the values are not the same if I have to make just one statement
about them. If you were to permit me, I'd go on to say that they have
values that convert to equal void *s. The C standard is very clear
that a pointer to a whole object and pointer to one of its initial
sub-objects must compare equal (provided you convert the pointers so
that comparison is permitted) so the pointers have the same value in
that limited sense.
 
Y

ymuntyan

These two statements are very different.  The first one is just wrong
and I am pretty sure you did not mean to suggest that.  There is no
object in C that is the same as its address.

The second one simply depends on a term that is not well-defined.

How about using the standard definition? Then all is good and
clear, answer is "no and the question doesn't make much sense".
Making up the meaning of "value of array" is silly otherwise.
(True, it's an interesting philosophical exercise, like whether
the element of one-element array is the array or not... And it
certainly is on-topic and so is "interesting and useful"!)

[snip long list of who (Ritchie included!) says what]

Yevgen
 
S

Szabolcs Borsanyi

Hi,


I try to find out what exactly means "an array and its address are the
same" or "have the same value".
Everybody seems to agree that they doesn't share the same type, of course.

I am glad that this discussion comes up again, as it is not merely of
academic nature. I don't really think that one truely wants to
compare (void*)&array to (void*)array, but consider the following:

I have a chunk of data:

float A[256];

And you would like to consider this as 32x8 matrix.
You can of course do A[32*i+j] for the (i,j)-th element, but it is
much more convenient to put it into an array form:

float (*B)[8]=(void*)A;

The (void*) here is merely to shut up the compiler (ie. to fulfil the language
constraints). B is a pointer to the first one of a series (float[8]) arrays.

Then, after using this layout of the data, I realise that I need an other
matrix format: 16x16, so I write.

float (*C)[16]=(void*)A;


Let now the experts tell if accessing the array members through B and C
invoke an undefined behaviour. In my understanding it does not, but it might
be far from the truth.

Szabolcs
 
B

Bartc

pete said:
Only one of those, is greater than -1.

(1u < -1)

This is ridiculous and dangerous behaviour on the part of C;

(a<b) /* True */

++a; ++b;

(a<b) /* Now false! And without any wrap or overflow */

Obviously some amateurish work in the early days of C which later had to be
condoned by the standard.

The correct handling would have been to have cast both into a type
encompassing both values before comparing, or to give a warning.

(OK, my own compiler efforts do exactly the same, but my compiler isn't used
for supercomputers or mission critical software)
 
B

Ben Bacarisse

How about using the standard definition?

I am not sure exactly what you mean. I don't think the term "same
value" is used clearly and unambiguously thought the standard. At
least, I don't think it is used in way that can be understood without
context.
Then all is good and
clear, answer is "no and the question doesn't make much sense".
Making up the meaning of "value of array" is silly otherwise.

The value of an array has a reasonable meaning in C. You can't so
much with them, but that is beside the point. I don't think I made up
a meaning for it.
(True, it's an interesting philosophical exercise, like whether
the element of one-element array is the array or not... And it
certainly is on-topic and so is "interesting and useful"!)

[snip long list of who (Ritchie included!) says what]

I thought my answer was helpful because, rather than taking a
definitive view on the meaning of the words, it explained why the
various phrases quoted are all consistent provided one does not assume
that slightly ambiguous terms can be pinned down one way or the other.
Most of the quotes went to some lengths to explain why the two values
in question were the same in some sense and different in others.
Plumping for one or the other if fine (I said as much) but not as
helpful as I was trying to be. Of course, I may have missed by a mile
and just confused the OP. Only time will tell.
 
V

vippstar

This is ridiculous and dangerous behaviour on the part of C;
No, it is not. It would be ridiculous and dangerous if anything else
happened.
What you're essentially saying here is that 1u > UINT_MAX should be
true, or rather, that it's ridiculous it's true.
Add to that, that (unsigned)1 is also different than 1 or 1u.
It doesn't make sense until you learn about integer promotions in
expressions.
 
B

Bartc

Eric Sosman said:
Having embarrassed myself once already on this topic,
it is with some trepidation that I suggest that's not what
he was saying. Here's the situation I think he had in mind:

I was merely talking about the (1u<-1) above:

#include <stdio.h>

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

if (a<b) printf("A<B\n"); else printf("A>=B\n");

++a;
++b;

if (a<b) printf("A<B\n"); else printf("A>=B\n");

}

The increment changes 1 to 2, and -1 to 0, nothing dramatic.

The problem seems to me that comparing unsigned to signed (by I think
treating both as unsigned) seems a little dangerous.
 
K

Keith Thompson

Eric Sosman said:
Eric said:
Bartc said:
Peter Nilsson wrote:

So 1 is _not_ the same value as 1u?
Only one of those, is greater than -1.

(1u < -1)

This is ridiculous and dangerous behaviour on the part of C;

(a<b) /* True */

++a; ++b;

(a<b) /* Now false! And without any wrap or overflow */
Perhaps I'm overlooking something obvious, [...]

Aha! Never mind; I overlooked something obvious. Still,
your characterization of pointer arithmetic as "amateurish
work in the early days of C" is silly.

Bartc was talking about comparisons between unsigned and signed
integers, not pointer arithmetic.

(Eric, I can't think of an example of the above problem involving
pointer arithmetic. Do you have one in mind?)

Here's an example of what Bartc was talking about:

#include <stdio.h>
int main(void)
{
unsigned a = 1;
int b = -1;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
++a; ++b;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
return 0;
}

The output is:

1U < -1
2U > 0

And the reason is that when the "<" operator has signed and unsigned
operands of the same rank, the signed operand is converted to the
unsigned type before the operator is applied (see "Usual arithmetic
conversions", C99 6.3.1.8), so the value -1 is converted to UINT_MAX.

Note that gcc, for example, warns about the
comparisons in my sample program:
c.c:6: warning: comparison between signed and unsigned
c.c:8: warning: comparison between signed and unsigned

The alternative would have been to convert the unsigned operand to the
signed type -- but such a conversion can yield an
implementation-defined result (or raise an implementation-defined
signal). Conversion from signed to unsigned is well defined.

Upthread, Bartc wrote:
| The correct handling would have been to have cast both into a type
| encompassing both values before comparing, or to give a warning.

(You mean convert, not cast.)

There won't necessarily be such a type. Note that the type would have
to encompass the full ranges of the types of both operands, not just
the values of the operands (which aren't known to the compiler).

As I recall, there was considerable controversy in the pre-ANSI era
between "value-preserving" and "signedness-preserving" conversions.
Some compilers, did it one way, some did it the other way. Both
approaches have problems, and the committee had to choose one or the
other. Probably the fact that unsigned-to-signed conversion is
implementation-defined was a large part of what motivated their
decision.

Another possibility might have been to disallow such comparisons, so
that if you want to compare a signed value to an unsigned value you
have to convert one of them explicitly. That might actually have been
less confusing.

Or they could have required the operators to be further "overloaded"
at the language level so that these:
u < i
i < u
i < i
u < u
actually invoke four different operations rather than just two. The
same would have had to be done for most other operators, and the
result would have been a substantial burden on compiler writers (how
would you actually implement a long long vs. unsigned long long
comparison?) for some fairly unusual cases.

The best workaround is to avoid such comparisons in your own code. If
you find yourself comparing a signed quantity to an unsigned quantity,
it's likely (but by no means certain) that they both simply should
have been of the same type in the first place.
 
K

Keith Thompson

Ben Bacarisse said:
I am not sure exactly what you mean. I don't think the term "same
value" is used clearly and unambiguously thought the standard. At
least, I don't think it is used in way that can be understood without
context.

Ah, but the standard does define the term "value", in C99 3.17:

value
precise meaning of the contents of an object when interpreted as
having a specific type

Given this definition, it doesn't make much sense to say that objects
of different types can have the "same value".

(One flaw in this definition is that it doesn't define the value of an
expression.)
The value of an array has a reasonable meaning in C. You can't so
much with them, but that is beside the point. I don't think I made up
a meaning for it.

Agreed; given the standard's definition of "value" the value of an
array is a fairly obvious concept.

[snip]
 
B

Bartc

Keith Thompson said:
Eric Sosman said:
Eric said:
Bartc wrote:
Peter Nilsson wrote:

So 1 is _not_ the same value as 1u?
Only one of those, is greater than -1.

(1u < -1)

This is ridiculous and dangerous behaviour on the part of C;

(a<b) /* True */

++a; ++b;

(a<b) /* Now false! And without any wrap or overflow */
Perhaps I'm overlooking something obvious, [...]
Here's an example of what Bartc was talking about:

#include <stdio.h>
int main(void)
{
unsigned a = 1;
int b = -1;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
++a; ++b;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
return 0;
}

The output is:

1U < -1
2U > 0

And the reason is that when the "<" operator has signed and unsigned
operands of the same rank, the signed operand is converted to the
unsigned type before the operator is applied (see "Usual arithmetic
conversions", C99 6.3.1.8), so the value -1 is converted to UINT_MAX.

Note that gcc, for example, warns about the
comparisons in my sample program:
c.c:6: warning: comparison between signed and unsigned
c.c:8: warning: comparison between signed and unsigned

I did try (obviously not too hard) to get a warning from gcc; it needs
something more than -Wall I think.
The alternative would have been to convert the unsigned operand to the
signed type -- but such a conversion can yield an
implementation-defined result (or raise an implementation-defined
signal). Conversion from signed to unsigned is well defined.

Upthread, Bartc wrote:
| The correct handling would have been to have cast both into a type
| encompassing both values before comparing, or to give a warning.

(You mean convert, not cast.)

What's the difference? I thought conversions between any numeric types were
all casts.
 
B

Bartc

Eric Sosman said:
Bartc said:
[...]
I was merely talking about the (1u<-1) above:

#include <stdio.h>

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

if (a<b) printf("A<B\n"); else printf("A>=B\n");

++a;
++b;

if (a<b) printf("A<B\n"); else printf("A>=B\n");

}

The increment changes 1 to 2, and -1 to 0, nothing dramatic.

But you said (in snippage that occurred a few messages
ago) that the example was "without any wrap or overflow."
Surely there's a "wrap" in the conversion of -1 to UINT_MAX?

That was here:

"(a<b) /* True */
++a; ++b;
(a<b) /* Now false! And without any wrap or overflow */"

I meant with no wrap/overflow occuring in the increment operations, because
they are still working well within their limits at that point.
Yes, it can be dangerous, and some compilers warn about it.
But what would you have instead? Make the attempted comparison
a compile-time error?

I said that having A<B but (A+1)>=(B+1), without "+" exceeding any numeric
limits, was ridiculous. I think it still is. But not much can be done about
it now, except to be aware of it or to avoid the problem by not mixing
signed/unsigned.
 
K

Keith Thompson

Eric Sosman said:
Bartc said:
[...]
I was merely talking about the (1u<-1) above:
#include <stdio.h>
int main(void)
{
unsigned int a=1;
signed int b=-1;
if (a<b) printf("A<B\n"); else printf("A>=B\n");
++a;
++b;
if (a<b) printf("A<B\n"); else printf("A>=B\n");
}
The increment changes 1 to 2, and -1 to 0, nothing dramatic.

But you said (in snippage that occurred a few messages
ago) that the example was "without any wrap or overflow."
Surely there's a "wrap" in the conversion of -1 to UINT_MAX?
The problem seems to me that comparing unsigned to signed (by I
think treating both as unsigned) seems a little dangerous.

Yes, it can be dangerous, and some compilers warn about it.
But what would you have instead? Make the attempted comparison
a compile-time error? The tactic of "widen *both* operands"
isn't always available, as for example when comparing intmax_t
to uintmax_t (by definition, the widest integers in the West).

I can't speak for Bartc, but yes, in my opinion making such a
comparison a constraint violation would have avoided confusion. In
the rare cases where you want to compare an unsigned value to a signed
value, it's not clear how the comparison should be done, except on a
case-by-case basis. Given a requirement to define it *somehow*, I
have no problem with the decision made by the standard committee, but
forcing programmers to make the conversion explicit could have avoided
a great deal of confusion. (It probably would also have broken a
great deal of pre-ANSI code, but at least it wouldn't have done so
quietly.)
 
B

Ben Bacarisse

Keith Thompson said:
Ah, but the standard does define the term "value", in C99 3.17:

value
precise meaning of the contents of an object when interpreted as
having a specific type

Given this definition, it doesn't make much sense to say that objects
of different types can have the "same value".

(One flaw in this definition is that it doesn't define the value of an
expression.)

To my mind, this is a fatal flaw for this discussion. The question is
all about expressions and not the values of objects.
 
K

Keith Thompson

Eric Sosman said:
Keith Thompson wrote: [...]
Bartc was talking about comparisons between unsigned and signed
integers, not pointer arithmetic.
(Eric, I can't think of an example of the above problem involving
pointer arithmetic. Do you have one in mind?)
Here's an example of what Bartc was talking about:
#include <stdio.h>
int main(void)
{
unsigned a = 1;
int b = -1;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
++a; ++b;
printf("%uU %c %d\n", a, a < b ? '<' : '>', b);
return 0;
}

I'd have thought that "without any wrap" would have
ruled this one out, since the conversion of -1 to unsigned
involves what I'd call a "wrap."

For the pointer example, see my reply to vippstar in
this thread. (And I see Bartc's replied to that reply
confirming your understanding. I still don't understand
why he doesn't think there's a "wrap" in (unsigned)-1,
though.)

I think his point is that there's no wrap in incrementing a and b, and
yet these non-wrapping increments changed the "<" relationship between
them. It is a bit counterintuitive, even though there are good
underlying reasons for the behavior.
 
Y

Yevgen Muntyan

Ben said:
I am not sure exactly what you mean.

I mean the definition of the term "value of an object"
from the standard.
I don't think the term "same
value" is used clearly and unambiguously thought the standard. At
least, I don't think it is used in way that can be understood without
context.

Could you provide an example perhaps? Really, once
you don't think that a "value of an array" can mean
value of the pointer it's converted to (namely, of
the result of the corresponding expression, or
whatever it is in legalese), then you don't have
any problems with the term "value" and its use in
a phrase "same value". I guess the problem is that
the standard uses human language in this case ;)
Then all is good and
clear, answer is "no and the question doesn't make much sense".
Making up the meaning of "value of array" is silly otherwise.

The value of an array has a reasonable meaning in C. You can't so
much with them, but that is beside the point. I don't think I made up
a meaning for it.
(True, it's an interesting philosophical exercise, like whether
the element of one-element array is the array or not... And it
certainly is on-topic and so is "interesting and useful"!)

[snip long list of who (Ritchie included!) says what]

I thought my answer was helpful because, rather than taking a
definitive view on the meaning of the words, it explained why the
various phrases quoted are all consistent provided one does not assume
that slightly ambiguous terms can be pinned down one way or the other.
Most of the quotes went to some lengths to explain why the two values
in question were the same in some sense and different in others.
Plumping for one or the other if fine (I said as much) but not as
helpful as I was trying to be. Of course, I may have missed by a mile
and just confused the OP. Only time will tell.

Nah, I don't think the explanation hurt someone. It's
the question that is silly. Discussing array-related
stuff isn't bad for sure.

Yevgen
 
K

Keith Thompson

Bartc said:
What's the difference? I thought conversions between any numeric types were
all casts.

Nope.

A conversion is an operation that translates a value of one type to
another type.

A cast is an operator that explicitly specifies a conversion.

Some conversions are specified by cast operators; some are implicit.
There's no such thing as an "implicit cast".
 
K

Keith Thompson

Ben Bacarisse said:
To my mind, this is a fatal flaw for this discussion. The question is
all about expressions and not the values of objects.

It's a minor flaw in the definition of "value". (It's not the only
definition in the standard that provides an example of the term being
defined rather than an exhaustive definition). It's clear that
expressions do have values; see the standard's (also incomplete)
definition if "expression" in 6.5p1:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

I think it's sufficiently clear for purposes of this discussion that a
"value", whether it's contained in an object or results from
evaluating an expression, has a specific type. I don't think it's
possible to discuss this stuff consistently without making that
assumption.
 
Y

Yevgen Muntyan

Richard said:
Peter Nilsson said:
Richard Heathfield said:
candide said:
I try to find out what exactly means "an array and
its address are the same"
They aren't. An array is an array. An address is a
pointer value. These are not the same thing. If you
mean that &array and &array[0] are the same,
they aren't. They have different types.

or "have the same value".
If you try to take the value of an array, what you
actually get is the value of a pointer to the first
member of the array. That doesn't mean that an array
is the same as a pointer. If you mean that &array
and &array[0] have the same value, they don't. They
have different types.
What about (void *) &array == (void *) &array[0]?

The expressions (void *) &array and (void *) &array[0] have the same type -
i.e. void *. Therefore, they /can/ have the same value (and may well
have).
So 1 is _not_ the same value as 1u?

Correct - it isn't. 1 has type int, whereas 1u has type unsigned int. They
may well (and in fact do) share a great many characteristics, but they are
*not* the same. I'd have explained why, if pete had not already done so.
Can you then tell me what the standard means when
it says...

"The range of nonnegative values of a signed
integer type is a subrange of the corresponding
unsigned integer type, and the representation
of the same value in each type is the same."
^^^^^^^^^^

It means that the Standard isn't as picky about its use of the word "value"
as it should be. :)

It is picky all right. 1 and 1u have the same value,
the real number 1. 6.3.1 quite agrees with it, and
there is no reason to think otherwise. Quoted text
says so, by the way.
In my opinion (since you ask!), the quoted line makes no sense. I'd have
been happier if it had said something like "the same numerical value" or
some such weasel phrase.

It doesn't have to because the value here *is*
the numerical value. For floating point numbers
you add special arithmetical entities from whatever
arithmetic model you use - NAN and INF for IEE????
for instance. Complex types add complex numbers.
Etc.
Two values can have the same numerical value
despite being intrinsically different.

They are not. For example, arithmetic operations
are not defined on representations, they are defined
on values. 1 + 1 is two and 1u + 1u is two; -1 * 1u
is some shit not because values are wrong or bad,
but because you do not multiply values in this case:
first you do the conversion, *then* you get two unsigned
values, then you multiply them, then you get some
shit.
Consider, for example, the
differences and similarities between -40degF (or, if you prefer, the very
different value -40degC) and -$40. If C had a Fahrenheit (or Celsius) type
and a dollar type, an assignment of one to the other (presumably with a
cast!) might well result in the numerical value -40 being preserved, and
they might even be represented in the same way internally. That doesn't
mean that degrees are dollars or that dollars are degrees.

Nice example, except it's irrelevant. C doesn't have
any types measuring something, all numerical types are
just numbers. It could, and in that case, it would...

Yevgen
 

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,776
Messages
2,569,603
Members
45,186
Latest member
vinaykumar_nevatia

Latest Threads

Top