Please help me find out the relative topics in C99 for Arithmetic on void and function pointers

X

Xiangliang Meng

Hi, all.

As far as I know, the speical arithmetic operator on void pointer is an
externsion in GNU CC. However, I could not find the relative topics in C99.
Would someone like to help me find them out?

in linux\mm\Slab.c,
typedef struct slab_s {
struct list_head list;
unsigned long colouroff;
void *s_mem; /* including colour offset */
unsigned int inuse; /* num of objs active in slab */
kmem_bufctl_t free;
} slab_t;

static inline void kmem_cache_init_objs (kmem_cache_t * cachep,
slab_t * slabp, unsigned long ctor_flags)
{
int i;

for (i = 0; i < cachep->num; i++) {
void* objp = slabp->s_mem+cachep->objsize*i; // it's one of the
externsions to the C Language Family in GNU CC
....
}

Arithmetic on void- and function-pointers
----------------------------------------------------------------------------
----
In GNU C, addition and subtraction operations are supported on pointers to
void and on pointers to functions. This is done by treating the size of a
void or of a function as 1.
A consequence of this is that sizeof is also allowed on void and on function
types, and returns 1. The option, ¡®-Wpointer-arith¡¯, requests a warning if
these extensions are used.

Thanks,

Best Regards,

Xiangliang Meng
 
R

Richard Bos

Xiangliang Meng said:
As far as I know, the speical arithmetic operator on void pointer is an
externsion in GNU CC.
Yes.

However, I could not find the relative topics in C99.

6.2.5#18: void is an incomplete type; and 6.5.6#2 (for additive
operators) ... or one operand shall be a pointer to an object type.

Since a void * is a pointer to an incomplete type, not to an object
type, and since addition requires a pointer to an object type, addition
to void *s is a constraint violation.
Ditto for subtraction, which can work on either one or two pointers, but
they, too, must all be pointers to an object type, so void * does not
qualify.

Also note 6.5.3.4#1: the sizeof operator shall not be applied to ... an
incomplete type. If you have a void *vp, then sizeof vp is allowed
(that's the size of the pointer _itself_, probably 4 or 8, but could be
anything); but sizeof *vp is not - that would be the size of a void, and
this is a violation of the constraints in 6.5.3.4.

Conclusion: in ISO C, no arithmetic is allowed on pointers to void.

Richard
 
K

Keith Thompson

Xiangliang Meng said:
Hi, all.

As far as I know, the speical arithmetic operator on void pointer is an
externsion in GNU CC. However, I could not find the relative topics in C99.
Would someone like to help me find them out?

in linux\mm\Slab.c,

typedef struct slab_s {
struct list_head list;
unsigned long colouroff;
void *s_mem; /* including colour offset */
unsigned int inuse; /* num of objs active in slab */
kmem_bufctl_t free;
} slab_t;

static inline void kmem_cache_init_objs (kmem_cache_t * cachep,
slab_t * slabp, unsigned long ctor_flags)
{
int i;

for (i = 0; i < cachep->num; i++) {
void* objp = slabp->s_mem+cachep->objsize*i; // it's one of the
externsions to the C Language Family in GNU CC
...
}

Shouldn't that *i be +i?

As Richard Bos pointed out, arithmetic on void pointers and function
pointers is allowed in GNU C, but not in C99. If you want to perform
arithmetic on a void pointer, cast it to char*:

void *p = whatever;
void *q;
q = p + 42; /* GNU C */
q = (void*)((char*)p + 24) /* C99 (also valid GNU C) */

(If you want to perform arithmetic on a function pointer, you're doing
something exceedingly odd.)
 

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
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top