Questions, please

B

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!
 
M

Mark A. Odell

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.
 
R

Régis Troadec

Hello,

bml said:
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
 
R

Richard Heathfield

bml said:
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.
 
C

Christopher Benson-Manica

Régis Troadec said:
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". :)
 
S

Sidney Cadot

Mark said:
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
 
K

Keith Thompson

Warning: The following has very little to do with what the OP was
asking about.

Mark A. Odell said:
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.
 
K

Keith Thompson

bml said:
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. :cool:}
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.
 
K

Kenneth Brody

Sidney said:
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." |
+---------+----------------------------------+-----------------------------+
 
E

Eric Sosman

Christopher said:
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?
 
E

Emmanuel Delahaye

bml said:
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.
 
B

bml

Emmanuel Delahaye said:
bml said:
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- (e-mail address removed) [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."
 
M

Malcolm

bml said:
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.
 
S

Sidney Cadot

Kenneth said:
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
 
P

Peter Nilsson

Richard Heathfield said:
(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.
 
J

J. J. Farrell

Régis Troadec said:

.... assuming a cast ...
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.
 
R

Richard Heathfield

bml said:
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.
 
R

Richard Heathfield

Peter said:
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. ;)


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;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,813
Members
47,357
Latest member
sitele8746

Latest Threads

Top