473,776 Members | 2,201 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
<Fr************ @googlemail.com wrote in message
news:11******** **************@ n59g2000hsh.goo glegroups.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
<Fr************ @googlemail.com wrote in message
news:11******** **************@ y66g2000hsf.goo glegroups.com.. .
On Mar 19, 7:33 pm, Keith Thompson <k...@mib.orgwr ote:
>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
<Fr************ @googlemail.com wrote in message
news:11******** *************@l 77g2000hsb.goog legroups.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
On Mar 20, 2:38 am, Jack Klein <jackkl...@spam cop.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
Fr************@ googlemail.com writes:
On Mar 20, 2:38 am, Jack Klein <jackkl...@spam cop.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_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 20 '07 #45
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
On Mar 21, 8:19 am, Richard Heathfield <r...@see.sig.i nvalidwrote:
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
On Mar 19, 2:28 pm, 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.

#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
On Mon, 19 Mar 2007 16:52:20 -0500, "Stephen Sprunk"
<st*****@sprunk .orgwrote:
><Fr*********** *@googlemail.co mwrote in message
news:11******* *************** @n59g2000hsh.go oglegroups.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
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!

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 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
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...
0
10117
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
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
8948
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7467
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
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...
1
4027
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.