]> git.saurik.com Git - wxWidgets.git/commitdiff
Avoid using "do { ... } while ( wxFalse )" pseudo-loop.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 2 Dec 2012 23:48:36 +0000 (23:48 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 2 Dec 2012 23:48:36 +0000 (23:48 +0000)
This loop can't be optimized away by the compiler because wxFalse is an extern
variable which can't be known to be always false. Additionally, this creates
many false positives from Coverity as it assumes that the loop can be executed
more than once.

Define wxSTATEMENT_MACRO_BEGIN/END macros abstracting the exact solution used
and replace wxFalse with "(void)0, 0" for now as this seems to placate MSVC
(which warns about using a bare "0" as a condition) while still allowing the
loop to be completely optimized away.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73101 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/checkeddelete.h
include/wx/cpp.h
include/wx/strvararg.h

index a9e14c3a2e560ccc0dde53e125eac2fd36837a8f..a03d7454d62d126e63d544b8815e8826909d32b9 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef _WX_CHECKEDDELETE_H_
 #define _WX_CHECKEDDELETE_H_
 
+#include "wx/cpp.h"
+
 // TODO: provide wxCheckedDelete[Array]() template functions too
 
 // ----------------------------------------------------------------------------
    still force a semicolon after the macro
 */
 
-#ifdef __WATCOMC__
-    #define wxFOR_ONCE(name)              for(int name=0; name<1; name++)
-    #define wxPRE_NO_WARNING_SCOPE(name)  wxFOR_ONCE(wxMAKE_UNIQUE_NAME(name))
-    #define wxPOST_NO_WARNING_SCOPE(name)
-#else
-    #define wxPRE_NO_WARNING_SCOPE(name)  do
-    #define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse )
-#endif
-
 #define wxCHECKED_DELETE(ptr)                                                 \
-    wxPRE_NO_WARNING_SCOPE(scope_var1)                                        \
-    {                                                                         \
+    wxSTATEMENT_MACRO_BEGIN                                                   \
         typedef char complete[sizeof(*ptr)];                                  \
         delete ptr;                                                           \
-    } wxPOST_NO_WARNING_SCOPE(scope_var1)
+    wxSTATEMENT_MACRO_END
 
 #define wxCHECKED_DELETE_ARRAY(ptr)                                           \
-    wxPRE_NO_WARNING_SCOPE(scope_var2)                                        \
-    {                                                                         \
+    wxSTATEMENT_MACRO_BEGIN                                                   \
         typedef char complete[sizeof(*ptr)];                                  \
         delete [] ptr;                                                        \
-    } wxPOST_NO_WARNING_SCOPE(scope_var2)
+    wxSTATEMENT_MACRO_END
 
 
 #endif // _WX_CHECKEDDELETE_H_
index 657b0673eb845d85e9122f25a7fadc100d7d8362..9fed106a76b2cb06174367aa518bbf53fddad057 100644 (file)
  */
 #define wxEMPTY_PARAMETER_VALUE /* Fake macro parameter value */
 
+/*
+    Helpers for defining macros that expand into a single statement.
+
+    The standatd solution is to use "do { ... } while (0)" statement but MSVC
+    generates a C4127 "condition expression is constant" warning for it so we
+    use something which is just complicated enough to not be recognized as a
+    constant but still simple enough to be optimized away.
+
+    Another solution would be to use __pragma() to temporarily disable C4127.
+
+    Notice that wxASSERT_ARG_TYPE in wx/strvargarg.h relies on these macros
+    creating some kind of a loop because it uses "break".
+ */
+#ifdef __WATCOMC__
+    #define wxFOR_ONCE(name) for(int name=0; name<1; name++)
+    #define wxSTATEMENT_MACRO_BEGIN wxFOR_ONCE(wxMAKE_UNIQUE_NAME(wxmacro)) {
+    #define wxSTATEMENT_MACRO_END }
+#else
+    #define wxSTATEMENT_MACRO_BEGIN  do {
+    #define wxSTATEMENT_MACRO_END } while ( (void)0, 0 )
+#endif
+
 /*
     Define __WXFUNCTION__ which is like standard __FUNCTION__ but defined as
     NULL for the compilers which don't support the latter.
index 0bde80b3a675504d8e853e489ae0725d148a4dff..8f2d16551ecc25c592cd497274ef276b1d149699 100644 (file)
@@ -309,14 +309,13 @@ struct wxFormatStringArgumentFinder<wxWCharBuffer>
     // the correct type (one of wxFormatString::Arg_XXX or-combination in
     // 'expected_mask').
     #define wxASSERT_ARG_TYPE(fmt, index, expected_mask)                    \
-        do                                                                  \
-        {                                                                   \
+        wxSTATEMENT_MACRO_BEGIN                                             \
             if ( !fmt )                                                     \
                 break;                                                      \
             const int argtype = fmt->GetArgumentType(index);                \
             wxASSERT_MSG( (argtype & (expected_mask)) == argtype,           \
                           "format specifier doesn't match argument type" ); \
-        } while ( wxFalse )
+        wxSTATEMENT_MACRO_END
 #else
     // Just define it to suppress "unused parameter" warnings for the
     // parameters which we don't use otherwise