473,776 Members | 2,173 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

void * vs char *

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
48 16975
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.co mwrote:
Francine.Ne...@ googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.co mwrote:
>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
Fr************@ googlemail.com writes:
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.co mwrote:
>Francine.Ne... @googlemail.com wrote:
On Mar 19, 12:11 am, Ian Collins <ian-n...@hotmail.co mwrote:
>>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_Keit h) 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
Fr************@ googlemail.com said:
On Mar 19, 10:39 am, Ian Collins <ian-n...@hotmail.co mwrote:
>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
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
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
[...]

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
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
incompatibl e 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
Fr************@ googlemail.com said:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
>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
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
Fr************@ googlemail.com wrote:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
>>Nevertheles s, 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
On Mar 19, 7:59 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
Francine.Ne...@ googlemail.com said:
On Mar 19, 7:35 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
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

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

Similar topics

4
2547
by: Pokerkook | last post by:
Hello, If anybody could help me with this I would greatly appreciate it. Or at least tell me why I get the output of this garbage: 49 49 10 49 52
1
2326
by: Steffen Fiksdal | last post by:
I have a function that base64 decodes some data. The incoming data is received as "const char*" (BASE64 characters are always safe ASCII characters, meaning they will always fit in a signed char positive range). The resulting decoded data is placed in memory, and the function exposes an "unsigned char*" to the caller. What does ANSI C say (if anything) about what kind of pointer is the correct one to use for...
33
3187
by: baumann.Pan | last post by:
hi all, i want to get the address of buf, which defined as char buf = "abcde"; so can call strsep(address of buf, pointer to token);
1
3283
by: lovecreatesbeauty | last post by:
There is a warning/(error? I remember it is an error for line 10 on some compilers before. At least on g++, it is an error.) for line 10. I first read a similar example from `Expert C Programming -- Deep Secrets, Perter van der Linden'. But I wonder why line 9 is ok but line 10 is illegal? Is what Keith Thompson said in another post also helpful to understand this question: "... The implicit conversion rule applies only to void*, not...
33
3667
by: Mark P | last post by:
A colleague asked me something along the lines of the following today. For some type X he has: X* px = new X; Then he wants to convert px to a char* (I'm guessing for the purpose of serializing the object array). I can think of three ways to do this:
18
10433
by: planetzoom | last post by:
Given the following code: #include <stdio.h> int main(void) { char array = "What is your favorite car?"; void *vp = &array; printf("%s\n", vp);
17
2293
by: mdh | last post by:
In trying to understand the issue, I wrote this; #include <stdio.h> void f_output(char arg1, int limit); int main () { f(); return 0; }
160
5712
by: raphfrk | last post by:
Is this valid? int a; void *b; b = (void *)a; // b points to a b += 5*sizeof(*a); // b points to a a = 100;
28
1824
by: junky_fellow | last post by:
Guys, Consider a function func(void **var) { /* In function I need to typecast the variable var as (int **) I mean to say, I need to access var as (int **) }
4
5070
by: Amera | last post by:
hello , I have written these codes : Mydll file : Mydll.h #ifndef MYDLL_H
0
9625
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9459
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10282
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10056
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9920
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6721
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5365
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3619
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2857
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.