Remove a static initializer by removing a global of non-POD type.

These are banned by the Google style guide, and Chromium has a hard
no-new-static-initializers policy preventing updating to a new version of
libprotobuf unless this is resolved.  This is the first such change, I'll need
to make at least one more in the future.

Luckily, the protobuf source tree already has an alternative to static
initializers in once.h; use that machinery instead.

I defined everything in the .cc file in a blob to replace the old implementation
rather than matching the .h layout precisely; let me know if a different
ordering is preferred.  I also eliminated the macro that used to be used here as
spelling everything out only takes one additional line, and the macro didn't
actually handle all details of using a particular member variable, just the
declaration, so it felt a bit error-prone.
This commit is contained in:
Peter Kasting 2015-08-27 20:16:33 -07:00
parent 47210ccd77
commit 4f3bead537
2 changed files with 80 additions and 65 deletions

View File

@ -34,7 +34,6 @@
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/io/coded_stream.h>
@ -1747,66 +1746,68 @@ void ExtensionSet::Extension::Free() {
// ==================================================================
// Default repeated field instances for iterator-compatible accessors
GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_);
GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_);
GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_);
void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() {
default_repeated_field_int32_ = new RepeatedField<int32>;
default_repeated_field_int64_ = new RepeatedField<int64>;
default_repeated_field_uint32_ = new RepeatedField<uint32>;
default_repeated_field_uint64_ = new RepeatedField<uint64>;
default_repeated_field_double_ = new RepeatedField<double>;
default_repeated_field_float_ = new RepeatedField<float>;
default_repeated_field_bool_ = new RepeatedField<bool>;
OnShutdown(&DestroyDefaultRepeatedFields);
}
void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() {
delete default_repeated_field_int32_;
delete default_repeated_field_int64_;
delete default_repeated_field_uint32_;
delete default_repeated_field_uint64_;
delete default_repeated_field_double_;
delete default_repeated_field_float_;
delete default_repeated_field_bool_;
}
void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() {
default_repeated_field_ = new RepeatedFieldType;
OnShutdown(&DestroyDefaultRepeatedFields);
}
void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() {
delete default_repeated_field_;
}
void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() {
default_repeated_field_ = new RepeatedFieldType;
OnShutdown(&DestroyDefaultRepeatedFields);
}
void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() {
delete default_repeated_field_;
}
const RepeatedField<int32>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL;
const RepeatedField<int64>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL;
const RepeatedField<uint32>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL;
const RepeatedField<uint64>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL;
const RepeatedField<double>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL;
const RepeatedField<float>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL;
const RepeatedField<bool>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL;
const RepeatedStringTypeTraits::RepeatedFieldType*
RepeatedStringTypeTraits::default_repeated_field_ = NULL;
const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
const RepeatedField<TYPE>* \
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
struct StaticDefaultRepeatedFieldsInitializer {
StaticDefaultRepeatedFieldsInitializer() {
InitializeDefaultRepeatedFields();
OnShutdown(&DestroyDefaultRepeatedFields);
}
} static_repeated_fields_initializer;
void InitializeDefaultRepeatedFields() {
RepeatedStringTypeTraits::default_repeated_field_ =
new RepeatedStringTypeTraits::RepeatedFieldType;
RepeatedMessageGenericTypeTraits::default_repeated_field_ =
new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
new RepeatedField<int32>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
new RepeatedField<int64>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
new RepeatedField<uint32>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
new RepeatedField<uint64>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
new RepeatedField<double>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
new RepeatedField<float>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
new RepeatedField<bool>;
}
void DestroyDefaultRepeatedFields() {
delete RepeatedStringTypeTraits::default_repeated_field_;
delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
}
} // namespace internal
} // namespace protobuf
} // namespace google

View File

@ -45,6 +45,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/repeated_field.h>
@ -716,15 +717,14 @@ class RepeatedPrimitiveTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField();
};
// Declared here so that this can be friended below.
void InitializeDefaultRepeatedFields();
void DestroyDefaultRepeatedFields();
LIBPROTOBUF_EXPORT extern ProtobufOnceType
repeated_primitive_generic_type_traits_once_init_;
class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
private:
template<typename Type> friend class RepeatedPrimitiveTypeTraits;
friend void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields();
static void InitializeDefaultRepeatedFields();
static void DestroyDefaultRepeatedFields();
static const RepeatedField<int32>* default_repeated_field_int32_;
static const RepeatedField<int64>* default_repeated_field_int64_;
static const RepeatedField<uint32>* default_repeated_field_uint32_;
@ -759,6 +759,9 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
} \
template<> inline const RepeatedField<TYPE>* \
RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() { \
GoogleOnceInit( \
&repeated_primitive_generic_type_traits_once_init_, \
&RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields); \
return RepeatedPrimitiveGenericTypeTraits:: \
default_repeated_field_##TYPE##_; \
} \
@ -812,6 +815,9 @@ class LIBPROTOBUF_EXPORT StringTypeTraits {
}
};
LIBPROTOBUF_EXPORT extern ProtobufOnceType
repeated_string_type_traits_once_init_;
class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
public:
typedef const string& ConstType;
@ -855,12 +861,14 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
}
static const RepeatedFieldType* GetDefaultRepeatedField() {
GoogleOnceInit(&repeated_string_type_traits_once_init_,
&InitializeDefaultRepeatedFields);
return default_repeated_field_;
}
private:
friend void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields();
static void InitializeDefaultRepeatedFields();
static void DestroyDefaultRepeatedFields();
static const RepeatedFieldType *default_repeated_field_;
};
@ -1019,6 +1027,9 @@ class RepeatedMessageTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField();
};
LIBPROTOBUF_EXPORT extern ProtobufOnceType
repeated_message_generic_type_traits_once_init_;
// This class exists only to hold a generic default empty repeated field for all
// message-type repeated field extensions.
class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
@ -1026,14 +1037,17 @@ class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
private:
template<typename Type> friend class RepeatedMessageTypeTraits;
friend void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields();
static void InitializeDefaultRepeatedFields();
static void DestroyDefaultRepeatedFields();
static const RepeatedFieldType* default_repeated_field_;
};
template<typename Type> inline
const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
GoogleOnceInit(
&repeated_message_generic_type_traits_once_init_,
&RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields);
return reinterpret_cast<const RepeatedFieldType*>(
RepeatedMessageGenericTypeTraits::default_repeated_field_);
}