Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #14097 > unrolled thread

Type interchange

Started byEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
First post2011-11-30 21:53 +0000
Last post2011-12-03 11:39 -0500
Articles 20 on this page of 41 — 8 participants

Back to article view | Back to comp.lang.c


Contents

  Type interchange Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-11-30 21:53 +0000
    Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-11-30 17:29 -0500
      Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-11-30 15:22 -0800
        Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-11-30 19:10 -0500
          Re: Type interchange Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-01 03:09 +0000
            Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 07:13 -0500
              Re: Type interchange Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-01 15:55 +0000
                Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 11:28 -0500
                  Re: Type interchange Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-12-01 16:45 +0000
                    Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 12:00 -0500
                  Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 14:31 -0800
                    Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 20:18 -0500
                      Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 17:35 -0800
                        Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-02 12:03 -0500
                          Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-02 13:49 -0800
                            Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-02 22:12 -0500
                              Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-03 02:01 -0800
                    Re: Type interchange Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 12:47 -0800
              Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-01 11:10 -0500
                Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 11:34 -0500
                Re: Type interchange Kaz Kylheku <kaz@kylheku.com> - 2011-12-01 17:48 +0000
                Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 14:17 -0800
                  Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-01 17:43 -0500
                    Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 15:00 -0800
                      Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-01 19:29 -0500
                        Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 16:59 -0800
                          Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-02 08:35 -0500
                            Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-02 08:46 -0500
                              Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-02 13:32 -0800
                            Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-02 13:30 -0800
                              Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-02 18:45 -0500
          Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-11-30 19:17 -0800
            Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 06:50 -0500
              Re: Type interchange Keith Thompson <kst-u@mib.org> - 2011-12-01 07:15 -0800
                Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 10:36 -0500
                  Re: Type interchange pete <pfiland@mindspring.com> - 2011-12-01 11:04 -0500
                    Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-01 11:37 -0500
                  Re: Type interchange Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 13:02 -0800
              Re: Type interchange Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 13:01 -0800
      Re: Type interchange Quentin Pope <qp19433@hotmail.NOSPAM.com> - 2011-12-02 22:15 +0000
        Re: Type interchange James Kuyper <jameskuyper@verizon.net> - 2011-12-03 11:39 -0500

Page 1 of 3  [1] 2 3  Next page →


#14097 — Type interchange

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2011-11-30 21:53 +0000
SubjectType interchange
Message-ID<jb68ju$icb$1@speranza.aioe.org>
Hello:

Can the following program generate an undefined behavior?

Thank you.

#include<limits.h>
int main()
{
#if INT_MAX == LONG_MAX
  long getchar();
#else
  int getchar();
#endif
  (void) getchar();
  return 0;
}

[toc] | [next] | [standalone]


#14103

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-11-30 17:29 -0500
Message-ID<4ED6AE65.8050901@verizon.net>
In reply to#14097
On 11/30/2011 04:53 PM, Edward Rutherford wrote:
> Hello:
> 
> Can the following program generate an undefined behavior?
> 
> Thank you.
> 
> #include<limits.h>
> int main()
> {
> #if INT_MAX == LONG_MAX
>   long getchar();
> #else
>   int getchar();
> #endif
>   (void) getchar();
>   return 0;
> }

Programs do not generate undefined behavior. "undefined behavior" does
not mean a particular kind of behavior. It means that the behavior is
NOT defined - it can be anything. Code with undefined behavior is
perfectly capable of behaving in precisely the fashion you incorrectly
thought it was required to behave.

Section 7.1.4 says "Provided that a library function can be declared
without reference to any type defined in a header, it is also
permissible to declare the function and use it without including its
associated header.", so the declaration using 'int' is permissible.
However, 6.5.2.2p9 says " If the function is defined with a type that is
not compatible with the type (of the expression) pointed to by the
expression that denotes the called function, the behavior is
undefined."

A function declaration that is not a function prototype, and is used in
a function call expression with no arguments, can be compatible with a
function defined as taking no parameters - but only if the return types
are compatible. Nothing in the standard allows you to assume that 'long'
and 'int' are compatible types, not even if INT_MAX == LONG_MAX. 'int'
could be a one's complement type, while 'long' is a 2's complement type.
'int' could be little-endian, while 'long' could be big-endian. When
used as function arguments, 'int' and 'long' values could be passed in
different registers.

None of those possibilities is very likely. In all probability, your
code will work fine, particularly since it discards the return value,
unused. However, the fact that it will probably work is NOT guaranteed
by the standard, the correct wording to describe that absence of a
guarantee is "the behavior of your program is undefined".

[toc] | [prev] | [next] | [standalone]


#14110

FromKeith Thompson <kst-u@mib.org>
Date2011-11-30 15:22 -0800
Message-ID<lnbortqjpg.fsf@nuthaus.mib.org>
In reply to#14103
James Kuyper <jameskuyper@verizon.net> writes:
[...]
> A function declaration that is not a function prototype, and is used in
> a function call expression with no arguments, can be compatible with a
> function defined as taking no parameters - but only if the return types
> are compatible. Nothing in the standard allows you to assume that 'long'
> and 'int' are compatible types, not even if INT_MAX == LONG_MAX. 'int'
> could be a one's complement type, while 'long' is a 2's complement type.
> 'int' could be little-endian, while 'long' could be big-endian. When
> used as function arguments, 'int' and 'long' values could be passed in
> different registers.
[...]

The standard defines the term "compatible type".  It's clear from
the standard that int and long are *not* compatible types.

I think what you mean is that you can't assume that int and
long have the same representation, alignment requirements, and
so forth.  But even if they do, the behavior of a program that
declares getchar() as a function returning long is undefined.
Representation is relevant to how the program is likely to behave
in practice, but it's not relevant to the question of whether the
standard define's the code's behavior.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#14115

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-11-30 19:10 -0500
Message-ID<4ED6C5F0.1080608@verizon.net>
In reply to#14110
On 11/30/2011 06:22 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> [...]
>> A function declaration that is not a function prototype, and is used in
>> a function call expression with no arguments, can be compatible with a
>> function defined as taking no parameters - but only if the return types
>> are compatible. Nothing in the standard allows you to assume that 'long'
>> and 'int' are compatible types, not even if INT_MAX == LONG_MAX. 'int'
>> could be a one's complement type, while 'long' is a 2's complement type.
>> 'int' could be little-endian, while 'long' could be big-endian. When
>> used as function arguments, 'int' and 'long' values could be passed in
>> different registers.
> [...]
> 
> The standard defines the term "compatible type".  It's clear from
> the standard that int and long are *not* compatible types.

The standard says that two types are compatible if they're the same. The
standard has several locations where it specifies that particular pairs
of types that are not the same are still compatible. There are rules for
derived types such as arrays, functions, structures, and unions, which
allow them to be compatible only if the derivations are sufficiently
similar. However, I couldn't find any place in the normative text where
it specifies that any particular pair of basic types must be
incompatible. Footnote 35 says that char, signed char, and unsigned char
are incompatible types, but I can't find supporting normative text.

I think that a particular pair of types are in fact compatible for a
given implementation, if everything that the standard says must work
when two types are compatible, does in fact work for that pair of types,
when using that implementation, even if the standard fails to guarantee
that those types are compatible.

Could you cite any specific requirement that would be violated by an
implementation that treated 'int' and 'long' as compatible types?

[toc] | [prev] | [next] | [standalone]


#14125

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-12-01 03:09 +0000
Message-ID<0.041cc3761d33f47105cd.20111201030905GMT.87d3c9ouni.fsf@bsb.me.uk>
In reply to#14115
James Kuyper <jameskuyper@verizon.net> writes:

> On 11/30/2011 06:22 PM, Keith Thompson wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>> [...]
>>> A function declaration that is not a function prototype, and is used in
>>> a function call expression with no arguments, can be compatible with a
>>> function defined as taking no parameters - but only if the return types
>>> are compatible. Nothing in the standard allows you to assume that 'long'
>>> and 'int' are compatible types, not even if INT_MAX == LONG_MAX. 'int'
>>> could be a one's complement type, while 'long' is a 2's complement type.
>>> 'int' could be little-endian, while 'long' could be big-endian. When
>>> used as function arguments, 'int' and 'long' values could be passed in
>>> different registers.
>> [...]
>> 
>> The standard defines the term "compatible type".  It's clear from
>> the standard that int and long are *not* compatible types.
>
> The standard says that two types are compatible if they're the same. The
> standard has several locations where it specifies that particular pairs
> of types that are not the same are still compatible. There are rules for
> derived types such as arrays, functions, structures, and unions, which
> allow them to be compatible only if the derivations are sufficiently
> similar. However, I couldn't find any place in the normative text where
> it specifies that any particular pair of basic types must be
> incompatible. Footnote 35 says that char, signed char, and unsigned char
> are incompatible types, but I can't find supporting normative text.
>
> I think that a particular pair of types are in fact compatible for a
> given implementation, if everything that the standard says must work
> when two types are compatible, does in fact work for that pair of types,
> when using that implementation, even if the standard fails to guarantee
> that those types are compatible.
>
> Could you cite any specific requirement that would be violated by an
> implementation that treated 'int' and 'long' as compatible types?

I think that is technically impossible since the only things that can
result from incompatibility are diagnostics and undefined behaviour.  If
an implementation always reported "hey, I treat int and long as
compatible" it would cover the first, and the second needs no special
treatment.

From a quality of implementation point of view, I'd want a diagnostic
here:

  long l = 0;
  int *ip;
  ip = &l;

and I'd want it to say that the assignment was the problem due to the
incompatibility of the pointed-to types (long and int).  But, as we
know, any diagnostic at all (such as the daft one above) will do.

Types are compatible or not as defined by the standard, and I think it
muddies the water to talk about types being "compatible for a given
implementation".

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#14152

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-01 07:13 -0500
Message-ID<jb7r0i$9ku$3@dont-email.me>
In reply to#14125
On 11/30/2011 10:09 PM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> I think that a particular pair of types are in fact compatible for a
>> given implementation, if everything that the standard says must work
>> when two types are compatible, does in fact work for that pair of types,
>> when using that implementation, even if the standard fails to guarantee
>> that those types are compatible.
>>
>> Could you cite any specific requirement that would be violated by an
>> implementation that treated 'int' and 'long' as compatible types?
> 
> I think that is technically impossible since the only things that can
> result from incompatibility are diagnostics and undefined behaviour.  If
> an implementation always reported "hey, I treat int and long as
> compatible" it would cover the first, and the second needs no special
> treatment.
> 
> From a quality of implementation point of view, I'd want a diagnostic
> here:
> 
>   long l = 0;
>   int *ip;
>   ip = &l;
> 
> and I'd want it to say that the assignment was the problem due to the
> incompatibility of the pointed-to types (long and int).  But, as we
> know, any diagnostic at all (such as the daft one above) will do.
> 
> Types are compatible or not as defined by the standard,

Yes, and the standard leaves the compatibility of types A and B
unspecified for a very large number of possible pairs of A and B,
including A='int' and B='long'.

> ... and I think it
> muddies the water to talk about types being "compatible for a given
> implementation".

It's no muddier than the fact that a given piece of code may have
undefined behavior on one implementation, and not on another, simply
because the condition that determines whether or not the behavior is
undefined depends upon something that's implementation defined:

	unsigned char array[sizeof(long double)];
	array[1] = 1;

Whether or not that code has undefined behavior depends upon whether or
not sizeof(long double) > 1, something that is implementation-defined.

Some people prefer to describe this by saying that if there's any
possible conforming implementation where the behavior is undefined, then
the behavior is undefined, period, even on other implementations where
the condition that makes it undefined isn't true - but I find that
interpretation incoherent.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#14167

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-12-01 15:55 +0000
Message-ID<0.62ba56f0dbe6531a64e1.20111201155527GMT.871usop9qo.fsf@bsb.me.uk>
In reply to#14152
James Kuyper <jameskuyper@verizon.net> writes:

> On 11/30/2011 10:09 PM, Ben Bacarisse wrote:
<snip>
>> Types are compatible or not as defined by the standard,
>
> Yes, and the standard leaves the compatibility of types A and B
> unspecified for a very large number of possible pairs of A and B,
> including A='int' and B='long'.

I don't think it does.  For your interpretation to be correct the
standard must fail to say if int and long are the same type.  The rule
is simple:

  "Two types have compatible type if their types are the
  same. Additional rules for determining whether two types are
  compatible..."

None of the additional rules apply, so all that matters is if we can
determine whether int and long are or are not the same type.  I think it
is clear that they can't ever be the same type.  For example, the
conversion rank of long is greater than that of int (always).  How could
two types be "the same type" if they differ in such a way?  Furthermore,
we read (in 6.2.5 p4) that

  There are five standard signed integer types, designated as signed
  char, short int, int, long int, and long long int.[1]

This is not the natural wording to describe these types if two (or more)
of them may be the same type.  Your supposed conforming implementation
would only have four standard signed integer types.

<snip>

[1] 6.7.2 p5 tell us that "long int" and "long" designate the same
type.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#14171

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-01 11:28 -0500
Message-ID<4ED7AB31.1010500@verizon.net>
In reply to#14167
On 12/01/2011 10:55 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 11/30/2011 10:09 PM, Ben Bacarisse wrote:
> <snip>
>>> Types are compatible or not as defined by the standard,
>>
>> Yes, and the standard leaves the compatibility of types A and B
>> unspecified for a very large number of possible pairs of A and B,
>> including A='int' and B='long'.
> 
> I don't think it does.  For your interpretation to be correct the
> standard must fail to say if int and long are the same type.  The rule
> is simple:
> 
>   "Two types have compatible type if their types are the
>   same. Additional rules for determining whether two types are
>   compatible..."

I never claimed that 'int' and 'long' could be compatible by reason of
being the same type. When I said that they could be compatible for a
particular implementation, I meant that this possibility exists despite
their being different types.

Some of the other rules referred to by 6.2.7p1 are worded in such a way
that any pair of types that they apply to which aren't identified as
compatible by that rule, must be incompatible. For instance, 6.7.3p9
says "For two qualified types to be compatible, both shall ..."; which
implies quite clearly that any pair of qualified types that don't match
the description following the "shall" are not compatible. However,
neither 'int' nor 'long' is a qualified type, so that doesn't apply.
Neither do any of the other rules referenced by 6.2.7p1.

6.2.7p1 itself contains no such wording. It could have been written as:
For two types to be compatible, they must either be the same type, or
covered by one of the additional rules in ...". It wasn't written that way.

[toc] | [prev] | [next] | [standalone]


#14174

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-12-01 16:45 +0000
Message-ID<0.0a07a1fef97d0950852c.20111201164546GMT.87mxbcnsud.fsf@bsb.me.uk>
In reply to#14171
James Kuyper <jameskuyper@verizon.net> writes:

> On 12/01/2011 10:55 AM, Ben Bacarisse wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>> 
>>> On 11/30/2011 10:09 PM, Ben Bacarisse wrote:
>> <snip>
>>>> Types are compatible or not as defined by the standard,
>>>
>>> Yes, and the standard leaves the compatibility of types A and B
>>> unspecified for a very large number of possible pairs of A and B,
>>> including A='int' and B='long'.
>> 
>> I don't think it does.  For your interpretation to be correct the
>> standard must fail to say if int and long are the same type.  The rule
>> is simple:
>> 
>>   "Two types have compatible type if their types are the
>>   same. Additional rules for determining whether two types are
>>   compatible..."
>
> I never claimed that 'int' and 'long' could be compatible by reason of
> being the same type. When I said that they could be compatible for a
> particular implementation, I meant that this possibility exists despite
> their being different types.
>
> Some of the other rules referred to by 6.2.7p1 are worded in such a way
> that any pair of types that they apply to which aren't identified as
> compatible by that rule, must be incompatible. For instance, 6.7.3p9
> says "For two qualified types to be compatible, both shall ..."; which
> implies quite clearly that any pair of qualified types that don't match
> the description following the "shall" are not compatible. However,
> neither 'int' nor 'long' is a qualified type, so that doesn't apply.
> Neither do any of the other rules referenced by 6.2.7p1.
>
> 6.2.7p1 itself contains no such wording. It could have been written as:
> For two types to be compatible, they must either be the same type, or
> covered by one of the additional rules in ...". It wasn't written that
> way.

Leaving open the possibility that a conforming implementation might have
"const char" and "double" as compatible types, or maybe having
"void (int)" (a function type) be compatible with _Bool *?

Your point would have been clearer had you chosen one of these more
dramatic examples.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#14175

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-01 12:00 -0500
Message-ID<4ED7B2A4.4090501@verizon.net>
In reply to#14174
On 12/01/2011 11:45 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> 6.2.7p1 itself contains no such wording. It could have been written as:
>> For two types to be compatible, they must either be the same type, or
>> covered by one of the additional rules in ...". It wasn't written that
>> way.
> 
> Leaving open the possibility that a conforming implementation might have
> "const char" and "double" as compatible types, or maybe having
> "void (int)" (a function type) be compatible with _Bool *?
> 
> Your point would have been clearer had you chosen one of these more
> dramatic examples.

The OP asked about 'int' and 'long'. Also, I wasn't sure whether or it
could be proven, on purely functional grounds, that radically different
types like those are incapable of being compatible. The standard says
that a variety of things should work if two types are compatible, and
I'm not sure that they all could be made to work if, for instance, one
is a function type and the other is _Bool. It's quite clear to me that
all of those things could be made to work for int and long, since those
two types could be identically implemented.

[toc] | [prev] | [next] | [standalone]


#14193

FromKeith Thompson <kst-u@mib.org>
Date2011-12-01 14:31 -0800
Message-ID<ln62hzq5zh.fsf@nuthaus.mib.org>
In reply to#14171
James Kuyper <jameskuyper@verizon.net> writes:
> On 12/01/2011 10:55 AM, Ben Bacarisse wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>> 
>>> On 11/30/2011 10:09 PM, Ben Bacarisse wrote:
>> <snip>
>>>> Types are compatible or not as defined by the standard,
>>>
>>> Yes, and the standard leaves the compatibility of types A and B
>>> unspecified for a very large number of possible pairs of A and B,
>>> including A='int' and B='long'.
>> 
>> I don't think it does.  For your interpretation to be correct the
>> standard must fail to say if int and long are the same type.  The rule
>> is simple:
>> 
>>   "Two types have compatible type if their types are the
>>   same. Additional rules for determining whether two types are
>>   compatible..."
>
> I never claimed that 'int' and 'long' could be compatible by reason of
> being the same type. When I said that they could be compatible for a
> particular implementation, I meant that this possibility exists despite
> their being different types.
>
> Some of the other rules referred to by 6.2.7p1 are worded in such a way
> that any pair of types that they apply to which aren't identified as
> compatible by that rule, must be incompatible. For instance, 6.7.3p9
> says "For two qualified types to be compatible, both shall ..."; which
> implies quite clearly that any pair of qualified types that don't match
> the description following the "shall" are not compatible. However,
> neither 'int' nor 'long' is a qualified type, so that doesn't apply.
> Neither do any of the other rules referenced by 6.2.7p1.
>
> 6.2.7p1 itself contains no such wording. It could have been written as:
> For two types to be compatible, they must either be the same type, or
> covered by one of the additional rules in ...". It wasn't written that way.

We know the standard is not 100% internally consistent.

I think that 6.2.7p1 should have been written as you suggest.
I think that your suggested wording is consistent with the intent.

The consequences of another interpretation are, IMHO, quite painful:

For an implementation where int and long have the same
representation, they *may or may not* be compatible, depending on
the implementation.  There is no requirement for this choice to
be documented.  Which means that this:

    int *ip = 0;
    long *lp = ip;

either does or does not violate a constraint, depending on an
undocumented characteristic of the implementation.

Furthermore, under your interpretation, I see nothing saying that
int and long must have the same representation to be compatible.
An implementation could have 32-bit int and 64-bit long, but if
it decides that int and long are compatible types, then the above
declarations may be accepted without so much as a warning.

My position: The definition of "compatible type" is intended to
be exhaustive, even though the standard doesn't say so explicitly.
int and long are incompatible for every implementation (and therefore
int* and long* are incompatible for every implementation).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#14207

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-01 20:18 -0500
Message-ID<jb991v$vfv$1@dont-email.me>
In reply to#14193
On 12/01/2011 05:31 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> 6.2.7p1 itself contains no such wording. It could have been written as:
>> For two types to be compatible, they must either be the same type, or
>> covered by one of the additional rules in ...". It wasn't written that way.
...
> Furthermore, under your interpretation, I see nothing saying that
> int and long must have the same representation to be compatible.
> An implementation could have 32-bit int and 64-bit long, but if
> it decides that int and long are compatible types, then the above
> declarations may be accepted without so much as a warning.

Keep in mind that if an implementation treats a 32-bit int and a 64-bit
long as being compatible, it can't hide behind the clauses that give
undefined behavior to code which treats them as compatible. I personally
don't see how they could conform to those requirements, but if they did
somehow manage to do so, I don't see any need for a warning except for
purposes of writing portable code - and as a matter of QoI, I would
consider providing such warnings to be essential.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#14208

FromKeith Thompson <kst-u@mib.org>
Date2011-12-01 17:35 -0800
Message-ID<lnobvroive.fsf@nuthaus.mib.org>
In reply to#14207
James Kuyper <jameskuyper@verizon.net> writes:
> On 12/01/2011 05:31 PM, Keith Thompson wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
> ...
>>> 6.2.7p1 itself contains no such wording. It could have been written as:
>>> For two types to be compatible, they must either be the same type, or
>>> covered by one of the additional rules in ...". It wasn't written that way.
> ...
>> Furthermore, under your interpretation, I see nothing saying that
>> int and long must have the same representation to be compatible.
>> An implementation could have 32-bit int and 64-bit long, but if
>> it decides that int and long are compatible types, then the above
>> declarations may be accepted without so much as a warning.
>
> Keep in mind that if an implementation treats a 32-bit int and a 64-bit
> long as being compatible, it can't hide behind the clauses that give
> undefined behavior to code which treats them as compatible. I personally
> don't see how they could conform to those requirements, but if they did
> somehow manage to do so, I don't see any need for a warning except for
> purposes of writing portable code - and as a matter of QoI, I would
> consider providing such warnings to be essential.

One question.

Under what circumstances, if any, may a conforming implementation *not*
issue a diagnostic for the following program?

int main(void) {
    int *ip = 0;
    long *lp = ip;
    return 0;
}

(My answer is that a diagnostic is always required.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#14233

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-02 12:03 -0500
Message-ID<4ED904D9.2070301@verizon.net>
In reply to#14208
On 12/01/2011 08:35 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> Keep in mind that if an implementation treats a 32-bit int and a 64-bit
>> long as being compatible, it can't hide behind the clauses that give
>> undefined behavior to code which treats them as compatible. I personally
>> don't see how they could conform to those requirements, but if they did
>> somehow manage to do so, I don't see any need for a warning except for
>> purposes of writing portable code - and as a matter of QoI, I would
>> consider providing such warnings to be essential.
> 
> One question.
> 
> Under what circumstances, if any, may a conforming implementation *not*
> issue a diagnostic for the following program?
> 
> int main(void) {
>     int *ip = 0;
>     long *lp = ip;
>     return 0;
> }

With the standard as currently written, I don't believe that 'int' and
'long' are required to be incompatible, thought they do have to be
different types. If that's correct, then as you suggest, it implies that
an implementation where they are compatible is not required to issue a
diagnostic for such code. As a matter of QoI, such an implementation
would be sufficiently bizarre that it should provide a warning anyway,
but I don't think it would be fail to conform for that reason.

However, they must actually be compatible: if you write any valid long
value using *lp, and read it back using *ip, you must read the same
value (and not cause any other problems as a side effect). How that
could possibly be true in the particular case you mentioned, with a
32-bit int and a 64-bit long, I have no idea - but if someone figured
out how to make it work, it would be a conforming implementation of C.

[toc] | [prev] | [next] | [standalone]


#14242

FromKeith Thompson <kst-u@mib.org>
Date2011-12-02 13:49 -0800
Message-ID<ln7h2eod9d.fsf@nuthaus.mib.org>
In reply to#14233
James Kuyper <jameskuyper@verizon.net> writes:
> On 12/01/2011 08:35 PM, Keith Thompson wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
> ...
>>> Keep in mind that if an implementation treats a 32-bit int and a 64-bit
>>> long as being compatible, it can't hide behind the clauses that give
>>> undefined behavior to code which treats them as compatible. I personally
>>> don't see how they could conform to those requirements, but if they did
>>> somehow manage to do so, I don't see any need for a warning except for
>>> purposes of writing portable code - and as a matter of QoI, I would
>>> consider providing such warnings to be essential.
>> 
>> One question.
>> 
>> Under what circumstances, if any, may a conforming implementation *not*
>> issue a diagnostic for the following program?
>> 
>> int main(void) {
>>     int *ip = 0;
>>     long *lp = ip;
>>     return 0;
>> }
>
> With the standard as currently written, I don't believe that 'int' and
> 'long' are required to be incompatible, thought they do have to be
> different types. If that's correct, then as you suggest, it implies that
> an implementation where they are compatible is not required to issue a
> diagnostic for such code. As a matter of QoI, such an implementation
> would be sufficiently bizarre that it should provide a warning anyway,
> but I don't think it would be fail to conform for that reason.
>
> However, they must actually be compatible: if you write any valid long
> value using *lp, and read it back using *ip, you must read the same
> value (and not cause any other problems as a side effect). How that
> could possibly be true in the particular case you mentioned, with a
> 32-bit int and a 64-bit long, I have no idea - but if someone figured
> out how to make it work, it would be a conforming implementation of C.

Do you believe that the committee *deliberately* left the
compatibility or incompatibility of int and long unspecified,
*and* failed to require implementations to document their choice?
Do you think they meant to allow implementations to make int and
long compatible even if they're of different sizes?  If so, do you
think it made sense to do so?

I don't.  I think they intended int and long to be incompatible in
all cases, but neglected to state explicitly that the definition
of "compatible types" is exhaustive.  And I think that the only
*sensible* interpretation of what the standard says (even if it
fails to state it explicitly) is that two types are compatible if
and only if the standard says they are.

Similarly, I assume that 42 is an expression (even though the
definition of "expression" in 6.5p1 implies that it isn't),
that it's not an lvalue (even though the definition of "lvalue"
in 6.3.2.1p1 implies that it is), and that it has a value (even
though the definition of "value" in 3.17 implies that it doesn't).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#14258

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-02 22:12 -0500
Message-ID<jbc43j$941$1@dont-email.me>
In reply to#14242
On 12/02/2011 04:49 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> With the standard as currently written, I don't believe that 'int' and
>> 'long' are required to be incompatible, thought they do have to be
>> different types. If that's correct, then as you suggest, it implies that
>> an implementation where they are compatible is not required to issue a
>> diagnostic for such code. As a matter of QoI, such an implementation
>> would be sufficiently bizarre that it should provide a warning anyway,
>> but I don't think it would be fail to conform for that reason.
>>
>> However, they must actually be compatible: if you write any valid long
>> value using *lp, and read it back using *ip, you must read the same
>> value (and not cause any other problems as a side effect). How that
>> could possibly be true in the particular case you mentioned, with a
>> 32-bit int and a 64-bit long, I have no idea - but if someone figured
>> out how to make it work, it would be a conforming implementation of C.
> 
> Do you believe that the committee *deliberately* left the
> compatibility or incompatibility of int and long unspecified,
> *and* failed to require implementations to document their choice?

I don't know - their intent has often significantly differed from the
words they wrote, but I think it's a definite possibility that they
intended to leave it unspecified.  For convenience, I'd like to
distinguish this concept of compatibility from my own concept. I'll call
this concept ISO compatibility, or I-compatibility for short. If two
types are specified by the standard to be compatible, then they are
I-compatible, otherwise they are I-incompatible.

> Do you think they meant to allow implementations to make int and
> long compatible even if they're of different sizes?  If so, do you
> think it made sense to do so?

You keep bringing up compatibility of int and long of different sizes. I
can't imagine any way to implement them so they're compatible, so the
issue shouldn't come up. However, it's been proven time and again that
my imagination is inadequate, so I try to cover all possibilities. If,
by some magic, they actually figure out how to make a 32-bit int
compatible with a 64-bit long, then I don't see anything wrong with
handling them as compatible types as far as the standard is concerned.

The case I'm much more concerned about is an int and a long that are
both handled identically by a given implementation. For example, they
could both be 32-bit big-endian types with no padding bits and no trap
representations. If you think that such an implementation is still
required to diagnose them as incompatible, assume that it does so - but
after issuing the diagnostic, it then generates an executable that
behaves exactly the way it would have if 'int' and 'long' were merely
two synonyms for the same type.

Would it be reasonable to describe such an implementation by saying that
'int' and 'long' were incompatible?

That's basically what "compatible" means to me - for the sake of
discussion, I'll call my concept Kuyper-compatibility, or
K-compatibility for short. If the actual behavior (not including the
generated diagnostics) for two different types is the same as it would
have been if they had been two synonyms for the same type, then they are
K-compatible types; otherwise, they are K-incompatible types.

After a long frustrating thread on some related topic a couple of years
ago, I reached the conclusion that when the standard says two types are
compatible, what it means is only that it guarantees that the two types
are K-compatible. When it leaves the question open, the two types might
be K-compatible, or they might be K-incompatible. On that basis, I
concluded that the standard meant "K-compatible" when it said "compatible".

What this means, therefore, is that I-compatible is essentially
equivalent to "guaranteed by the standard to be K-compatible", while
I-incompatible means "not guaranteed by the standard to be
K-compatible". I consider it plausible that the committee may have
intended "compatible" to mean I-compatible rather than K-compatible.
However, that has not been my understanding, and I'm not yet convinced
of it. Any authoritative statement on that matter from someone like
Larry Jones would convince me. I don't see any problems (other than
footnote 35) associated with the possibility that the committee meant
K-compatible when they used the term "compatible".
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#14260

FromKeith Thompson <kst-u@mib.org>
Date2011-12-03 02:01 -0800
Message-ID<lnzkfam0su.fsf@nuthaus.mib.org>
In reply to#14258
James Kuyper <jameskuyper@verizon.net> writes:
> On 12/02/2011 04:49 PM, Keith Thompson wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
> ...
>>> With the standard as currently written, I don't believe that 'int' and
>>> 'long' are required to be incompatible, thought they do have to be
>>> different types. If that's correct, then as you suggest, it implies that
>>> an implementation where they are compatible is not required to issue a
>>> diagnostic for such code. As a matter of QoI, such an implementation
>>> would be sufficiently bizarre that it should provide a warning anyway,
>>> but I don't think it would be fail to conform for that reason.
>>>
>>> However, they must actually be compatible: if you write any valid long
>>> value using *lp, and read it back using *ip, you must read the same
>>> value (and not cause any other problems as a side effect). How that
>>> could possibly be true in the particular case you mentioned, with a
>>> 32-bit int and a 64-bit long, I have no idea - but if someone figured
>>> out how to make it work, it would be a conforming implementation of C.
>> 
>> Do you believe that the committee *deliberately* left the
>> compatibility or incompatibility of int and long unspecified,
>> *and* failed to require implementations to document their choice?
>
> I don't know - their intent has often significantly differed from the
> words they wrote, but I think it's a definite possibility that they
> intended to leave it unspecified.

[big snip]

>        Any authoritative statement on that matter from someone like
> Larry Jones would convince me. I don't see any problems (other than
> footnote 35) associated with the possibility that the committee meant
> K-compatible when they used the term "compatible".

Hmm.  I'll post to comp.std.c and see if we can get a more or less
definitive answer.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#16226

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-01-25 12:47 -0800
Message-ID<kfnwr8f7blv.fsf@x-alumni2.alumni.caltech.edu>
In reply to#14193
Keith Thompson <kst-u@mib.org> writes:

> [snip]
>
> My position: The definition of "compatible type" is intended to
> be exhaustive, even though the standard doesn't say so explicitly.

In fact, I believe all definitions in the Standard are intended
to be exhaustive;  it's just that some do a better job at that
than others.

> int and long are incompatible for every implementation (and therefore
> int* and long* are incompatible for every implementation).

Of course.  The idea that int and long might be compatible
types is completely nonsensical.  And, more to the point,
not supported to any degree whatsoever by any text in the
Standard.  The burden of proof is on those who say they might
be compatible to find some supporting text that suggests
they might be.  No such evidence has been offered.

[toc] | [prev] | [next] | [standalone]


#14170

Frompete <pfiland@mindspring.com>
Date2011-12-01 11:10 -0500
Message-ID<4ED7A703.4658@mindspring.com>
In reply to#14152
James Kuyper wrote:
 
> Some people prefer to describe this by saying that if there's any
> possible conforming implementation
> where the behavior is undefined, then
> the behavior is undefined, period, even on other implementations where
> the condition that makes it undefined isn't true - but I find that
> interpretation incoherent.

That way, 
whether or not a program contains undefined behavior
is a property of the C program,
and not a property of the 
combination of the implementation and C program.

-- 
pete

[toc] | [prev] | [next] | [standalone]


#14172

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-12-01 11:34 -0500
Message-ID<jb8aa6$f8r$1@dont-email.me>
In reply to#14170
On 12/01/2011 11:10 AM, pete wrote:
> James Kuyper wrote:
>  
>> Some people prefer to describe this by saying that if there's any
>> possible conforming implementation
>> where the behavior is undefined, then
>> the behavior is undefined, period, even on other implementations where
>> the condition that makes it undefined isn't true - but I find that
>> interpretation incoherent.
> 
> That way, 
> whether or not a program contains undefined behavior
> is a property of the C program,
> and not a property of the 
> combination of the implementation and C program.

Yes, that's a nice feature to have, but it seems incompatible with the
descriptions given in the standard of the reasons why a given piece of
code has undefined behavior.

For example, any attempt to dereference a pointer one-past-the end of an
array has undefined behavior; but in the example I gave, on any
implementation where sizeof(long double) > 1, array[1] is NOT an attempt
to dereference a pointer one past the end of the array - so how could
such a program qualify has having undefined behavior when translated by
such an implementation?

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web