Re: [9fans] void*
In case someone is asking why this guy is suddenly so thoughtful about void pointers, it is because I'm porting Ali Gholami Rudi's neatroof, and he uses a lot of arithmetics with void* in neatmkfn. I got rid of ape, and this troff looks really easy to port and has a lot of features. I'll share it when it's working in case someone is interested. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M683ed8fb049de7a5d4457cbf Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
Quoth Bakul Shah : > void*f(void*x){return x+1;} $ echo 'void*f(void*x){return x+1;}' > test.c $ cc -pedantic -std=c99 test.c test.c:4:24: warning: arithmetic on a pointer to void is a GNU extension [-Wpointer-arith] void*f(void*x){return x+1;} ~^ -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-Mfcc883e249a0aefbd19623f0 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
> On May 15, 2022, at 8:23 AM, Dan Cross wrote: > > On Sun, May 15, 2022 at 9:16 AM adr wrote: > On Sun, 15 May 2022, adr wrote: > > What I mean is if we are going to follow C99 in the use of void*, > > we should allow arithmetic on them. > > Let me be clear, I know that C99 requires the pointer to be a > complete object type to do arithmetic, and I like that, is consistent. > But then I don't see the point to use void* as a generic pointer. > > I confess that I am confused about what, precisely, you are asking for. > > You are correct that standard C only allows arithmetic on pointers to > complete object types. But `void *` is not a pointer to a complete object > type, and so therefore pointer arithmetic on pointers of type `void *` is > illegal. So in that sense, Plan 9 C is already following C99. > > - Dan C. Can't quote chapter and verse but AFAIK standard C allows +/- on void*. So for example the following is legal: void*f(void*x){return x+1;} The returned value will be one more than the arg. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M57ca9f2db655438f69c42dbf Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
On Sun, 15 May 2022, o...@eigenstate.org wrote: On Sun, 15 May 2022, arn...@skeeve.com wrote: It allows you pass pointers of any type without requiring casts: struct foo s[5] = ... memmove(s, & s[1], 4 * sizeof(struct foo)); // shift down 1 The compiler won't complain because any pointer type can be passed to a void* parameter. Otherwise you'd need to cast: memmove((uchar*) s, (uchar*) & s[1], 4 * sizeof(struct foo)); Sure, but you could change it to do the same with char*. char* has legitimate uses for things other than generic pointers, and the conversion complaints catch bugs. My point here is that It makes more sense to me to use a generic pointer which have a size (the type it points) of 1, so arithmetic can be applied to it. Of course I'm not proposing to change the compiler and all the code. It was just a reflection. Allowing arithmetic on void* solves the problem. Reading the definition of void this could look incongruous, but C99 already specifies: "A pointer to void shall have the same representation and alignment requirements as a pointer to a character type" So I don't see any real trouble to allow the same operations as with char*. Again, just some thoughts. The comments about uchar* or uint8* are because arithmetic on void* brakes the concept of void, I don't really like it. But sometime things are doomed to staid as they are, even if they don't make sense... adr. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M7092e86f1d4c6f710af49d81 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
On Sun, May 15, 2022 at 9:16 AM adr wrote: > On Sun, 15 May 2022, adr wrote: > > What I mean is if we are going to follow C99 in the use of void*, > > we should allow arithmetic on them. > > Let me be clear, I know that C99 requires the pointer to be a > complete object type to do arithmetic, and I like that, is consistent. > But then I don't see the point to use void* as a generic pointer. I confess that I am confused about what, precisely, you are asking for. You are correct that standard C only allows arithmetic on pointers to complete object types. But `void *` is not a pointer to a complete object type, and so therefore pointer arithmetic on pointers of type `void *` is illegal. So in that sense, Plan 9 C is already following C99. - Dan C. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M697dfcf01429a681db4155b2 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
Quoth adr : > On Sun, 15 May 2022, arn...@skeeve.com wrote: > > > It allows you pass pointers of any type without requiring casts: > > > >struct foo s[5] = ... > >memmove(s, & s[1], 4 * sizeof(struct foo)); // shift down 1 > > > > The compiler won't complain because any pointer type can be passed > > to a void* parameter. Otherwise you'd need to cast: > > > >memmove((uchar*) s, (uchar*) & s[1], 4 * sizeof(struct foo)); > > Sure, but you could change it to do the same with char*. > char* has legitimate uses for things other than generic pointers, and the conversion complaints catch bugs. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M78e7984543661c669776370b Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
Quoth adr : > Hi, > one of the first thing I noticed compiling in plan9 is that arithmetic > on void* is illegal. Other compilers treat void* as uchar*. > Conceptually, it makes sense. A pointer to void doesn't point to > any object. But then I've seen the use of void* in functions (like > memccpy) when the pointed object is going to be processed as a > byte array. Local uchar*'s are used to do the trick inside the > function. > arithmetic on void* is a gnu extension. It also implies sizeof(void) == 1; this is indeed true with gcc. I also don't think it's useful enough to add a special case to an already special case: it's rare to be able to do pointer arithmetic on void and *not* access the memory, in my experience. > It wouldn't make more sense to avoid the use of void* > and just use instead uchar* or better still u8int*? the unique thing about void* is that there is an implicit conversion from any pointer type to void*; there is not for uchar* or u8int*. memset((u8int*), 0, sizeof(x)); seems unnecessarily clunky. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-Ma63068d9d401c85e69d9d87f Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
On Sun, 15 May 2022, arn...@skeeve.com wrote: It allows you pass pointers of any type without requiring casts: struct foo s[5] = ... memmove(s, & s[1], 4 * sizeof(struct foo)); // shift down 1 The compiler won't complain because any pointer type can be passed to a void* parameter. Otherwise you'd need to cast: memmove((uchar*) s, (uchar*) & s[1], 4 * sizeof(struct foo)); Sure, but you could change it to do the same with char*. void* has been standard practice (even on Plan 9) for 30+ years. It's not worth changing it now. :-) I agree, I just wanted to share some opinions. Regards, adr. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M9bc3acdf4dd19efb75ea5a51 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
adr wrote: > On Sun, 15 May 2022, adr wrote: > > > What I mean is if we are going to follow C99 in the use of void*, > > we should allow arithmetic on them. > > Let me be clear, I know that C99 requires the pointer to be a > complete object type to do arithmetic, and I like that, is consistent. > But then I don't see the point to use void* as a generic pointer. It allows you pass pointers of any type without requiring casts: struct foo s[5] = ... memmove(s, & s[1], 4 * sizeof(struct foo)); // shift down 1 The compiler won't complain because any pointer type can be passed to a void* parameter. Otherwise you'd need to cast: memmove((uchar*) s, (uchar*) & s[1], 4 * sizeof(struct foo)); void* has been standard practice (even on Plan 9) for 30+ years. It's not worth changing it now. :-) HTH, Arnold -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-Md96cca95ce4773408cff1b24 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
On Sun, 15 May 2022, adr wrote: What I mean is if we are going to follow C99 in the use of void*, we should allow arithmetic on them. Let me be clear, I know that C99 requires the pointer to be a complete object type to do arithmetic, and I like that, is consistent. But then I don't see the point to use void* as a generic pointer. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M1f0eaeec24bbe0f8c2c06b0f Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
What I mean is if we are going to follow C99 in the use of void*, we should allow arithmetic on them. If not, there is not point to use void* as char*, just use char* as the generic pointer. When I ask something here about the Plan9 compilers, I'm not asking about some committee's standard, I have access to them, like everyone else. By the way I'm curious, someone knows a modern machine with CHAR_BIT>8? I would prefer to use fixed-width types and let the compiler deal with these (nowadays) eccentricities. Regards, adr. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M3ffa29ce3e6bd94227835bd6 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
Re: [9fans] void*
one of the first thing I noticed compiling in plan9 is that arithmetic on void* is illegal. That’s what the standard says. While Plan 9 C doesn’t pretend to be compliant, the core language does roughly match C89 with a few C99 extensions. Other compilers treat void* as uchar*. Conceptually, it makes sense. A pointer to void doesn't point to any object. But then I've seen the use of void* in functions (like memccpy) when the pointed object is going to be processed as a byte array. Local uchar*'s are used to do the trick inside the function. It wouldn't make more sense to avoid the use of void* and just use instead uchar* or better still u8int*? (Those are different. On Plan 9, we do make (too many) assumptions about type sizes, but conceptually, a byte need not be limited to eight bit.) I’m now quoting the C99 Rationale (revision 5.10). Page 37, § 6.2.5: A pointer to void must have the same representation and alignment as a pointer to char; the intent of this rule is to allow existing programs that call library functions such as memcpy and free to continue to work. Page 48, § 6.3.2.3: The use of void* (“pointer to void”) as a generic object pointer type is an invention of the C89 Committee. Adoption of this type was stimulated by the desire to specify function prototype arguments that either quietly convert arbitrary pointers (as in fread) or complain if the argument type does not exactly match (as in strcmp). -- Humm -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-Me2a3b163527df44b207e4fc3 Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
[9fans] void*
Hi, one of the first thing I noticed compiling in plan9 is that arithmetic on void* is illegal. Other compilers treat void* as uchar*. Conceptually, it makes sense. A pointer to void doesn't point to any object. But then I've seen the use of void* in functions (like memccpy) when the pointed object is going to be processed as a byte array. Local uchar*'s are used to do the trick inside the function. It wouldn't make more sense to avoid the use of void* and just use instead uchar* or better still u8int*? Some thoughts? Regards, adr. -- 9fans: 9fans Permalink: https://9fans.topicbox.com/groups/9fans/Tecaea3b9ec8e7066-M7d5d7a58e7e77b74d2aa123a Delivery options: https://9fans.topicbox.com/groups/9fans/subscription