Re: VC++.NET 2003 should not issue C4090 ompiler warning in the following case

From: Doug Harrison [MVP] (dsh_at_mvps.org)
Date: 08/03/04


Date: Mon, 02 Aug 2004 23:59:37 -0500

John Smith wrote:

>Hi,
>
>I would like to understand what's going on here:
>
>const void *foo[10];
>
>void bar(void)
>{
> // issues warning C4090: 'function' : different 'const' qualifiers
> memset(foo, 0, sizeof(const void *) * 10);
>}
>
>Why does the VC++ compiler (7.1.3088) issue a warning here? The foo
>array is not declared constant. Only the cell of the array is of type
>const void *.
>This is my first question.
>
>Now, if I replace the code with:
>
>typedef void *MYTYPE;
>typedef const MYTYPE MYCONSTTYPE;
>
>MYCONSTTYPE foo[10];
>
>memset(foo, 0, sizeof(const void *) * 10);
>
>then no warning is issued, although the code looks quite identical.
>
>How is this possible?

Don't you have that backwards? The first one is legal, but the second one is
not. The second actually declares foo to be an array of void* const. You're
probably thinking that:

 typedef const MYTYPE MYCONSTTYPE;

makes MYCONSTTYPE equivalent to:

 const void*

as if simple textual substitution were performed. But typedefs don't work
that way. In fact, given that MYTYPE is a typedef, it doesn't matter where
you place the const; the following are equivalent:

 typedef const MYTYPE MYCONSTTYPE;
 typedef MYTYPE const MYCONSTTYPE;

Given that MYTYPE is void*, they both mean:

 void* const

You can think of it this way. The const and volatile modifiers don't
penetrate into typedefs. Instead, they modify the thing being declared,
which above is MYCONSTTYPE.

P.S. You can replace:

  memset(foo, 0, sizeof(const void *) * 10);

with:

  memset(foo, 0, sizeof(void *) * 10);

or better still, given that foo is an array:

  memset(foo, 0, sizeof(foo));

Speaking ultra-pedantically, memsetting pointers to zero isn't guaranteed to
set them to null, though I can't name a system where it doesn't.

-- 
Doug Harrison
Microsoft MVP - Visual C++


Relevant Pages

  • Re: VC++.NET 2003 should not issue C4090 ompiler warning in the following case
    ... Only the cell of the array is of type ... The second actually declares foo to be an array of void* const. ... > typedef const MYTYPE MYCONSTTYPE; ...
    (microsoft.public.vc.language)
  • Re: strange behaviour
    ... array as an argument instead of a double pointer. ... Technically it behaves exactly like char **s2, ... unsigned int const dst_buffer_length, ... void array_truncate; ...
    (comp.lang.c)
  • Re: const variables
    ... case this variable is a rather large array. ... treat whatever sp points to as const. ... void foo1 ... pointer is of type:  struct data *ptr and I have to then call the ...
    (comp.lang.c)
  • VC++.NET 2003 should not issue C4090 ompiler warning in the following case
    ... Why does the VC++ compiler issue a warning here? ... Only the cell of the array is of type ... const void *. ... typedef const MYTYPE MYCONSTTYPE; ...
    (microsoft.public.vc.language)
  • SWIG typemap problem
    ... void SetPoint; ... %typemapconst double value{ ... convert ruby array in c++ array ... now i add another SetPoint to the class Foo: ...
    (comp.lang.ruby)

Quantcast