john@basho.uucp (John Lacey) (08/10/90)
What operations are legal on pointers to void? K&R2 is it's usual self
on the matter---no one can tell if what they say is possible, required,
complete, a couple of examples, or what. Harbison and Steele are their
much more explicit selves, but still, all they say is that void *'s can
be assigned to or from without casts, and that dereferencing and
subscripting are illegal.
But, what about pointer arithmetic? And it that is legal, what size object
does a void * point to? If there was justice in the world, I suppose that
it should be legal, and that a void * points to an object of size 0, but
gcc thinks the size is 1 (and gives no complaints about the following code
compiled with -ansi -pedantic -Wall:
#include <stdio.h>
int
main()
{
char foo [] = "This is a test string.";
void * a = foo;
void * b = &foo[1];
printf ( "%s\n", (++a == b) ? "Object size is 1" : "Object size is NOT 1" );
return ( 0 );
}
and further, gives the aforementioned result of "Object size is 1").
Ah what gives?
--
John Lacey,
E-mail: ...!osu-cis!n8emr!uncle!basho!john (coming soon: john@basho.uucp)
V-mail: (614) 436--3773, or 487--8570
"What was the name of the dog on Rin-tin-tin?" --Mickey Rivers, ex-Yankee CF
steve@taumet.com (Stephen Clamage) (08/10/90)
john@basho.uucp (John Lacey) writes: >What operations are legal on pointers to void? ... You may cast to or from type void*. You may assign, initialize, or pass as a parameter any pointer to an object of type void*, and vice versa. You may not dereference an object of type void*. >But, what about pointer arithmetic? And it that is legal, what size object >does a void * point to? You cannot do pointer arithmetic with an object of void*. No object may have type void, so no size can be associated with it. It is helpful to think of void as "not anything", rather than "zero". Void* is a special case, and you can think of it as "pointing to something unspecified". -- Steve Clamage, TauMetric Corp, steve@taumet.com
henry@zoo.toronto.edu (Henry Spencer) (08/10/90)
In article <1990Aug9.231614.5196@basho.uucp> john@basho.uucp (John Lacey) writes: >... dereferencing and subscripting are illegal. >But, what about pointer arithmetic? ... Subscripting *is* pointer arithmetic. Apart from passing them around and comparing them to each other and to NULL, there is *nothing* you can do with `void *'s except convert them to another kind of pointer. No dereferencing, no arithmetic. They are containers for other kinds of pointers, not pointers themselves. Many compilers, especially old ones with `void *' hastily kludged in, treat `void *' much like `char *'. That is a compiler bug. -- It is not possible to both understand | Henry Spencer at U of Toronto Zoology and appreciate Intel CPUs. -D.Wolfskill| henry@zoo.toronto.edu utzoo!henry
colin@array.UUCP (Colin Plumb) (08/11/90)
In article <1990Aug10.165644.9238@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: > Subscripting *is* pointer arithmetic. Apart from passing them around and > comparing them to each other and to NULL, there is *nothing* you can do > with `void *'s except convert them to another kind of pointer. No > dereferencing, no arithmetic. They are containers for other kinds of > pointers, not pointers themselves. Exactly. A void * can be assigned, passed, returned, and compared. Period. > Many compilers, especially old ones with `void *' hastily kludged in, > treat `void *' much like `char *'. That is a compiler bug. Actually, gcc documents its permission of pointer arithmetic on void * as a feature. I disagree. Certainly -ansi -pedantic should complain about the extension. -- -Colin
browns@astro.pc.ab.com (Stan Brown, Oak Road Systems) (08/12/90)
In article <1990Aug9.231614.5196@basho.uucp>, john@basho.uucp (John Lacey) writes: > What operations are legal on pointers to void? It may help you to think of them as "void pointers" rather than "pointers to void". "Pointer to void" sounds too much like "pointer to int" and makes me (at least) think of a real pointer to a real object of unspecified type. In fact a void pointer is just storage in memory where you may later put a pointer to any type of data. Only then does the value of the pointer become meaningful. And even then, if you're going to do much beyond simple assignments you haave to use casts. Do you have a particular use of void* in mind, or is this a general-info question? > K&R2 is it's usual self > on the matter---no one can tell if what they say is possible, required, > complete, a couple of examples, or what. Hey--don't insult my religion! :-) Stan Brown, Oak Road Systems, (216) 371-0043 The opinions expressed are mine. Mine alone! Nobody else is responsible for them or even endorses them--except my cat Dexter, and he signed the power of attorney only under my threat to cut off his Cat Chow!
darcy@druid.uucp (D'Arcy J.M. Cain) (08/13/90)
In article <482@array.UUCP> colin@array.UUCP (Colin Plumb) writes: >In article <1990Aug10.165644.9238@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: >> Many compilers, especially old ones with `void *' hastily kludged in, >> treat `void *' much like `char *'. That is a compiler bug. > >Actually, gcc documents its permission of pointer arithmetic on void * >as a feature. I disagree. Certainly -ansi -pedantic should complain >about the extension. I'll buy the argument about -pedantic but in general I think it is useful to be able to manipulate generic data. Things like memcpy for example. We know that the data can be any type but we want to treat it as bytes. Perhaps we need a new type which acts like void * but allows pointer arithmetic based on the smallest data type supported by the system, usually (but not always) a byte. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay West Hill, Ontario, Canada | of operating systems. + 416 281 6094 |
henry@zoo.toronto.edu (Henry Spencer) (08/14/90)
In article <1990Aug12.231202.23826@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >I'll buy the argument about -pedantic but in general I think it is useful >to be able to manipulate generic data. Things like memcpy for example. We >know that the data can be any type but we want to treat it as bytes. Perhaps >we need a new type which acts like void * but allows pointer arithmetic based >on the smallest data type supported by the system... It's called `char *'. :-) The various tricky implementations in which it would not be a valid "generic pointer" have pretty well all been outlawed by various rules in ANSI C. Note that `void *' and `char *' are constrained to have the same representation. -- It is not possible to both understand | Henry Spencer at U of Toronto Zoology and appreciate Intel CPUs. -D.Wolfskill| henry@zoo.toronto.edu utzoo!henry
johnb@srchtec.UUCP (John Baldwin) (08/15/90)
In article <1990Aug12.231202.23826@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >know that the data can be any type but we want to treat it as bytes. Perhaps >we need a new type which acts like void * but allows pointer arithmetic based >on the smallest data type supported by the system, usually (but not always) >a byte. There is a simple fix to this: you can operate on void pointers by casting them to a useful type. For example, perhaps you are writing a function foo() which can take a pointer to anything, and for some (unspecified) reason, you want to "bump" the pointer up three bytes.... SOMETYPE foo( void *myptr, size_t someval, ... ) { . . *((char *)&myptr) += 3; . . } -- John T. Baldwin | johnb@srchtec.uucp Search Technology, Inc. | johnb%srchtec.uucp@mathcs.emory.edu standard disclaimer: | ...uunet!samsung!emory!stiatl!srchtec.. opinions and mistakes purely my own. | ...mailrus!gatech!stiatl!srchtec...
karl@haddock.ima.isc.com (Karl Heuer) (08/16/90)
In article <1990Aug12.231202.23826@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >Perhaps we need a new type which acts like void * but allows pointer >arithmetic based on the smallest data type supported by the system, usually >(but not always) a byte. Trouble is, there's no convenient way to describe the operation of incrementing a pointer by less than a byte, since `sizeof(char)' is required to be exactly 1. (This, in turn, is really caused by the unfortunate overloading of `char' for three logically distinct types; but it's much too late to fix that.) Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
karl@haddock.ima.isc.com (Karl Heuer) (08/16/90)
In article <174@srchtec.UUCP> johnb@srchtec.UUCP (John Baldwin) writes: > void *myptr; ... *((char *)&myptr) += 3; The cast should be to `char **', and it won't work if `myptr' is a register. I think `myptr = (void *)((char *)myptr + 3);' is better, or (if all the operations are on the same datatype anyway) just make a `char *' copy of the original pointer and use it exclusively. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
darcy@druid.uucp (D'Arcy J.M. Cain) (08/16/90)
In article <174@srchtec.UUCP> johnb@srchtec.UUCP (John Baldwin) writes: >In article <1990Aug12.231202.23826@druid.uucp> darcy@druid.uucp > (D'Arcy J.M. Cain) writes: >>know that the data can be any type but we want to treat it as bytes. Perhaps >>we need a new type which acts like void * but allows pointer arithmetic based >>on the smallest data type supported by the system, usually (but not always) >>a byte. > >There is a simple fix to this: you can operate on void pointers by casting >them to a useful type. For example, perhaps you are writing a function foo() I understand how to cast. All I am saying is that it shouldn't be necessary. I find casts to be clumsy and try to avoid them wherever I can. I think it is better to define your functions and data types so that any conversion is automatically done by the compiler. If the language supported pointer arithmetic on void * (or supplied another data type with the same features) this would be possible. Note that GNU C does support it and I can't see any harm in it. ANSI code that doesn't know about it runs just fine but if you use the feature you do no harm either. So can anyone suggest any reason why supporting this feature would break code or otherwise be a problem. Of course code which used this feature would be unportable but what other problems would this cause? -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay West Hill, Ontario, Canada | of operating systems. + 416 281 6094 |
karl@haddock.ima.isc.com (Karl Heuer) (08/17/90)
In article <1990Aug16.014947.1999@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >If the language supported pointer arithmetic on void * this would be >possible. Note that GNU C does support it and I can't see any harm in it. The potential harm is when somebody writes code like vp = (struct foo *)vp; ... ++vp ... without realizing that it doesn't do what was intended. (Somebody *did* recently post code much like this, in fact.) This type of error will be caught by the ANSI rule, which makes sense because `void' is an incomplete type of undefined size. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint