473,320 Members | 2,071 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,320 software developers and data experts.

Questions, please

bml
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
Is this a problem since p has not been initialized, it could point to any
place in memory and assign a value to it could cause access violation?

Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?

Q3:
Why casting in C is so "dangerous" sometimes?

Thanks a lot!



Nov 14 '05 #1
59 2581
"bml" <le*****@yahoo.com> wrote in
news:F4**********************@bgtnsc05-news.ops.worldnet.att.net:
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
This is an error, p is a pointer to char, i is an integer. They are not
compatible types. You can assign p to point to i via:

char *p = (char *) &i;

If you like or assign the value of i to *p once p has some memory
allocated, e.g.

char *p = malloc(1);
if (p)
{
int i = 0;
*p = (char) i;
free(p);
}
Is this a problem since p has not been initialized, it could point to
any place in memory and assign a value to it could cause access
violation?
p will point to address zero if your compiler allows this to compile.
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
Don't bring this up again, read the C-FAQ section on malloc.
Q3:
Why casting in C is so "dangerous" sometimes?


Because it is often times, but not always, an indication of poor design.

--
- Mark ->
--
Nov 14 '05 #2
Hello,

"bml" <le*****@yahoo.com> a écrit dans le message de news:
F4**********************@bgtnsc05-news.ops.worldnet.att.net...
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
0 to p
Is this a problem since p has not been initialized,
No
it could point to any place in memory and assign a value to it could cause access violation?
Sure that using p could cause some access violation, since p is an adress of
a character and p=NULL in this case.
NULL is a macro commonly defined as 0 or ((void *)0)
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?


I have been teached here that casting malloc() is in fact obsolete since the
introduction of the generic (void*) pointer in ISO C90. (void*) is
implicitly converted in the destination type.
The real error is that you could omit to include <stdlib.h>, and casting
malloc() can hide to the compiler this omission.

regards, regis
Nov 14 '05 #3
sorry,

"Régis Troadec" <re**@wanadoo.fr> a écrit dans le message de news:
bv**********@news-reader4.wanadoo.fr...
Hello,

"bml" <le*****@yahoo.com> a écrit dans le message de news:
F4**********************@bgtnsc05-news.ops.worldnet.att.net...
Q1:
int i = 0;
char *p = i; /*incompatible types, error while compiling*/
by considering this of course : char *p = (char*)i;
Is this assign 0 to p or assigning the value pointed by p to 0?


0 to p

Nov 14 '05 #4
bml wrote:
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
K&R2, pp93-94.
Is this a problem since p has not been initialized, it could point to any
place in memory and assign a value to it could cause access violation?
K&R2, pp234-237.
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
(1) all code should either do something good or stop something bad
happening; a cast on malloc does neither.
(2) the conversion can actually cause some compilers not to warn you if you
forgot to #include <stdlib.h>

Casting is usually the wrong thing to do, and the places where it's the
right thing are rarely the places you'd expect.

Q3:
Why casting in C is so "dangerous" sometimes?


Any C code is dangerous if it is written by someone who does not understand
that code. If you don't understand what casts are for and when to use them
(and when not to use them), then all your C code, both with and without
casts, is dangerous.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #5
Mark A. Odell wrote:
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?


Don't bring this up again, read the C-FAQ section on malloc.


It doesn't properly address the "why" question. And yes, I intend to
keep making this point as long as people suggest that it does :-)

Best regards,

Sidney

Nov 14 '05 #6
"Régis Troadec" <re**@wanadoo.fr> spoke thus:
I have been teached here


Consider this post a friendly favor, then - teach is yet another
lovely irregular English verb, whose past tense is "taught". :)
--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #7
Warning: The following has very little to do with what the OP was
asking about.

"Mark A. Odell" <no****@embeddedfw.com> writes:
[...]
p will point to address zero if your compiler allows this to compile.


The context is a bit murky, but it was something like this:

int i = 0;
char *p = (char*)i;

p will point to whatever address results from casting the integer
value 0 to type char*. This may or may not be "address zero",
whatever thay may mean for a given implementation.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #8
"bml" <le*****@yahoo.com> writes:
[...]
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
This has been discussed here at great length. The FAQ discusses it
briefly. If that's not enough for you, spending a little time at
groups.google.com will probably cure you of the urge to discuss it
further. 8-)}
Q3:
Why casting in C is so "dangerous" sometimes?


Because a cast is often (but not always) the equivalent of using a
sledgehammer to drive a screw. To stretch the analogy to the breaking
point, a sledgehammer doesn't care whether it's being used on a
flathead or Phillips-head screw, a wood screw, a metal screw, or a
quarter-inch bolt. As a carpenter or programmer, you *should* care.

Assume you have types FOO and BAR.

FOO x;
BAR y = some_value;

x = (FOO)y;

You may think that the cast means "convert the value of y from type
BAR to type FOO". What it really means is "convert the value of y to
type FOO; I don't care what type you think y really has, just convert
it and don't complain about it". That's a bit of an exaggeration (for
example, if FOO is an integer type and BAR is a struct type, the
compiler *will* complain about the cast), but it's close enough to
demonstrate the potential danger.

C's type system is far from perfect; sometimes casts are necessary.
But the general consensus around here is that they should be avoided
whenever possible. If the language provides an implicit conversion in
some particular case, it's usually better to take advantage of it than
to use an explicit cast, because the implicit conversion will be more
restrictive, and therefore safer, than the cast.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #9
Sidney Cadot wrote:

Mark A. Odell wrote:
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?


Don't bring this up again, read the C-FAQ section on malloc.


It doesn't properly address the "why" question. And yes, I intend to
keep making this point as long as people suggest that it does :-)


What part of the answer to 7.7 does not answer "why"?

Under ANSI/ISO Standard C, these casts are no longer necessary,
and in fact modern practice discourages them, since they can
camouflage important warnings which would otherwise be generated
if malloc() happened not to be declared correctly;

--

+---------+----------------------------------+-----------------------------+
| Kenneth | kenbrody at spamcop.net | "The opinions expressed |
| J. | http://www.hvcomputer.com | herein are not necessarily |
| Brody | http://www.fptech.com | those of fP Technologies." |
+---------+----------------------------------+-----------------------------+

Nov 14 '05 #10
Christopher Benson-Manica wrote:

"Régis Troadec" <re**@wanadoo.fr> spoke thus:
I have been teached here


Consider this post a friendly favor, then - teach is yet another
lovely irregular English verb, whose past tense is "taught". :)


Régis did not attempt to use the past tense of "teach,"
but the past participle of "teach." The first is "taught,"
as Christopher correctly states, but the second is "taught."
See the difference?

Strained attempt at topicality: In C, the keyword stating
that an identifier has internal linkage is "static." The
keyword stating that an identified data object persists for
the entire life of the program is also "static." See the
difference?

--
Er*********@sun.com
Nov 14 '05 #11
In 'comp.lang.c', "bml" <le*****@yahoo.com> wrote:
Q1:
int i = 0;
char *p = i;
This is not portable. The result of assigning an integer to a pointer is
implementation dependent.
Is this assign 0 to p or assigning the value pointed by p to 0?
It tends to assign the integer value 0. It may produce a useful result or
not.
Is this a problem since p has not been initialized, it could point to any
No. There is no dereferencement at this moment.
place in memory and assign a value to it could cause access violation?

Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
Its not that bad, but
- It's useless for more than ten years. (Yes, the 'void' thing is useful)
- It tends to mask nasty errors like the lack of a visible prototype for
malloc()
- It makes the code more difficult to read and to maintain.
Q3:
Why casting in C is so "dangerous" sometimes?


Because masking a problem is different than curing it. The times where
typecasts are necessary are rare. Parameters of variadic functions, for
example.

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #12
bml
Emmanuel Delahaye <em**********@noos.fr> wrote in message
news:Xn***************************@213.228.0.75...
In 'comp.lang.c', "bml" <le*****@yahoo.com> wrote:
Q1:
int i = 0;
char *p = i;
This is not portable. The result of assigning an integer to a pointer is
implementation dependent.
Is this assign 0 to p or assigning the value pointed by p to 0?


It tends to assign the integer value 0. It may produce a useful result or
not.
Is this a problem since p has not been initialized, it could point to

any
No. There is no dereferencement at this moment.
place in memory and assign a value to it could cause access violation?

Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?


Its not that bad, but
- It's useless for more than ten years. (Yes, the 'void' thing is useful)
- It tends to mask nasty errors like the lack of a visible prototype for
malloc()
- It makes the code more difficult to read and to maintain.
Q3:
Why casting in C is so "dangerous" sometimes?


Because masking a problem is different than curing it. The times where
typecasts are necessary are rare. Parameters of variadic functions, for
example.

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Thank you all for responses!
Here is another line I am reading, which is confusing to me. Would you
elaborate on it?
"If no prototype for a function specifying its argument types, value of
short is cast'ed to int."
Nov 14 '05 #13
In 'comp.lang.c', Emmanuel Delahaye <em**********@noos.fr> wrote:
Its not that bad, but


I know, it's boring...

"It's not that bad, but..."

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #14

"bml" <le*****@yahoo.com> wrote in message news:F4wTb.162161
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
Is this a problem since p has not been initialized, it could point to any
place in memory and assign a value to it could cause access violation?
The * here is used to declare a pointer. * is also used as the indirection
operator, which causes a lot of confusion.
Your statement will set p to 0, ie to the NULL pointer. However most
compilers will issue a warning because i is an integer, and assigning an
integer to a pointer makes no sense in portable C code.
Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
C allows implict conversions from void * to a pointer type. If you fail to
#include <stdlib.h> the compiler will give you a warning, which will be
suppressed by the cast, so there is some justification for not casting.
The reason for keeping the cast in is to allow the code to compile under
C++.
Q3:
Why casting in C is so "dangerous" sometimes?

With the exception of casts from floating point types to integers, C casts
are simple reinterpretations of bits. If the bit pattern doesn't make sense
for the type you are casting to, you will get garbage results and the
compiler won't warn about them.

eg

char buff[32];

void *ptr = buff;

double *real = (double *) ptr;

could well load "real" with an illegal value, if the platform demands
doubles aligned on an 8-bit boundary but "buff" is not so aligned.
Nov 14 '05 #15
Kenneth Brody wrote:
Sidney Cadot wrote:
Mark A. Odell wrote:

Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?

Don't bring this up again, read the C-FAQ section on malloc.


It doesn't properly address the "why" question. And yes, I intend to
keep making this point as long as people suggest that it does :-)

What part of the answer to 7.7 does not answer "why"?

Under ANSI/ISO Standard C, these casts are no longer necessary,
and in fact modern practice discourages them, since they can
camouflage important warnings which would otherwise be generated
if malloc() happened not to be declared correctly;


Good grief... All along, I have been looking at the HTML version that
doesn't have this part (http://www.eskimo.com/~scs/C-faq/q7.7.html).
Thanks for pointing this out to me.

Best regards,

Sidney

Nov 14 '05 #16
Richard Heathfield <do******@address.co.uk.invalid> wrote in message news:<bv**********@titan.btinternet.com>...
bml wrote:

Q2:
Why might explicit casts on malloc's return value, as in
int *ip = (int *)malloc(10 * sizeof(int));
be a bad style?
(1) all code should either do something good or stop something bad
happening; a cast on malloc does neither.


AKAICS, neither does...

va_list ap = 0;

....or...

while (yadda)
{
continue;
}

Yet there is at least one clc regular who chooses to utilise such
practices. ;)
(2) the conversion can actually cause some compilers not to warn you if
you forgot to #include <stdlib.h>


Explicit redundant initialisation of all automatic variables can also
hide bugs. Yet, again, some people choose to do it because: they're
aware of the issues and feel confident that their practices minimise
the potential for problems; and they feel that what they gain in
'aesthetics' outways the cons.

--
Peter
Nov 14 '05 #17
"Régis Troadec" <re**@wanadoo.fr> wrote in message news:<bv**********@news-reader4.wanadoo.fr>...
"bml" <le*****@yahoo.com> a écrit dans le message de news:
F4**********************@bgtnsc05-news.ops.worldnet.att.net...

int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?


0 to p


.... assuming a cast ...
Is this a problem since p has not been initialized,


No
it could point to any place in memory and assign a value to it could
cause access violation?


Sure that using p could cause some access violation, since p is an adress of
a character and p=NULL in this case.
NULL is a macro commonly defined as 0 or ((void *)0)


p would not necessarily be == NULL in this case. It would contain an
implementation-defined bit pattern that might or might not compare
equal to NULL, and might or might not be a valid pointer.

Only integral constant expressions with value 0 (or those cast to
(void *)) are guaranteed to create a null pointer when assigned to
a pointer variable. The object i is an integer variable that has
the value 0.
Nov 14 '05 #18
bml wrote:
Thank you all for responses!
Here is another line I am reading, which is confusing to me. Would you
elaborate on it?
"If no prototype for a function specifying its argument types, value of
short is cast'ed to int."


That's not true.

The Standard (or rather, my copy of the draft) says:

If the expression that precedes the parenthesized argument list in a
function call consists solely of an identifier, and if no declaration is
visible for this identifier, the identifier is implicitly declared exactly
as if, in the innermost block containing the function call, the declaration

extern int identifier();
As you can see, no casting is involved.
--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #19
Peter Nilsson wrote:
Richard Heathfield <do******@address.co.uk.invalid> wrote in message
news:<bv**********@titan.btinternet.com>...
bml wrote:
>
> Q2:
> Why might explicit casts on malloc's return value, as in
> int *ip = (int *)malloc(10 * sizeof(int));
> be a bad style?
(1) all code should either do something good or stop something bad
happening; a cast on malloc does neither.


AKAICS, neither does...

va_list ap = 0;


This code gives ap a known value, which is useful in ensuring that the
program is deterministic. i.e. it prevents (or rather, helps to prevent)
the program's behaviour from being unpredictable. That's a Good Thing.

...or...

while (yadda)
{
continue;
}
This shows that the loop is "intentionally left blank" to use that awful
phrase, and thus has a certain self-documenting value.
Yet there is at least one clc regular who chooses to utilise such
practices. ;)
(2) the conversion can actually cause some compilers not to warn you if
you forgot to #include <stdlib.h>
Explicit redundant initialisation of all automatic variables can also
hide bugs.


On balance, I find that the benefits outweigh the costs.
Yet, again, some people choose to do it because: they're
aware of the issues and feel confident that their practices minimise
the potential for problems;
Indeed.
and they feel that what they gain in
'aesthetics' outways the cons.


Form follows function. If C had implicit initialisation of all temps, then:

int i;

would be aesthetically superior to:

int i = 0;

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #20
On Mon, 02 Feb 2004 16:20:12 -0500, Eric Sosman <Er*********@sun.com>
wrote in comp.lang.c:
Christopher Benson-Manica wrote:

"Régis Troadec" <re**@wanadoo.fr> spoke thus:
I have been teached here


Consider this post a friendly favor, then - teach is yet another
lovely irregular English verb, whose past tense is "taught". :)


Régis did not attempt to use the past tense of "teach,"
but the past participle of "teach." The first is "taught,"
as Christopher correctly states, but the second is "taught."
See the difference?

Strained attempt at topicality: In C, the keyword stating
that an identifier has internal linkage is "static." The
keyword stating that an identified data object persists for
the entire life of the program is also "static." See the
difference?


Aside from the extreme reluctance to wear out valuable and expensive
teletypes (after all, "ls" is one character shorter than spendthrift
excesses like "dir" or old HP's "cat"), the originators of C and UNIX
were properly parsimonious with keywords.

Still, there is a certain sense to it. Any object, file or block
scope, defined as static has both of the following two
characteristics:

- no external linkage

- static storage duration

There is no way other than using the static keyword to define a data
object with both of these attributes, only one or the other.

So effectively a static object has essentially the same properties
regardless of whether it is defined at file or block scope.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #21
On Tue, 3 Feb 2004 02:24:25 +0000 (UTC), Richard Heathfield
<do******@address.co.uk.invalid> wrote in comp.lang.c:
bml wrote:
Thank you all for responses!
Here is another line I am reading, which is confusing to me. Would you
elaborate on it?
"If no prototype for a function specifying its argument types, value of
short is cast'ed to int."


That's not true.

The Standard (or rather, my copy of the draft) says:

If the expression that precedes the parenthesized argument list in a
function call consists solely of an identifier, and if no declaration is
visible for this identifier, the identifier is implicitly declared exactly
as if, in the innermost block containing the function call, the declaration

extern int identifier();
As you can see, no casting is involved.


You misread the question. He was not asking about the type assumed by
the compiler for the function, but the fate of an argument of type
short passed to a function without a prototype in scope.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #22
On Mon, 02 Feb 2004 22:11:53 GMT, "bml" <le*****@yahoo.com> wrote in
comp.lang.c:

[snip]
Thank you all for responses!
Here is another line I am reading, which is confusing to me. Would you
elaborate on it?
"If no prototype for a function specifying its argument types, value of
short is cast'ed to int."


The sentence you quoted accurately describes what happens, but is uses
incorrect wording to do so.

Given this declaration:

void func(); /* declaration with no information about arguments */

int main(voia)
{
short x = 3;
func(x);
return 0;
}

Then the value of "x", a short, is not "cast'ed" to int. The only
thing that performs a cast in C is a cast operator. If you wanted to
cast the value of "x" to int, you would write a cast like this:

int y = (int)x;

What C has are conversions and promotions. Many conversions and
promotions are implicit, that is they happen automatically and do not
require a cast, like assigning the value of short "x" to the int "y",
above. The value of "x" is converted to int before assigning to the
int "y" even if the cast is removed.

There is no such thing as an "implicit" or "automatic" cast in C, a
cast is an explicit conversion.

In the case of a function without a prototype, all integer types of
rank less than int, that is _Bool, char, and short, are passed as
either int or in some cases unsigned int. This is an automatic
conversion (not any kind of cast) and this particular automatic
conversion is called "default argument promotion".

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #23
regarding
va_list ap = 0;

In article <news:bv**********@sparta.btinternet.com>
Richard Heathfield <bi****@eton.powernet.co.uk> wrote:This code gives ap a known value, which is useful in ensuring that the
program is deterministic. i.e. it prevents (or rather, helps to prevent)
the program's behaviour from being unpredictable. That's a Good Thing.


Except when it does not compile, such as when "va_list" is an alias
for an array type (e.g., array 1 of some struct, on the PowerPC).

You can safely write:

va_list ap = { 0 };

since braces are legal for both scalar and aggregate types, and 0
is always a valid initializer. The resulting "va_list" is not
good for anything, but could at least fail in a more-reproducible
manner.

(I prefer not to initialize "intentionally uninitialized" variables
myself, and turn on compiler warnings where possible to make sure
that code paths that use them uninitialized are caught, but this
is one of the more difficult compromise-choices. Unlike the debate
about casting malloc, no single way is statistically much more
reliable than the other, in my own observations at least.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #24
Peter Nilsson wrote:
Richard Heathfield <do******@address.co.uk.invalid> wrote
.... snip ...
(1) all code should either do something good or stop something
bad happening; a cast on malloc does neither.


AKAICS, neither does...

va_list ap = 0;

...or...

while (yadda)
{
continue;
}

Yet there is at least one clc regular who chooses to utilise
such practices. ;)


You misquote me :-). I recommend:

while (yadda) continue;

which avoids the pain of using the shift key for /* do nothing */
comments, yet firmly reminds the casual reader that "yadda"
contains the meat. This, to me, comes under the heading of
"something good".

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #25
Malcolm wrote:

.... snip ...

With the exception of casts from floating point types to integers,
C casts are simple reinterpretations of bits. If the bit pattern
doesn't make sense for the type you are casting to, you will get
garbage results and the compiler won't warn about them.


Likely, but NOT guaranteed. The only data type that is guaranteed
not to have any padding or guard bits is unsigned char. Anything
else can have trap values.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #26
Jack Klein wrote:
On Tue, 3 Feb 2004 02:24:25 +0000 (UTC), Richard Heathfield
<do******@address.co.uk.invalid> wrote in comp.lang.c:
bml wrote:
> Thank you all for responses!
> Here is another line I am reading, which is confusing to me. Would you
> elaborate on it?
> "If no prototype for a function specifying its argument types, value of
> short is cast'ed to int."


That's not true.

The Standard (or rather, my copy of the draft) says:
<snip perfectly good quote which happens not to apply to question!>
As you can see, no casting is involved.


You misread the question. He was not asking about the type assumed by
the compiler for the function, but the fate of an argument of type
short passed to a function without a prototype in scope.


Oops! My apologies to the OP.

Anyway, IMHO it's still not true, since an implicit conversion occurs,
rather than a cast.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #27
Chris Torek wrote:
regarding
va_list ap = 0;

In article <news:bv**********@sparta.btinternet.com>
Richard Heathfield <bi****@eton.powernet.co.uk> wrote:
This code gives ap a known value, which is useful in ensuring that the
program is deterministic. i.e. it prevents (or rather, helps to prevent)
the program's behaviour from being unpredictable. That's a Good Thing.


Except when it does not compile, such as when "va_list" is an alias
for an array type (e.g., array 1 of some struct, on the PowerPC).


Yes, I should have pointed that out, and chose to gloss over it.

You can safely write:

va_list ap = { 0 };
And I do...
since braces are legal for both scalar and aggregate types, and 0
is always a valid initializer. The resulting "va_list" is not
good for anything, but could at least fail in a more-reproducible
manner.
....but (well, not necessarily for va_list, but for structs in general) I get
a really, really annoying gcc diagnostic:

wnnint.c:3119: warning: missing initializer
wnnint.c:3119: warning: (near initialization for `j.sign')

I really wish there were a way of turning this off without losing any other
diagnostics.

<OT> Is there? :-) </OT>

(I prefer not to initialize "intentionally uninitialized" variables
myself, and turn on compiler warnings where possible to make sure
that code paths that use them uninitialized are caught, but this
is one of the more difficult compromise-choices. Unlike the debate
about casting malloc, no single way is statistically much more
reliable than the other, in my own observations at least.)


Indeed.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #28
On Mon, 2 Feb 2004 23:15:32 -0000, "Malcolm"
<ma*****@55bank.freeserve.co.uk> wrote in comp.lang.c:

[snip]
With the exception of casts from floating point types to integers, C casts
are simple reinterpretations of bits. If the bit pattern doesn't make sense
for the type you are casting to, you will get garbage results and the
compiler won't warn about them.
Um, err, cough, all right out with it...

RUBBISH! BALDERDASH!

Consider our old friend the signed magnitude integer machine, with 16
bit ints (INT_MAX = 32767, UINT_MAX = 65534). On such a platform, the
humble value of -1 is represented as (binary):

1000000000000001 (or 0x8001, if you prefer)

And yet, should such a value be cast (or even converted by assignment)
to unsigned int, the bits needs must rearrange themselves,
instantaneously, into:

1111111111111111 (known to friends as 0xFFFF) eg

char buff[32];

void *ptr = buff;

double *real = (double *) ptr;

could well load "real" with an illegal value, if the platform demands
doubles aligned on an 8-bit boundary but "buff" is not so aligned.


Remember too that a pointer to char and/or void may actually be
physically larger, and contain more bits, than a pointer to some or
all other object types. I've heard that such is true of some Cray
boxes, but I can't confirm by direct experience because no one's been
silly enough to give me one to play with.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #29
"Jack Klein" <ja*******@spamcop.net> wrote:
Consider our old friend the signed magnitude integer machine, with 16
bit ints (INT_MAX = 32767, UINT_MAX = 65534). On such a platform, the

^^^^^
UINT_MAX must be of the form pow(2,n)-1 where n is the number of value bits.
Therefore 65534 is impossible, it would still be 65535.

The thing with signed magnitude is that INT_MIN == -32767
instead of the usual INT_MIN == -32767-1

--
Simon.
Nov 14 '05 #30
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:

"bml" <le*****@yahoo.com> wrote in message news:F4wTb.162161
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
Is this a problem since p has not been initialized, it could point to any
place in memory and assign a value to it could cause access violation?

The * here is used to declare a pointer. * is also used as the indirection
operator, which causes a lot of confusion.
Your statement will set p to 0, ie to the NULL pointer.


No, it won't. At least, it probably will, but that's not guaranteed.

What it will do is to set p to _the pointer value that results from
translating an integer object with value 0 to pointer_.
This is not necessarily the same thing as the pointer value that results
from translating a _constant_ integral zero to pointer - _that_ is a
null pointer. (Note, btw: null pointer, not NULL pointer. NULL is a
macro which expands to a null pointer constant, but it isn't a pointer
itself - it's a compile-time constant.)
On the majority, indeed probably the vast majority of systems, these
will be the same. However, a system which has a hardware null pointer of
<FFFF:FFFF> is not unimaginable, and on that system, a wise
implementation might well compile this code:

#include <stdio.h>

int main(void)
{
int i=0;
void *p_int=i, p_direct=0;

printf("p_int is %p; p_direct is %p.\n", p_int, p_direct);
return 0;
}

to output

p_int is <FFFF:FFFF>; p_direct is <0000:0000>.

Not very likely on everyday systems, perhaps, but far from impossible.
Why casting in C is so "dangerous" sometimes?

With the exception of casts from floating point types to integers, C casts
are simple reinterpretations of bits.


No; of values. From n869, 6.5.4:

# [#4] Preceding an expression by a parenthesized type name
# converts the value of the expression to the named type.

Note: _value_ of the expression. Not bit pattern.

Richard
Nov 14 '05 #31
In <Xn***************************@213.228.0.75> Emmanuel Delahaye <em**********@noos.fr> writes:
In 'comp.lang.c', "bml" <le*****@yahoo.com> wrote:
Q1:
int i = 0;
char *p = i;


This is not portable. The result of assigning an integer to a pointer is
implementation dependent.


This is not C. The attempt to assign an integer (other than the null
pointer constant) to a pointer requires a diagnostic.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #32
In <JW*********************@bgtnsc04-news.ops.worldnet.att.net> "bml" <le*****@yahoo.com> writes:
Here is another line I am reading, which is confusing to me. Would you
elaborate on it?
"If no prototype for a function specifying its argument types, value of
short is cast'ed to int."


You should choose your C tutorials more carefully. The value is
converted, not cast and this is only a particular case of a general rule:
the integer promotions are applied to the arguments of unprototyped
functions.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #33
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
"bml" <le*****@yahoo.com> wrote in message news:F4wTb.162161
Q1:
int i = 0;
char *p = i;

Is this assign 0 to p or assigning the value pointed by p to 0?
Is this a problem since p has not been initialized, it could point to any
place in memory and assign a value to it could cause access violation?

The * here is used to declare a pointer. * is also used as the indirection
operator, which causes a lot of confusion.
Your statement will set p to 0, ie to the NULL pointer.


No, `i' is not an integer *constant* expression. Therefore, after the
following definitions

int i = 0;
char *p = (char *)i;

the value of `p' is implementation-defined. It is /not/ guaranteed to be
a null pointer.

Martin
Nov 14 '05 #34
"Chris Torek" <no****@torek.net> wrote in message
news:bv*********@enews4.newsguy.com...

(I prefer not to initialize "intentionally uninitialized" variables
myself, and turn on compiler warnings where possible to make sure
that code paths that use them uninitialized are caught, but this
is one of the more difficult compromise-choices. Unlike the debate
about casting malloc, no single way is statistically much more
reliable than the other, in my own observations at least.)


You say 'statistically', have there been any formal studies on malloc
casting? If so, I'd love to read them. [Seriously!]

For me, sitting on the 'outside' observing the debates, I can't help but
think of the Stroustrup quote about C in general...

"C has its problems, ... [but] we know C's problems."

One of those problems is the use of unprototyped functions. Another is the
inherent weakness of type weak languages. C programmers have dealt
relatively comfortably with both for decades.

--
Peter
Nov 14 '05 #35
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bv**********@sparta.btinternet.com...
Peter Nilsson wrote:
Richard Heathfield <do******@address.co.uk.invalid> wrote in message
news:<bv**********@titan.btinternet.com>...
bml wrote:
>
> Q2:
> Why might explicit casts on malloc's return value, as in
> int *ip = (int *)malloc(10 * sizeof(int));
> be a bad style?

(1) all code should either do something good or stop something bad
happening; a cast on malloc does neither.
AKAICS, neither does...

va_list ap = 0;
I misremembered... va_list ap = { 0 };

This code gives ap a known value,
What _value_ would that be? What is the benefit of this known value (sic)?
which is useful in ensuring that the
program is deterministic.
Um, how does _not_ initialising va_lists make a program less or
non-deterministic?
i.e. it prevents (or rather, helps to prevent)
the program's behaviour from being unpredictable.
<Insert paraphrase of last question here>
That's a Good Thing.


It's a style thang! ;)
...or...

while (yadda)
{
continue;
}


This shows that the loop is "intentionally left blank" to use that awful
phrase, and thus has a certain self-documenting value.


'Self-documenting' is how some malloc casters describe the malloc cast.
Irrespective of 'cost', if a redundant token 'adds' something to the above
code in your mind, then couldn't a redundant cast also 'add' something in
the minds of some other C programmers?
Yet there is at least one clc regular who chooses to utilise such
practices. ;)
(2) the conversion can actually cause some compilers not to warn you if
you forgot to #include <stdlib.h>


Explicit redundant initialisation of all automatic variables can also
hide bugs.


On balance, I find that the benefits outweigh the costs.


That is _your_ finding, in _this_ case. Yet I've yet to see yourself
vehemently thrusting this as the One True Style on newbies, let alone other
similarly competent C experts who have disagreed with your style.
Yet, again, some people choose to do it because: they're
aware of the issues and feel confident that their practices minimise
the potential for problems;


Indeed.

So, quite seriously I ask: how is the situation different for malloc
casting?

The pros and cons of either side have been stated. I simply want to know why
some clc regulars find it an almost pathological urge to convert the pagens,
so to speak, when the issue is nothing more than a balance of benefits v
costs?

I'm quite sure that casted malloc has caused problems in more than one
non-trivial program written by one or more experts. I'm just not convinced
that disaster is the forgone inevitability that it's portrade as. I'm quite
sure that other quirks of C have caused considerably more problems,
considerably more often.
and they feel that what they gain in
'aesthetics' outways the cons.


Form follows function.


Interesting. Would you say that void * and its associated deliberate type
weakness was a _good_ choice for the C language? Would you say it was the
_best_ choice?

--
Peter
Nov 14 '05 #36
"Peter Nilsson" <ai***@acay.com.au> writes:
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bv**********@sparta.btinternet.com...
Peter Nilsson wrote:

while (yadda)
{
continue;
}


This shows that the loop is "intentionally left blank" to use that
awful phrase, and thus has a certain self-documenting value.


'Self-documenting' is how some malloc casters describe the malloc
cast. Irrespective of 'cost', if a redundant token 'adds' something to
the above code in your mind, then couldn't a redundant cast also 'add'
something in the minds of some other C programmers?


If it does, then why stop with `malloc'? By that logic, every expression
(including every subexpression it might be composed of) should be cast
to its type... ;)

Martin
Nov 14 '05 #37
Malcolm wrote:
[...]
With the exception of casts from floating point types to integers, C casts
are simple reinterpretations of bits. If the bit pattern doesn't make sense
for the type you are casting to, you will get garbage results and the
compiler won't warn about them.


Nonsense. Here are a few examples of casts that are
*not* mere "reinterpretations of bits" on most implementations:

(long)0
`0' has type `int', which might have as few as sixteen
bits. `(long)0' has type `long', which has at least
thirty-two. What sort of "reinterpretation" created
the additional bits?

(double)1u
`1u' has type `unsigned int', and exactly one of its
bits is non-zero. `(double)1u' has type `double', and
the number of non-zero bits is unspecified. How did
"reinterpretation" arrive at different values for
corresponding bit positions?

(float)1.0
`1.0' has type `double', usually represented as a 64-
bit value. `(float)1.0' has type `float', usually
represented in 32 bits. How did "reinterpretation"
destroy 32 bits?

(double*)NULL
This one's trickier, since the Standard doesn't specify
the type of the expression `NULL'. However, one of the
allowed types for `NULL' is `void*', and on a platform
where this is so it may also be the case that a `void*'
value has more bits than a `double*'. On a platform
where `NULL' has type `int', it is not necessarily the
case that a `double*' has the same number of bits as
an `int', nor that all the bits of `(double*)NULL' are
zeros. See Question 5.17 in the comp.lang.c FAQ --
in fact, read all of Section 5; it will do you good.

A cast is an operator, just like `+' or `%'. Almost all[*]
C operators work with the values of their operand or operands,
and none[**] works with the representations.
[*] The only operators I can think of that do not use their
operands' values are `sizeof' and unary `&', but perhaps
I've overlooked something.

[**] Perhaps it's debatable, but I consider this true even of
the bitwise operators: binary `&', `|', and `^'. They
are described as operating on the binary digits of their
operand values, but that's a convenience, an aid to
clarity of exposition. In particular, note that they are
not defined to operate on any "padding bits," which are
part of the representation (if present), but not part of
the value.

C programmers are often tempted to think about the representations
of the values their programs manipulate. IMHO this is a temptation
worth resisting: if you concentrate on the values themselves and
let the implementation figure out how to represent them, you will
be a happier programmer in the long run.

--
Er*********@sun.com
Nov 14 '05 #38
"Martin Dickopp" <ex****************@zero-based.org> wrote:
"Peter Nilsson" <ai***@acay.com.au> writes:

'Self-documenting' is how some malloc casters describe the malloc
cast. Irrespective of 'cost', if a redundant token 'adds' something to
the above code in your mind, then couldn't a redundant cast also 'add'
something in the minds of some other C programmers?


If it does, then why stop with `malloc'? By that logic, every expression
(including every subexpression it might be composed of) should be cast
to its type... ;)


Of ourse (given short x),
x = (short)(x + 42);
is _much_ clearer than
x += 42;
At least to my compiler, that is. Otherwise it whines about possible loss
of data in the latter case ;-)

Peter
Nov 14 '05 #39
Peter Nilsson wrote:
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bv**********@sparta.btinternet.com...
Peter Nilsson wrote:
> Richard Heathfield <do******@address.co.uk.invalid> wrote in message
> news:<bv**********@titan.btinternet.com>...
>> bml wrote:
>> >
>> > Q2:
>> > Why might explicit casts on malloc's return value, as in
>> > int *ip = (int *)malloc(10 * sizeof(int));
>> > be a bad style?
>>
>> (1) all code should either do something good or stop something bad
>> happening; a cast on malloc does neither.
>
> AKAICS, neither does...
>
> va_list ap = 0;
I misremembered... va_list ap = { 0 };
Yup.
This code gives ap a known value,


What _value_ would that be? What is the benefit of this known value (sic)?


Good question. :-)

Your followup makes it clear that your choice of va_list wasn't random, so I
went to have a look at a va_list-using function I wrote for my CLINT
library, some months ago.

Here's the first part of the function, warts and all:

void wnn_Log(unsigned char wnn_Depth,
unsigned long wnn_LogFlags,
const char *wnn_Owner,
const char *wnn_Library,
const char *wnn_Filename,
const char *wnn_Function,
int wnn_Line,
const char *wnn_Format,
...)
{
static unsigned long LineNumber = 0;
va_list ap;
assert(wnn_GlobalConfig != NULL);
va_start(ap, wnn_Format);

Clearly, I agree with you on this occasion! :-)

which is useful in ensuring that the
program is deterministic.


Um, how does _not_ initialising va_lists make a program less or
non-deterministic?


In the more general case, however, it's a useful hobbit I'll leave that typo
there for what little amusement value it has but I meant to type that it's
a useful /habit/ to get into.
i.e. it prevents (or rather, helps to prevent)
the program's behaviour from being unpredictable.
<Insert paraphrase of last question here>
That's a Good Thing.


It's a style thang! ;)


You have said so. :-)
> ...or...
>
> while (yadda)
> {
> continue;
> }
This shows that the loop is "intentionally left blank" to use that awful
phrase, and thus has a certain self-documenting value.


'Self-documenting' is how some malloc casters describe the malloc cast.


Yes. I'm not convinced by that argument, however. Otherwise, surely instead
of:
printf("%f\n", d);

they'd write:

(void)(int)((int(*)(const char *, ...))printf((const char *)"%f\n",
(double)d));

Yes, you could argue that that's self-documenting, but it's hardly clearer,
is it?
Irrespective of 'cost', if a redundant token 'adds' something to the above
code in your mind, then couldn't a redundant cast also 'add' something in
the minds of some other C programmers?
But the cast isn't redundant - that is, code with it does not have the same
meaning as code without it. An explicit conversion is performed that
otherwise would not be performed.
> Yet there is at least one clc regular who chooses to utilise such
> practices. ;)
>
>> (2) the conversion can actually cause some compilers not to warn you
>> if you forgot to #include <stdlib.h>
>
> Explicit redundant initialisation of all automatic variables can also
> hide bugs.


On balance, I find that the benefits outweigh the costs.


That is _your_ finding, in _this_ case.


That's right.
Yet I've yet to see yourself
vehemently thrusting this as the One True Style on newbies, let alone
other similarly competent C experts who have disagreed with your style.
That's for the very obvious reason that there are advantages and
disadvantages to both styles. Chris Torek rightly points out that it's a
close call. The malloc thing isn't.
> and they feel that what they gain in
> 'aesthetics' outways the cons.


Form follows function.


Interesting. Would you say that void * and its associated deliberate type
weakness was a _good_ choice for the C language?


Yes.
Would you say it was the
_best_ choice?


I can't think of a better one off-hand (although I wish it also applied to
function pointers, and that void ** had the same kinds of guarantees that
come with void *).

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #40
Richard Heathfield <do******@address.co.uk.invalid> scribbled the following:
Peter Nilsson wrote:
"Richard Heathfield" <do******@address.co.uk.invalid> wrote in message
news:bv**********@sparta.btinternet.com...
Peter Nilsson wrote:
> ...or...
>
> while (yadda)
> {
> continue;
> }

This shows that the loop is "intentionally left blank" to use that awful
phrase, and thus has a certain self-documenting value.
'Self-documenting' is how some malloc casters describe the malloc cast.

Yes. I'm not convinced by that argument, however. Otherwise, surely instead
of:
printf("%f\n", d); they'd write: (void)(int)((int(*)(const char *, ...))printf((const char *)"%f\n",
(double)d)); Yes, you could argue that that's self-documenting, but it's hardly clearer,
is it?


Hmm, interesting. Try this for a program to calculate the sum of ten
numbers:

#include <stdio.h>
int main(void) {
int a[(int)10];
int i;
int sum=(int)0;
for ((int)(i=(int)0); (int)((int)i<(int)10); (int)i++) {
(void)(int)(((int *)a)[(int)i]=(int)i);
}
for ((int)(i=(int)0); (int)((int)i<(int)10); (int)i++) {
(void)(int)(sum=(int)((int)sum+(int)((int *)a)[(int)i])));
}
(void)(int)((int(*)(const char *, ...))printf((const char *)
"The sum is %d\n", (int)sum));
return (int)0;
}

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"This isn't right. This isn't even wrong."
- Wolfgang Pauli
Nov 14 '05 #41

"Jack Klein" <ja*******@spamcop.net> wrote in message
With the exception of casts from floating point types to integers, C
casts are simple reinterpretations of bits. If the bit pattern doesn't
make sense for the type you are casting to, you will get garbage
results and the compiler won't warn about them.


Um, err, cough, all right out with it...

RUBBISH! BALDERDASH!

Consider our old friend the signed magnitude integer machine, with 16
bit ints (INT_MAX = 32767, UINT_MAX = 65534). On such a platform, the
humble value of -1 is represented as (binary):

1000000000000001 (or 0x8001, if you prefer)

And yet, should such a value be cast (or even converted by assignment)
to unsigned int, the bits needs must rearrange themselves,
instantaneously, into:

1111111111111111 (known to friends as 0xFFFF)

You don't understand how to use natural language. NL statements are
generalisations, and failure to hold in some specialised circumstances
doesn't make them untrue.

eg Mammals are viviparous, true or false? The right answer is not "false"
(because of the montremes), "true" is acceptable, but not strictly correct.

Actually your example illustrates my point. x = (unsigned int) -1 should
ideally generate an error. In C it doesn't, probably to avoid the necessity
of introducing a test and conditional jump. It produces the bit pattern all
ones because that is a simple reinterpretation of bits on two's complement
machines, which are the vast majority in use. This leaves us with the
problem of what to do on one's complement machines - since they are not so
important they are forced to be an exception.
Nov 14 '05 #42
Malcolm wrote:

Actually your example illustrates my point. x = (unsigned int) -1 should
ideally generate an error.
Why?
In C it doesn't, probably to avoid the necessity
of introducing a test and conditional jump.
More probably, because the conversion from signed to
unsigned integers is well-defined by the Standard, and is
not an error of any kind. The compiler may complain about
the construct (it may complain about your Argyle socks if
it so chooses), but it may not reject the program if it's
free of other errors and exceeds no implementation limits.
There's no error in what you've shown, assuming `x' has a
reasonable definition (e.g., not `const FILE* x').
It produces the bit pattern all
ones because that is a simple reinterpretation of bits on two's complement
machines, which are the vast majority in use.
No: It produces the bit pattern of all ones because that
is the representation of UINT_MAX on all C-faring machines.
This leaves us with the
problem of what to do on one's complement machines - since they are not so
important they are forced to be an exception.


No: Even on a ones' complement or signed magnitude machine,
the result is the same. Of course, on these machines the cast
does more than the "reinterpretation of the bits" you mentioned
in an earlier post. WHY does the same value come out? Because
the conversion from signed int to unsigned int is defined in
terms of the *values* being converted, not of the bit patterns
that represent those values.

--
Er*********@sun.com
Nov 14 '05 #43

"Eric Sosman" <Er*********@sun.com> wrote in message
Actually your example illustrates my point. x = (unsigned int) -1
should ideally generate an error.
Why?

Because it is nonsense to try to express a negative number as an unsigned
integer.
More probably, because the conversion from signed to
unsigned integers is well-defined by the Standard, and is
not an error of any kind.
But the standard itself is a human construct. I would imagine that the main
reason it allows it is to avoid breaking hundreds of pre-standard programs.
The reason K and R allowed it was probably efficiency.
The compiler may complain about
the construct (it may complain about your Argyle socks if
it so chooses), but it may not reject the program if it's
free of other errors and exceeds no implementation limits.
There's no error in what you've shown, assuming `x' has a
reasonable definition (e.g., not `const FILE* x').
Obviously since I say the construct "should ideally generate an error" there
must be circumstances, non-ideal ones, in which the error is not generated.
No: It produces the bit pattern of all ones because that
is the representation of UINT_MAX on all C-faring machines.
So why does the standard specify that -1, of all things, must cast to
UINT_MAX?
No: Even on a ones' complement or signed magnitude machine,
the result is the same. Of course, on these machines the cast
does more than the "reinterpretation of the bits" you mentioned
in an earlier post. WHY does the same value come out? Because
the conversion from signed int to unsigned int is defined in
terms of the *values* being converted, not of the bit patterns
that represent those values.

You need to look at the motivation. Read what I said to Jack Klein about
natural language.
-1 casts to 0xFFFF because that is a reinterpretation of bits on two's
complement machines, and because the conversion can be accomplished in a
single machine instruction. Natural language needs to be socially
appropriate as well as literally accurate. In this case I am explaining C
casting to someone who doesn't understand very much about it, so mention of
one's complement machines, or the text of the standard, is not useful and
confuses.
Nov 14 '05 #44
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
"Eric Sosman" <Er*********@sun.com> wrote in message
Actually your example illustrates my point. x = (unsigned int) -1
should ideally generate an error.
Why?

Because it is nonsense to try to express a negative number as an
unsigned integer.


Only if you think of `unsigned int' as a model for integer numbers,
which would be a pretty bad model, since there is an infinite number of
integers. It therefore makes sense to model integers modulo n instead.

Since it is a mathematical property of integers modulo n that -1 is
congruent to n-1, why shouldn't the same be true for `unsigned int'?
So why does the standard specify that -1, of all things, must cast to
UINT_MAX?


Probably because it is a sensible choice to base the properties of
`unsigned int' on integers modulo UINT_MAX+1. If you don't agree with
that, what other mathematical object do you think should `unsigned int'
be based on?

Martin
Nov 14 '05 #45
Hi,

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> a écrit dans le
message de news: bv**********@chessie.cirr.com...
"Régis Troadec" <re**@wanadoo.fr> spoke thus:
I have been teached here
Consider this post a friendly favor, then - teach is yet another
lovely irregular English verb, whose past tense is "taught". :)


Yes, I did a nice mistake. Thank you to correct me. My compiler is C89
full-compliant but my brain isn't english language full-compliant yet. :)

Regis
--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.

Nov 14 '05 #46
On Tue, 3 Feb 2004 19:26:48 +1100, "Simon Biber"
<ne**@ralminNOSPAM.cc> wrote in comp.lang.c:
"Jack Klein" <ja*******@spamcop.net> wrote:
Consider our old friend the signed magnitude integer machine, with 16
bit ints (INT_MAX = 32767, UINT_MAX = 65534). On such a platform, the

^^^^^
UINT_MAX must be of the form pow(2,n)-1 where n is the number of value bits.
Therefore 65534 is impossible, it would still be 65535.

The thing with signed magnitude is that INT_MIN == -32767
instead of the usual INT_MIN == -32767-1


Thanks, my typo (or think-o).

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #47
Eric Sosman wrote:
.... snip ...
A cast is an operator, just like `+' or `%'. Almost all[*]
C operators work with the values of their operand or operands,
and none[**] works with the representations.


And, IMO, a cast is another example of an overloaded C construct.
I consider that it would have been better to limit casts to
altering the 'typewise' interpretation of a bit pattern, provided
that the size of that pattern is the same for the original and the
cast type. After that there should specific functions to perform
the various transformations. However, that is not the situation.

Continuing the 'might have been speculation', we would then attach
different meanings to:

ch = (int)x; /* asserts sizeof x = sizeof int */
ch = int(x); /* transforms, preserving something */

However, 'tain't so, so nobody should assume such.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #48
Malcolm wrote:

"Eric Sosman" <Er*********@sun.com> wrote in message
Actually your example illustrates my point. x = (unsigned int) -1
should ideally generate an error.
Why?

Because it is nonsense to try to express a negative number as an unsigned
integer.


That's not what the snippet attempts to do. It *converts*
a negative number to an `unsigned int', and the conversion obeys
the rules of modular arithmetic modulus `UINT_MAX+1'.

It is equally nonsensical to try to express a number with a
fractional part as an integer, but do you think `(int)(9.7 + 0.5)'
should be an error? Of course not: the *conversion* from `double'
to `int' is well-defined (for numbers in an appropriate range),
and is also useful. Should the compiler reject a useful and well-
defined operation as erroneous?
More probably, because the conversion from signed to
unsigned integers is well-defined by the Standard, and is
not an error of any kind.

But the standard itself is a human construct. I would imagine that the main
reason it allows it is to avoid breaking hundreds of pre-standard programs.
The reason K and R allowed it was probably efficiency.


Perhaps. Have you asked them? Or "him," rather, because
K's role was to assist in describing R's invention. However,
until you can produce a statement from R to support your contention,
I'll continue to shave you with Occam's razor, and persist in my
outlandish supposition that the conversion is defined and not
erroneous because it is useful and well-behaved.
The compiler may complain about
the construct (it may complain about your Argyle socks if
it so chooses), but it may not reject the program if it's
free of other errors and exceeds no implementation limits.
There's no error in what you've shown, assuming `x' has a
reasonable definition (e.g., not `const FILE* x').

Obviously since I say the construct "should ideally generate an error" there
must be circumstances, non-ideal ones, in which the error is not generated.


This argument can, of course, justify or condemn absolutely
anything you like. As long as the arguer gets to control the
definition of "ideal," there's no externalizable content to the
debate. Solipsism rules -- and even the paranoid have enemies.
No: It produces the bit pattern of all ones because that
is the representation of UINT_MAX on all C-faring machines.

So why does the standard specify that -1, of all things, must cast to
UINT_MAX?


Look up "modular arithmetic" and "congruence."
No: Even on a ones' complement or signed magnitude machine,
the result is the same. Of course, on these machines the cast
does more than the "reinterpretation of the bits" you mentioned
in an earlier post. WHY does the same value come out? Because
the conversion from signed int to unsigned int is defined in
terms of the *values* being converted, not of the bit patterns
that represent those values.

You need to look at the motivation. Read what I said to Jack Klein about
natural language.


I read it, but I confess I didn't understand it. It seemed
entirely beside the point, a fog rather than an illumination. My
failing perhaps -- but when "everyone is out of step except
Johnny" it is reasonable to wonder about Johnny's sense of rhythm.
-1 casts to 0xFFFF because that is a reinterpretation of bits on two's
complement machines, and because the conversion can be accomplished in a
single machine instruction.
Already refuted, multiple times by multiple people. Also
self-contradictory: if the representation is already correct,
it should be "convertible" in *zero* machine instructions.
Natural language needs to be socially
appropriate as well as literally accurate. In this case I am explaining C
casting to someone who doesn't understand very much about it, so mention of
one's complement machines, or the text of the standard, is not useful and
confuses.


You are explaining your own mistaken understanding of C.
Your original statement was

"With the exception of casts from floating point types
to integers, C casts are simple reinterpretations of bits.
If the bit pattern doesn't make sense for the type you are
casting to, you will get garbage results and the compiler
won't warn about them."

.... and this is demonstrably (and demonstratedly) false. Perhaps
it would have been true if you had invented the language, and perhaps
you feel it "should" be true -- but it is not true, has never been
true, and (I'll bet) will never be true. When your "explanation"
of casting is flat-out wrong, you do a disservice by propounding it.

--
Er*********@sun.com
Nov 14 '05 #49
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Eric Sosman wrote:

... snip ...

A cast is an operator, just like `+' or `%'. Almost all[*]
C operators work with the values of their operand or operands,
and none[**] works with the representations.


And, IMO, a cast is another example of an overloaded C construct.
I consider that it would have been better to limit casts to
altering the 'typewise' interpretation of a bit pattern, provided
that the size of that pattern is the same for the original and the
cast type. After that there should specific functions to perform
the various transformations.


I don't get it. What's wrong with

double pi = 3.14;
(float)pi;

but would be OK with the hypothetical

float(pi);

???

I freely admit that I like the C++ way better, but I can't find anything
wrong with the C way of doing it. There is no fundamental difference
between (float)pi and float(pi). The latter merely saves a couple
of parentheses when a more complex expression is converted.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #50

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

Similar topics

0
by: Boris Ammerlaan | last post by:
This notice is posted about every week. I'll endeavor to use the same subject line so that those of you who have seen it can kill-file the subject; additionally, Supersedes: headers are used to...
0
by: softwareengineer2006 | last post by:
All Interview Questions And Answers 10000 Interview Questions And Answers(C,C++,JAVA,DOTNET,Oracle,SAP) I have listed over 10000 interview questions asked in interview/placement test papers for...
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...
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...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.