bug-gnulib
[Top][All Lists]
Advanced

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

Re: unused test files, verify.h problem in libvirt


From: Paul Eggert
Subject: Re: unused test files, verify.h problem in libvirt
Date: Wed, 05 May 2010 12:55:45 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Eric Blake <address@hidden> writes:

>    * This implementation exploits the fact that GCC does not warn about
>      the last declaration mentioned above.  If a future version of GCC
>      introduces a warning for this, the problem could be worked around
>      by using code specialized to GCC, e.g.,:
>
>        #if 4 <= __GNUC__
>        # define verify(R) \
>            extern int (* verify_function__ (void)) \
>                       [__builtin_constant_p (R) && (R) ? 1 : -1]
>        #endif
>
> So there has already been some thought on what to do if gcc gets too
> picky (although the solution mentioned in that comment doesn't look like
> it will silence -Wredundant-decls).

That comment looks obsolete to me, as it is talking about a
previous implementation of verify.h, which used negative-sized arrays.
(The current implementation uses negative-width bitfields.)

To fix the problem you mentioned with verify.h, I installed the
following patch into gnulib.  It uses the new __COUNTER__ macro of GCC
(4.3 and later), which is designed for this problem.  So this should fix
the warnings for GCC 4.3 and later.  Older GCCs will still generate the
warning with -Wredundant_decls, but that's OK: people will upgrade
eventually.  This patch defines new macros GL_CONCAT and GL_GENSYM which
may well be useful elsewhere in gnulib, so I gave them a GL_ prefix
rather than a verify_ prefix; if (as I suspect) they are generally
useful, we will probably need to break them out into a different .h file.


Modify verify.h to pacify gcc -Wredundant_decls.
* lib/verify.h (GL_CONCAT, GL_CONCAT0, GL_GENSYM): New macros.
These use the prefix "GL_" since they're likely to be useful elsewhere.
We may need to break them out into a different .h file.
(__COUNTER__): Define to 0 if the compiler doesn't support it.
(verify) [!defined __cplusplus]: Use them to avoid duplicate decls
of verify_function__.
diff --git a/lib/verify.h b/lib/verify.h
index bcd3f5a..dbca35c 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -75,7 +75,8 @@

      But this has the problem that two invocations of verify from
      within the same macro would collide, since the __LINE__ value
-     would be the same for both invocations.
+     would be the same for both invocations.  (The GCC __COUNTER__
+     macro solves this problem, but is not portable.)

      A solution is to use the sizeof operator.  It yields a number,
      getting rid of the identity of the type.  Declarations like
@@ -103,20 +104,38 @@

        extern int (*dummy (void)) [sizeof (struct {...})];

+   * GCC warns about duplicate declarations of the dummy function if
+     -Wredundant_decls is used.  GCC 4.3 and later have a builtin
+     __COUNTER__ macro that can let us generate unique identifiers for
+     each dummy function, to suppress this warning.
+
    * This implementation exploits the fact that GCC does not warn about
      the last declaration mentioned above.  If a future version of GCC
      introduces a warning for this, the problem could be worked around
-     by using code specialized to GCC, e.g.,:
+     by using code specialized to GCC, just as __COUNTER__ is already
+     being used if available.

        #if 4 <= __GNUC__
-       # define verify(R) \
-           extern int (* verify_function__ (void)) \
-                      [__builtin_constant_p (R) && (R) ? 1 : -1]
+       # define verify(R) [another version to keep GCC happy]
        #endif

    * In C++, any struct definition inside sizeof is invalid.
      Use a template type to work around the problem.  */

+/* Concatenate two preprocessor tokens.  */
+# define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
+# define GL_CONCAT0(x, y) x##y
+
+/* __COUNTER__ evaluates to 0, 1, 2,..., adding one one each time the
+   preprocessor uses it.  If the preprocessor doesn't support this
+   builtin macro, define it to 0.  */
+# ifndef __COUNTER__
+#  define __COUNTER__ 0
+# endif
+
+/* Generate a symbol with the given prefix, making it unique if
+   possible.  */
+# define GL_GENSYM(prefix) GL_CONCAT(prefix, __COUNTER__)

 /* Verify requirement R at compile-time, as an integer constant expression.
    Return 1.  */
@@ -135,6 +154,7 @@ template <int w>
 /* Verify requirement R at compile-time, as a declaration without a
    trailing ';'.  */

-# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)]
+# define verify(R) \
+    extern int (* GL_GENSYM(verify_function) (void)) [verify_true (R)]

 #endif




reply via email to

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