473,386 Members | 1,652 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Is it conformant to substract two pointer-to-void ?

Is it OK to substract two pointer-to-void ? Are they guaranteed to act
as pointer-to-char ?
I fail to find that discussed in ISO/IEC 9899:1999.

In other words (hopefully), is the following program guaranteed to
output 1?

#include <stdio.h>
int main(void)
{
char t[2] = {'0','1',};
void *p0,*p1;
p0 = &t[0];
p1 = &t[1];
printf("%d\n",(int)(p1-p0));
return 0;
}

TIA,
Francois Grieu
Mar 12 '08 #1
9 2361
On Wed, 12 Mar 2008 05:54:56 -0700,Francois Grieu wrote:
Is it OK to substract two pointer-to-void ? Are they guaranteed to act
as pointer-to-char ?
I fail to find that discussed in ISO/IEC 9899:1999.

In other words (hopefully), is the following program guaranteed to
output 1?

#include <stdio.h>
int main(void)
{
char t[2] = {'0','1',};
void *p0,*p1;
p0 = &t[0];
p1 = &t[1];
printf("%d\n",(int)(p1-p0));
return 0;
}

TIA,
Francois Grieu
No, afaik only gcc treats void* as char*.

C99 states:

"For subtraction, one of the following shall hold:
— both operands have arithmetic type;
— both operands are pointers to qualified or unqualified versions of
compatible object types; or
— the left operand is a pointer to an object type and the right operand
has integer type."

And the void* pointer is not a pointer to an object type so should
not take part in this operation directly.

--
Hi, I'm a .signature virus, please copy/paste me to help me spread
all over the world.
Mar 12 '08 #2
Francois Grieu <fg****@gmail.comwrote:
Is it OK to substract two pointer-to-void ? Are they guaranteed to act
as pointer-to-char ?
No, and no. It's a constraint violation, IIRC.
I fail to find that discussed in ISO/IEC 9899:1999.
That's because it is implicit in the combination of several articles. In
short, you can only subtract pointers to complete object types; void is
an uncompletable type; therefore, void pointers cannot be subtracted.

Richard
Mar 12 '08 #3
Francois Grieu <fg****@gmail.comwrites:
Is it OK to substract two pointer-to-void ? Are they guaranteed to act
as pointer-to-char ?
I fail to find that discussed in ISO/IEC 9899:1999.

In other words (hopefully), is the following program guaranteed to
output 1?

#include <stdio.h>
int main(void)
{
char t[2] = {'0','1',};
void *p0,*p1;
p0 = &t[0];
p1 = &t[1];
printf("%d\n",(int)(p1-p0));
return 0;
}
Nope.

Why not just declare p0 and p1 as char*? (The answer is that this is
just an example, of course, but there's no good reason not to use
char* in whatever real code this represents.)

gcc allows arithmetic on void* as an extension. As far as I know, gcc
is the only compiler that does this (along with any other compilers
that deliberately imitate it). To make this work, gcc causes
sizeof(void) to yield 1 rather than a compile-time error message.

<OPINION>Ick.</OPINION>

With the "-pedantic" option, gcc warns about this. With a carefully
chosen set of options ("-ansi -pedantic -Wextra -Wall"), gcc is
reasonably close to being a conforming C90 compiler (it merely warns
about some things that are constraint violations, but that's permitted
by the standard).

More generally, most C compilers are not fully conforming by default,
but can be persuaded to be very nearly conforming to one or more C
standards with compile-time options.

Why do you *want* this to work?

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 12 '08 #4
Why do you *want* this to work?

My application includes the following:

#define CHK_PTR_TYPE(ptr,basetype) (1?(ptr):((ptr)-(basetype*)(ptr))+
(ptr))

and I am concerned that this wont reliably work when basetype is
void or const void
[My actual application is a set of macros, portable across several
platforms (8051, Win32, others) to store a pointer of parameterized
type, but constrained to belong to some 64KB structure, into a typed 2-
byte structure, so that the conversion is reversible, accidental type
mixes are caught at compile time, and the complexities of memory
domain attributes (xdata and the like) is hidden by the macros.]

Francois Grieu
Mar 12 '08 #5
Francois Grieu wrote:
Why do you want this to work?

My application includes the following:

#define CHK_PTR_TYPE(ptr,basetype) (1?(ptr):((ptr)-(basetype*)(ptr))+
(ptr))

and I am concerned that this wont reliably work when basetype is
void or const void
But what do you expect the result of it to be? What do you think the
stride of a void pointer should be?

Brian

Mar 12 '08 #6
Francois Grieu wrote:
>Why do you *want* this to work?

My application includes the following:

#define CHK_PTR_TYPE(ptr,basetype) (1?(ptr):((ptr)-(basetype*)(ptr))+
(ptr))

and I am concerned that this wont reliably work when basetype is
void or const void
I guess that by "work" you mean "produce a diagnostic if
the type of *ptr is not compatible with basetype?" (If
that's the goal, I don't understand what the addition at the
end is for -- which means that maybe I don't understand what
"work" means. So the rest may be irrelevant ...)

As written, the test should elicit a diagnostic if the
types are incompatible (which is what I think you want), or
if ptr is void* or if basetype is void (which I think you'd
regard as false positives). If you'd be happy with a slightly
different test (compatibility of ptr with basetype* instead
of *ptr with basetype), you might try

#define CHK_PTR_TYPE(ptr,basetype) \
(1 ? (ptr) : (basetype*)(ptr))

.... the idea being that the second and third operands of ?:
must be of compatible pointer types (6.5.15p3), and the
compiler must diagnose a constraint violation.

--
Er*********@sun.com
Mar 12 '08 #7
On 12 mar, 22:36, Eric Sosman <Eric.Sos...@sun.comwrote:
Francois Grieu wrote:
>>Why do you *want* this to work?
>My application includes the following:
#define CHK_PTR_TYPE(ptr,basetype) (1?(ptr):((ptr)-(basetype*)(ptr))+
(ptr))
>
>and I am concerned that this wont reliably work when basetype is
void or const void

I guess that by "work" you mean "produce a diagnostic if
the type of *ptr is not compatible with basetype?"
Yes, that's my goal.
As written, the test should elicit a diagnostic if the
types are incompatible (which is what I think you want), or
if ptr is void* or if basetype is void (which I think you'd
regard as false positives).
Yes.
I don't understand what the addition at the end is for
It is here to make the expression correct. (ptr)-(basetype*)(ptr)
is a ptrdiff_t and we need to add a ptr to make that
compatible with a ptr, on the left side of the :

If you'd be happy with a slightly different test (compatibility
of ptr with basetype* instead of *ptr with basetype), you might
try

#define CHK_PTR_TYPE(ptr,basetype) \
(1 ? (ptr) : (basetype*)(ptr))

... the idea being that the second and third operands of ?:
must be of compatible pointer types (6.5.15p3), and the
compiler must diagnose a constraint violation.
Indeed that SHOULD do the job. <OTI'll check with the
various compilers that I target, but I'm a bit pessimistic,
I think I remember one of them is hapy with mixing int and
pointers on each side of : </OT>

Francois Grieu
Mar 13 '08 #8
Francois Grieu wrote:
>
Is it OK to substract two pointer-to-void ? Are they guaranteed
to act as pointer-to-char ?
I fail to find that discussed in ISO/IEC 9899:1999.

In other words (hopefully), is the following program guaranteed
to output 1?

#include <stdio.h>
int main(void) {
char t[2] = {'0','1',};
void *p0,*p1;

p0 = &t[0];
p1 = &t[1];
Fine up to here. The auto pointer to void* has taken effect.
printf("%d\n",(int)(p1-p0));
This should be:
printf("%d\n", (int)((char*)p1 - (char*)p0));
return 0;
}
--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 13 '08 #9
>Is it OK to substract two pointer-to-void ?

No.
>Are they guaranteed to act
as pointer-to-char ?
char *cp;
void *vp;
... initialize cp and vp to point somewhere ...

*cp has type char, and should cause no problems.
*vp has type void, and should cause a compile-time error.

>In other words (hopefully), is the following program guaranteed to
output 1?

#include <stdio.h>
int main(void)
{
char t[2] = {'0','1',};
void *p0,*p1;
p0 = &t[0];
p1 = &t[1];
printf("%d\n",(int)(p1-p0));
return 0;
}
On a very old compiler I once used, which claimed C89 conformance
and C99 hadn't been written yet, that program would have caused a
*COMPILE TIME* division by zero fault and core dump of the compiler,
since it treated sizeof(void) as 0. I believe that behavior is
C89-conformant, although the quality-of-implementation, crashing if
the compiler divides by zero, is poor.

Mar 14 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: Radde | last post by:
HI all, Whats the difference b/w pass by ref and pass by pointer in C++ when ur passing objects as args.. Cheers..
20
by: __PPS__ | last post by:
Hello everybody in a quiz I had a question about dangling pointer: "What a dangling pointer is and the danger of using it" My answer was: "dangling pointer is a pointer that points to some...
27
by: Riaan Cillié | last post by:
Hi I'm trying to learn C, but I am struggling with using scanf and a struct. I want to define a structure and declare a variable of that type in int main. This has to be passed to a function and...
20
by: joe | last post by:
Hi all! I just have quick, possibly stupid question.... is it possible to do the following: int func(){ int *pointer; foo(pointer); } int foo(int *pointer){
20
by: Bill Potter | last post by:
I am a learning programmer in C and i want to know why some one would use pointers instead of going direct!
69
by: fieldfallow | last post by:
Hello all, Before stating my question, I should mention that I'm fairly new to C. Now, I attempted a small demo that prints out the values of C's numeric types, both uninitialised and after...
5
by: dotnetchic | last post by:
I'm having some trouble interpreting some legacy code...here's a single line of the kind of pointer arithmetic that baffles me. I need help both interpreting and understanding the reasoning behind...
4
by: code break | last post by:
Hi all, What is the difference between stack pointer and frame pointer ? Any suggestions are welcome ,,,
6
by: reji_thomas | last post by:
Hi, I have a doubt in the following code: struct xyz { int x; long l; float f; };
13
by: william | last post by:
code segment: long int * size; char entry; ............. size=&entry; ************************************* Gcc reported 'assignment of incompatible pointer type'.
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.