Я вижу две вещи, которые отсутствуют в вашем анализе.
Программа: Стандарт устанавливает требования к выполнению программы.Ваша программа состоит из (исполняемого) файла, созданного командой g++ main.cpp -ltest
, предположительно a.out
или a.exe
.В частности, ваша программа не содержит общих библиотек, с которыми она связана.Поэтому все, что делается совместно используемой библиотекой, выходит за рамки стандарта.
Ну, почти.Поскольку вы написали свою разделяемую библиотеку на C ++, ваш файл libtest.so
или test.dll
действительно входит в сферу действия стандарта, но делает это сам по себе, независимо от исполняющего файла, который его вызывает.То есть наблюдаемое поведение a.exe
, игнорирующее наблюдаемое поведение разделяемых библиотек, должно соответствовать стандарту, а наблюдаемое поведение test.dll
, игнорирующее наблюдаемое поведение исполняемого файла, должно соответствовать стандарту.
У вас есть две связанные, но технически независимые программы.Стандарт распространяется на каждого из них в отдельности.Стандарт C ++ не охватывает, как независимые программы взаимодействуют друг с другом.
Если вам нужна ссылка для этого, я хотел бы взглянуть на пункт 9 «Фазы перевода» ([lex.phases] -- раздел 2.2 в той версии стандарта, на которую вы ссылаетесь).Результатом связывания a.out
является образ программы, в то время как test.dll
является частью среды выполнения.
Упорядочено раньше: Похоже, вы пропустили определениеиз "последовательности перед".Да, выход имеет «B ctor» перед «A ctor».Однако это само по себе не означает, что конструктор b
был секвенирован до конструктора a
.Стандарт C ++ дает точное значение для «последовательности перед» в [intro.execution] (пункт 13 раздела 1.9 в версии стандарта, на которую вы ссылались).Используя точное значение, можно сделать вывод, что если конструктор b
секвенируется перед конструктором a
, то вывод должен иметь «B ctor» перед «A ctor».Однако обратное (то, что вы предполагали) не выполняется.
В комментариях вы предположили, что это было незначительное изменение, когда слово «секвенировано до» было заменено на «сильно случается раньше».Это не так, поскольку «более строго происходит раньше» также имеет точное значение в более новой версии стандарта ( пункт 12 раздела 6.8.2.1 [intro.races]).Оказывается, что «сильно случается раньше» означает «последовательность перед» или один из трех дополнительных случаев.Таким образом, изменение формулировки было преднамеренным расширением этой части стандарта и охватывало больше случаев, чем раньше.