bug-gnulib
[Top][All Lists]
Advanced

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

Symbol availability in C, C++


From: Albert Chin
Subject: Symbol availability in C, C++
Date: Sat, 26 Nov 2005 01:05:25 -0600
User-agent: Mutt/1.5.6i

It's not necessarily safe to assume a system variable/function/header,
if available to the C compiler, is available to the C++ compiler. This
is even in the case the same vendor provides the C and C++ compiler.
For example:
  1. On Tru64 UNIX 5.1, <stdint.h> is available to the C compiler,
     but not the C++ compiler.
     $ cat test.c
#include <stdint.h>
     $ cc -c test.c
     $ cp test.c test.cc
     $ cxx -c test.cc
cxx: Error: test.cc, line 1: could not open source file "stdint.h"
#include <stdint.h>
-------------------^
cxx: Info: 1 error detected in the compilation of "test.cc".

  2. On HP-UX 11.23/IA, <wchar.h> will bring in mbstate_t for the
     C++ compiler, but not the C89 compiler.
     $ cat test.c
#include <wchar.h>
     $ cc -E test.c | grep mbstate_t
     $ c99 -E test.c | grep mbstate_t
#line 1 "/usr/include/sys/_mbstate_t.h"
      } mbstate_t;
     ...
     $ cp test.c test.cc
     $ aCC -E test.cc | grep mbstate_t
#line 1 "/usr/include/sys/_mbstate_t.h"
      } mbstate_t;
     ...

We ran into a few problems like the above building lftp, a C++
command-line ftp client, which includes some of the gnulib modules. In
the case of #1 above, if a C++ program includes human.h, and
<stdint.h> is available, then the following code in human.h is called:
  # if HAVE_STDINT_H
  #  include <stdint.h>
  # endif
While HAVE_STDINT_H is in config.h, <stdint.h> is not available to the
C++ compiler. This caveat is specific to the compiler. The Sun C++
compiler is happy to bring in <stdint.h>.

How do we solve this? We've currently solved it by implementing
separate defines depending on the language. As an example, I've
attached our patched mbstate_t.m4 below. We've done something similar
for inttypes_h.m4, stdint_h.m4, and uintmax_t.m4. Is this the correct
approach? Ideally, we should autodetect AC_PROG_CXX and build with the
C++ compiler only if AC_PROG_CXX has been called (AC_PROVIDE_IFELSE?).

-- 
albert chin (address@hidden)

-- snip snip
--- mbstate_t.m4.orig   2005-01-26 00:38:40.000000000 -0600
+++ mbstate_t.m4        2005-11-26 00:36:42.285226000 -0600
@@ -13,7 +13,7 @@
 # AC_TYPE_MBSTATE_T
 # -----------------
 AC_DEFUN([AC_TYPE_MBSTATE_T],
-  [AC_CACHE_CHECK([for mbstate_t], ac_cv_type_mbstate_t,
+  [AC_CACHE_CHECK([for mbstate_t under C], ac_cv_type_mbstate_t,
      [AC_COMPILE_IFELSE(
        [AC_LANG_PROGRAM(
           [AC_INCLUDES_DEFAULT
@@ -22,9 +22,45 @@
        [ac_cv_type_mbstate_t=yes],
        [ac_cv_type_mbstate_t=no])])
    if test $ac_cv_type_mbstate_t = yes; then
-     AC_DEFINE([HAVE_MBSTATE_T], 1,
-              [Define to 1 if <wchar.h> declares mbstate_t.])
+     AC_DEFINE([HAVE_C_MBSTATE_T], 1,
+              [Define to 1 if <wchar.h> under C declares mbstate_t.])
    else
-     AC_DEFINE([mbstate_t], int,
-              [Define to a type if <wchar.h> does not define.])
-   fi])
+     AC_DEFINE([c_mbstate_t], int,
+              [Define to a type if <wchar.h> under C does not define.])
+   fi
+
+   AC_CACHE_CHECK([for mbstate_t under C++], ac_cv_cxx_type_mbstate_t,
+     [AC_LANG_PUSH(C++)
+      AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [AC_INCLUDES_DEFAULT
+#          include <wchar.h>],
+          [mbstate_t x; return sizeof x;])],
+       [ac_cv_cxx_type_mbstate_t=yes],
+       [ac_cv_cxx_type_mbstate_t=no])
+      AC_LANG_POP(C++)])
+   if test $ac_cv_cxx_type_mbstate_t = yes; then
+     AC_DEFINE([HAVE_CXX_MBSTATE_T], 1,
+              [Define to 1 if <wchar.h> under C++ declares mbstate_t.])
+   else
+     AC_DEFINE([cxx_mbstate_t], int,
+              [Define to a type if <wchar.h> under C++ does not define.])
+   fi
+
+   AH_VERBATIM([mbstate_t],
+              [/* Define to 1 if <wchar.h> declares mbstate_t.  */
+#ifdef __cplusplus
+#ifdef HAVE_CXX_MBSTATE_T
+#define HAVE_MBSTATE_T 1
+#endif
+#ifdef cxx_mbstate_t
+#define mbstate_t cxx_mbstate_t
+#endif
+#else
+#ifdef HAVE_C_MBSTATE_T
+#define HAVE_MBSTATE_T 1
+#endif
+#ifdef c_mbstate_t
+#define mbstate_t c_mbstate_t
+#endif
+#endif])])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]