Type-casting void pointers?

C

Christian Bau

Tim Rentsch said:
Well said. *applause*

Example for _really_ stupid warnings:

unsigned char f (int x) { return (x > 0); }

gives a warning on brain-damaged compilers because (x > 0) has type int,
and conversion from int to unsigned char is not always value conserving,
BUT (x > 0) has a value of 0 or 1 and will be converted without problems.

char f (int x) { return x ? 'y' : 'n'; }

Same problem here; the result of (x ? 'y' : 'n') is of type int, but the
actual result can always be converted to char without problems.
 
C

Chris Croughton

Out of interest, which compilers do warn about correct usage of
malloc?

You mean assigning void* to a pointer to non-void? At least one I've
used (could have been the IAR H8 series compiler, but I wouldn't
guarantee it).
The worst I've seen is a warning when you cast something to
the same type it already was. For example:

isprint( (unsigned char)ch );

If you compile with plain char unsigned, it will warn about this
cast.

Try things like:

unsigned char ch;
int in;
in = getc(stdin);
if (in != EOF)
ch = in;

On some of the ARM compilers it gives a warning:

conversion from 'int ' to 'unsigned char ', possible loss of data
It gets really annoying in macros, where you often put in casts
because the macro could really be called with any integral type,
and then this compiler would warn when you use the one type that
matches the cast.

It was possible to turn off this warning, but not without also
turning off important warnings. :X

Exactly. And the 'silly' warnings can mask the real ones (and even mask
the rrors, I've had occasions where it's taken me a lot of time even to
find the error message knowing that there is one, because it's been lost
in the 'noise' of the spurious warnings).
How many platforms have you programmed on where int, size_t,
and void* are not interchangeable, and the compiler does not
have special recognition of standard library functions?

Lots. Including (but not limited to, these are only the ones which I
remember definitely had different sizes for at least one of those
types):

Z8000
M68000
H8 family
80x86

The only "special recognition" by the compilers has been when the
appropriate header -- and therefore the appropriate prototype -- has
been included.

I haven't programmed for a C compiler where int and void* were
interchangeable without a cast since I left university where we had a
pre-K&R compiler (thinking of it, I don't think it had void at all so
they weren't interchangeable then either).
There would not have been any diagnostic in either case, if the
parameter to malloc were wrong, ie.

pointer = (correct_type*) malloc(sizeof(my_type));

True. Easier is to do something like:

#define NEW(t) ((T*)malloc(sizeof(T)))

and then

int *p = NEW(char);

gives a diagnostic (usually an error, occasionally a warning).
So this is a bit of a Pascal's wager.

Note that this problem can be eschewed with:

malloc(sizeof *ptr);

But that doesn't catch the case where you know what the type should be
and you want to ensure that the pointer is the correct type.

Chris C
 
H

hugo2

Stephan said:
I think some compilers give a warning without the explicit cast.
Maybe the author wanted to write 'warning-free' code.

Stephan

hugo July 17
Ah! I too had a feeling the casts were not
strickly needed, but were for 'portablitiy'
reasons.
Portability issues are very murky waters
to me, and I don't dive by myself.
 
H

hugo2

pete said:
What do you mean by that?
I don't see any code about "unsigned int".
"byte" either means "unsigned char" or the definition is wrong.
memcpy works on objects of all types.

hugo July 18
As far as I know, addresses are memory locations
and are always integers. Negative or fractional
addresses don't make any sense, do they?
So the addresses are all positive integers,
and that is what is being assigned to pbTo
and pbFrom to initalize them.

That is what I ment.

The 'byte' type is a data type, which I
assumed to have some meaning either in
a header file or a program typedef.
Maguire did not explain it.

hugo.
 
K

Keith Thompson

hugo2 said:
hugo July 18
As far as I know, addresses are memory locations
and are always integers. Negative or fractional
addresses don't make any sense, do they?
So the addresses are all positive integers,
and that is what is being assigned to pbTo
and pbFrom to initalize them.

No. Addresses are addresses. The language defines conversions
between addresses (pointers) and integers, but it says very little
about what those conversions do. Basically, if you convert an address
value to an integer big enough to hold it, then convert it back to the
pointer type, you'll get the original value -- but the intermediate
integer value may be completely meaningless.

It happens that, on many actual systems, addresses look a lot like
unsigned integers, but that's an implementation detail.
 
C

CBFalconer

hugo2 said:
As far as I know, addresses are memory locations and are always
integers. Negative or fractional addresses don't make any sense,
do they? So the addresses are all positive integers, and that is
what is being assigned to pbTo and pbFrom to initalize them.

You are surrounded all day by addresses that are not integers. For
example, "1234 W Foo St, Bar, State of Fee, Foe". What makes you
think computers have to linearize their addresses? Some of them
are so linearized, such as which memory chip, L2 Cache or main
memory or virtual memory. But down under that layer the
differences still exist.
 

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,166
Messages
2,570,907
Members
47,448
Latest member
DeanaQ4445

Latest Threads

Top