Back to index

nagios-plugins  1.4.16
verify.h
Go to the documentation of this file.
00001 /* Compile-time assert-like macros.
00002 
00003    Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc.
00004 
00005    This program is free software: you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 /* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
00019 
00020 #ifndef VERIFY_H
00021 # define VERIFY_H 1
00022 
00023 /* Each of these macros verifies that its argument R is nonzero.  To
00024    be portable, R should be an integer constant expression.  Unlike
00025    assert (R), there is no run-time overhead.
00026 
00027    There are two macros, since no single macro can be used in all
00028    contexts in C.  verify_true (R) is for scalar contexts, including
00029    integer constant expression contexts.  verify (R) is for declaration
00030    contexts, e.g., the top level.
00031 
00032    Symbols ending in "__" are private to this header.
00033 
00034    The code below uses several ideas.
00035 
00036    * The first step is ((R) ? 1 : -1).  Given an expression R, of
00037      integral or boolean or floating-point type, this yields an
00038      expression of integral type, whose value is later verified to be
00039      constant and nonnegative.
00040 
00041    * Next this expression W is wrapped in a type
00042      struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.
00043      If W is negative, this yields a compile-time error.  No compiler can
00044      deal with a bit-field of negative size.
00045 
00046      One might think that an array size check would have the same
00047      effect, that is, that the type struct { unsigned int dummy[W]; }
00048      would work as well.  However, inside a function, some compilers
00049      (such as C++ compilers and GNU C) allow local parameters and
00050      variables inside array size expressions.  With these compilers,
00051      an array size check would not properly diagnose this misuse of
00052      the verify macro:
00053 
00054        void function (int n) { verify (n < 0); }
00055 
00056    * For the verify macro, the struct verify_type__ will need to
00057      somehow be embedded into a declaration.  To be portable, this
00058      declaration must declare an object, a constant, a function, or a
00059      typedef name.  If the declared entity uses the type directly,
00060      such as in
00061 
00062        struct dummy {...};
00063        typedef struct {...} dummy;
00064        extern struct {...} *dummy;
00065        extern void dummy (struct {...} *);
00066        extern struct {...} *dummy (void);
00067 
00068      two uses of the verify macro would yield colliding declarations
00069      if the entity names are not disambiguated.  A workaround is to
00070      attach the current line number to the entity name:
00071 
00072        #define _GL_CONCAT0(x, y) x##y
00073        #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
00074        extern struct {...} * _GL_CONCAT (dummy, __LINE__);
00075 
00076      But this has the problem that two invocations of verify from
00077      within the same macro would collide, since the __LINE__ value
00078      would be the same for both invocations.  (The GCC __COUNTER__
00079      macro solves this problem, but is not portable.)
00080 
00081      A solution is to use the sizeof operator.  It yields a number,
00082      getting rid of the identity of the type.  Declarations like
00083 
00084        extern int dummy [sizeof (struct {...})];
00085        extern void dummy (int [sizeof (struct {...})]);
00086        extern int (*dummy (void)) [sizeof (struct {...})];
00087 
00088      can be repeated.
00089 
00090    * Should the implementation use a named struct or an unnamed struct?
00091      Which of the following alternatives can be used?
00092 
00093        extern int dummy [sizeof (struct {...})];
00094        extern int dummy [sizeof (struct verify_type__ {...})];
00095        extern void dummy (int [sizeof (struct {...})]);
00096        extern void dummy (int [sizeof (struct verify_type__ {...})]);
00097        extern int (*dummy (void)) [sizeof (struct {...})];
00098        extern int (*dummy (void)) [sizeof (struct verify_type__ {...})];
00099 
00100      In the second and sixth case, the struct type is exported to the
00101      outer scope; two such declarations therefore collide.  GCC warns
00102      about the first, third, and fourth cases.  So the only remaining
00103      possibility is the fifth case:
00104 
00105        extern int (*dummy (void)) [sizeof (struct {...})];
00106 
00107    * GCC warns about duplicate declarations of the dummy function if
00108      -Wredundant_decls is used.  GCC 4.3 and later have a builtin
00109      __COUNTER__ macro that can let us generate unique identifiers for
00110      each dummy function, to suppress this warning.
00111 
00112    * This implementation exploits the fact that GCC does not warn about
00113      the last declaration mentioned above.  If a future version of GCC
00114      introduces a warning for this, the problem could be worked around
00115      by using code specialized to GCC, just as __COUNTER__ is already
00116      being used if available.
00117 
00118        #if 4 <= __GNUC__
00119        # define verify(R) [another version to keep GCC happy]
00120        #endif
00121 
00122    * In C++, any struct definition inside sizeof is invalid.
00123      Use a template type to work around the problem.  */
00124 
00125 /* Concatenate two preprocessor tokens.  */
00126 # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
00127 # define _GL_CONCAT0(x, y) x##y
00128 
00129 /* _GL_COUNTER is an integer, preferably one that changes each time we
00130    use it.  Use __COUNTER__ if it works, falling back on __LINE__
00131    otherwise.  __LINE__ isn't perfect, but it's better than a
00132    constant.  */
00133 # if defined __COUNTER__ && __COUNTER__ != __COUNTER__
00134 #  define _GL_COUNTER __COUNTER__
00135 # else
00136 #  define _GL_COUNTER __LINE__
00137 # endif
00138 
00139 /* Generate a symbol with the given prefix, making it unique if
00140    possible.  */
00141 # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
00142 
00143 /* Verify requirement R at compile-time, as an integer constant expression.
00144    Return 1.  */
00145 
00146 # ifdef __cplusplus
00147 template <int w>
00148   struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
00149 #  define verify_true(R) \
00150      (!!sizeof (verify_type__<(R) ? 1 : -1>))
00151 # else
00152 #  define verify_true(R) \
00153      (!!sizeof \
00154       (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
00155 # endif
00156 
00157 /* Verify requirement R at compile-time, as a declaration without a
00158    trailing ';'.  */
00159 
00160 # define verify(R) \
00161     extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
00162 
00163 #endif