473,770 Members | 3,983 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 5704
Richard wrote:
Chris Dollin <ch**********@h p.comwrites:
>Richard wrote:
....
>>My only comment was that in most cases an uninitialised pointer will
indeed increment in the real world.
That's cool, so long as you acknowledge that "most" and don't
confuse it with an "all".

Huh?!?!?!?!

Please quote where I said all. Where I did not qualify with "in my
experience" or "my platforms".
You really should check to make sure before issuing such a challenge.
You left out all such qualifying phrases in your very first two messages
on the issue:

You wrote:
Date: Tue, 16 Sep 2008 18:43:31 +0200
....
Even if it wasnt initialized it would be incremented by something.
Your assertion contained no qualifiers. It has no "in my experience", no
"on my platform", no "on most platforms". You just flatly assert that
"it would be incremented". Later in that same message, you did use the
phrase "on my machine", but not as a phrase qualifying this assertion.

You also wrote:
Date: Tue, 16 Sep 2008 19:39:26 +0200
....
Whatever. x will be incremented.
Again, you did not qualify your assertion in any way. You just flatly
asserted it. This was in response to, and apparently intended as a
contradiction of, someone pointing out the existence of platforms where
the increment will not occur because loading the address into a register
in preparation to increment it will cause the program to abort before
the increment can occur. Again, later on you did use the phrase "on my
machine", but not as a qualifying phrase that would moderate your assertion.
Sep 17 '08 #111
On Sep 17, 11:55*am, James Kuyper <ja*********@ve rizon.netwrote:
s0****@gmail.co m wrote:
On Sep 17, 3:02 am, Nick Keighley <ni************ ******@hotmail. com>
wrote:
On 16 Sep, 21:14, s0s...@gmail.co m wrote:
...
>>>>>Besides, void * seems more natural for this kind
>of task.
rubbish
Why is it rubbish? If you have a void pointer, it will typically point
to any kind of object: int, double, long long, structures, anything.
Does it seem natural to you to treat such an object as if it were a
*character*?

Tracing back, "this kind of task" refers to:

int a[20];
void *b;
b = (void *)a; *// b points to a[0]
b += 5*sizeof(*a); // b points to a[5]

In this case, 'b' is being used as a pointer to char, because the amount
that is being added to is a number of bytes, not a number of ints. That
being the case, it should be declared as char*, not void*.
Shouldn't it be unsigned char *? Anyway, my argument was that if your
compiler can perform arithmetic with the void *, then go void *, as
you did above.
If you want use it as a pointer to int, declare it as such:

b *= (int*)b + 5;

That has the advantage of being not only more portable than the
original, but simpler, too.
But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).

Sebastian

Sep 17 '08 #112
Richard wrote:
James Kuyper <ja*********@ve rizon.netwrites :
>Richard wrote:
...
>>3) In ALL cases I have ever known it IS incremented.
How is that relevant? You clearly do not know ALL cases, since there

Where did I say ALL cases? Please post a link. And it is relevant
because I am telling MY experience.
When you said that you were describing your own experience, and also
when you added qualifying phrases like "on most implementations ", then
there was nothing objectionable about those comments (though they were
of debatable relevance - people should be writing code based upon what
the standard guarantees, not based upon what Richard NoLastName has
experienced).

However, you made unqualified assertions about the behavior of such
code. See the last message I posted, on another branch of this
discussion, for precise citations. And that's where the problem lies.
What are you taking about? I never said there were no machines where the
increment DID NOT take place. I countered the argument that was "the
increment will not happen" or words to that affect.
The only time those words, or words to that effect, have been used in
this discussion was when you used them to incorrectly describe what
other people were saying.
>No one but you has said anything like that, and you have said it only
to refute the claim (which no one made). What has been said is that
your claim that it is incremented is not always true.

Err, I said that. I made it clear maybe 5 times now.
Yes, and you said it wrong the first 2 times, and have denied ("no more,
no less") that there was any difference between those first 2 times and
the 5 later ones.
>And if you had qualified your original statement with "in the great
majority of cases", it would have been unobjectionable . It was your
flat out, unqualified assertion that it is incremented that people
have been objecting to.

I dont recall ever saying that.
Follow up the two citations in my other message.
Sep 17 '08 #113
s0****@gmail.co m writes:
On Sep 17, 11:55*am, James Kuyper <ja*********@ve rizon.netwrote:
>s0****@gmail.co m wrote:
On Sep 17, 3:02 am, Nick Keighley <ni************ ******@hotmail. com>
wrote:
On 16 Sep, 21:14, s0s...@gmail.co m wrote:
...
>>>>>>Besides , void * seems more natural for this kind
>>of task.
rubbish
Why is it rubbish? If you have a void pointer, it will typically point
to any kind of object: int, double, long long, structures, anything.
Does it seem natural to you to treat such an object as if it were a
*character*?

Tracing back, "this kind of task" refers to:

int a[20];
void *b;
b = (void *)a; *// b points to a[0]
b += 5*sizeof(*a); // b points to a[5]

In this case, 'b' is being used as a pointer to char, because the amount
that is being added to is a number of bytes, not a number of ints. That
being the case, it should be declared as char*, not void*.
It depends on what you want to do with it. If you're going to
dereference it to examine the representation of whatever it points to,
then yes, unsigned char* is better than char*. If you're not going to
dereference it, it doesn't matter whether you use char* or unsigned
char*; both have the same stride, 1 byte.

But the use of the expression "5*sizeof(* a)" indicates that the actual
intent is advance the pointer by 5 ints. The type int* will do
exactly that.

It's impossible to tell from the short snippet what the intent is, but
it does nothing that couldn't be done more conveniently, and with less
risk of error, than this:

int a[20];
int *b;
b = a; /* b points to a[0] */
b += 5; /* b points to a[5] */

Maybe there's some reason for b to be a void* rather than an int*, but
it's not evident from what's been posted so far.
Shouldn't it be unsigned char *? Anyway, my argument was that if your
compiler can perform arithmetic with the void *, then go void *, as
you did above.
That advice is questionable, in my opinion, even if you're only
concerned with gcc. But if you're writing code for, for example, the
Linux kernel, which has no pretense of portability to compilers other
than gcc, then I suppose it's not too bad.

The advice is very bad if there's any possibility that the code will
need to be compiled with something other than gcc.

If you have a void* pointer object, and you want to advance it by N
bytes, it is in my opinion *better* to write:

ptr = (char*)ptr + N;

because it's portable, and because it expresses the idea that you're
doing something that doesn't make sense for void*.
>If you want use it as a pointer to int, declare it as such:

b *= (int*)b + 5;

That has the advantage of being not only more portable than the
original, but simpler, too.

But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).
Of course it will. That's the point. If you're accessing an array of
int, a pointer of type int* is the best way to do it. You *can* use
void* or unsigned char*, but then you have to write additional code
(casting pointers, multiplying offsets by sizeof(int)).

If you need to access the individual bytes of an array of int, then
void* or unsigned char* is better, but that's a fairly unusual
requirement.

If you show us a problem you need to solve, involving an array of int,
for which int* pointers are not adequate, please do so, and we can
discuss the best way to go about it.

--
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 17 '08 #114
s0****@gmail.co m wrote:
On Sep 17, 11:55 am, James Kuyper <ja*********@ve rizon.netwrote:
....
>Tracing back, "this kind of task" refers to:

int a[20];
void *b;
b = (void *)a; // b points to a[0]
b += 5*sizeof(*a); // b points to a[5]

In this case, 'b' is being used as a pointer to char, because the amount
that is being added to is a number of bytes, not a number of ints. That
being the case, it should be declared as char*, not void*.

Shouldn't it be unsigned char *?
In general, yes. If you need to do byte-based pointer arithmetic,
there's a pretty good chance that sooner or later you'll be using those
pointers to read or write those bytes, and in that case you should be
using unsigned char*. However, in code like this, that only works with
pointers to bytes, without ever dereferencing those pointers, I prefer
'char *', because it requires less typing. In my experience, such cases
don't come up very often.
... Anyway, my argument was that if your
compiler can perform arithmetic with the void *, then go void *, as
you did above.
Please don't say that! I didn't use it - I was quoting code written by
others. I don't want anyone thinking I would write such code.

And I believe, as others have said, that you are giving very bad advice.
There's no good reason not to use char* instead of void*, which would
make your code portable. It's not as if it makes the code any more
complicated. The complication comes only from using void* and repeatedly
converting to and from char*; if you declared is as char* in the first
place, such repetitions could be avoided.
>If you want use it as a pointer to int, declare it as such:

b = (int*)b + 5;

That has the advantage of being not only more portable than the
original, but simpler, too.

But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).
No, they are exactly identical: (int*)b+5 == b+5*sizeof(int) , at least
on the implementations you're talking about that allow the right hand
side as an extension, rather than rejecting the code because it's a
constraint violation. If you think otherwise, you're going to have to
explain why.
Sep 17 '08 #115
s0****@gmail.co m wrote:
On Sep 17, 11:55 am, James Kuyper <ja*********@ve rizon.netwrote:
>[...]
Tracing back, "this kind of task" refers to:

int a[20];
void *b;
b = (void *)a; // b points to a[0]
b += 5*sizeof(*a); // b points to a[5]

In this case, 'b' is being used as a pointer to char, because the amount
that is being added to is a number of bytes, not a number of ints. That
being the case, it should be declared as char*, not void*.

Shouldn't it be unsigned char *?
Why? You've said this at least twice in this thread, but I've
seen no justification. Before you say "trap representation, " note
that the pointer (whatever its type) is not dereferenced in this
fragment, and in the original it is dereferenced only after conversion
to int*.
Anyway, my argument was that if your
compiler can perform arithmetic with the void *, then go void *, as
you did above.
Two comments: First, the "do whatever your compiler lets you
get away with" line leads straight back to the pre-Standard chaos.
Would you recommend "#pragma stdio" instead of "#include <stdio.h>"
just because the compiler at hand happens to do something with it?

Second, it wasn't James Kuyper who wrote the misuse of void*;
he was quoting the O.P.'s code.
>If you want use it as a pointer to int, declare it as such:

b = (int*)b + 5;

That has the advantage of being not only more portable than the
original, but simpler, too.

But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).
It points `b' to the same spot the corrected original did, and
is a cleaner correction. And `b' cannot be dereferenced anyhow, so
the second half of your objection makes no sense.

--
Er*********@sun .com
Sep 17 '08 #116
In article <ga**********@r egistered.motza rella.org>,
Richard <rg****@gmail.c omwrote:
....
>Yes it is. Vippstar is currying favour with the regs. He is obstreperous
to the extreme in his desire to "live and breath the standard".
Indeed. Note that it has yet to be determined exactly whose sock puppet
vippy really is.

Sep 17 '08 #117
On Sep 17, 12:36*pm, Keith Thompson <ks***@mib.orgw rote:
s0****@gmail.co m writes:
<snip>
If you want use it as a pointer to int, declare it as such:
b *= (int*)b + 5;
That has the advantage of being not only more portable than the
original, but simpler, too.
But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).

Of course it will. *That's the point. *If you're accessing an array of
int, a pointer of type int* is the best way to do it. *You *can* use
void* or unsigned char*, but then you have to write additional code
(casting pointers, multiplying offsets by sizeof(int)).

If you need to access the individual bytes of an array of int, then
void* or unsigned char* is better, but that's a fairly unusual
requirement.

If you show us a problem you need to solve, involving an array of int,
for which int* pointers are not adequate, please do so, and we can
discuss the best way to go about it.
Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:

void *buf1;
void *buf2;
int n, buf2len;
...
memcpy(buf1 + n, buf2, buf2len);

This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:

memcpy((char *) buf1 + n, buf2, buf2len);

Sebastian

Sep 17 '08 #118
ga*****@shell.x mission.com (Kenny McCormack) writes:
In article <ga**********@r egistered.motza rella.org>,
Richard <rg****@gmail.c omwrote:
...
>>Yes it is. Vippstar is currying favour with the regs. He is obstreperous
to the extreme in his desire to "live and breath the standard".

Indeed. Note that it has yet to be determined exactly whose sock puppet
vippy really is.
Indeed Mr Kenny. Indeed.
Sep 17 '08 #119
In article <ga**********@r egistered.motza rella.org>,
Richard <rg****@gmail.c omwrote:
....
>Quite why this has turned into a crusade for clc standard correctness is
any ones guess.
It's what we do here. Had you not noticed?

Sep 17 '08 #120

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

Similar topics

11
2577
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
1347
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
1851
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
1563
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
2326
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
2645
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
9425
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
10228
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
10057
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
10002
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
9869
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
8883
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
7415
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
6676
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
5449
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.