Adding to void *

K

Keith Thompson

blargg said:
Andrew Tomazos wrote: [...]
With the strict solution we have to cast to some other pointer type
before doing pointer arithmetic.

In the looser solution we don't have to cast, but there is a small
chance of accidentally doing pointer arithmetic by accident, or in the
wrong unit. This will not be caught until runtime in this case.

The looser solution also breaks consistency. In C, adding n to a T*
equivalently adds n*sizeof(T) to a char*-casted version.

gcc, with extensions enabled, has sizeof(void) == 1. Presumably this
is a side effect of allowing pointer arithmetic on void*.

gcc also allows pointer arithmetic on function pointers -- and yes,
sizeof applied to a function type yields 1. For example,
sizeofmain == 1.
Along with allowing arithmetic as if it were a char*, why not also allow
dereferencing? Then you're left with a type that behaves just like
char*, except it also allows implicit conversion to/from other pointer
types.

At least gcc doesn't go so far as to allow dereferencing void*.
(Actually it does allow it, with a warning, as long as the result
isn't used.)
 
K

Keith Thompson

blargg said:
Keith said:
blargg said:
Andrew Tomazos wrote: [...]
With the strict solution we have to cast to some other pointer type
before doing pointer arithmetic.

In the looser solution we don't have to cast, but there is a small
chance of accidentally doing pointer arithmetic by accident, or in the
wrong unit. This will not be caught until runtime in this case.

The looser solution also breaks consistency. In C, adding n to a T*
equivalently adds n*sizeof(T) to a char*-casted version.

gcc, with extensions enabled, has sizeof(void) == 1. Presumably this
is a side effect of allowing pointer arithmetic on void*.

So it treats void as sort of a struct like the following?

struct void { char __inaccessible; };
typedef struct void void;

The gcc front-end probably just sets the size attribute for type
"void" to 1; I doubt that there's any need to invent a phony structure
for that.

Missing space: I meant "sizeof main == 1".
What, does gcc also allow the following?

int f(void) [2] { return 123; } { return 456; }

void use(void)
{
int (*fp)(void) = f;
assert( fp[0]() == 123 );
assert( fp[1]() == 456 );
}

If not, what use is incrementing a function pointer, other than to cause
a crash?

Just incrementing a pointer is almost certainly useless, but something
like computing the difference between two function pointers *might*
tell you the code size of one of the functions, given enough
compiler-specific assumptions about how the code is generated. Or
adding some compiler-specific constant to a function pointer might let
you access some particular chunk of machine code.

IMHO, if you really want to do that kind of thing it makes more sense
to convert the function pointer to char* (which is itself an
extension, but a more reasonable one). Oddly enough, the gcc
developers didn't ask my opinion before implementing this. :cool:}
 
B

Beej Jorgensen

Keith Thompson said:
gcc, with extensions enabled, has sizeof(void) == 1. Presumably this
is a side effect of allowing pointer arithmetic on void*.

And, IIRC, in the good old days there was no void*; char* was used
instead...?

-Beej
 
K

Keith Thompson

Beej Jorgensen said:
And, IIRC, in the good old days there was no void*; char* was used
instead...?

Yes, but that was pre-ANSI (before 1989).

Whatever the gcc maintainer's reason for allowing pointer arithmetic
on void*, it wasn't backward compatibility; pre-ANSI code didn't use
void*, and post-ANSI code should have used it correctly.
 
T

Tim Rentsch

Richard Heathfield said:
(e-mail address removed) said:
But grepping around in the C99 draft, I
can't find the section that defines or forbids [addition to
a void *]

I am PDC (Pretty Damn Certain) this applies even on C99.

It violates constraint 6.5.6(2) of C99, because void * is neither an
object type nor an arithmetic type.

Of course what you meant is that (void *) is not a pointer
to an object type; it is itself an object type.
 
R

Richard Bos

cr88192 said:
pretty much, only that I will invoke fire, and mention that absent an
explicit cast, C++ compilers will give a warning here (this matters a little
to those of us who write code which might be compiled in either a C or a C++
compiler...).

I know only one such person who _needs_ that feature. For the rest of
us, there's extern "C".

Richard
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top