> -----Original Message-----
> From: Joe Wilson [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, January 24, 2007 5:04 PM
> To: sqlite-users@sqlite.org
> Subject: RE: [sqlite] Fix for sqlite3.h in version 3.3.10
> 
> --- James Dennett <[EMAIL PROTECTED]> wrote:
> > Joe Wilson wrote:
> > > The proposed expression ((sqlite3_destructor_type)-1) is
equivalent to
> > > ((void(*)(void *))-1). They are interchangable.
> >
> > Not in C++.  The difference being linkage; with the typedef declared
in
> > an extern "C" block, the type is something that can't be written
> > directly.
> 
> Now I understand your confusion. SQLite is a C. All its API
definitions in
> sqlite3.h and its function pointers are obviously C-based. 

They are intended, I believe, to be usable from both C and C++, and they
have code present to allow their use from C++ -- it's just not quite
complete.

> So to avoid
> these
> warnings related to using SQLITE_TRANSIENT (or SIG_ERR for that
matter)
> in your C++ code, your C++ implementation file must do the following:

That would be one workaround, but it's cleaner to make the header work
with C++ as intended.  The #ifdef __cplusplus sections in the header
file are clearly present to allow its use from C++ without needing
contortions.  That is common practice in C header files which make some
basic effort to integrate smoothly with C++.  The effort required is not
large.

> // example.cpp
> #include "sqlite3.h"
> extern "C" {
>   void example(sqlite3_context* c, const char* b, int n) {
>     sqlite3_result_text(c, b, n, SQLITE_TRANSIENT);
>   }
>   // you can even put class member function implementations in here
>   // i.e., void Foo::bar() {...}
>   // without affecting their C++ linkage.
> }
> 
> You'll find that it compiles in Sun C++ 5.8 2005/10/13 without
warnings
> using the unmodified sqlite3.h file.

I expect it would, but it's suboptimal.  C++ code ought not to need such
extern "C" blocks except for 

> The C++ code does not need the proposed typedef to handle
> SQLITE_TRANSIENT,
> although if it were added to sqlite3.h it would not do any harm, and
you
> might be able to avoid the extern "C" block around your sqlite-related
> function implementations.

Correct.

> > >   #define SIG_IGN (void(*)(int))1
> > >   #define SIG_ERR (void(*)(int))-1
> > >
> > > Such C code is grandfathered in C++. If it wasn't you wouldn't be
able
> > > to do any UNIX systems programming in C++.
> >
> > It's not portable C, and it's not portable C++.  It does seem to be
> > blessed by POSIX, but POSIX is just a subset of the much larger
range of
> > platforms supported by ISO/ANSI C and C++.
> 
> In your original question you asked:
> 
>  On a related but separate note, is there any standard that guarantees
>  that casting -1 to a function pointer type is reasonably portable?
> 
> And yes, it is reasonably portable as shown by every UNIX variant that
> must deal with POSIX and every major C++ compiler vendor, as a
> consequence.

The POSIX reference you provided didn't show any such examples though,
unless I missed something.  It shows APIs that specify that certain
arguments can use given named values or function pointers, but the named
values aren't specified, and could themselves be distinguished function
pointers.

POSIX does blur the distinction between data pointers and code pointers
(e.g., with dlsym), but that's a separate issue.

> That's good enough for me. It may or may not be blessed by the C++
> standard,
> but if you can dig up a modern popular C++ compiler that does not work
> with
> such code, I'd be surprised.

It's likely that I can find C++ tools that will diagnose it as an error;
there are reasonable implementation techniques which would mean that it
is not reliable (such as ignoring the bottom bits of function pointers).
I don't know of any platform which would have problems, but why break
the rules when a standards-conforming solution is trivial?

My proposed patch didn't address the int->void(*)(void*) conversion
issue, only the C++-compatibility wart.  Is there any good argument for
not doing so?

-- James

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to