Re: C++ ansi/pedantic problem



On Mon, 27 Dec 1999, Karl Nelson wrote:

> Date: Mon, 27 Dec 1999 18:04:35 -0800
> From: Karl Nelson <kenelson@ece.ucdavis.edu>
> Reply-To: gtk-devel-list@redhat.com
> To: gtk-devel-list@redhat.com
> Cc: kenelson@sequoia.ece.ucdavis.edu
> Subject: C++ ansi/pedantic problem 
> Resent-Date: 28 Dec 1999 02:04:57 -0000
> Resent-From: gtk-devel-list@redhat.com
> Resent-cc: recipient list not shown: ;
> 
> 
> The gtk-- project is having a problem with one of the declarations
> in the gtk+ headers.  Apparently, a compiler switch for checking
> for ansi violations in C++ code is also changing the nature of some 
> of the declarations.  
> 
>   typedef void (*GtkSignalFunc) ();
> 
>      ==  void (*)(void)   default
>      ==  void (*)(...)    -ansi -pedantic

In C++, the type GtkSignalFunc is declared as a pointer to a function that
takes no parameters and returns void. If the -ansi -pedantic options bring
about any other meaning, then the compiler is broken.

The only way to get the (...) meaning is to write a declarator with (...).

However, in the C language, the type is declared as a pointer to a
(non-variadic) function  having an uknown number and types of arguments---this
information will be deduced from the call.

> This means that if unless the gtk+ library and the applications
> are compiled with the same switchs there is linker errors for
> C++ programs.  (A demo of how this is a problem is attached.)

Without looking at the attached code, I suspect that the problem might be
related due to lack of proper extern "C" linkage specification.

> The solution is to fix the declaration of GtkSignalFunc to 
> the desired meaning when working with C++ compilers.
> 
> Replacing the declaration with 
> 
>   #ifdef __cplusplus
>   typedef void (*GtkSignalFunc) (void);
>   #else
>   typedef void (*GtkSignalFunc) ();
>   #endif

This is backwards. In C, the parameter list (void) fully specifies that the
function doesn't take any parameters. In C++, the (void) parameter list is
unnecessary, but supported for backward compatibility with C. You
should never use (void) in C++ programs. It's a syntactic hack specifically
introduced in ANSI C to solve problems unique to that language.

If you want to interface new C++ code with a C library which depends on
the use of less-than-fully specified function types, you might have to
resort to the (...) declaration, e.g.

    /* header file for brain-damaged C library */
    #ifdef __cplusplus
    typedef void (*callback_function_with_uknown_parameters)(...);
    #else /* ANSI C */
    typedef void (*callback_function_with_unknown_parameters)();
    #endif

The real solution in this case is to use a type that has a well defined
parameter list, and stop writing in 1978 C once and for all.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]