casts

B

Bill Cunningham

So many people I have noticed in their code use casts. Something
Richard Heathfield said once very much sticks out in my mind. If code is
written properly there is no need (or rarely) for casts. Why do they seem to
be used so much then?

Bill
 
M

Mark Bluemel

    So many people I have noticed in their code use casts.

Which people where?
 Something
Richard Heathfield said once very much sticks out in my mind. If code is
written properly there is no need (or rarely) for casts. Why do they seem to
be used so much then?

Perhaps you're looking at badly written code? Or at least code which
is not written as well as it might be...
 
B

Bill Cunningham

So many people I have noticed in their code use casts.

Which people where?

Perhaps you're looking at badly written code? Or at least code which
is not written as well as it might be...

I meant no one in particular. Just lurking clc I see so much like
(void*) and such but here is one example.

By Arnuld on clc

" At my job, I am working on a piece of code (around 16 source files)
where I have to call malloc() and free() around 20 times. Every time I
have to check the return value of malloc(). So I cam up with this idea
of writing my own malloc() and then using it. is this a good idea ?


#include <stdio.h>
#include <stdlib.h>


enum { ARRSIZE = 10 };

struct my_struct
{
int i;
char arrc[ARRSIZE];
};


void* malloc_my_struct(int num, size_t s);
void free_my_struct( struct my_struct** p );


int main(void)
{
struct my_struct* m = malloc_my_struct(1, sizeof(*m));

printf("Memory allocated: %p\n", (void*)m);
free_my_struct(&m);
printf("Memory freed: %p\n", (void*)m);
return 0;
}


void* malloc_my_struct(int num, size_t s)
{
void* p = malloc(num * s);

if(NULL == p) fprintf(stderr, "IN: %s: Memory Exhausted, can not
allocate more memory\n", __func__);

return p;
}


void free_my_struct( struct my_struct** p )
{
free(*p);
*p = NULL;
} "


============ OUTPUT ======================
[arnuld@dune programs]$ gcc -std=c99 -pedantic -Wall -Wextra xmalloc.c
[arnuld@dune programs]$ ./a.out
Memory allocated: 0x804a008
Memory freed: (nil)
[arnuld@dune programs]$



I got this idea actually from GNU C Library manual:
http://www.gnu.org/software/hello/manual/libc/Malloc-Examples.html#Malloc-Examples
.. 2md, I am using -std=c99 rather than -ansi flag because I am unable
to find any alternative to __func__ . Do you know any ?
 
N

nicolas.sitbon

(void*) and such but here is one example.
  printf("Memory allocated: %p\n", (void*)m);

Well, C99 says : "The argument shall be a pointer to void. The value
of the pointer is
converted to a sequence of printing characters, in an implementation-
deï¬ned
manner."
so in that case, the cast is required.
 
A

Antoninus Twink

Something Richard Heathfield said once very much sticks out in my
mind. If code is written properly there is no need (or rarely) for
casts.

As with most things Heathfield says, this needs to be taken with a pinch
of salt. As is typical for Heathfield, this statement is pure polemic to
push his "Sola ISO C" fundamentalism.

There are many places where casts are essential: for example, to
implement polymorphism in object-oriented C programming or for type
punning. There are also many places where casts are useful: for example,
casting a uint64_t to a uint32_t is a simple way to reduce it mod 2^32.
 
F

Fred

As with most things Heathfield says, this needs to be taken with a pinch
of salt. As is typical for Heathfield, this statement is pure polemic to
push his "Sola ISO C" fundamentalism.

There are many places where casts are essential: for example, to
implement polymorphism in object-oriented C programming or for type
punning. There are also many places where casts are useful: for example,
casting a uint64_t to a uint32_t is a simple way to reduce it mod 2^32.

Also, it is difficult to use qsort without using cast.
 
P

Paul N

    So many people I have noticed in their code use casts.  Something
Richard Heathfield said once very much sticks out in my mind. If code is
written properly there is no need (or rarely) for casts. Why do they seem to
be used so much then?

The program I'm writing (which is in C++ rather than C, but similar
considerations apply) is for Windows. In Windows, there is a function
called SendMessage which is used to inform a window that various
things have happened (or occasionally to ask the window something).
Different messages take different conceptual arguments of different
types, but these arguments have to be passed to SendMessage in a fixed
form (there is only one prototype for SendMessage) which means a
certain amount of casting to get the arguments into the standard form.
This is where most of the casts in my program seem to stem from.

Hope that helps.
Paul.
 
F

Fred

Fred said:




Also, it is difficult to use qsort without using cast.

No, it's easy (see below).

Don't make the mistake of believing Antoninus Twink. Casts are almost
never a good idea, and the places where they are a good idea are not
the places you'd think.

Here is an example of using qsort without a cast:

#include <stdlib.h> /* for qsort */
#include <string.h> /* for strcmp, used in comparison function */

struct bigramfreq_
{
  char bigram[3];
  unsigned long freq;

};

typedef struct bigramfreq_ bigramfreq; /* the things we're sorting */

/* comparison function */
int compbigramfreq(const void *vp1, const void *vp2)
{
  const bigramfreq *p1 = vp1;
  const bigramfreq *p2 = vp2;
  int diff = (p1->freq < p2->freq) - (p1->freq > p2->freq);
  if(diff == 0)
  {
    diff = strcmp(p1->bigram, p2->bigram);
  }
  return diff;

}

Once all the furniture is in place (a type to sort, and an ordering
function), we can define our data:

  bigramfreq bgf[26*26] = {0};

and, having populated it (not shown here), can sort it thusly:

  qsort(bgf,
        sizeof bgf / sizeof bgf[0],
        sizeof bgf[0],
        compbigramfreq);

I see no need for a cast anywhere here.

Yes, you are right. I spoke too soon about when I need casts.
Using the Xt toolkit's XtMalloc function, I cast its return
to what I need (or else get compiler warnings):
Widget *warray = (Widget *)XtMalloc(...);

The reason is that the writers of the Xt toolkit
prototyped XtMalloc to return a (char *), not a (void *).
 
A

Antoninus Twink

Don't make the mistake of believing Antoninus Twink.

Why do you have to turn everything into a question about personalities,
Heathfield? Stick to the facts.
Casts are almost never a good idea, and the places where they are a
good idea are not the places you'd think.

Such useless dogmatism!

Casts are a useful implement in the C programmer's toolbox, no different
in that respect from sizeof or strlen or #ifdef.

Use them when they're appropriate. Don't use them when they're not
appropriate. Why do you feel the need to turn a completely practical
matter into a religious issue?
 
K

Keith Thompson

Bill Cunningham said:
So many people I have noticed in their code use casts.

Which people where?

Perhaps you're looking at badly written code? Or at least code which
is not written as well as it might be...

I meant no one in particular. Just lurking clc I see so much like
(void*) and such but here is one example.

By Arnuld on clc
[snip]
printf("Memory allocated: %p\n", (void*)m);
free_my_struct(&m);
printf("Memory freed: %p\n", (void*)m);
[snip]

Arguments to variadic functions like printf are one of the few
cases where casts are necessary and appropriate. For non-variadic
functions, as long as a prototype is visible, the compiler knows
the type of the parameter and can (and must) implicitly convert
the argument to the correct type. Similar considerations apply for
initializations, assignments, and most other expression contexts.
But for a variadic function the compiler doesn't know the expected
type, so you have to make sure the argument is already of the
correct type. This often requires a cast.

Bill, *please* fix whatever it is that's preventing you from quoting
properly. I'm fairly sure you've been told about "Quotefix",
which supposedly corrects the relevant bug Outlook Express.
 
B

Ben Pfaff

Keith Thompson said:
Bill Cunningham said:
printf("Memory allocated: %p\n", (void*)m);
free_my_struct(&m);
printf("Memory freed: %p\n", (void*)m);
[snip]

Arguments to variadic functions like printf are one of the few
cases where casts are necessary and appropriate.

Appropriate? Sure.

Necessary? No:

int *m = ...;
void *m_void = m;
printf("Memory allocated: %p\n", m_void);
 
B

Bill Cunningham

[snip]
I see no need for a cast anywhere here.

I very much hope Richard I understood and quoted you correctly. Some of
the code is above my head but is there ever a need for a cast?

double Gma (double *num, int n)
{
int i;
double total=0;
for (i=0;i<n;i++)
total +=num;
return total/1*i;
}

I hope this code is correct. But on that last line I've seen a double cast.
That isn't necessary is it?

Bill
 
S

spinoza1111

    So many people I have noticed in their code use casts.  Something
Richard Heathfield said once very much sticks out in my mind. If code is
written properly there is no need (or rarely) for casts. Why do they seem to
be used so much then?

Bill

Lo! Groans Richard Heathfield, descending from the sky
"Casts considered harmful": the folk they dare not ask why.
He is dres't in priestly Robes but he hath dirty Feet
And we need not consider him a Dijkstra paraclete.
He's more a parrot or perhaps a parakeet:
He hath learned many a seeming saw which he transmits as the Law
But is not able to think beyond a lower bound lower than his Maw.
Excessive casting may be a sign of deficiency
Or it may be Genius' fate to make a velvet glove out of swinish C.
Int to void or void to int or void to byte array
Try what cast you like this isn't gold...it's lead that you assay.
 
K

Keith Thompson

Fred said:
Yes, you are right. I spoke too soon about when I need casts.
Using the Xt toolkit's XtMalloc function, I cast its return
to what I need (or else get compiler warnings):
Widget *warray = (Widget *)XtMalloc(...);

The reason is that the writers of the Xt toolkit
prototyped XtMalloc to return a (char *), not a (void *).

I suspect that Xt was originally written before ANSI C became
widespread, so it wasn't possible to assume that all compilers
would support void*.
 
K

Keith Thompson

Ben Pfaff said:
Keith Thompson said:
Bill Cunningham said:
printf("Memory allocated: %p\n", (void*)m);
free_my_struct(&m);
printf("Memory freed: %p\n", (void*)m);
[snip]

Arguments to variadic functions like printf are one of the few
cases where casts are necessary and appropriate.

Appropriate? Sure.

Necessary? No:

int *m = ...;
void *m_void = m;
printf("Memory allocated: %p\n", m_void);

Right, good point.

Here the initialization of m_void supplies the implicit conversion.
In this particular case, though the object seems to exist only for
the purpose of avoiding the cast. So yes, it's appropriate but
not entirely necessary.

Richard Heathfield showed an example of a qsort comparison function
which refers to its arguments several times. In that example,
copying the parameters to local variables (and incidentally
implicitly converting them from void*) made sense; the equivalent
code with casts would have been substantially more verbose.
 
P

Phil Carmody

Keith Thompson said:
Ben Pfaff said:
Keith Thompson said:
printf("Memory allocated: %p\n", (void*)m);
free_my_struct(&m);
printf("Memory freed: %p\n", (void*)m);
[snip]

Arguments to variadic functions like printf are one of the few
cases where casts are necessary and appropriate.

Appropriate? Sure.

Necessary? No:

int *m = ...;
void *m_void = m;
printf("Memory allocated: %p\n", m_void);

Right, good point.

Here the initialization of m_void supplies the implicit conversion.
In this particular case, though the object seems to exist only for
the purpose of avoiding the cast. So yes, it's appropriate but
not entirely necessary.

Richard Heathfield showed an example of a qsort comparison function
which refers to its arguments several times. In that example,
copying the parameters to local variables (and incidentally
implicitly converting them from void*) made sense; the equivalent
code with casts would have been substantially more verbose.

When I saw that sort function, the first thing I thought was
that it was too verbose using additional autos! I guess I like
my code denser that others do.

Phil
 
M

Morris Keesan

double Gma (double *num, int n)
{
int i;
double total=0;
for (i=0;i<n;i++)
total +=num;
return total/1*i;
}
I hope this code is correct. But on that last line I've seen a double
cast.
That isn't necessary is it?


I hope you realize that the last line is equivalent to
return (total/1) * i;
which is equivalent to
return total * i;

It looks like you're probably trying to compute the mean of a set of
doubles, in which case it should be
return total / i;

(which I would write as
return total / n;
which is the same value, but I think the meaning is
much more immediately apparent to the reader).

But in none of these cases is a double cast necessary.
A cast would be appropriate here:

double avg(int *nums, int n)
{
int i;
int total = 0;

for (i = 0; i < n; ++i) total += nums;

return (double)total/n;
}

to force the division to be computed as a double value instead of
an int, because otherwise both operands of the division are ints.
 
N

Nick Keighley

So many people I have noticed in their code use casts.

Which people where?

Perhaps you're looking at badly written code? Or at least code which
is not written as well as it might be...

    I meant no one in particular. Just lurking clc I see so much like
(void*) and such but here is one example.

By Arnuld on clc

" At my job, I am working on a piece of code (around 16 source files)
where I have to call malloc() and free() around 20 times. Every time I
have to check the return value of malloc(). So I cam up with this idea
of writing my own malloc() and then using it. is this a good idea ?

 #include <stdio.h>
#include <stdlib.h>

enum { ARRSIZE = 10 };

struct my_struct
{
  int i;
  char arrc[ARRSIZE];

};

void* malloc_my_struct(int num, size_t s);
void free_my_struct( struct my_struct** p );

int main(void)
{
  struct my_struct* m = malloc_my_struct(1, sizeof(*m));

  printf("Memory allocated: %p\n", (void*)m);
  free_my_struct(&m);
  printf("Memory freed:     %p\n", (void*)m);
  return 0;

}

void* malloc_my_struct(int num, size_t s)
{
  void* p = malloc(num * s);

  if(NULL == p) fprintf(stderr, "IN: %s: Memory Exhausted, can not
allocate more memory\n", __func__);

  return p;

}

void free_my_struct( struct my_struct** p )
{
  free(*p);
  *p = NULL;

} "

============ OUTPUT ======================
[arnuld@dune programs]$ gcc -std=c99 -pedantic -Wall -Wextra xmalloc.c
[arnuld@dune programs]$ ./a.out
Memory allocated: 0x804a008
Memory freed:     (nil)
[arnuld@dune programs]$

I got this idea actually from GNU C Library manual:http://www.gnu.org/software/hello/manual/libc/Malloc-Examples.html#Ma...
. 2md, I am using -std=c99 rather than -ansi flag because I am unable
to find any alternative to __func__ . Do you know any ?


what casts?
 

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
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top