incrementing void *

  • Thread starter subramanian100in
  • Start date
A

Adrian Hawryluk

spacecriter said:
I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

But my answer is ++(int*)ptr. The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.

Which is correct ?

How about something along the lines of:

ptr = &myArray[j++];
What about it?
 
S

spacecriter \(Bill C\)

Adrian said:
spacecriter said:
I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

But my answer is ++(int*)ptr. The reason is that ptr being void *,
we cannot add any number to it. It must be cast to a valid object
before incrementing.

Which is correct ?

How about something along the lines of:

ptr = &myArray[j++];
What about it?

I meant to say that this will produce the desired effect (implied by their
"correct" option number 5) without operating on the poiner directly.
 
I

Ian Collins

Nonsense. There are dangers in incrementing (int *)ptr if
myStruct is not on at least as strong a storage boundary as
int (or if you're on a machine where even ten MyStruct are
smaller than a single int). But lvaleness has nothing to do
with it.

You can add 1 to (int *)ptr, but you can't assign the result to
it, because (int *)ptr is indeed not an lvalue (since some draft
of C89).

You can do ptr = (int *)ptr + 1 which converts the value back
to void * before assigning it to plain uncast ptr.
The posed question doesn't answer the burning question,
"increment by what?". One possible sensible interpretation
is to undo the implicit void cast and write:

ptr = ++((myStruct *)ptr);

I think you're temporarily confused. You can't apply ++ to cast
expressions in standard C.
[/QUOTE]
Thank you Richard, so I didn't post total bollocks after all.
 
A

Adrian Hawryluk

spacecriter said:
Adrian said:
spacecriter said:
(e-mail address removed) wrote:
I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

But my answer is ++(int*)ptr. The reason is that ptr being void *,
we cannot add any number to it. It must be cast to a valid object
before incrementing.

Which is correct ?
How about something along the lines of:

ptr = &myArray[j++];
What about it?

I meant to say that this will produce the desired effect (implied by their
"correct" option number 5) without operating on the poiner directly.

It looks correct to me. It is just like saying:

prt = &myArray[j];
j += 1;

Personally, I don't see any reason nowadays for the ++/-- pre/post
operators. Yeah, their somewhat covenant, but they can make code hard
to read. I think the comma operator is more understandable as the
sequence point is *right* there.


Adrian
 
P

P.J. Plauger

Yep. Been writing too much C++ lately. The irony is that I'm the
guy who insisted that ++x be an rvalue in C89.
Thank you Richard, so I didn't post total bollocks after all.

But I contributed at least a partial version of same.

Thanks for the re-education.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
M

Malcolm McLean

Adrian Hawryluk said:
Personally, I don't see any reason nowadays for the ++/-- pre/post
operators. Yeah, their somewhat covenant, but they can make code hard to
read. I think the comma operator is more understandable as the sequence
point is *right* there.
Preincrement can go.
Postincrement is idiomatic. It means "do something to this, then go on to
the next one".
 
P

pete

I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

But my answer is ++(int*)ptr. The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.

Which is correct ?

ptr = (char *)ptr + sizeof *myArray;
 
O

Old Wolf

ptr = ++((myStruct[10] *)ptr);

These at least have the virtue of being well defined.

As well as what has already been mentioned, this attempted
cast is a syntax error. I guess you mean (mystruct (*)[10]).
 
A

Adrian Hawryluk

Malcolm said:
Preincrement can go.
Postincrement is idiomatic. It means "do something to this, then go on
to the next one".

Still leads to bad code. Take for instance:

x = y++ + y++;

That has no sequence point between the y++s. x could equal to
(y+1)+(y+1) or (y+1)+(y+2). This goes for all operators except comma
',' which is defined as a sequence point.

Though I guess the same could be said for:

x = (y+=1) + (y+=1);

and other variants. The best thing to do is just not use operators with
side-effects inside an equation.


Adrian

--
==========================================================
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
==========================================================
 
K

Keith Thompson

Adrian Hawryluk said:
Still leads to bad code. Take for instance:

x = y++ + y++;

That has no sequence point between the y++s. x could equal to
(y+1)+(y+1) or (y+1)+(y+2). This goes for all operators except comma
',' which is defined as a sequence point.

Though I guess the same could be said for:

x = (y+=1) + (y+=1);

and other variants. The best thing to do is just not use operators
with side-effects inside an equation.

The best thing to do is to learn the rules and not use operators with
side effects *improperly* inside an expression (I'm not sure what you
mean by "equation"). For example, "x = y++;" is perfectly legitimate.
Even if you choose not to write code like that, you'll need to be able
to read and understand it.
 
P

pete

Adrian said:
x = y++ + y++;

That has no sequence point between the y++s. x could equal to
(y+1)+(y+1) or (y+1)+(y+2). This goes for all operators except comma
',' which is defined as a sequence point.

There are also other operators besides the comma operator
which are sequence points.
 
W

websnarf

I saw this question fromwww.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?

Increment it with respect to what? Its a void * pointer. If they
mean increment it with respect to the unit of item its pointing at
(likely) then they want you to treat ptr as if it were a myStruct *
rather than a void * pointer. But it is also pointing at a
myStruct[10] array (excuse the Java syntax, C doesn't allow for
ordinary english discourse on this matter) so the question is not well
defined.
Choice 1 ptr = ptr + sizeof(ptr);

There is no indication that ptr is pointing at an array of items that
is the same time as the ptr itself (I think this is a logical
impossiblity; though I could be proven wrong -- I am too lazy to work
it out either way at the moment.) Intuitively, in this case, void *
does not point to void * (that would be void **). If you can
establish that sizeof(void*) == sizeof(myStruct) or sizeof(myArray),
then its hard to make a case for the correctness of this answer.
Choice 2 increment(ptr);

This is not Pascal. But technically I guess it would depend on
whether or not a macro named "increment()" was defined that made this
have a valid interpretation that "incremented ptr".
Choice 3 ++(int*)ptr;

There is no definitively described int here. If myStruct has been
defined at the preprocessor level or via a typedef to be an int, then
this is technically ok, but even then would be in bad form.
Choice 4 ptr = ptr + sizeof(myArray);

This is a possible answer. sizeof (myArray) referrs to the whole
array at once (essential 10 sequential myStruct's). So if the unit of
increment that the question is referring to is the whole myArray, then
this increments to the position right past it. Technically this is
legal in C.

If ptr is meant to be pointing at the entries *in* the myArray array
then, this would not be correct. But because the thing is a void *,
we really don't have a clue as to what the programmer really means
here.
Choice 5 ptr = ptr + sizeof(myStruct);

This also a possible correct answer (and the more likely one.) Here
we are treating ptr as if it were a pointer to the *insides* of
myStruct. I.e., as if ptr is really a myStruct * pointer. The result
after this operation will be to make ptr equal to &myStruct[1].

Now the problem with this, of course, is that there is no good reason
to declare ptr as a void *, if this is how you intend to use it. So
this is a question about the output/result of code that is written in
very bad form.
THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

Of course. They didn't think to hard when making or answering the
question.
But my answer is ++(int*)ptr. The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.

Yeah, but the question is trying to imply that there is an
*appropriate* object, I think. I can see how you are technically
correct here as well, since you basically just make ptr into something
that can be incremented, then increment it.

However since myStruct is not described, it might be typdefed to a
char or something, and your platform might, theoretically have
sizeof(int)=16 (this will occurr or rare machines in roughly 190 years
from now, if you believe in Moore's Law continuing) at which point ptr
will be pointing *past* the end of any knowably legally defined C
object, which would make this wrong.
Which is correct ?

Well they told you which is the correct answer, so I guess that's the
"correct" one. The question isn't so much about legal C, I think, as
it is about "Can you think like the kind of drone we want you to be?"
I mean the questioner has some notions about how one might interpret a
void * pointer in this context, and he just wants you to interpret it
the same way. Nevermind that there isn't a real iron clad way or
reason for doing so (C standard or not).
 
M

Miojo Lamen

I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
Choice 1 ptr = ptr + sizeof(ptr);
Choice 2 increment(ptr);
Choice 3 ++(int*)ptr;
Choice 4 ptr = ptr + sizeof(myArray);
Choice 5 ptr = ptr + sizeof(myStruct);

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

But my answer is ++(int*)ptr. The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.

Which is correct ?

I have also (wrongly) assumed once that void* had the same arithmetic of a
char*.

So, the answers ALL wrong. The resumee of all answers given was:

1,4 and 5 due to the fact that void* have no arithmetic.
(Choice 5 would be correct if void* has the arithmetic of a char*. Read PS
below)
2 because it would be a macro. But no type is passed.
3 would be correct if myStruct had the same size of an int. But it has the
problem that a casted variable is not a lvalue. (Even in this situation Gcc
compiles and only issues a message of a deprecated feature)

Isn't it?

Regards



PS. A little note
Some compilers (Gcc, under DevC++ 4.9.9.2) don't even issue any warnings to
the following code (which I have compiled in strictly ansi mode)
------------
#include <stdio.h>

int main(void)
{
void *p;

printf("%p", p+1);

return 0;
}
---------
 
J

J. J. Farrell

Still leads to bad code. Take for instance:

x = y++ + y++;

That has no sequence point between the y++s. x could equal to
(y+1)+(y+1) or (y+1)+(y+2). This goes for all operators except comma
',' which is defined as a sequence point.

Though I guess the same could be said for:

x = (y+=1) + (y+=1);

and other variants. The best thing to do is just not use operators with
side-effects inside an equation.

Why is that best? Is it best to not use cars because car drivers
sometimes hit things or people? I'd say the best thing to do in C is
to use C operators correctly and write correct C.
 
K

Keith Thompson

I saw this question fromwww.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;

Which of the following is the correct way to increment the variable
"ptr"?
[snip]
Choice 4 ptr = ptr + sizeof(myArray);

This is a possible answer. sizeof (myArray) referrs to the whole
array at once (essential 10 sequential myStruct's). So if the unit of
increment that the question is referring to is the whole myArray, then
this increments to the position right past it. Technically this is
legal in C.

No, it isn't. C does not define arithmetic on void* pointers (though
some compilers may do so as an extension).

[...]
This also a possible correct answer (and the more likely one.)

Again, C does not define arithmetic on void* pointers.

[...]

All five solutions, with the possible exception of "increment(ptr);"
(*if* increment is defined appropriately as a macro) are illegal.
More precisely, they're constraint violations, requiring compiler
diagnostics from any conforming C compiler.

This has already been discussed at considerable length. If you missed
the discussion, you can see it at groups.google.com.
 
C

CBFalconer

Adrian said:
.... snip ...

Still leads to bad code. Take for instance:

x = y++ + y++;

That has no sequence point between the y++s. x could equal to
(y+1)+(y+1) or (y+1)+(y+2). This goes for all operators except comma
',' which is defined as a sequence point.

Or anything else, since the result is undefined. Some models of
the DS9000 will exterminate the programmer.

--
If you want to post a followup via groups.google.com, ensure
you quote enough for the article to make sense. Google is only
an interface to Usenet; it's not Usenet itself. Don't assume
your readers can, or ever will, see any previous articles.
More details at: <http://cfaj.freeshell.org/google/>
 
K

Keith Thompson

Miojo Lamen said:
PS. A little note
Some compilers (Gcc, under DevC++ 4.9.9.2) don't even issue any warnings to
the following code (which I have compiled in strictly ansi mode)
------------
#include <stdio.h>

int main(void)
{
void *p;

printf("%p", p+1);

return 0;
}
---------

<OT>
With "gcc -ansi -pedantic", or even just "gcc -pedantic", I get:

c.c: In function `main':
c.c:7: warning: pointer of type `void *' used in arithmetic

That's gcc 3.4.4 (not "DevC++").
</OT>
 
R

Richard Heathfield

(e-mail address removed), India said:
I saw this question from www.brainbench.com

void *ptr;
myStruct myArray[10];

ptr = myArray;
[...]

THEIR Correct Answer given in this site is: ptr = ptr +
sizeof(myStruct);

If that is the case, then the Brainbench test remains meaningless.
But my answer is ++(int*)ptr.

That's wrong, too.
The reason is that ptr being void *, we
cannot add any number to it. It must be cast to a valid object before
incrementing.

Which is correct ?

Avoiding the Brainbench test would be favourite, I think.
 
A

Adrian Hawryluk

J. J. Farrell said:
Why is that best? Is it best to not use cars because car drivers
sometimes hit things or people? I'd say the best thing to do in C is
to use C operators correctly and write correct C.

It can be if the car's wheels are apt to fall off, or the driver is
usually drunk. Yes, it is done, it can be done, it will be done. It is
just not always intuitive as to what is happening, and many people learn
a language by use and not reading a thick specification book of it.

I am not illegitimatising the use of it, I am saying that it makes the
code that much more difficult to read. When you have to do it, fine.
When you do it whimsically without need, then you should just enter the
C Obfuscation contest.

Clarity in programming makes for more maintainable, understandable code,
reducing costs across the board.


Adrian

--
==========================================================
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
==========================================================
 
A

Adrian Hawryluk

pete said:
There are also other operators besides the comma operator
which are sequence points.
Yes, but I didn't describe any here except for the '='.


Adrian

--
==========================================================
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
==========================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top