]> granicus.if.org Git - postgresql/commitdiff
Start using flexible array members
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 16 Jun 2011 19:39:09 +0000 (22:39 +0300)
committerPeter Eisentraut <peter_e@gmx.net>
Thu, 16 Jun 2011 19:45:38 +0000 (22:45 +0300)
Flexible array members are a C99 feature that avoids "cheating" in the
declaration of variable-length arrays at the end of structs.  With
Autoconf support, this should be transparent for older compilers.

We start with one use in gist.h because gcc 4.6 started to raise a
warning there.  Over time, it can be expanded to other places in the
source, but they will likely need some review of sizeof and offsetof
usage.  The current change in gist.h appears to be safe in this
regard.

configure
configure.in
src/include/access/gist.h
src/include/pg_config.h.in

index a2c3aab407b0e9effb75803145bf563967f9094d..9b8cb48931da9d7f0ab42625c9eb6806b0718c52 100755 (executable)
--- a/configure
+++ b/configure
@@ -14954,6 +14954,77 @@ _ACEOF
 
 fi
 
+
+  { $as_echo "$as_me:$LINENO: checking for flexible array members" >&5
+$as_echo_n "checking for flexible array members... " >&6; }
+if test "${ac_cv_c_flexmember+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+           #include <stdio.h>
+           #include <stddef.h>
+           struct s { int n; double d[]; };
+int
+main ()
+{
+int m = getchar ();
+           struct s *p = malloc (offsetof (struct s, d)
+                                 + m * sizeof (double));
+           p->d[0] = 0.0;
+           return p->d != (double *) NULL;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_c_flexmember=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_c_flexmember=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_flexmember" >&5
+$as_echo "$ac_cv_c_flexmember" >&6; }
+  if test $ac_cv_c_flexmember = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define FLEXIBLE_ARRAY_MEMBER /**/
+_ACEOF
+
+  else
+    cat >>confdefs.h <<\_ACEOF
+#define FLEXIBLE_ARRAY_MEMBER 1
+_ACEOF
+
+  fi
+
 { $as_echo "$as_me:$LINENO: checking for signed types" >&5
 $as_echo_n "checking for signed types... " >&6; }
 if test "${pgac_cv_c_signed+set}" = set; then
index ddc4cc9a1676af06b2987a164d1834e9973bab0b..e873c7b157237d1161d6a24a8e5c4b320949238c 100644 (file)
@@ -1110,6 +1110,7 @@ AC_C_BIGENDIAN
 AC_C_CONST
 PGAC_C_INLINE
 AC_C_STRINGIZE
+AC_C_FLEXIBLE_ARRAY_MEMBER
 PGAC_C_SIGNED
 AC_C_VOLATILE
 PGAC_C_FUNCNAME_SUPPORT
index df9f39c7b8932455959badc0ba08e48bda82295d..5ce7325ff9badf0a334cad21823dc34610e405f7 100644 (file)
@@ -144,7 +144,7 @@ typedef struct GISTENTRY
 typedef struct
 {
        int32           n;                              /* number of elements */
-       GISTENTRY       vector[1];              /* variable-length array */
+       GISTENTRY       vector[FLEXIBLE_ARRAY_MEMBER];
 } GistEntryVector;
 
 #define GEVHDRSZ       (offsetof(GistEntryVector, vector))
index 5d38f25d263a0b1a9175fa36620e822ece6cd85d..19f38cc0fd0839fe8b41f80b4fb30b7a332ecfde 100644 (file)
    (--enable-thread-safety) */
 #undef ENABLE_THREAD_SAFETY
 
+/* Define to nothing if C supports flexible array members, and to 1 if it does
+   not. That way, with a declaration like `struct s { int n; double
+   d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99
+   compilers. When computing the size of such an object, don't use 'sizeof
+   (struct s)' as it overestimates the size. Use 'offsetof (struct s, d)'
+   instead. Don't use 'offsetof (struct s, d[0])', as this doesn't work with
+   MSVC and with C++ compilers. */
+#undef FLEXIBLE_ARRAY_MEMBER
+
 /* float4 values are passed by value if 'true', by reference if 'false' */
 #undef FLOAT4PASSBYVAL