2014-07-23 5 views
0

Существует инфраструктура RPC, использующая hessian как стандартную сериализацию по умолчанию. Затем некоторым клиентам нужен протобуф. Чтобы быть совместимым с теми людьми, у которых нет протобуфа, мы помещаем все опоры protobuf в один файл и скомпилируем его условно в соответствии с текущей средой (имеют pb или нет).
. Структура имеет серию типов данных (Long, String, карта, и т.д.), каждый из них имеет сериалайзер отдельно, мы используем статическую-структуру зарегистрировать эти функции, она выглядит следующим образом:статическая структура и статическая глобальная переменная в C++

/*file register.cc */ 

в файле поддержки Protobuf, мы делаем аналогичные вещи:

/* pb_support.cc */ 

эти две файлов в разных каталогах:
В gcc 4.1.2 с Redhat5.6 он работает хорошо. В gcc 4.8 с Ubuntu 13.04, когда protobuf включен, pb_object_install всегда выдает первый результат, но результат равен нулю, это означает, что результат регистрации pb был уничтожен, поэтому протокол protobuf бесполезен.
Почему? и есть ли какая-либо замена для выполнения той же функции?

+2

Статический порядок инициализации не указан. Два файла-статических объектов в двух разных файлах просто не могут ссылаться друг на друга. Вы должны сделать 'serializer_registry' функцией статической, а не статической, чтобы гарантировать ее инициализацию при первом использовании. Или сделайте его подходящим синглтоном. –

ответ

3

Инициализация переменных в глобальном пространстве имен находится в порядке объявления в одном translation unit. Однако порядок инициализации между translation units не указан.

Это означает, что если у вас есть два исходных файла, вы не можете сказать, какие переменные файлов будут инициализированы первыми. Это, конечно, вызовет проблемы, если переменная в одном исходном файле зависит от переменной в другом исходном файле, который сначала инициализируется.

+0

, если сначала часть pb вычиталась, почему массив serializer_registry по-прежнему пуст, когда дело доходит до части hessian? две инициализации, инициированные один за другим? – nzomkxia

+2

Программа имеет UB. Исправьте его и не спрашивайте, почему UB проявляется именно таким образом. Такие вопросы непродуктивны. (Хотя легко видеть, что часть pb незаконно записывает в реестр до вызова его конструктора, затем вызывается конструктор, вытирая все, что было написано). –

+0

@ н.м. спасибо, я планирую изменить всю логику об этом. просто любопытно, что означает «реестр перед его конструктором», с моей точки зрения, regist_serializer вызывает вызов внутри конструктора pb. – nzomkxia

Смежные вопросы