From 569fd66c4a7165499ed45f4881693f6657c55312 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 15 Sep 2016 01:03:15 +0300 Subject: [PATCH] Eliminate 'constructor with 1 argument is not explicit' cppcheck warning Note that -D CPPCHECK should be passed to cppcheck to activate this workaround. * include/gc_allocator.h (GC_ATTR_EXPLICIT): New macro (defined to "explicit" keyword if at least C++11 or CPPCHECK, otherwise to empty). * include/gc_allocator.h (gc_allocator::gc_allocator, gc_allocator_ignore_off_page::gc_allocator_ignore_off_page, traceable_allocator::traceable_allocator): Use GC_ATTR_EXPLICIT. * tests/test_cpp.cc (A::A, B::B, C::C, D::D): Likewise. * tests/test_cpp.cc (GC_ATTR_EXPLICIT): Define macro (as empty) unless already defined in included gc_allocator.h. --- include/gc_allocator.h | 17 +++++++++++++---- tests/test_cpp.cc | 12 ++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/include/gc_allocator.h b/include/gc_allocator.h index 367cfe2..3ea80a0 100644 --- a/include/gc_allocator.h +++ b/include/gc_allocator.h @@ -50,6 +50,14 @@ # define GC_ATTR_UNUSED #endif +#ifndef GC_ATTR_EXPLICIT +# if (__cplusplus >= 201103L) || defined(CPPCHECK) +# define GC_ATTR_EXPLICIT explicit +# else +# define GC_ATTR_EXPLICIT /* empty */ +# endif +#endif + /* First some helpers to allow us to dispatch on whether or not a type * is known to be pointer-free. * These are private, except that the client may invoke the @@ -116,7 +124,8 @@ public: gc_allocator(const gc_allocator&) throw() {} # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200) // MSVC++ 6.0 do not support member templates - template gc_allocator(const gc_allocator&) throw() {} + template GC_ATTR_EXPLICIT + gc_allocator(const gc_allocator&) throw() {} # endif ~gc_allocator() throw() {} @@ -191,7 +200,7 @@ public: gc_allocator_ignore_off_page(const gc_allocator_ignore_off_page&) throw() {} # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200) // MSVC++ 6.0 do not support member templates - template + template GC_ATTR_EXPLICIT gc_allocator_ignore_off_page(const gc_allocator_ignore_off_page&) throw() {} # endif @@ -271,8 +280,8 @@ public: traceable_allocator(const traceable_allocator&) throw() {} # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200) // MSVC++ 6.0 do not support member templates - template traceable_allocator - (const traceable_allocator&) throw() {} + template GC_ATTR_EXPLICIT + traceable_allocator(const traceable_allocator&) throw() {} # endif ~traceable_allocator() throw() {} diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index d9ebd28..642bdfd 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -76,10 +76,14 @@ extern "C" { # define ATTR_UNUSED /* empty */ #endif +#ifndef GC_ATTR_EXPLICIT +# define GC_ATTR_EXPLICIT /* empty */ +#endif + class A {public: /* An uncollectible class. */ - A( int iArg ): i( iArg ) {} + GC_ATTR_EXPLICIT A( int iArg ): i( iArg ) {} void Test( int iArg ) { my_assert( i == iArg );} int i;}; @@ -88,7 +92,7 @@ class A {public: class B: public GC_NS_QUALIFY(gc), public A { public: /* A collectible class. */ - B( int j ): A( j ) {} + GC_ATTR_EXPLICIT B( int j ): A( j ) {} ~B() { my_assert( deleting );} static void Deleting( int on ) { @@ -101,7 +105,7 @@ int B::deleting = 0; class C: public GC_NS_QUALIFY(gc_cleanup), public A { public: /* A collectible class with cleanup and virtual multiple inheritance. */ - C( int levelArg ): A( levelArg ), level( levelArg ) { + GC_ATTR_EXPLICIT C( int levelArg ): A( levelArg ), level( levelArg ) { nAllocated++; if (level > 0) { left = new C( level - 1 ); @@ -133,7 +137,7 @@ class D: public GC_NS_QUALIFY(gc) { public: /* A collectible class with a static member function to be used as an explicit clean-up function supplied to ::new. */ - D( int iArg ): i( iArg ) { + GC_ATTR_EXPLICIT D( int iArg ): i( iArg ) { nAllocated++;} static void CleanUp( void* obj, void* data ) { D* self = static_cast(obj); -- 2.7.4