Ответ 1
В предложении не вводится сборщик мусора - он просто разрешает его в определенных ситуациях, если реализация выбирает. Стандарт просто описывает эти ситуации как вызывающие поведение undefined. При этом он расслабляет требования реализации, предоставляя минимальную свободу для сборщика мусора.
Простой пример, приведенный в в предложении, учитывает, когда вы берете указатель на динамически выделенный объект, XOR его с другим значением, тем самым скрывая значение указателя, а затем восстановить исходное значение указателя для доступа к объекту через него. До С++ 11 это было бы прекрасно, и все равно было бы полезно использовать. Однако теперь такая операция может быть (см. Следующий абзац) рассмотрена как поведение undefined, что означает, что реализация может выполнять сборку мусора на объекте, на который указывалось.
В стандарте указано, что реализация может либо иметь расслабленную безопасность указателя, и в этом случае поведение такое, как было раньше, или строгая безопасность указателя, что позволяет вводить сборщик мусора.
Реализация может иметь расслабленную безопасность указателя, и в этом случае ценность значения указателя не зависит от того, является ли это безопасным производным значением указателя. В качестве альтернативы, реализация может иметь строгую безопасность указателей, и в этом случае значение указателя, которое не является безопасным производным значением указателя, является недопустимым значением указателя, если только указанный объект цели не имеет динамической продолжительности хранения и ранее был объявлен достижимым (20.6.4). [...] Реализация определяется, является ли реализация имеет расслабленную или строгую безопасность стрелка.
Значение указателя представляет собой безопасное производное значение указателя, если оно указывает на динамически выделенный объект и не имеет никакого смешного дела с ним (более конкретно, в §3.7.4.3).
Если ваша реализация имеет строгую безопасность указателя, но вы все же хотите сделать этот смешной бизнес указателю без введения поведения undefined, вы можете объявить указатель p
как доступный следующим образом:
declare_reachable(p);
Эта функция определена в заголовке <memory>
вместе со связанными функциями, такими как undeclare_reachable
, declare_no_pointers
и undeclare_no_pointers
. Вы также можете определить строгость своей реализации с помощью get_pointer_safety
.