To the rest of the list:  I apologize for the long and rambling post that
follows.  Please feel free to flame me privately for the wasted band-width
- my e-mail is <mailto:[EMAIL PROTECTED]>.  Thanks for your patience!

Alan,

I went back to my example:

   char* data = "A string";
   const char** dataP = (char**) &data;

   // Legal stuff:
   **dataP = '\0';   // data now equals ""

This time  the last line fails to compile!  Which, I think, is what you
want.  So now I'm confused.  Damn!  I fell into the dreaded 'C' const
declaration trap myself!

Let me think out loud, here:

void * is a pointer to memory
void ** is a pointer to a pointer to memory
void const * is a pointer to const memory (equivalent to const void*).
void const * * is a pointer to a pointer to constant memory (equivalent,
evidentally, to const void**).
void * const * is a pointer to a constant pointer to memory.
void const * const * is a pointer to a const pointer to const memory.
void const * const * const is a const pointer to a const pointer to const
memory.

So I would think that void const ** (or const void**) is the one you want.

First I constructed a test file that exercises this.  Interestingly enough,
VC6 works according to this analysis, CW blithely casts char** to const
void**, as you mentioned.

And then I noticed that I was working with a CPP file.  I'm not surprised
that VC6/CPP caught the char** cast to const void** as it is really picky
about this stuff as per the ANSI C++ standard.  I copied my CPP file to a
'C' file and tried again.  Both VC6 and CW compiled it exactly as you said
it would!  I have to confess that I am now completely at a loss as to what
the proper declaration is.  

But wait!  I have a thought.  If I have a function that takes a pointer to
a constant character array:

   void Foo (const char* stringP);

and I pass it a non-const string:

   char aString[25];
   Foo (aString);

then this is okay.  What the declaration says is that I promise that Foo
will not change the contents pointed to by stringP.  It does not require
that stringP be a const char*.

I guess that this similarly applies to our problem:

   void Bar (const char** stringPP);

This function promises that it will not change the contents pointed to by
(*stringPP).    Again, it does not require that (*stringPP) be a const char*.

I guess the easy answer is just to return the pointer, rather than stuffing
it in an out-param:

   const void* Squonk ( );

The return value must be assigned to a const void* variable:

   const void* p = Squonk ( );

Of course, the user can still get around this by casting:

   void* p = (void*) Squonk ( );

Another approach would be to create a structure to return these in:

   typedef struct
   {
      const void* p;
   } ValueType, *ValuePtr;

and pass this to the function:

   void Clank (ValuePtr valP);

This would allow you to provide more info, as well, such as the size of the
data at p, the type of data, etc.  This is the approach I would probably take.
   
Please contact me off-list (mailto: [EMAIL PROTECTED]) and I'll
send you my little test file.  Perhaps we can solve this mystery!

Regards,
Greg (quietly eating his earlier words)



Greg Winton
Bachmann Software and Services, LLC
mailto:[EMAIL PROTECTED]
http://www.bachmannsoftware.com
Software Development for Handheld & Mobile Computing, Windows and the Internet
Home of Bachmann Print Manager, the only graphical printing solution for
the Palm Computing Platform

Reply via email to