void * in ANSC

M

Mark Jiao

void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");
}
 
V

vippstar

void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
You are performing arithmetic operations with a void * pointer which
is not allowed.
&data[len] means &*(data + len)
Try this
 
F

frog

void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");



}- Òþ²Ø±»ÒýÓÃÎÄ×Ö -

- ÏÔʾÒýÓõÄÎÄ×Ö -

??
 
M

Mark Jiao

void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
You are performing arithmetic operations with a void * pointer which
is not allowed.
&data[len] means &*(data + len)
Sorry!
I am very poor English!
How many the memery address would be add?? 1? or No Standards ??

Thanks!



--
 
K

Keith Thompson

Mark Jiao said:
void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");
}

I think what you're asking is why the compiler prints just a warning
rather than an error message.

Attempting to dereference a void*, as you've done here, is a
constraint violation. The compiler is required to issue some sort of
diagnostic message, but it doesn't have to be a fatal error (the
standard doesn't distinguish between warnings and other diagnostics).

As it happens, at least one major compiler allows, as an extension,
certain operations on void* that are not supported by the language.
If you're using gcc, that explains it.

Most warnings should be treated as errors anyway.
 
P

pete

Mark said:
void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
You are performing arithmetic operations with a void * pointer which
is not allowed.
&data[len] means &*(data + len)
Sorry!
I am very poor English!
How many the memery address would be add?? 1? or No Standards ??

No Standards for ((void *)data + 1).

1 memery address would be added for ((char *)data + 1).
 
V

vippstar

Mark Jiao said:
void printhex(const void *data,size_t len)
{
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");
}

I think what you're asking is why the compiler prints just a warning
rather than an error message.

Attempting to dereference a void*, as you've done here, is a
constraint violation. The compiler is required to issue some sort of
diagnostic message, but it doesn't have to be a fatal error (the
standard doesn't distinguish between warnings and other diagnostics).
I believe, since x[y] expands to (or, is equal to) *(x + y) what the
compiler should diagnose is about arithmetic on a 'void *' pointer.
 
H

Harald van Dijk

Mark Jiao said:
void printhex(const void *data,size_t len) {
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");
}

I think what you're asking is why the compiler prints just a warning
rather than an error message.

Attempting to dereference a void*, as you've done here, is a constraint
violation. The compiler is required to issue some sort of diagnostic
message, but it doesn't have to be a fatal error (the standard doesn't
distinguish between warnings and other diagnostics).
I believe, since x[y] expands to (or, is equal to) *(x + y) what the
compiler should diagnose is about arithmetic on a 'void *' pointer.

You're correct. Dereferencing a void * is allowed, though not
particularly useful, since you can't do anything with the result but
discard it or take its address again. Performing arithmetic on a void *
is not allowed, because void is an incomplete type. It's the same as how
performing arithmetic on int (*)[] is not allowed, because int [] is an
incomplete type.
 
J

Jack Klein

void printhex(const void *data,size_t len) {
unsigned char * tmp = data;
while(tmp < &data[len]) //just warning , ??
printf("%.2X ",*tmp++);
printf("\n");
}

I think what you're asking is why the compiler prints just a warning
rather than an error message.

Attempting to dereference a void*, as you've done here, is a constraint
violation. The compiler is required to issue some sort of diagnostic
message, but it doesn't have to be a fatal error (the standard doesn't
distinguish between warnings and other diagnostics).
I believe, since x[y] expands to (or, is equal to) *(x + y) what the
compiler should diagnose is about arithmetic on a 'void *' pointer.

You're correct. Dereferencing a void * is allowed, though not

Allowed by whom? Certainly not by the C language standard. Can you
cite C&V to the contrary?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
K

Keith Thompson

Jack Klein said:
[...]
You're correct. Dereferencing a void * is allowed, though not

Allowed by whom? Certainly not by the C language standard. Can you
cite C&V to the contrary?

Can you cite C&V that says it's *not* allowed? I checked earlier, and
I was surprised to discover that it does appear to be allowed.

In C99 6.5.3.2, the only constraint for the unary "*" operator is:

The operand of the unary * operator shall have pointer type.

and void* is a pointer type. Obviously there's very little you can do
with the result, but this:

void *ptr = /* some non-null value */
*ptr;

appears to be legal (though not particularly useful).
 
A

Army1987

Keith said:
In C99 6.5.3.2, the only constraint for the unary "*" operator is:

The operand of the unary * operator shall have pointer type.

and void* is a pointer type. Obviously there's very little you can do
with the result, but this:

void *ptr = /* some non-null value */
*ptr;

appears to be legal (though not particularly useful).

This has a curious consequence:
volatile void *ptr = SOMEWHERE;
*ptr;

How many bytes does that access?
 
P

Peter Nilsson

Army1987 said:
This has a curious consequence:
     volatile void *ptr = SOMEWHERE;
     *ptr;

How many bytes does that access?

None. [How many bytes does any other void expression access?]
 
A

Army1987

Peter said:
Army1987 said:
     volatile void *ptr = SOMEWHERE;
     *ptr;

How many bytes does that access?

None. [How many bytes does any other void expression access?]
(void)memcpy(foo, bar, 42) accesses 42 bytes.
 
W

Walter Roberson

Army1987 wrote:
84 bytes, I meant.

How do you arrive at that number? memcpy() does not define
the behaviour if the fields overlap. memmove() is the function
that defines the copying "as if" the data were copied into a
temporary buffer, and if such temporary copies were to take
place then Yes that would increase the byte count, but as you
have not defined the extent to which foo overlaps with bar,
you cannot say with any degree of certainty -exactly- how many
bytes would be accessed or how many times those bytes would be
accessed.
 
H

Harald van Dijk

How many bytes does the following access?

memcpy;

None. You've got a function designator which is not the operand of sizeof
or &, so it automatically gets converted to a pointer to memcpy. Besides,
functions aren't objects, and don't have to be made up of bytes at all,
and in some cases really might not be -- consider a C program running on
a virtual machine, where memcpy is implemented as a system call to the
host.
 
H

Harald van Dijk

How do you arrive at that number? memcpy() does not define the behaviour
if the fields overlap.

So assuming the fields don't overlap, memcpy reads 42 bytes, and writes
42 different bytes, so accesses 84 bytes in total.
 
P

Peter Nilsson

Army1987 said:
Peter said:
     volatile void *ptr = SOMEWHERE;
     *ptr;

How many bytes does that access?

None. [How many bytes does any other void expression
access?]

(void)memcpy(foo, bar, 42) accesses [84] bytes.
<snip>

[In light of Harald van Dijk's point on my followup...]
How many bytes does the following access?

memcpy(foo, bar, 0);

If it's none, then why should *memcpy(foo, bar, 0) be
any different? If it isn't different, then why should
dereferencing a volatile void pointer be any different?
 
W

Walter Roberson

So assuming the fields don't overlap, memcpy reads 42 bytes, and writes
42 different bytes, so accesses 84 bytes in total.

I must have been having a Duh moment. :(

Okay, so I'll turn it around: since the overlap of foo and bar is
not defined, we don't know that they occupy 42 distinct bytes each;
for example they might be offset by one byte from each other and
perhaps only 43 distinct bytes are accessed, 41 of them twice each.
The memcpy result is not defined for overlap, so we don't know
what the answer will be (fault for overlapping DMA perhaps), but
we can't say 84 bytes accessed for sure.
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top