LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-28-2009, 10:01 AM   #1
charlitos
Member
 
Registered: Feb 2009
Posts: 51

Rep: Reputation: 16
void pointers


I was checking out some examples where I noticed there are a few void pointers.

like

Code:
void * myvar;
then this variable is used to point to anything.

Code:
myvar = &data;
is it ok to do this? If i know that probably I will need the same variable to point to some reference or the other, I guess it is the right thing to do right?

Are there any other steps involved? Like should I try to allocate memory dynamically for this void pointer before I pass a reference to it? Or should I just do it straight forward as in the example.

Are void pointers even a good programming practice at all?
 
Old 03-28-2009, 11:21 AM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by charlitos View Post
I was checking out some examples where I noticed there are a few void pointers.

like

Code:
void * myvar;
then this variable is used to point to anything.

Code:
myvar = &data;
is it ok to do this? If i know that probably I will need the same variable to point to some reference or the other, I guess it is the right thing to do right?

Are there any other steps involved? Like should I try to allocate memory dynamically for this void pointer before I pass a reference to it? Or should I just do it straight forward as in the example.

Are void pointers even a good programming practice at all?
No, they are not.
 
Old 03-28-2009, 11:32 AM   #3
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by charlitos View Post
I was checking out some examples where I noticed there are a few void pointers.

like

Code:
void * myvar;
then this variable is used to point to anything.

Code:
myvar = &data;
is it ok to do this?
It's so-so... It will work, but not recommended, unless there's a special reason. But if you to ask here, you don't have such a special reason.

Quote:
Originally Posted by charlitos View Post
If i know that probably I will need the same variable to point to some reference or the other, I guess it is the right thing to do right?
I don't get what you mean by this question.

Quote:
Originally Posted by charlitos View Post
Are there any other steps involved? Like should I try to allocate memory dynamically for this void pointer before I pass a reference to it? Or should I just do it straight forward as in the example.
No, you don't need to allocate memery for it if you use it to refer to the value of data.

Quote:
Originally Posted by charlitos View Post
Are void pointers even a good programming practice at all?
No, they are not. But sometimes there is no other way. Well, there actually would be another way. But in those special cases a char * (or essentially any other type) could as well be used. But the keyword void makes it more clear that it is a special case for a programmer that reads the code. So, essentially void* only exist for clarity in cases we would rather not have..

Really, once in memory in the running program, a pointer to int is no different that a pointer to a 1Mb string or a pointer-to-a-pointer-to-a-struct. They are just all 4-byte numbers (or 8-byte if you have such a fancy Itanium or AMD64 CPU and you are running a 64-bit OS on it). Those 4-byte number refer to an address in memory.

But to the C-compiler it does matter a bit what type a pointer will point to. Not because the compiler needs that, but for programmers it is convenient. If programmers make a mistake and a use a pointer-to-int where it should be a pointer to char for example. The compiler will issue a warning or an error, thus pointing the programmer to a mistake he (may have) made. I the programmer (and the libraries) only used pointers-to-void, the compiler can not know if it is a mistake. Such mistake can be easily made because using pointers can be tricky. So those errors/warnings are A Good Thing. And you only get them if you avoid void*.

There's another reason for typed pointer ("typed" means: non-void, but int*,char*,...whatever): If you have more of an item (say, int) in a row (i.e. like a dynamically allocated array), you will probably want to access them with an index, or loop over them some way. E.g.:
Code:
#define NUMBER_OF_INTS 18

int *mypointer, *temppointer;
int i;

mypointer = calloc(NUMBER_OF_INTS, sizeof(int));
temppointer = mypointer;
for (i=0; i<NUMBER_OF_INTS, ++i) {
   *temppointer = 3 * i;
   ++mypointer;
}
In the bold line the pointer is increase to point to place where the next int can be stored.

This would go awfully wrong if you would have declared temppointer as a void*!

Why?

Because if it was a void* the compiler would not know it was pointing to int's and then ++mypointer would increase the pointer by one byte, while int's are 4 bytes. So 3 bytes of the previous integer would be overwritten by bytes from the second. If you would later print out the int's stored, would get totally wrong numbers and it would be hard to imagine it was your own fault because the code looks deceptively correct. Such an bug in a real world program would be hard to find, or even go undetected until some user or customer complains about wrong and unpredictable results...

And this happened only because the programmer (me, in this case :-) used void* instead of the correct int *. With a pointer to int, the compiler would silently, automatically and conveniently do the right thing and increase the pointer with 4 when it sees "++temppointer", and the code would be correct.

If you think: "hey, void-pointer can point to anything. That is nice! I can use them for anything!" then you are going to wrong way. So, just don't use them, unless... (but then you would know).

Recently I found video's of (C-) programming lectures by Richard Buckland. If you google him, you get the impression he's probably the most popular lecturer/teacher on earth.

Here's a lecture by him about pointers: http://www.youtube.com/watch?v=Rxvv9krECNw

(not about void pointers though, but pointer in general).

Last edited by Hko; 03-28-2009 at 12:31 PM.
 
Old 03-28-2009, 11:58 AM   #4
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
* accidental double post *
Please ingore..

Last edited by Hko; 03-28-2009 at 12:00 PM.
 
Old 03-28-2009, 12:17 PM   #5
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
As a historical note, one of the motivations for moving from the B (or bcpl) language to C was that bcpl did not implement any data types, and pointer usage often went horribly wrong. B was an improvement over A (or asm), but the addition of data types made C much more usable.
 
Old 03-28-2009, 12:27 PM   #6
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
[off-topic]

Quote:
Assiduously eschew obfuscation.
-- Paraphrased from Richard F. Davidson's sig on GROKLAW
..except for the sole sake of obfucation itself of course :-)
 
Old 03-28-2009, 12:56 PM   #7
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
Just out of interest, would this yield a correct result? I mean correct it the sense that it points to the next integer.

void *mypointer;

mypointer = &my_int;
(int*) mypointer++;

jlinkels
 
Old 03-28-2009, 01:34 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by jlinkels View Post
Just out of interest, would this yield a correct result? I mean correct it the sense that it points to the next integer.

void *mypointer;

mypointer = &my_int;
(int*) mypointer++;

jlinkels
I don't want to break my head over precedence, so I would rather write it as

Code:
((int *)mypointer)++
, and this will bring the correct result. I.e. first make sure the pointer is correct(pointer to int), then increment.
 
Old 03-28-2009, 02:03 PM   #9
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by jlinkels View Post
Just out of interest, would this yield a correct result? I mean correct it the sense that it points to the next integer.

void *mypointer;

mypointer = &my_int;
(int*) mypointer++;

jlinkels
IIRC no and should result in a compiler error that you are incrementing a void pointer. A cast has lower order of precedence than a postfix increment.
 
Old 03-28-2009, 02:45 PM   #10
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 179Reputation: 179
off-topic, continued

Quote:
Originally Posted by Hko View Post
..except for the sole sake of obfucation itself of course :-)
At least some obfuscated C programs actually do something. I couldn't get that one to compile.

For some gloriously obfuscated C programs, go here.
 
Old 03-28-2009, 03:48 PM   #11
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,195

Rep: Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043Reputation: 1043
Quote:
Originally Posted by dmail View Post
IIRC no and should result in a compiler error that you are incrementing a void pointer. A cast has lower order of precedence than a postfix increment.
The parentheses, yes... thanks.

jlinkels
 
Old 03-30-2009, 11:42 AM   #12
charlitos
Member
 
Registered: Feb 2009
Posts: 51

Original Poster
Rep: Reputation: 16
Question

what if I want to create a pointer that under certain conditions will be pointing to 2 similar structs, in one case a sockaddr_in and on the other case a sockaddr_in6.

?
 
Old 03-30-2009, 01:33 PM   #13
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by charlitos View Post
what if I want to create a pointer that under certain conditions will be pointing to 2 similar structs, in one case a sockaddr_in and on the other case a sockaddr_in6.

?
then you'll have to typecast each time you use it. And you'll have to keep track of what type your pointer points to. It is possible, but i would prefer to avoid it unless absolutely necessary.
 
Old 03-30-2009, 02:54 PM   #14
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by millgates View Post
then you'll have to typecast each time you use it. And you'll have to keep track of what type your pointer points to. It is possible, but i would prefer to avoid it unless absolutely necessary.
Well, the following approach is possible:

Code:
typedef struct
  {
  // enter fields for sockaddr_in here
  } sockaddr_in_type;


typedef struct
  {
  // enter fields for sockaddr_in6 here
  } sockaddr_in6_type;

typedef struct
  {
  sockaddr_in_type  *sockaddr_in_ptr;
  sockaddr_in6_type *sockaddr_in6_ptr;
  } combined_ptr_type;

...

combined_ptr_type combined_ptr = {.sockaddr_in_ptr = NULL, .sockaddr_in6_ptr = NULL};

...

combined_ptr.sockaddr_in_type = <actual_object_address>;

...

if(combined_ptr.sockaddr_in_ptr != NULL)
  {
  // sockaddr_in case
  }
else if(combined_ptr.sockaddr_in6_ptr != NULL)
  {
  // sockaddr_in6 case
  }
, i.e. the field which is not NULL tells which kind of object it is.

The cost is one machine word - negligible today.
 
Old 03-30-2009, 04:09 PM   #15
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
Quote:
Originally Posted by Sergei Steshenko View Post
Well, the following approach is possible: [...]
Doesn't anybody use unions any more? I'm starting to feel a bit like a dinosaur here...

Back on topic: IMO, void pointers are quite useful in the right conditions. I agree that they need to be used only where necessary, and not as a catch-all convenience but I have several classes where their polymorphic properties would not be possible without void pointers. Bad practice? I think not, just another tool.
 
  


Reply

Tags
pointer, void


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Generic Function Pointers In C And Void * LXer Syndicated Linux News 0 02-22-2009 07:10 PM
what are void pointers used for? aditya1 Linux - General 10 03-14-2005 03:06 PM
void pointers suchi_s Programming 9 11-08-2004 03:05 PM
void main(void) linuxanswer Programming 4 10-26-2003 12:37 AM
void foo(void) and void foo() lackluster Programming 9 02-15-2003 10:57 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:43 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration