By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,918 Members | 2,258 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,918 IT Pros & Developers. It's quick & easy.

void * vs char *

P: n/a
I've been reflecting on these two types of pointer. As far as I can
glean from books, void * and char * are functionally equivalent: the
key property of both is that they are pointers that can be faithfully
cast to any other pointer type.

The only difference seems to be that it is legal to perform arithmetic
on a char *, but not on a void *.

So if a char * really is just a more functional void *, why would
anyone ever use a void * in their code, instead of a char *?

Mar 19 '07 #1
Share this Question
Share on Google+
48 Replies


P: n/a
Fr************@googlemail.com wrote:
>
I've been reflecting on these two types of pointer. As far as I can
glean from books, void * and char * are functionally equivalent: the
key property of both is that they are pointers that can be faithfully
cast to any other pointer type.

The only difference seems to be that it is legal to perform arithmetic
on a char *, but not on a void *.

So if a char * really is just a more functional void *, why would
anyone ever use a void * in their code, instead of a char *?
The sole purpose of void*
is to reduce the amount of casts in a program.
Most pointer conversions to and from void* can be done without a cast.
Most other pointer conversions require a cast.

Before the invention of type void, char* was used instead.

--
pete
Mar 19 '07 #2

P: n/a
Fr************@googlemail.com wrote:
I've been reflecting on these two types of pointer. As far as I can
glean from books, void * and char * are functionally equivalent: the
key property of both is that they are pointers that can be faithfully
cast to any other pointer type.

The only difference seems to be that it is legal to perform arithmetic
on a char *, but not on a void *.

So if a char * really is just a more functional void *, why would
anyone ever use a void * in their code, instead of a char *?
To avoid casting every assignment of something other than a char* to and
from a char*.

--
Ian Collins.
Mar 19 '07 #3

P: n/a
In article <11**********************@n59g2000hsh.googlegroups .com>,
<Fr************@googlemail.comwrote:
>So if a char * really is just a more functional void *, why would
anyone ever use a void * in their code, instead of a char *?
char * means that it points to characters or bytes. void * doesn't;
it means that it points to something of unspecified type. Even if
there was no functional difference between them, it would be
worthwhile to be able to express your intent.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Mar 19 '07 #4

P: n/a
pete <pf*****@mindspring.comwrites:
Fr************@googlemail.com wrote:
>>
I've been reflecting on these two types of pointer. As far as I can
glean from books, void * and char * are functionally equivalent: the
key property of both is that they are pointers that can be faithfully
cast to any other pointer type.

The only difference seems to be that it is legal to perform arithmetic
on a char *, but not on a void *.

So if a char * really is just a more functional void *, why would
anyone ever use a void * in their code, instead of a char *?

The sole purpose of void*
is to reduce the amount of casts in a program.
Most pointer conversions to and from void* can be done without a cast.
Most other pointer conversions require a cast.
No, that's not the *sole* purpose.

The problem with a char* is that you can't tell whether it's intended
to be a generic pointer (in pre-C89 code), or a pointer to actual
character data, or a pointer to a small integer (or an array thereof),
or a pointer to byte data (or an array thereof). The ANSI committee
invented void* to give us a generic pointer type, one that has the
advantage that you can't accidentally dereference it and obtain a
possibly meaningless char value.
Before the invention of type void, char* was used instead.
Yes.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 19 '07 #5

P: n/a
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
To avoid casting every assignment of something other than a char* to and
from a char*.
I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

#include <stdio.h>

void call(void *);
struct s { int a; };

main()
{
struct s a;
a.a=1234;
call(&a);
return 0;
}

void call(void *p)
{
printf("%d\n",p->a);
}

--
Ian Collins.

Mar 19 '07 #6

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
>>To avoid casting every assignment of something other than a char* to and
from a char*.

I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.
No, you don't.
#include <stdio.h>
Let's start by making it legal C:
void call(void *);
struct s { int a; };

main()
int main(void)
{
struct s a;
a.a=1234;
call(&a);
return 0;
}

void call(void *p)
{
printf("%d\n",p->a);
struct s *ps = p;
printf("%d\n",ps->a);
}
Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning level high
enough.

--
Ian Collins.
Mar 19 '07 #7

P: n/a
Flash Gordon wrote, On 19/03/07 10:10:

<snip>
> printf("%d\n",p->a);
struc s *sp = p;
A perfect example of why I should have copied and pasted even a small
example, not retyped on a different computer. That should have been
struct not struc, of course.
--
Flash Gordon
Mar 19 '07 #8

P: n/a
Fr************@googlemail.com wrote, On 19/03/07 09:28:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
>To avoid casting every assignment of something other than a char* to and
from a char*.

I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

#include <stdio.h>

void call(void *);
struct s { int a; };

main()
{
struct s a;
a.a=1234;
call(&a);
No cast here that I can see, but if call took a char* as a parameter one
would be required.
return 0;
}

void call(void *p)
{
printf("%d\n",p->a);
struc s *sp = p;
printf("%d\n",sp->a);

Now it works since you are translating back to a compatible (the
original) type and not a cast in sight.
}
Also as a side note it would be better to be explicit about main
returning an int, especially as C99 has dropped implicit int. Best to be
specific about not taking parameters as well.
int main(void)
--
Flash Gordon
Mar 19 '07 #9

P: n/a
Fr************@googlemail.com wrote:
>
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
To avoid casting every assignment of something other than a char* to and
from a char*.

I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

#include <stdio.h>

void call(void *);
struct s { int a; };

main()
{
struct s a;
a.a=1234;
call(&a);
return 0;
}

void call(void *p)
{
printf("%d\n",p->a);
}
The problem is that you have used the (void *) type badly.

The prototype of the call function
void call(void *p);
indicates that it is intended
to take a pointer to any type object.
But it isn't intended to take a pointer to any type object.
The printf call statement, shows that p must be a pointer
to a struct with a member "a" of type int.
The right way to write that program is:

/* BEGIN new.c */

#include <stdio.h>

struct s {
int a;
};

void call(struct s* p);

int main(void)
{
struct s a;

a.a = 1234;
call(&a);
return 0;
}

void call(struct s *p)
{
printf("%d\n", p->a);
}

/* END new.c */

mem_cpy is an example of a function that uses
void * type parameters more better.

void *mem_cpy(void *s1, const void *s2, size_t n)
{
unsigned char *p1 = s1;
const unsigned char *p2 = s2;

while (n-- != 0) {
*p1++ = *p2++;
}
return s1;
}
--
pete
Mar 19 '07 #10

P: n/a
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.comwrote:
Francine.Ne...@googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
>To avoid casting every assignment of something other than a char* to and
from a char*.
I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

No, you don't.
#include <stdio.h>

Let's start by making it legal C:
void call(void *);
struct s { int a; };
main()
int main(void)
???

main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int. You may have a personal preference for
the more verbose form, but that doesn't make it invalid. I've borrowed
a copy of the ANSI Standard from the library, so now I too can quote
chapter & verse :)
>From 6.3.2.2:
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();
appeared.

and from 6.5.4.3:
An empty list in a function declarator that is part of a definition of
that function specifies that the function has no parameters.

(For reference, it continues: The empty list in a function declarator
that is not part of
a definition of that function specifies that no information about the
number or types of the parameters is supplied.)
void call(void *p)
{
printf("%d\n",p->a);

struct s *ps = p;
A rose by any other name... I don't see that this gains anything in
terms of clarity or brevity over "printf("%d\n",((struct s*)p)->a);" -
in fact it just leads to an additional pointer floating around.
Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning level high
enough.
As this conversion is lossless, I don't see why the compiler should
take it upon itself to warn me about it!
--
Ian Collins.

Mar 19 '07 #11

P: n/a
Fr************@googlemail.com writes:
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.comwrote:
>Francine.Ne...@googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
>>To avoid casting every assignment of something other than a char* to and
from a char*.
I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

No, you don't.
#include <stdio.h>

Let's start by making it legal C:
void call(void *);
struct s { int a; };
main()
int main(void)

???

main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int. You may have a personal preference for
the more verbose form, but that doesn't make it invalid. I've borrowed
a copy of the ANSI Standard from the library, so now I too can quote
chapter & verse :)
>>From 6.3.2.2:
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();
appeared.
[...]

I think you're looking at a copy of the 1990 standard. C99 dropped
implicit int.

Yes, "main()" is legal in C90 (Ian was partly mistaken on that point),
but in my opinion "int main(void)" is better.

[...]
>Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning level high
enough.

As this conversion is lossless, I don't see why the compiler should
take it upon itself to warn me about it!
Because char* is not (since 1989) a generic pointer type, and a
warning is likely to tell you about a logical error in your code. In
fact, since there is no implicit conversion from struct s* to char*,
the call is a constraint violation; the compiler *must* issue a
diagnostic, and it *may* reject the program altogether.

You seem to be arguing that the compiler should shut up about implicit
conversions that don't lose any information; in other words, you want
C's type checking to be even weaker than it is. You're certainly
entitled to that opinion, but it's not one many people share. If you
want a generic pointer type, use void*. There are plenty of
mechanisms that let you be sloppy with types if you do it
deliberately; *I* want the compiler to warn me if I do it
accidentally.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 19 '07 #12

P: n/a
Fr************@googlemail.com said:
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.comwrote:
>Francine.Ne...@googlemail.com wrote:
<snip>
#include <stdio.h>

Let's start by making it legal C:
void call(void *);
struct s { int a; };
main()
int main(void)

???

main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int.
Agreed. (In C99, it has to be int main() at the very least, but in C90
main() is legal.)
You may have a personal preference for
the more verbose form,
Yes. Adding the return type makes it C99-conforming, and using the
prototype form is good style, but these are choices, not requirements.

<snip>
void call(void *p)
{
printf("%d\n",p->a);

struct s *ps = p;

A rose by any other name... I don't see that this gains anything in
terms of clarity or brevity over "printf("%d\n",((struct s*)p)->a);" -
in fact it just leads to an additional pointer floating around.
Nevertheless, it represents a considerable gain in correctness over
printf("%d\n", p->a), wouldn't you agree?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #13

P: n/a
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Nevertheless, it represents a considerable gain in correctness over
printf("%d\n", p->a), wouldn't you agree?
Well, yes :)

The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Mar 19 '07 #14

P: n/a
[...]

I think you're looking at a copy of the 1990 standard. C99 dropped
implicit int.

Yes, "main()" is legal in C90 (Ian was partly mistaken on that point),
but in my opinion "int main(void)" is better.
Where I'm sitting, C == C99 :)

--
Ian Collins.
Mar 19 '07 #15

P: n/a
Fr************@googlemail.com wrote:
>
>>>void call(void *p)
{
printf("%d\n",p->a);

struct s *ps = p;

A rose by any other name... I don't see that this gains anything in
terms of clarity or brevity over "printf("%d\n",((struct s*)p)->a);" -
in fact it just leads to an additional pointer floating around.
You said "I still need to explicitly cast p to a (struct s*) to avoid a
compile-time error", which I showed by example to be incorrect. That's
the thing with a void*, you can use implicit conversion. What harm does
a temporary pointer cause?
>
>>Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning level high
enough.

As this conversion is lossless, I don't see why the compiler should
take it upon itself to warn me about it!
Keith answered this better than I could.

--
Ian Collins.
Mar 19 '07 #16

P: n/a
Fr************@googlemail.com said:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Nevertheless, it represents a considerable gain in correctness over
printf("%d\n", p->a), wouldn't you agree?

Well, yes :)

The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.
But it was lousy code. Sorry, but it was. That simply isn't the kind of
place where void * is a win.

Several examples of putting void * to good use can be seen in the
standard library: memcpy, memcmp, memset, qsort and bsearch all spring
to mind.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #17

P: n/a
Ian Collins said:
>
>[...]

I think you're looking at a copy of the 1990 standard. C99 dropped
implicit int.

Yes, "main()" is legal in C90 (Ian was partly mistaken on that
point), but in my opinion "int main(void)" is better.
Where I'm sitting, C == C99 :)
You must have a very small seat. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #18

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>Nevertheless, it represents a considerable gain in correctness over
printf("%d\n", p->a), wouldn't you agree?


Well, yes :)

The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.
But it didn't!
>
>>--
>
*Please* don't quote signatures.

--
Ian Collins.
Mar 19 '07 #19

P: n/a
On Mar 19, 7:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Nevertheless, it represents a considerable gain in correctness over
printf("%d\n", p->a), wouldn't you agree?
Well, yes :)
The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.

But it was lousy code. Sorry, but it was. That simply isn't the kind of
place where void * is a win.
Ease up there! I wasn't submitting it to a good code contest - it was
just an example to illustrate a point, proof-of-context if you like.
Several examples of putting void * to good use can be seen in the
standard library: memcpy, memcmp, memset, qsort and bsearch all spring
to mind.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Mar 19 '07 #20

P: n/a
On Mar 19, 8:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.

But it didn't!
Didn't what?
*Please* don't quote signatures.
Sorry - I'll try to be careful with that in future.

Mar 19 '07 #21

P: n/a
just an example to illustrate a point, proof-of-context if you like.

Oops meant concept of course.

Mar 19 '07 #22

P: n/a
On Mar 19, 7:33 pm, Keith Thompson <k...@mib.orgwrote:
You seem to be arguing that the compiler should shut up about implicit
conversions that don't lose any information; in other words, you want
C's type checking to be even weaker than it is. You're certainly
entitled to that opinion, but it's not one many people share. If you
want a generic pointer type, use void*. There are plenty of
mechanisms that let you be sloppy with types if you do it
deliberately; *I* want the compiler to warn me if I do it
accidentally.
That's an interesting way to put it. Maybe that's what's happening -
I've been forced to use Java for the last couple of years, which has
this horrible over-bearing strict typing, so maybe I'm reacting
against that now and trying to push the liberating flexibility that C
gives me...

However, I'm not completely sure it should be the job of the compiler
and not some optional lint tool to pick through my code for places
where I might just have meant something else.

Mar 19 '07 #23

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 8:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>>The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.

But it didn't!


Didn't what?
Require an explicit cast. I used implicit conversion from void*.

--
Ian Collins.
Mar 19 '07 #24

P: n/a
Fr************@googlemail.com said:
On Mar 19, 7:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Francine.Ne...@googlemail.com said:
The whole point of that example was that it was code that used a
void * but wouldn't compile unless you added in an explicit cast.

But it was lousy code. Sorry, but it was. That simply isn't the kind
of place where void * is a win.

Ease up there! I wasn't submitting it to a good code contest - it was
just an example to illustrate a point, proof-of-context if you like.
Sure, but the point is that it doesn't illustrate your point well,
because it's like saying "screwdrivers are a waste of time - I tried
hammering a nail in with one and hey, I might as well have used a
hammer". Your illustration did not provide a reason not to use void *.
It just showed that there are circumstances where void * may not be
appropriate - and we already knew that.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 19 '07 #25

P: n/a
On Mar 19, 9:34 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:
On Mar 19, 7:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:
The whole point of that example was that it was code that used a
void * but wouldn't compile unless you added in an explicit cast.
But it was lousy code. Sorry, but it was. That simply isn't the kind
of place where void * is a win.
Ease up there! I wasn't submitting it to a good code contest - it was
just an example to illustrate a point, proof-of-context if you like.

Sure, but the point is that it doesn't illustrate your point well,
because it's like saying "screwdrivers are a waste of time - I tried
hammering a nail in with one and hey, I might as well have used a
hammer". Your illustration did not provide a reason not to use void *.
It just showed that there are circumstances where void * may not be
appropriate - and we already knew that.
Maybe you're right! I guess the issue I have is that I'm not really
convinced that void * should exist at all. I mean, char * can double
up perfectly well as both a pointer to char and a "generic pointer",
but for some reason if you work with char * you need to do a lot of
extra explicit casting. At the very least, there seems to be a lot of
duplication between the function of void * and char *, whereas I
always think minimality and efficiency is a virtue.

Mar 19 '07 #26

P: n/a
On Mar 19, 9:27 pm, Ian Collins <ian-n...@hotmail.comwrote:
Francine.Ne...@googlemail.com wrote:
On Mar 19, 8:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>The whole point of that example was that it was code that used a void
* but wouldn't compile unless you added in an explicit cast.
>But it didn't!
Didn't what?

Require an explicit cast. I used implicit conversion from void*.
Well, that's true, though the net result was you saved a pair of
parentheses in your source code, and in exchange picked up an extra
pointer to carry round!

Mar 19 '07 #27

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 9:34 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>
Sure, but the point is that it doesn't illustrate your point well,
because it's like saying "screwdrivers are a waste of time - I tried
hammering a nail in with one and hey, I might as well have used a
hammer". Your illustration did not provide a reason not to use void *.
It just showed that there are circumstances where void * may not be
appropriate - and we already knew that.

Maybe you're right! I guess the issue I have is that I'm not really
convinced that void * should exist at all. I mean, char * can double
up perfectly well as both a pointer to char and a "generic pointer",
but for some reason if you work with char * you need to do a lot of
extra explicit casting. At the very least, there seems to be a lot of
duplication between the function of void * and char *, whereas I
always think minimality and efficiency is a virtue.
No, void* serves as a generic pointer, to have char* double up (and
don't forget it used to, before void* was added to the language) adds
complexity.

void foo( char* );

Does foo() expect an generic pointer, or does foo() only expect a char*?
void* removes the ambiguity and adds clarity.

Efficiency is completely irrelevant.

--
Ian Collins.
Mar 19 '07 #28

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 9:27 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>Francine.Ne...@googlemail.com wrote:
>>>On Mar 19, 8:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>>>>The whole point of that example was that it was code that used a void
>* but wouldn't compile unless you added in an explicit cast.
>>>>But it didn't!
>>>Didn't what?

Require an explicit cast. I used implicit conversion from void*.

Well, that's true, though the net result was you saved a pair of
parentheses in your source code, and in exchange picked up an extra
pointer to carry round!
The net result was I was able to use implicit conversion from void* and
didn't have to resort to (explicit, as all casts are) casting.

I'm not sure where you get the issue with the temporary pointer from.
It's just that, a temporary variable. In the trivial example you posted
it is used exactly once, in a more complex case, it would be used
wherever the passed parameter is dereferenced.

--
Ian Collins.
Mar 19 '07 #29

P: n/a
On 19 Mar 2007 14:13:36 -0700, Fr************@googlemail.com wrote:
>On Mar 19, 7:33 pm, Keith Thompson <k...@mib.orgwrote:
>You seem to be arguing that the compiler should shut up about implicit
conversions that don't lose any information; in other words, you want
C's type checking to be even weaker than it is. You're certainly
entitled to that opinion, but it's not one many people share. If you
want a generic pointer type, use void*. There are plenty of
mechanisms that let you be sloppy with types if you do it
deliberately; *I* want the compiler to warn me if I do it
accidentally.

That's an interesting way to put it. Maybe that's what's happening -
I've been forced to use Java for the last couple of years, which has
this horrible over-bearing strict typing, so maybe I'm reacting
against that now and trying to push the liberating flexibility that C
gives me...

However, I'm not completely sure it should be the job of the compiler
and not some optional lint tool to pick through my code for places
where I might just have meant something else.
With most compilers, the "linting" level is controllable. Find a set
of switches you like. However, keep in mind that compilers actually
aren't always smart enough to distinguish warnings from errors.

--
Al Balmer
Sun City, AZ
Mar 19 '07 #30

P: n/a
On Mar 19, 10:33 pm, Ian Collins <ian-n...@hotmail.comwrote:
No, void* serves as a generic pointer, to have char* double up (and
don't forget it used to, before void* was added to the language) adds
complexity.
Surely a language with a superfluous extra pointer type has "more
complexity" than one without??

It's interesting to think - if void * was added to the language, at
the time it was added people must have thought there was a compelling
reason to put it in. It would be interesting to read the discussions
of the Powers That Be from that time to see what the original
rationale was.

Mar 19 '07 #31

P: n/a
On Mar 19, 4:50 pm, Francine.Ne...@googlemail.com wrote:
On Mar 19, 10:33 pm, Ian Collins <ian-n...@hotmail.comwrote:
No, void* serves as a generic pointer, to have char* double up (and
don't forget it used to, before void* was added to the language) adds
complexity.

Surely a language with a superfluous extra pointer type has "more
complexity" than one without??

It's interesting to think - if void * was added to the language, at
the time it was added people must have thought there was a compelling
reason to put it in. It would be interesting to read the discussions
of the Powers That Be from that time to see what the original
rationale was.
Track down a copy of the original ANSI C Standard - X3.159-1989. The
Rationale for the Committee's decisions is given in the "Rationale"
appendix. The rationale for void * is what people here have been
telling you repeatedly - to distinguish between a 'generic object
pointer' and a 'pointer to char'. To quote from the Rationale for
section 3.2.2.3

"The use of void * ("pointer to void") as a generic object pointer
type is an invention of the Committee. Adoption of this type is
stimulated by the desire to specify function prototype arguments that
either quietly convert arbitrary pointers (as in fread) or complain if
the argument type does not exactly match (as in strcmp)."

As I remember, this was one of the committee inventions which was
broadly welcomed for the clarity and reduction in confusion which it
brought to the language.
Mar 20 '07 #32

P: n/a
Ian Collins <ia******@hotmail.comwrites:
>[...]

I think you're looking at a copy of the 1990 standard. C99 dropped
implicit int.

Yes, "main()" is legal in C90 (Ian was partly mistaken on that point),
but in my opinion "int main(void)" is better.
Where I'm sitting, C == C99 :)
Ok, given that context, you're correct. (You might want to make that
a bit clearer, but we needn't re-open that debate.)

I see the smiley, but I'm ignoring it because I'm a humorless pedant.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 20 '07 #33

P: n/a
Fr************@googlemail.com writes:
On Mar 19, 7:33 pm, Keith Thompson <k...@mib.orgwrote:
>You seem to be arguing that the compiler should shut up about implicit
conversions that don't lose any information; in other words, you want
C's type checking to be even weaker than it is. You're certainly
entitled to that opinion, but it's not one many people share. If you
want a generic pointer type, use void*. There are plenty of
mechanisms that let you be sloppy with types if you do it
deliberately; *I* want the compiler to warn me if I do it
accidentally.

That's an interesting way to put it. Maybe that's what's happening -
I've been forced to use Java for the last couple of years, which has
this horrible over-bearing strict typing, so maybe I'm reacting
against that now and trying to push the liberating flexibility that C
gives me...

However, I'm not completely sure it should be the job of the compiler
and not some optional lint tool to pick through my code for places
where I might just have meant something else.
There are limits to how much I'm willing to trust the compiler to
figure out what I actually meant.

In particular, if I have a function that expects a char* argument, and
I call it with a struct foo* argument, that's a constraint violation.
The compiler shouldn't try to guess that I meant to insert a cast, and
quietly do the conversion for me implicitly. Such a guess would be
wrong; it's far more likely that what I *meant* to do was write
correct code in the first place.

When I was first exposed to C (many many years ago), I was horrified
by how lax it was about certain things (I called a function with the
wrong number of arguments, and the compiler didn't complain). That
particular problem is largely solved by prototypes, but I still see C
as an extremely permissive language. Flexibility is good, but failure
to diagnose obvious errors is not.

In most other languages I've used, there's no separate "lint" tool;
the compiler does all the checking (and may have an option to control
how strict it is).

I won't go beyond that because I don't want to start a language war.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 20 '07 #34

P: n/a
Fr************@googlemail.com writes:
On Mar 19, 10:33 pm, Ian Collins <ian-n...@hotmail.comwrote:
>No, void* serves as a generic pointer, to have char* double up (and
don't forget it used to, before void* was added to the language) adds
complexity.

Surely a language with a superfluous extra pointer type has "more
complexity" than one without??
[...]

No, I don't think it does.

C has the concept of a generic pointer type and the concept of a
pointer-to-character type. Using the same name for both of these
concepts doesn't reduce the complexity; it merely makes the existing
complexity more difficult to deal with.

strlen() takes a char* argument. Suppose I have an abstract type that
represents a dynamic string, and it's represented as a pointer. If I
accidentally call strlen() with one of my dynamic_string pointers, I
want the compiler to tell me I've made a mistake.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 20 '07 #35

P: n/a
On Mon, 19 Mar 2007 19:35:07 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote in comp.lang.c:
Fr************@googlemail.com said:
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.comwrote:
Francine.Ne...@googlemail.com wrote:

<snip>
#include <stdio.h>

Let's start by making it legal C:

void call(void *);
struct s { int a; };

main()
int main(void)
???

main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int.

Agreed. (In C99, it has to be int main() at the very least, but in C90
main() is legal.)
You may have a personal preference for
the more verbose form,

Yes. Adding the return type makes it C99-conforming, and using the
prototype form is good style, but these are choices, not requirements.
<rant>

I have absolutely no idea why you persist in your anti-C99 crusade.

Have you tried putting the effort into lobbying the suppliers of the
compilers you use, instead of putting it into denigrating those who
point out the latest standard?

As for the use of prototype form being "good style" and not a
requirement, your attitude is questionable at best, dangerous at
worst.

A responsible professional programmer always has coding requirements,
whether they are the policy of the organization he/she works for, or
self-imposed.

It is possible even today that a professional C programmer has to
write or maintain code for a pre-standard compiler which does not
accept prototypes in declarations and definitions.

Other than that remote scenario, any C programmer who chooses to write
non-prototype function declarations and definitions, rejecting the
single most important language improvement in almost 25 years of
standardization efforts, is either ignorant or an egotistical prima
donna.

There are many reasons why so many software/firmware projects these
days are late, cancelled, seriously over budget, and/or riddled with
defects. Many of those reasons are beyond the control of the
programmer, but several of the major ones are not.

The majority of programmers (software engineers, whatever) do not
actually know the standard and specification of their programming
language, whether it is C or anything else. Of course that does not
apply to the majority of clc regulars, but we hardly represent the
average C programmer.

And the majority of programmers, regardless of language, do not know
who their real customer is. It is not the manager, the company, the
client, even the user. The real customer of computer source code is
programmers, whether it is the author at some time in the future, a
maintenance programmer who has to update the code, or participants in
code inspections.

There are very true "matters of style" in C programming. As an
example, where to put the braces is one of them, absent an
organization's coding guide. Whether to put in optional braces, is
not.

Sadly, one of the greatest impediments to better software is
programmers' egos.

</rant>

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
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
Mar 20 '07 #36

P: n/a
Keith Thompson wrote:
>
When I was first exposed to C (many many years ago), I was horrified
by how lax it was about certain things (I called a function with the
wrong number of arguments, and the compiler didn't complain). That
particular problem is largely solved by prototypes, but I still see C
as an extremely permissive language. Flexibility is good, but failure
to diagnose obvious errors is not.
My experience was similar.

C's use of void* as a generic pointer type is an elegant solution to the
problem faced by all typed languages, writing a generic function.
My recent work has been split between four languages, C++, C, PHP and
JavaScript listed in order of "type strictness". At one extreme, a
strongly typed language requires a combination of function overloading
and generics and at the other, there isn't any type checking at all. C
fits in the middle, rudimentary type checking and a simple, elegant,
solution to the generic function: void*.

--
Ian Collins.
Mar 20 '07 #37

P: n/a
Jack Klein said:
On Mon, 19 Mar 2007 19:35:07 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote in comp.lang.c:
<snip>
>>
Yes. Adding the return type makes it C99-conforming, and using the
prototype form is good style, but these are choices, not
requirements.

<rant>

I have absolutely no idea why you persist in your anti-C99 crusade.
I don't know what makes you think I'm anti-C99. For example, I take
great care to ensure that all the new code I produce is C99-conforming
so that, when - or rather *if* - it eventually becomes mainstream, I
won't have a bunch of re-work to do.
Have you tried putting the effort into lobbying the suppliers of the
compilers you use, instead of putting it into denigrating those who
point out the latest standard?
I have not denigrated anyone for pointing out the latest standard. In
the very article to which you replied, I myself was pointing out the
latest standard. I think you may have replied in haste, Jack.

As for lobbying compiler suppliers, why bother? I have no particular axe
to grind with regard to C99. I see no particular need for it, but if it
ever happens I'll be ready. Why trouble myself to hurry along a change
that I consider pointless? If those who want C99 to become a reality
can't persuade their compiler suppliers to provide conforming C99
implementations, why should those same suppliers listen to those who
don't care either way?
As for the use of prototype form being "good style" and not a
requirement, your attitude is questionable at best, dangerous at
worst.
My attitude is that prototypes are good style but not required by the
language. This is the simple truth. I use prototypes myself, I advocate
them, I recommend them, and I wholeheartedly endorse them - but they
are *not* required by the rules of C. To claim otherwise would be
questionable at best, dangerous at worst.
[...] any C programmer who chooses to write
non-prototype function declarations and definitions, rejecting the
single most important language improvement in almost 25 years of
standardization efforts, is either ignorant or an egotistical prima
donna.
Nevertheless, it is not a requirement of the language.
The majority of programmers (software engineers, whatever) do not
actually know the standard and specification of their programming
language, whether it is C or anything else.
Then I suggest they learn. And one thing they need to learn is the
difference between a requirement and a recommendation. Prototypes are a
very, very good and important feature of C, and it is very, very, very
good style to use them, because they are such a boon to the compiler's
type-checking of arguments. But they are *not* a requirement.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 20 '07 #38

P: n/a
Fr************@googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
>To avoid casting every assignment of something other than a char*
to and from a char*.

I don't really follow this argument about minimizing number of casts.
casts. For example, the following code fails - I still need to
explicitly cast p to a (struct s*) to avoid a compile-time error.
No you don't. See modification below.
>
#include <stdio.h>

void call(void *);
struct s { int a; };

main()
{
struct s a;
a.a=1234;
call(&a);
return 0;
}

void call(void *p)
{
struct s *ps;

ps = p; /* alternatively use local initialization */
printf("%d\n", ps->a); /* look ma, no casts */
printf("%d\n",p->a);
}

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews

--
Posted via a free Usenet account from http://www.teranews.com

Mar 20 '07 #39

P: n/a
Keith Thompson wrote:
>
.... snip ...
>
When I was first exposed to C (many many years ago), I was horrified
by how lax it was about certain things (I called a function with the
wrong number of arguments, and the compiler didn't complain). That
particular problem is largely solved by prototypes, but I still see
C as an extremely permissive language. Flexibility is good, but
failure to diagnose obvious errors is not.
I somewhat parallel your experience. Before C89 appeared I
absolutely refused to use it, because of its insecurities. At
least I could see exactly what was going on in assembly. All else
used Pascal.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 20 '07 #40

P: n/a
<Fr************@googlemail.comwrote in message
news:11**********************@n59g2000hsh.googlegr oups.com...
main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int. You may have a personal
preference for the more verbose form, but that doesn't make it
invalid. I've borrowed a copy of the ANSI Standard from the
library, so now I too can quote chapter & verse :)
That's C89/C90; C99 deprecated implicit int. There's no reason, short of
laziness, to leave off the int, and there's reason enough not to just to be
compatible with C99 if you ever end up with a compiler that supports it ;)

BTW, go grab a copy of n1124.pdf; that'll be more useful to you than a bunch
of dead trees since it's searchable, and if you lose it you just burn a few
more bits instead of having to pay the library...
void call(void *p)
{
printf("%d\n",p->a);

struct s *ps = p;

A rose by any other name... I don't see that this gains anything in
terms of clarity or brevity over "printf("%d\n",((struct s*)p)->a);" -
in fact it just leads to an additional pointer floating around.
Any decent compiler will end up generating the exact same code for both
snippets. However, one is easier to understand and less likely to contain
bugs.

Remember that the primary audience for code is _not_ the compiler but rather
the coder who has to maintain the project after you. Clarity and
correctness are all that is important for 99% of code, and brevity is not
only irrelevant but also counter-productive.

(Yes, there is that 1% where performance is critical, but until you can
_prove_ there's no way to coerce your compiler to emit faster code for clear
source and there's no better algorithm available, assume you're not in that
1%.)
>Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning
level high enough.

As this conversion is lossless, I don't see why the compiler should
take it upon itself to warn me about it!
Because it's most likely a bug, even when it's lossless.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Mar 20 '07 #41

P: n/a
<Fr************@googlemail.comwrote in message
news:11**********************@y66g2000hsf.googlegr oups.com...
On Mar 19, 7:33 pm, Keith Thompson <k...@mib.orgwrote:
>You seem to be arguing that the compiler should shut up about
implicit conversions that don't lose any information; in other
words, you want C's type checking to be even weaker than it is.
You're certainly entitled to that opinion, but it's not one many
people share. If you want a generic pointer type, use void*.
There are plenty of mechanisms that let you be sloppy with
types if you do it deliberately; *I* want the compiler to warn me
if I do it accidentally.

That's an interesting way to put it. Maybe that's what's happening -
I've been forced to use Java for the last couple of years, which has
this horrible over-bearing strict typing, so maybe I'm reacting
against that now and trying to push the liberating flexibility that C
gives me...
C, unlike Java, gives you the power to shoot yourself in the foot in a
thousand different ways; however, one must consider whether the fact you
have that power means that you should do so. For instance, if you need to
cast, odds are you're doing something wrong or at least unportable. That
doesn't mean never cast, but it does mean that if the compiler is warning
you, you should generally assume it's right. Blindly adding a cast will
usually just hide a bug that will bite you later.
However, I'm not completely sure it should be the job of the compiler
and not some optional lint tool to pick through my code for places
where I might just have meant something else.
If you don't like your compiler being helpful, either turn off or ignore the
warnings. The rest of us, however, prefer to have tools tells us where our
bugs are as soon as we write them, as opposed to trying to figure out where
they are long after we've forgotten that chunk of code.

Sure, there are warnings that are just plain wrong. There's well-known
idioms that silence them in nearly all cases. For instance, most decent
compilers will complain about "if (x=y)" but not "if ((x=y)!=0)".

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Mar 20 '07 #42

P: n/a
<Fr************@googlemail.comwrote in message
news:11*********************@l77g2000hsb.googlegro ups.com...
Maybe you're right! I guess the issue I have is that I'm not really
convinced that void * should exist at all. I mean, char * can double
up perfectly well as both a pointer to char and a "generic pointer",
but for some reason if you work with char * you need to do a lot of
extra explicit casting.
All casting is explicit. The reason you have to cast a char* to other
things is because you've told the compiler you have a pointer to char; if
you want to use it for something else, you have to make that clear. OTOH,
when you use a void* you're telling the compiler you have a pointer to
something unknown, and converting that to, say, a pointer to int doesn't
need a cast.

When you "double up" on the meaning of constructs, you're introducing
ambiguity, and ambiguity breeds bugs. Differentiating between char* and
void* allows you to remove ambiguity, and that's always a good thing.
At the very least, there seems to be a lot of duplication between
the function of void * and char *, whereas I always think minimality
and efficiency is a virtue.
And the supposed duplication you speak of was intentionally added to C due
to the problems with using char* for pointers to things other than chars.
Not needing to cast a void* improves programmer efficiency and code
maintainability by making the intent clearer. Remember, the primary
audience for your code is other programmers (or even yourself), not the
compiler.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com

Mar 20 '07 #43

P: n/a
On Mar 20, 2:38 am, Jack Klein <jackkl...@spamcop.netwrote:
As for the use of prototype form being "good style" and not a
requirement, your attitude is questionable at best, dangerous at
worst.
Sorry I've set off this firestorm!

I think Jack Klein has got the wrong end of the stick here. My own
opinion is that prototypes are an extremely useful device, and I
certainly use them most of the time. However, the discussion here had
been about main(), and the things in issue were whether it's better to
explicitly say main() returns int, and whether it's better to define
main(void) to make intentions clearer than main(). So prototyping
isn't really relevant - after all, I don't think anyone would go so
far as to include a prototype for main!

Mar 20 '07 #44

P: n/a
Fr************@googlemail.com writes:
On Mar 20, 2:38 am, Jack Klein <jackkl...@spamcop.netwrote:
>As for the use of prototype form being "good style" and not a
requirement, your attitude is questionable at best, dangerous at
worst.

Sorry I've set off this firestorm!

I think Jack Klein has got the wrong end of the stick here. My own
opinion is that prototypes are an extremely useful device, and I
certainly use them most of the time. However, the discussion here had
been about main(), and the things in issue were whether it's better to
explicitly say main() returns int, and whether it's better to define
main(void) to make intentions clearer than main(). So prototyping
isn't really relevant - after all, I don't think anyone would go so
far as to include a prototype for main!
"int main(void)" is a prototype, even if it's part of the definition
of main (i.e., immediately followed by '{'). A definition is a
declaration; a prototype is a function declaration that includes the
types of the parameters (none, in this case).

A *separate* prototype for main is rarely useful.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 20 '07 #45

P: n/a
Fr************@googlemail.com said:
I don't think anyone would go so
far as to include a prototype for main!
I always do. If I'm taking args, it's unavoidable anyway, and even if
I'm not, it's only four characters more, for heaven's sake:

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 21 '07 #46

P: n/a
On Mar 21, 8:19 am, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:
I don't think anyone would go so
far as to include a prototype for main!

I always do. If I'm taking args, it's unavoidable anyway, and even if
I'm not, it's only four characters more, for heaven's sake:
Ah, sorry, I meant a prototype separate from the function definition.
It seems to me this is definitely unneeded, as the compiler knows
there are only two possible signatures for main, and if main is called
before its definition appears then there can never be any doubt which
is the right one to pick: one takes arguments and the other doesn't.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Mar 21 '07 #47

P: n/a
On Mar 19, 2:28 pm, Francine.Ne...@googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.comwrote:
To avoid casting every assignment of something other than a char* to and
from a char*.

I don't really follow this argument about minimizing number of casts.
For example, the following code fails - I still need to explicitly
cast p to a (struct s*) to avoid a compile-time error.

#include <stdio.h>

void call(void *);
struct s { int a; };

main()
{
struct s a;
a.a=1234;
call(&a);
return 0;

}

void call(void *p)
{
printf("%d\n",p->a);
warning i guess here.
p->a without telling compiler what kind of pointer is p is not legal.
if you want to use void * like this make it

void call(void *p)
{
struct s* t = p;
printf("%d\n",t->a);
}

This is the correct way i guess.

CMIIW
--psr
>
}
--
Ian Collins.

Mar 21 '07 #48

P: n/a
On Mon, 19 Mar 2007 16:52:20 -0500, "Stephen Sprunk"
<st*****@sprunk.orgwrote:
><Fr************@googlemail.comwrote in message
news:11**********************@n59g2000hsh.googleg roups.com...
>main() is perfectly valid C - it defines main to be a function taking
no arguments and returning int. You may have a personal
preference for the more verbose form, but that doesn't make it
invalid. I've borrowed a copy of the ANSI Standard from the
library, so now I too can quote chapter & verse :)

That's C89/C90; C99 deprecated implicit int. There's no reason, short of
laziness, to leave off the int, and there's reason enough not to just to be
compatible with C99 if you ever end up with a compiler that supports it ;)

BTW, go grab a copy of n1124.pdf; that'll be more useful to you than a bunch
of dead trees since it's searchable, and if you lose it you just burn a few
more bits instead of having to pay the library...
>void call(void *p)
{
printf("%d\n",p->a);

struct s *ps = p;

A rose by any other name... I don't see that this gains anything in
terms of clarity or brevity over "printf("%d\n",((struct s*)p)->a);" -
in fact it just leads to an additional pointer floating around.

Any decent compiler will end up generating the exact same code for both
snippets. However, one is easier to understand and less likely to contain
bugs.

Remember that the primary audience for code is _not_ the compiler but rather
the coder who has to maintain the project after you. Clarity and
correctness are all that is important for 99% of code, and brevity is not
only irrelevant but also counter-productive.
i can see clear you on above have wrong
>(Yes, there is that 1% where performance is critical, but until you can
_prove_ there's no way to coerce your compiler to emit faster code for clear
source and there's no better algorithm available, assume you're not in that
1%.)
>>Now change call to

void call( char* );

And see what your compiler has to say. If you don't get two
incompatible type warnings, you haven't turned your warning
level high enough.

As this conversion is lossless, I don't see why the compiler should
take it upon itself to warn me about it!

Because it's most likely a bug, even when it's lossless.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
Mar 21 '07 #49

This discussion thread is closed

Replies have been disabled for this discussion.