Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #14097 > unrolled thread
| Started by | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| First post | 2011-11-30 21:53 +0000 |
| Last post | 2011-12-03 11:39 -0500 |
| Articles | 20 on this page of 41 — 8 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| Date | 2011-11-30 21:53 +0000 |
| Subject | Type 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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-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]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-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