473,326 Members | 2,104 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

casting

Hi,

a question on castings.

My code example:

#include <stdio.h>

int main( void )
{
unsigned int a = 4294967295U;
signed int b = 4294967295U;
signed int c = (signed int) a;

printf( "a:%ud\n", a );
printf( "b:%ud\n", b );
printf( "c:%ud\n", c );

return 0;
}

The output is:
a:4294967295d
b:4294967295d
c:4294967295d

I don't understand why "b" and "c" are also a 32-bit values. Since I
defined "b" and "c" as signed int, there are ony 31 bits that can be used
to represent the number, thus the value range is [-2147483648, 2147483647].
When assigning "b" the value 4294967295U, I thought that an implicit cast
is performed that converts the value to a 31bit value + 1 bit for the sign.
In a similar way, "c = (signed int)a" is an explicit cast that should
convert the 32bit value of "a" into a 31bit value represented by "c".
However, printf indicates that casting is not performed. Why?

Regards,
Chris
Jun 9 '06 #1
23 1931
"Christian Christmann" <pl*****@yahoo.de> wrote in message
news:pa****************************@yahoo.de...
Hi,

a question on castings.

My code example:

#include <stdio.h>

int main( void )
{
unsigned int a = 4294967295U;
signed int b = 4294967295U;
signed int c = (signed int) a;

printf( "a:%ud\n", a );
printf( "b:%ud\n", b );
printf( "c:%ud\n", c );

return 0;
}

The output is:
a:4294967295d
b:4294967295d
c:4294967295d

I don't understand why "b" and "c" are also a 32-bit values. Since I
defined "b" and "c" as signed int, there are ony 31 bits that can be used
to represent the number, thus the value range is [-2147483648,
2147483647].
When assigning "b" the value 4294967295U, I thought that an implicit cast
is performed that converts the value to a 31bit value + 1 bit for the
sign.
In a similar way, "c = (signed int)a" is an explicit cast that should
convert the 32bit value of "a" into a 31bit value represented by "c".
However, printf indicates that casting is not performed. Why?


A cast just means to reinterpret the value as another type. I think in this
case it is not doing what you think it ought to do, but it is doing what it
is supposed to do.

You would probably find :
signed int d = -1;
unsigned int e = -1;
....
printf( "d:%ud\n", d );

printf( "e:%ud\n", e );

equally surprising.

Have a look at this:
http://en.wikipedia.org/wiki/Two's_complement
http://www.azillionmonkeys.com/qed/2scomp.html
http://www.hal-pc.org/~clyndes/compu...omplement.html

Jun 9 '06 #2
Christian Christmann said:
Hi,

a question on castings.

My code example:

#include <stdio.h>

int main( void )
{
unsigned int a = 4294967295U;
signed int b = 4294967295U;
signed int c = (signed int) a;

printf( "a:%ud\n", a );
printf( "b:%ud\n", b );
printf( "c:%ud\n", c );

return 0;
}

The output is:
a:4294967295d
b:4294967295d
c:4294967295d

I don't understand why "b" and "c" are also a 32-bit values.
C doesn't guarantee that they are.
Since I
defined "b" and "c" as signed int, there are ony 31 bits that can be used
to represent the number,
Again, C doesn't guarantee this.
thus the value range is [-2147483648, 2147483647].
Nor this.
When assigning "b" the value 4294967295U, I thought that an
implicit cast
No such thing. A cast is an explicit conversion.
is performed that converts the value to a 31bit value + 1
bit for the sign.
C doesn't guarantee this.
In a similar way, "c = (signed int)a" is an explicit
cast
And as I write this it is now 8:38 A.M. (GMT) in the morning of the
forenoon, courtesy of the Department of Redundancy Department.
that should convert the 32bit value of "a" into a 31bit value
represented by "c". However, printf indicates that casting is not
performed. Why?


printf indicates nothing of the kind. All it indicates is that you have not
yet got around to reading page 244 of K&R.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 9 '06 #3
"Dann Corbit" <dc*****@connx.com> writes:
[...]
A cast just means to reinterpret the value as another type.


No, a cast is an operator that performs a type conversion. In some
cases, the conversion might have the same effect as reinterpreting the
bits of the source expression as if they represented a value of the
target type, but that's not how it's defined. (Consider (int)3.14 or
(double)42, for example.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 9 '06 #4
Christian Christmann <pl*****@yahoo.de> writes:
a question on castings.

My code example:
Your code assumes that int and unsigned int are 32 bits (something not
guaranteed by the language).
#include <stdio.h>

int main( void )
{
unsigned int a = 4294967295U;
signed int b = 4294967295U;
The value 4294967295U is implicitly converted from unsigned int to
signed int. Since the value cannot be represented in the target type,
the conversion yields an implementation-defined result (or raises an
implementation-defined signal, but we can ignore that possibility).

On most implementations, the conversion will yield the value -1.
signed int c = (signed int) a;
This is the same as above, except that the conversion is explicit.
printf( "a:%ud\n", a );
printf( "b:%ud\n", b );
printf( "c:%ud\n", c );
Use "%d" for int, "%u" for unsigned int. In "%ud", the "%u" prints an
unsigned int, and the "d" prints a letter 'd'.
return 0;
}

The output is:
a:4294967295d
b:4294967295d
c:4294967295d

I don't understand why "b" and "c" are also a 32-bit values. Since I
defined "b" and "c" as signed int, there are ony 31 bits that can be used
to represent the number, thus the value range is [-2147483648, 2147483647].
You lied to the printf() function. The "%u" format expects an
unsigned int; you gave it a signed int. I think the standard happens
to guarantee that this will work for values that are within the range
of both signed int and unsigned int, but you're passing passing a
value of -1. I'm fairly sure this invokes undefined behavior (it's at
least implementation-specific).

Most likely the value -1 is represented in two's-complement as 32 1
bits, a sign bit followed by 31 value bits. printf() interprets this
as an unsigned value with the same representation, namely 4294967295
(0xffffffff). If you used the correct format "%d", for the signed
values, the output would be:

a:4294967295d
b:-1
c:-1
When assigning "b" the value 4294967295U, I thought that an implicit cast
is performed that converts the value to a 31bit value + 1 bit for the sign.
There is no such thing as an "implicit cast". A cast is an explicit
operator that performs a conversion. There are implicit conversions,
as I mentioned above. In this case, the implicit conversion happens
to convert the unsigned value 4294967295U to the signed value -1.
In a similar way, "c = (signed int)a" is an explicit cast that should
convert the 32bit value of "a" into a 31bit value represented by "c".
However, printf indicates that casting is not performed. Why?


If the printf were correct, it would show a value of -1. But again,
this particular result for the conversion is very common, but it's
implementation-specific.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 9 '06 #5
Christian Christmann wrote:

a question on castings.

My code example:

#include <stdio.h>

int main( void )
{
unsigned int a = 4294967295U;
signed int b = 4294967295U;
signed int c = (signed int) a;

printf( "a:%ud\n", a );
printf( "b:%ud\n", b );
printf( "c:%ud\n", c );

return 0;
}

The output is:
a:4294967295d
b:4294967295d
c:4294967295d

I don't understand why "b" and "c" are also a 32-bit values.

.... snip ...

Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.

--
"Our enemies are innovative and resourceful, and so are we.
They never stop thinking about new ways to harm our country
and our people, and neither do we." -- G. W. Bush.
"The people can always be brought to the bidding of the
leaders. All you have to do is tell them they are being
attacked and denounce the pacifists for lack of patriotism
and exposing the country to danger. It works the same way
in any country." --Hermann Goering.

Jun 9 '06 #6
CBFalconer <cb********@yahoo.com> writes:
[...]
Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.


On a conversion to a signed integer type, if the value cannot be
represented, "either the result is implementation-defined or an
implementation-defined signal is raised". There is no undefined
behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 9 '06 #7
Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
[...]
Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.


On a conversion to a signed integer type, if the value cannot be
represented, "either the result is implementation-defined or an
implementation-defined signal is raised". There is no undefined
behavior.


Doesn't the phrase "implementation defined behaviour" mean just
that? To me, that includes signalling or peculiar result values.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
Jun 10 '06 #8
On Fri, 09 Jun 2006 23:45:28 -0400, CBFalconer <cb********@yahoo.com>
wrote:
Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
[...]
Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.


On a conversion to a signed integer type, if the value cannot be
represented, "either the result is implementation-defined or an
implementation-defined signal is raised". There is no undefined
behavior.


Doesn't the phrase "implementation defined behaviour" mean just
that? To me, that includes signalling or peculiar result values.


So what you're saying is that the consequences of "implementation
defined behaviour" could be the same as the consequences of "undefined
behaviour"?

If that were the case, and I'm not saying that it is or isn't,
shouldn't we expect some hard-core pedantics to start telling us that
use of "implementation defined behaviou" could lead to formatting of
our hard drives?

Personally, I could see going with your way of thinking, and thusly I
proclaim these two universal truths about those who have programmed in
C:

The probability of you committing undefined bahavior is greater than
50%. Note that it's "greater than" and not "greater than or equal to.

The probability of you committing undefined bahavior that results in
formatting of your hard drive is less than 50%. Note that it's "less
than" and not "less than or equal to".

Regards
--
jay
Jun 10 '06 #9
jaysome said:

<snip>
So what you're saying is that the consequences of "implementation
defined behaviour" could be the same as the consequences of "undefined
behaviour"?

If that were the case, and I'm not saying that it is or isn't,
shouldn't we expect some hard-core pedantics to start telling us that
use of "implementation defined behaviou" could lead to formatting of
our hard drives?


It *can*. And in some cases it does.

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to format
your drive, such a feature can be extremely useful, n'est-ce-pas?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 10 '06 #10
On Sat, 10 Jun 2006 08:19:35 +0000, Richard Heathfield
<in*****@invalid.invalid> wrote:
jaysome said:

<snip>
So what you're saying is that the consequences of "implementation
defined behaviour" could be the same as the consequences of "undefined
behaviour"?

If that were the case, and I'm not saying that it is or isn't,
shouldn't we expect some hard-core pedantics to start telling us that
use of "implementation defined behaviou" could lead to formatting of
our hard drives?


It *can*. And in some cases it does.

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to format
your drive, such a feature can be extremely useful, n'est-ce-pas?


But it still leaves me uneasy about investing in
HowToEasilyFormatYourHardDrive.com. I've lost a lot of money on other
ventures, so maybe I'll take your advice on this one. Put me down for
$500.00.

--
jay
Jun 10 '06 #11
CBFalconer <cb********@yahoo.com> writes:
Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
[...]
Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.


On a conversion to a signed integer type, if the value cannot be
represented, "either the result is implementation-defined or an
implementation-defined signal is raised". There is no undefined
behavior.


Doesn't the phrase "implementation defined behaviour" mean just
that? To me, that includes signalling or peculiar result values.


Yes, it's implementation-defined behavior, *not* undefined behavior.
The implementation has to document what it does, but it must choose
from the options specified by the standard. Setting off bombs or
causing nasal demons are not allowed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 10 '06 #12
Richard Heathfield <in*****@invalid.invalid> writes:
jaysome said:

<snip>
So what you're saying is that the consequences of "implementation
defined behaviour" could be the same as the consequences of "undefined
behaviour"?

If that were the case, and I'm not saying that it is or isn't,
shouldn't we expect some hard-core pedantics to start telling us that
use of "implementation defined behaviou" could lead to formatting of
our hard drives?


It *can*. And in some cases it does.

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to format
your drive, such a feature can be extremely useful, n'est-ce-pas?


The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them. (Unspecified behavior is the
same, except that the implementation needn't document its choice.)

These terms are all defined in section 3 of the standard.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 10 '06 #13
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to
format your drive, such a feature can be extremely useful, n'est-ce-pas?


The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them. (Unspecified behavior is the
same, except that the implementation needn't document its choice.)


Well, yes, you're right - but because you're right, it is clear that the C99
Standard is broken (again). I'm thinking of alternative forms of main()
other than the two defined by the Standard. The Standard says that main()
may be defined "in some other implementation-defined manner" but, as far as
I can tell, no alternative possibilities are described. So the implementor
who wishes to provide an alternative main() interface has zero alternatives
from which to choose.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 10 '06 #14
Keith Thompson <ks***@mib.org> wrote:
CBFalconer <cb********@yahoo.com> writes:
[...]
Trying to stuff a value into a signed object that cannot hold that
value results in implementation defined behaviour. You could have
just set off that 3 tons of fertilizer they found in Canada. Only
stuffing into unsigned objects has a defined action.


On a conversion to a signed integer type, if the value cannot be
represented, "either the result is implementation-defined or an
implementation-defined signal is raised". There is no undefined
behavior.


However, in the cases where the I-D signal is raised, the Standard does
not completely define what the outcome of this signal is; indeed, in
those cases where the startup handler for this signal is SIG_IGN (which
returns as if nothing has happened), the behaviour is explicitly
undefined by 7.14.1.1#3.

Richard
Jun 12 '06 #15
Keith Thompson wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to format
your drive, such a feature can be extremely useful, n'est-ce-pas?


The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them.


What are the two or more possibilities for an out-of-range
assignment?

Jun 13 '06 #16
Old Wolf said:
Keith Thompson wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to
format your drive, such a feature can be extremely useful, n'est-ce-pas?


The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them.


What are the two or more possibilities for an out-of-range
assignment?


That doesn't smell like "implementation-defined" to me, but for the sake of
a quiet life and not having to look it up, I'll assume you're right (for
the purposes of this discussion at least). Given all that, and in the
absence of any other information to the contrary, I would argue that the
range of possibilities implied by the Standard would include (a) any of the
possible legal values, and (b) a rule for deducing the effect of the out of
range assignment. For example, if you have this: int x = INT_MAX + n (where
n is positive), then the implementation might say "it wraps around to
INT_MIN + n - 1", or something of that nature.

But an out-of-range assignment smells undefined from where I'm sitting.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 13 '06 #17
On Sat, 10 Jun 2006 14:42:05 +0000, Richard Heathfield
<in*****@invalid.invalid> wrote:
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to
format your drive, such a feature can be extremely useful, n'est-ce-pas?


The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them. (Unspecified behavior is the
same, except that the implementation needn't document its choice.)


Well, yes, you're right - but because you're right, it is clear that the C99
Standard is broken (again). I'm thinking of alternative forms of main()
other than the two defined by the Standard. The Standard says that main()
may be defined "in some other implementation-defined manner" but, as far as
I can tell, no alternative possibilities are described. So the implementor
who wishes to provide an alternative main() interface has zero alternatives
from which to choose.


Where in the Standard does it say that alternative possibilities of
implementation-defined behavior must be described?

The way I read it, an implementation is conforming as long as it
documents something such as this:

void main(void)
{
return;
}

--
jay
Jun 13 '06 #18
jaysome said:
On Sat, 10 Jun 2006 14:42:05 +0000, Richard Heathfield
<in*****@invalid.invalid> wrote:
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:

The difference is that, for implementation-defined behaviour, the
implementation is required to *document* this effect. If you want to
format your drive, such a feature can be extremely useful,
n'est-ce-pas?

The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them. (Unspecified behavior is the
same, except that the implementation needn't document its choice.)
Well, yes, you're right - but because you're right, it is clear that the
C99 Standard is broken (again). I'm thinking of alternative forms of
main() other than the two defined by the Standard. The Standard says that
main() may be defined "in some other implementation-defined manner" but,
as far as I can tell, no alternative possibilities are described. So the
implementor who wishes to provide an alternative main() interface has zero
alternatives from which to choose.


Where in the Standard does it say that alternative possibilities of
implementation-defined behavior must be described?


Like Keith, I was under the impression that the implementation does have to
choose from among possibilities provided by the Standard, but - remarkably
- I can find no evidence to support this impression at present. So either
Keith and I are both wrong about this, or I simply didn't look in the right
place just now. Either possibility is, of course, possible.

The way I read it, an implementation is conforming as long as it
documents something such as this:

void main(void)
{
return;
}


It's even conforming if it doesn't. No implementation is /required/ to
define the behaviour of void main programs.

But the code itself is not conforming, except when viewed as a
"MyFavouriteForgivingCompiler C" program rather than as a "C" program.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 13 '06 #19
Richard Heathfield <in*****@invalid.invalid> writes:
jaysome said:
On Sat, 10 Jun 2006 14:42:05 +0000, Richard Heathfield
<in*****@invalid.invalid> wrote:
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:
> The difference is that, for implementation-defined behaviour, the
> implementation is required to *document* this effect. If you want to
> format your drive, such a feature can be extremely useful,
> n'est-ce-pas?

The other difference is that, in the case of implementation-defined
behavior, the standard provides two or more possibilities and the
implementation has to pick one of them. (Unspecified behavior is the
same, except that the implementation needn't document its choice.)

Well, yes, you're right - but because you're right, it is clear that the
C99 Standard is broken (again). I'm thinking of alternative forms of
main() other than the two defined by the Standard. The Standard says that
main() may be defined "in some other implementation-defined manner" but,
as far as I can tell, no alternative possibilities are described. So the
implementor who wishes to provide an alternative main() interface has zero
alternatives from which to choose.


Where in the Standard does it say that alternative possibilities of
implementation-defined behavior must be described?


Like Keith, I was under the impression that the implementation does have to
choose from among possibilities provided by the Standard, but - remarkably
- I can find no evidence to support this impression at present. So either
Keith and I are both wrong about this, or I simply didn't look in the right
place just now. Either possibility is, of course, possible.


The definition changed between C90 and C99 (and again between C99 and
N1124).

C90 3.10:
implementation-defined behavior: Behavior. for a correct program
construct and correct data, that depends on the characteristics of
the implementation and that each implementation shall document.

C90 3.17:
unspecified behavior: Behavior, for a correct program construct
and correct data, for which this International Standard explicitly
imposes no requirements.

C99 3.4.1:
implementation-defined behavior

unspecified behavior where each implementation documents how the
choice is made

EXAMPLE An example of implementation-defined behavior is the
propagation of the high-order bit when a signed integer is
shifted right.

C99 3.4.4:
unspecified behavior

behavior where this International Standard provides two or more
possibilities and imposes no further requirements on which is
chosen in any instance

EXAMPLE An example of unspecified behavior is the order in which
the arguments to a function are evaluated.

(The definition of "unspecified behavior" was tweaked slightly in
N1124; the revised definition is "use of an unspecified value, or
other behavior where ...".)

C99 5.1.2.2.1 allows main() to be defined in either of the traditional
ways "or in some other implementation-defined manner". But this
doesn't use the term "implementation-defined behavior", which is
defined in section 3. The standard doesn't provide a definition of
"implementation-defined" other than in the context of
"implementation-defined behavior" or "implementation-defined value",
so I think we just have to read it as ordinary English text; "some
other implementation-defined manner" simply means "some other manner
which is defined (i.e., documented) by the implementation". For
implementation-defined *behavior*, the standard must provide two or
more possibilities; for implementation-defined anything-else, it
needn't do so.
The way I read it, an implementation is conforming as long as it
documents something such as this:

void main(void)
{
return;
}


It's even conforming if it doesn't. No implementation is /required/ to
define the behaviour of void main programs.

But the code itself is not conforming, except when viewed as a
"MyFavouriteForgivingCompiler C" program rather than as a "C" program.


Which is exactly what "conforming" means.

A *conforming program* is one that is acceptable to a conforming
implementation.

If I wrote a conforming implementation that allows
struct {char c; long double x;}main(void) {}
then that would become a conforming program. (The concept of a
"conforming program" isn't all that useful.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 13 '06 #20
On Tue, 13 Jun 2006 09:53:25 GMT, Keith Thompson <ks***@mib.org>
wrote:
Richard Heathfield <in*****@invalid.invalid> writes:
jaysome said:
On Sat, 10 Jun 2006 14:42:05 +0000, Richard Heathfield
<in*****@invalid.invalid> wrote:
Keith Thompson said:
> Richard Heathfield <in*****@invalid.invalid> writes:
>> The difference is that, for implementation-defined behaviour, the
>> implementation is required to *document* this effect. If you want to
>> format your drive, such a feature can be extremely useful,
>> n'est-ce-pas?
>
> The other difference is that, in the case of implementation-defined
> behavior, the standard provides two or more possibilities and the
> implementation has to pick one of them. (Unspecified behavior is the
> same, except that the implementation needn't document its choice.)

Well, yes, you're right - but because you're right, it is clear that the
C99 Standard is broken (again). I'm thinking of alternative forms of
main() other than the two defined by the Standard. The Standard says that
main() may be defined "in some other implementation-defined manner" but,
as far as I can tell, no alternative possibilities are described. So the
implementor who wishes to provide an alternative main() interface has zero
alternatives from which to choose.

Where in the Standard does it say that alternative possibilities of
implementation-defined behavior must be described?


Like Keith, I was under the impression that the implementation does have to
choose from among possibilities provided by the Standard, but - remarkably
- I can find no evidence to support this impression at present. So either
Keith and I are both wrong about this, or I simply didn't look in the right
place just now. Either possibility is, of course, possible.


The definition changed between C90 and C99 (and again between C99 and
N1124).

C90 3.10:
implementation-defined behavior: Behavior. for a correct program
construct and correct data, that depends on the characteristics of
the implementation and that each implementation shall document.

C90 3.17:
unspecified behavior: Behavior, for a correct program construct
and correct data, for which this International Standard explicitly
imposes no requirements.

C99 3.4.1:
implementation-defined behavior

unspecified behavior where each implementation documents how the
choice is made

EXAMPLE An example of implementation-defined behavior is the
propagation of the high-order bit when a signed integer is
shifted right.

C99 3.4.4:
unspecified behavior

behavior where this International Standard provides two or more
possibilities and imposes no further requirements on which is
chosen in any instance

EXAMPLE An example of unspecified behavior is the order in which
the arguments to a function are evaluated.

(The definition of "unspecified behavior" was tweaked slightly in
N1124; the revised definition is "use of an unspecified value, or
other behavior where ...".)

C99 5.1.2.2.1 allows main() to be defined in either of the traditional
ways "or in some other implementation-defined manner". But this
doesn't use the term "implementation-defined behavior", which is
defined in section 3. The standard doesn't provide a definition of
"implementation-defined" other than in the context of
"implementation-defined behavior" or "implementation-defined value",
so I think we just have to read it as ordinary English text; "some
other implementation-defined manner" simply means "some other manner
which is defined (i.e., documented) by the implementation". For
implementation-defined *behavior*, the standard must provide two or
more possibilities; for implementation-defined anything-else, it
needn't do so.
The way I read it, an implementation is conforming as long as it
documents something such as this:

void main(void)
{
return;
}


It's even conforming if it doesn't. No implementation is /required/ to
define the behaviour of void main programs.

But the code itself is not conforming, except when viewed as a
"MyFavouriteForgivingCompiler C" program rather than as a "C" program.


Which is exactly what "conforming" means.

A *conforming program* is one that is acceptable to a conforming
implementation.

If I wrote a conforming implementation that allows
struct {char c; long double x;}main(void) {}
then that would become a conforming program. (The concept of a
"conforming program" isn't all that useful.)


I think a conforming program may be more useful than you think. Your
example of a conforming main() might not be so useful, but other
aspects of a conforming program can definitely be useful. That's what
the C Standard allows.

I prefer a conforming implementation to a non-conforming one. And if
my conforming implementation tells me through documentation that I
need to define main() as:

struct {char c; long double x;}main(void) {}

and that I need to set c to my favorite character and set x to the
average price of a pound of baloney in the Salt Lake City region on
the third day of the month, averaged over the past year, then, by God,
I'll do that to get my ZOG 32-bit DSP--where sizeof(char) ==
sizeof(long)--working and appease my boss and collect a well-deserved
paycheck. And I'll have the added comfort knowing that I am
programming in Standard C.

--
jay

Jun 14 '06 #21
Keith Thompson said:
Richard Heathfield <in*****@invalid.invalid> writes:
jaysome said:
<snip>
The way I read it, an implementation is conforming as long as it
documents something such as this:

void main(void)
{
return;
}
It's even conforming if it doesn't. No implementation is /required/ to
define the behaviour of void main programs.

But the code itself is not conforming, except when viewed as a
"MyFavouriteForgivingCompiler C" program rather than as a "C" program.


Which is exactly what "conforming" means.


Yes, but my point is that the /same/ code can and often will become
non-conforming when submitted to a different implementation.
A *conforming program* is one that is acceptable to a conforming
implementation.

If I wrote a conforming implementation that allows
struct {char c; long double x;}main(void) {}
then that would become a conforming program. (The concept of a
"conforming program" isn't all that useful.)


We do have a slightly more useful concept available to us, however, which
was mooted here some years ago - that of "a comp.lang.c-conforming
program", which is defined as follows: "a program is acceptable to
comp.lang.c if and only if it is acceptable to comp.lang.c."

I find this concept to be much more relevant here in comp.lang.c than the
concepts "conforming program" and "strictly conforming program".

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 16 '06 #22
jaysome said:

<snip>
And if
my conforming implementation tells me through documentation that I
need to define main() as:

struct {char c; long double x;}main(void) {}


....then it is a freestanding implementation.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 16 '06 #23
Richard Heathfield wrote:

Keith Thompson said:

If I wrote a conforming implementation that allows
struct {char c; long double x;}main(void) {}
then that would become a conforming program. (The concept of a
"conforming program" isn't all that useful.)


We do have a slightly more useful concept available to us,
however, which
was mooted here some years ago - that of "a comp.lang.c-conforming
program", which is defined as follows: "a program is acceptable to
comp.lang.c if and only if it is acceptable to comp.lang.c."

I find this concept to be much more relevant here
in comp.lang.c than the
concepts "conforming program" and "strictly conforming program".


A "correct program" is acceptable to me on this newsgroup.

--
pete
Jun 16 '06 #24

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

Similar topics

4
by: Jacob Jensen | last post by:
This question has probably been asked a million time, but here it comes again. I want to learn the difference between the three type cast operators: static_cast, reinterpret_cast, dynamic_cast. A...
231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
35
by: ytrama | last post by:
Hi, I have read in one of old posting that don't cast of pointer which is returned by the malloc. I would like to know the reason. Thanks in advance, YTR
7
by: yufufi | last post by:
lets say we have a 'shape' class which doesn't implement IComparable interface.. compiler doesn't give you error for the lines below.. shape b= new shape(); IComparable h; h=(IComparable)b;...
7
by: Jim Bancroft | last post by:
Hi everyone, A basic one here, I think. I haven't found the pattern yet, but sometimes when I cast a variable to another type using the "C" style cast operator the compiler refuses to play...
2
by: Enrique Bustamante | last post by:
Casting arrays that works on watch and command window but not in code. My application is casting arrays in a way it should work. To test if I was doing something invalid, I wrote a test code that...
7
by: S. Lorétan | last post by:
Hi guys, Sorry for this stupid question, but I don't know why it isn't working. Here is my (example) code: namespace Test { class A { public string Label1; }
17
by: sophia.agnes | last post by:
Hi , I was going through peter van der linden's book Expert C programming, in this book there is a section named "How and why to cast" the author then says as follows (float) 3 - it's a...
9
by: Taras_96 | last post by:
Hi everyone, I was experimenting with static_cast and reinterpret cast #include <iostream> struct A1 { int a; }; struct A2 { double d; }; struct B : public A1, A2
101
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.