void * in ANSC

Discussion in 'C Programming' started by Mark Jiao, Feb 3, 2008.

  1. Mark Jiao

    Mark Jiao Guest

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

  2. Mark Jiao

    Guest

    On Feb 3, 5:13 am, "Mark Jiao" <> wrote:
    > 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
    --
    while(tmp < (char *)data + len)
     
    , Feb 3, 2008
    #2
    1. Advertising

  3. Mark Jiao

    frog Guest

    On 2ÔÂ3ÈÕ, ÉÏÎç11ʱ13·Ö, "Mark Jiao" <> wrote:
    > void printhex(const void *data,size_t len)
    > {
    > unsigned char * tmp = data;
    > while(tmp < &data[len]) //just warning , ??
    > printf("%.2X ",*tmp++);
    > printf("\n");
    >
    >
    >
    > }- Òþ²Ø±»ÒýÓÃÎÄ×Ö -
    >
    > - ÏÔʾÒýÓõÄÎÄ×Ö -


    ??
     
    frog, Feb 3, 2008
    #3
  4. Mark Jiao

    Mark Jiao Guest

    ÔÚ Sun, 03 Feb 2008 11:22:09 +0800£¬<> дµÀ:

    > On Feb 3, 5:13 am, "Mark Jiao" <> wrote:
    >> 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!
    > Try this
    > --
    > while(tmp < (char *)data + len)




    --
     
    Mark Jiao, Feb 3, 2008
    #4
  5. "Mark Jiao" <> writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 3, 2008
    #5
  6. Mark Jiao

    pete Guest

    Mark Jiao wrote:
    >
    > ÔÚ Sun, 03 Feb 2008 11:22:09 +0800£¬<> дµÀ:
    >
    > > On Feb 3, 5:13 am, "Mark Jiao" <> wrote:
    > >> 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).

    > > Try this
    > > --
    > > while(tmp < (char *)data + len)


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

    --
    pete
     
    pete, Feb 3, 2008
    #6
  7. Mark Jiao

    Guest

    On Feb 3, 9:32 am, Keith Thompson <> wrote:
    > "Mark Jiao" <> writes:
    > > 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.
     
    , Feb 3, 2008
    #7
  8. On Sun, 03 Feb 2008 03:31:07 -0800, vippstar wrote:
    > On Feb 3, 9:32 am, Keith Thompson <> wrote:
    >> "Mark Jiao" <> writes:
    >> > 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.
     
    Harald van Dijk, Feb 3, 2008
    #8
  9. Mark Jiao

    Jack Klein Guest

    On Sun, 03 Feb 2008 12:47:45 +0100, Harald van D?k <>
    wrote in comp.lang.c:

    > On Sun, 03 Feb 2008 03:31:07 -0800, vippstar wrote:
    > > On Feb 3, 9:32 am, Keith Thompson <> wrote:
    > >> "Mark Jiao" <> writes:
    > >> > 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
     
    Jack Klein, Feb 3, 2008
    #9
  10. Jack Klein <> writes:
    > On Sun, 03 Feb 2008 12:47:45 +0100, Harald van D?k <>
    > wrote in comp.lang.c:

    [...]
    >> 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).

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 3, 2008
    #10
  11. Mark Jiao

    Army1987 Guest

    Keith Thompson wrote:

    > 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?



    --
    Army1987 (Replace "NOSPAM" with "email")
     
    Army1987, Feb 4, 2008
    #11
  12. Army1987 <> wrote:
    > Keith Thompson wrote:
    > > 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?


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

    --
    Peter
     
    Peter Nilsson, Feb 4, 2008
    #12
  13. Mark Jiao

    Army1987 Guest

    Peter Nilsson wrote:

    > Army1987 <> wrote:
    >>      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.



    --
    Army1987 (Replace "NOSPAM" with "email")
     
    Army1987, Feb 4, 2008
    #13
  14. Mark Jiao

    Army1987 Guest

    Army1987 wrote:

    > (void)memcpy(foo, bar, 42) accesses 42 bytes.

    84 bytes, I meant.

    --
    Army1987 (Replace "NOSPAM" with "email")
     
    Army1987, Feb 4, 2008
    #14
  15. Army1987 <> wrote:
    > Peter Nilsson wrote:
    > > Army1987 <> wrote:
    > > >      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.


    How many bytes does the following access?

    memcpy;

    --
    Peter
     
    Peter Nilsson, Feb 4, 2008
    #15
  16. In article <fo6th2$mls$>, Army1987 <> wrote:
    >Army1987 wrote:


    >> (void)memcpy(foo, bar, 42) accesses 42 bytes.


    >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.
    --
    "Okay, buzzwords only. Two syllables, tops." -- Laurie Anderson
     
    Walter Roberson, Feb 4, 2008
    #16
  17. On Mon, 04 Feb 2008 14:08:56 -0800, Peter Nilsson wrote:
    > 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.
     
    Harald van Dijk, Feb 4, 2008
    #17
  18. On Mon, 04 Feb 2008 22:21:04 +0000, Walter Roberson wrote:
    > In article <fo6th2$mls$>, Army1987 <>
    > wrote:
    >>Army1987 wrote:

    >
    >>> (void)memcpy(foo, bar, 42) accesses 42 bytes.

    >
    >>84 bytes, I meant.

    >
    > 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.
     
    Harald van Dijk, Feb 4, 2008
    #18
  19. > Army1987 <> wrote:
    > > Peter Nilsson wrote:
    > > > Army1987 <> wrote:
    > > > >      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?

    --
    Peter
     
    Peter Nilsson, Feb 4, 2008
    #19
  20. In article <1fad2$47a790c3$541dfcd3$1.nb.home.nl>,
    =?UTF-8?q?Harald_van_D=C4=B3k?= <> wrote:
    >On Mon, 04 Feb 2008 22:21:04 +0000, Walter Roberson wrote:
    >> In article <fo6th2$mls$>, Army1987 <>
    >> wrote:
    >>>Army1987 wrote:


    >>>> (void)memcpy(foo, bar, 42) accesses 42 bytes.


    >>>84 bytes, I meant.


    >> 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.


    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.

    --
    "Any sufficiently advanced bug is indistinguishable from a feature."
    -- Rich Kulawiec
     
    Walter Roberson, Feb 4, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sergio

    returning a void (*)(void)

    Sergio, Jan 5, 2005, in forum: C++
    Replies:
    6
    Views:
    453
    Jonathan Turkanis
    Jan 5, 2005
  2. Ollej Reemt
    Replies:
    7
    Views:
    600
    Jack Klein
    Apr 22, 2005
  3. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    836
    The Real OS/2 Guy
    Oct 28, 2003
  4. Replies:
    5
    Views:
    880
    S.Tobias
    Jul 22, 2005
  5. Replies:
    1
    Views:
    434
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page