473,761 Members | 1,784 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about void pointers

Is this valid?

int a[20];
void *b;

b = (void *)a; // b points to a[0]

b += 5*sizeof(*a); // b points to a[5]

a[5] = 100;

printf( "%d\n" , *((int *)b) ); // prints 100

If so, if a had been a struct, would it still work?

Is there a possibility that the array could contain some padding, so
rather than sizeof, the assignment would be

b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));

which seems more more complex.

Would any padding be incorporated into sizeof anyway?
Sep 16 '08
160 5674
On Sep 16, 7:59 pm, s0s...@gmail.co m wrote:
On Sep 16, 11:51 am, raph...@gmail.c om wrote:
On Sep 16, 4:20 pm, vipps...@gmail. com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.

No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Sep 16 '08 #11
On Sep 16, 12:06*pm, vi******@gmail. com wrote:
On Sep 16, 7:59 pm, s0s...@gmail.co m wrote:
On Sep 16, 11:51 am, raph...@gmail.c om wrote:
On Sep 16, 4:20 pm, vipps...@gmail. com wrote:
>b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly..
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.

You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.

Sebastian

Sep 16 '08 #12
vi******@gmail. com writes:
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.
I admit that, occasionally, I've used pointer arithmetic on void
* in cases where GCC is the only compiler that matters. (Code
inside the Linux kernel is one example.) The nice thing about
doing it that way is that it avoids having to insert additional
casts, which are ugly.

I wouldn't do it in a place where portability matters.
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield
Sep 16 '08 #13
Richard<rg****@ gmail.comwrites :
vi******@gmail. com writes:
>On Sep 16, 7:13 pm, sh.vi...@gmail. com wrote:
>>when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.
If x isn't initialized, referring to its value invokes undefined
behavior. It's likely, but by no means certain, that the behavior
would be *as if* it were incremented. It's also possible, on some
systems, that x could have a value such that attempting to read it
causes a program crash. (Before you ask, no, I don't have an
example.)
>Here's proof:

Proof of nothing. You are, again, being purposely difficult.
The ++ operator increments its operand by 1, by definition. The
question is, 1 what? In the case of:

long int *x = some_value;
x ++;

it advances it by 1 long int object, i.e., causes it to point to the
next adjacent long int object in memory, assuming that such an object
exists; it can also legally point just past the end of an array.
>long int i[1], *p = i, *q = &i[1];
Note that evaluating &i[1] is ok, and equivalent to i+1, but only
because of a special-case rule; see C99 6.5.3.2p3.
>printf("%d\n ", (int)(q - p));

Will always print 1.
Yes, because of the way pointer subtraction is defined.
And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p ++);
printf("%u\n",p ++);
printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.
You're using "%u" to print pointer values. Surely you know that
invokes undefined behavior, and I know of common real-world systems
where it won't work (e.g., where int is 32 bits and pointers are 64
bits). You're also using "%u" to print an int value; if you had
written
printf("%u\n", (unsigned)(p - q));
that wouldn't be no problem. (Actually printing a non-negative int
value using %u is probably ok, due to another special-case rule, but
there's no point in taking advantage of that fact.) Finally, p starts
as a pointer to the first and only element of a 1-element array. You
increment it twice, causing it to point *past* the end of the array.
Yet another instance of undefined behavior that happens to "work" on
your system -- and it wasn't even necessary to demonstrate your point.

You're making unwarranted (though commonly valid) assumptions about
pointer representations and conversions. This program:

#include <stdio.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
printf("%d %d %d\n",
(int)sizeof(lon g), (int)(q - p), (int)q - (int)p);
return 0;
}

will typically print "4 1 4" on a system where sizeof(long)==4 . I've
worked on a real-world system where it would print "8 1 1" due to a
rather unusual pointer representation.

And the thing is, all this undefined behavior wasn't even necessary to
demonstrate your point. Here's a portable program (with
implementation-defined but not undefined behavior) that illustrates
what you're trying to talk about:

#include <stdio.h>
#include <assert.h>
int main(void)
{
long array[10];
long *p = &array[0];
long *q = &array[1];
int diff = q - p;
int byte_diff = (char*)q - (char*)p;
printf("p = %p\n", (void*)p);
printf("q = %p\n", (void*)q);
printf("sizeof( long) = %d\n", (int)sizeof(lon g));
printf("diff = %d\n", diff);
printf("byte_di ff = %d\n", byte_diff);
assert(diff == 1);
assert(byte_dif f == sizeof(long));
return 0;
}

On my system, I get:

p = 0xbfce19ac
q = 0xbfce19b0
sizeof(long) = 4
diff = 1
byte_diff = 4

And here's the point:

p++ increments p by 1. If p is a long*, this means that it advances
the memory location to which it points by 1 long, or by sizeof(long)
bytes.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #14
Richard wrote:
vi******@gmail. com writes:
On Sep 16, 7:13 pm, sh.vi...@gmail. com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.
Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.
On real, widely used machines, attempting to access an unitialized
pointer value can cause your program to abort before that value ever
gets a chance to be incremented.

....
long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.

And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p ++);
printf("%u\n",p ++);
That is undefined behavior by reason of trying to print an pointer
value using a format string that calls for an unsigned integer. The
behavior is technically meaningless, though in practice it will
produce much the same effect as casting the the pointer value to
unsigned int on many systems. You could have demonstrated your point
without undefined behavior by using uintptr_t; why didn't you?
printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.
Yes, but that difference has no portable meaning, and the
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.

It is only the third printf() that provides a meaningful answer to the
question of how big the difference is between p and q is. You'll get a
different answer, if you cast both pointer to char* before subtracting
them. On your machine that answer will probably be 4, but that answer
is to a different question,
Sep 16 '08 #15
ra*****@gmail.c om writes:
On Sep 16, 4:20 pm, vipps...@gmail. com wrote:
>b = ((unsigned char *)b) + 5 * sizeof *a;

I see, got to switch to char * so that it can be incremented properly.
>Yes, but by using the offsetof() macro in <stddef.h>

I meant to point to the structure.

struct st { int val; } a[100];

void *b;

a[5].val = 100;

b = a;
b = ((unsigned char *)b) + 5 * sizeof *a;

printf( "%d\n" , b->val );
If you want to point to a structure, why not just use a
pointer-to-structure rather than a pointer-to-void?

But if you must use void* for some reason, I think this is more
straightforward :

b = (struct st*)b + 5;

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 16 '08 #16
On Sep 16, 9:46*pm, Keith Thompson <ks...@mib.orgw rote:
sh.vi...@gmail. com writes:
On Sep 16, 8:15*pm, raph...@gmail.c om wrote:
Is this valid?

*In my opinion this
extension is a bad idea; it can be convenient, but it doesn't give you
anything you can't do by other means, it has some bizarre
consequences,

I think Bus Error,on some machines, is one of those consequences.
Thanks all for gcc info. I thought gcc didn't take anything as stride
value for void pointers
--
vIpIn
Sep 16 '08 #17
Keith Thompson <ks***@mib.orgw rites:
Richard<rg****@ gmail.comwrites :
>vi******@gmail. com writes:
>>On Sep 16, 7:13 pm, sh.vi...@gmail. com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.

If x isn't initialized, referring to its value invokes undefined
behavior. It's likely, but by no means certain, that the behavior
would be *as if* it were incremented. It's also possible, on some
systems, that x could have a value such that attempting to read it
causes a program crash. (Before you ask, no, I don't have an
example.)
Whatever. x will be incremented.
>
>>Here's proof:

Proof of nothing. You are, again, being purposely difficult.

The ++ operator increments its operand by 1, by definition. The
question is, 1 what? In the case of:

long int *x = some_value;
x ++;

it advances it by 1 long int object, i.e., causes it to point to the
next adjacent long int object in memory, assuming that such an object
exists; it can also legally point just past the end of an array.
>>long int i[1], *p = i, *q = &i[1];

Note that evaluating &i[1] is ok, and equivalent to i+1, but only
because of a special-case rule; see C99 6.5.3.2p3.
>>printf("%d\n" , (int)(q - p));

Will always print 1.

Yes, because of the way pointer subtraction is defined.
>And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p ++);
printf("%u\n",p ++);
printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.

You're using "%u" to print pointer values. Surely you know that
invokes undefined behavior, and I know of common real-world systems
Garbage. On my machine it prints a 32 bit value. Pointers are values
which I can printf and see and they correspond to physical memory
locations. Its a number get over it.
Sep 16 '08 #18
ja*********@ver izon.net writes:
Richard wrote:
>vi******@gmail. com writes:
On Sep 16, 7:13 pm, sh.vi...@gmail. com wrote:
when you do
--char *c; c++; ==c is incremented by 1
--long int *x; x++ ==x is incremented by 4.

Wrong, assuming x was initialized, it would be incremented by 1.

Even if it wasnt initialised it would be incremented by something.

On real, widely used machines, attempting to access an unitialized
pointer value can cause your program to abort before that value ever
gets a chance to be incremented.
Never come across it. Which machines? I do believe you btw. However in
the great majority (99.9999%= of machines on this planet it will indeed
by incremented.
>
...
long int i[1], *p = i, *q = &i[1];
printf("%d\n", (int)(q - p));

Will always print 1.

And the following:

int main() {
long int i[1], *p = i, *q = &i[1];
printf("%u\n",p ++);
printf("%u\n",p ++);

That is undefined behavior by reason of trying to print an pointer
value using a format string that calls for an unsigned integer. The
behavior is technically meaningless, though in practice it will
produce much the same effect as casting the the pointer value to
unsigned int on many systems. You could have demonstrated your point
without undefined behavior by using uintptr_t; why didn't you?
> printf("%u\n", (int)(p - q));

}

The first printf gives me:

3214862936

And the second:

3214862940

Now, that is 4. On my machine.

Yes, but that difference has no portable meaning, and the
It has a meaning. The VALUE of p is incremented by 4. On my machine. And
probably the OPs.
implementation-specific meaning on your machine is (probably) only
that p and q point at locations 4 bytes apart; that doesn't say
anything about how much has been added to q to get the current value
of p.

It is only the third printf() that provides a meaningful answer to the
question of how big the difference is between p and q is. You'll get a
different answer, if you cast both pointer to char* before subtracting
them. On your machine that answer will probably be 4, but that answer
is to a different question,
--
Sep 16 '08 #19
s0****@gmail.co m wrote:
On Sep 16, 12:06 pm, vi******@gmail. com wrote:
>On Sep 16, 7:59 pm, s0s...@gmail.co m wrote:
>>On Sep 16, 11:51 am, raph...@gmail.c om wrote:
On Sep 16, 4:20 pm, vipps...@gmail. com wrote:
b = ((unsigned char *)b) + 5 * sizeof *a;
I see, got to switch to char * so that it can be incremented properly.
No, to unsigned char *. But if your compiler can do it with the void
*, then do it with the void *. It's probably specialized for that kind
of stuff anyway.
You can have the "worst advice of the month" clc award.
You have two options, do it portably, or do it with an extension, with
absolutely no loss in efficiency or size, and you advice to choose the
extension.

Well, perhaps the OP doesn't need portability (or at least not this
kind of portability). Besides, void * seems more natural for this kind
of task.
"This kind of task" was an artificial bit of code specifically
written to experiment with manipulating pointers. An investigative
doodle, nothing more.

Personally, I'm not as ready as vippstar is to give you the
award; we're only halfway through the month. But I'd be surprised
if you weren't on the ballot a couple weeks from now. Have you
chosen your running mate yet?

--
Er*********@sun .com

Sep 16 '08 #20

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

Similar topics

11
2576
by: kazack | last post by:
I am under the the impression that a variable is what is stored in a memory address and a pointer is the memory address of the variable? I was looking to use a function that does not return a value void whatever(whatever) and not have a variable global but in main and change the value in the void whatever function. using namespace std; void whatever(int);
18
2129
by: steve | last post by:
I'm trying to create a structure of three pointers to doubles. For which I have: typedef struct { double *lst_t, *lst_vc, *lst_ic; } last_values; I then need to allocate space for last_values as well as assign the value of a pointer to the assigned space. Which I think I'm doing by using:
14
1344
by: streamkid | last post by:
i'm a learning newbie at c++... and i have the following question... reading some source code, i saw this: int function(const void * one, const void * two) { int var1, var2; var1 = *((int*)one); var2 = *((int*)two); /* sm other code here*/ }
21
1848
by: Bo Yang | last post by:
As long as I write c++ code, I am worry about the pointer. The more the system is, the dangerous the pointer is I think. I must pass pointers erverywhere, and is there a way to ensure that every object pointered by any pointer will be deleted and only be deleted once?
4
1860
by: Jeffrey Spoon | last post by:
Hello, I am trying to make a simple function that returns a pointer to another function. In my header file I've declared my function pointer: void (*pStateFunction) (void); //assume the function pointed to returns void and the actual function that returns the pointer: void* getState(CString myString);
10
1719
by: Zero | last post by:
Hello all, I wonder about void? To which category in the C programming language does it belong? Of how many bits consits void? Is it possible to define a varibale called void a;
21
1560
by: Chad | last post by:
At the following url http://c-faq.com/lib/qsort2.html, they have the following Q: Now I'm trying to sort an array of structures with qsort. My comparison function takes pointers to structures, but the compiler complains that the function is of the wrong type for qsort. How can I cast the function pointer to shut off the warning? A: The conversions must be in the comparison function, which must be declared as accepting ``generic...
17
2324
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the same as its address. The second one simply depends on a term that is not well-defined. Most people consider the type to be an important part of the notion of
18
2644
by: mdh | last post by:
May I ask the following. By K&R's own admission, the example used to describe function pointers is complex ( on P119). In addition, the use of casts has been stated by some on this group as being, again, a poor/bad example of it's use. For the moment, accepting these criticisms, I would still like to get some insight into why/how some things work as even poor code is enlightening, to me at least. The example uses K&R's version of...
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 **) }
0
9554
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
9377
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
10136
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
9925
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
9811
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
8814
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
7358
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...
3
3509
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2788
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.