Skip to content

UnknownMember: обращение к члену, когда в наборе типов есть «Неопределено» #4355

Description

@nixel2007

Суть

UnknownMemberDiagnostic сообщает об обращении к члену по каждому типу из набора получателя. Когда в наборе есть Неопределено, находка появляется даже там, где остальные типы набора нужный член имеют.

Практический источник таких наборов — переменная модуля, объявленная через Перем: до первого присваивания её значение равно Неопределено, а присваивают её из другого метода. Набор в точке обращения выглядит как Неопределено, Структура, и обращение к полю структуры даёт находку на Неопределено.

Перем ПараметрыЗаписи;   // значение до присваивания — Неопределено

Процедура Заполнить()
    ПараметрыЗаписи = Новый Структура;
КонецПроцедуры

Процедура Использовать()
    ПараметрыЗаписи.Вставить("Ключ", Значение);
    // У типа "Неопределено" нет метода или свойства "Вставить"
КонецПроцедуры

Насколько это заметно

На конфигурации «Стандартные подсистемы 3.1» (2252 модуля, все диагностики кроме Typo) таких находок 125. Замер сделан по четырём прогонам на сборку, сравнивались устойчивые наборы находок (пересечение прогонов).

О чём хочется договориться

  1. Молчать, когда в наборе есть другие типы. Неопределено, Структура + .Вставить — находки нет; Неопределено в одиночку — находка остаётся. Убирает шум, но и настоящую ошибку «обратились к члену на пути, где значение ещё не присвоено» тоже.
  2. Молчать по Неопределено всегда. Проще; обращение к члену на Неопределено тогда ловится только другими средствами.
  3. Оставить как есть. Находка формально верна: путь, на котором значение равно Неопределено, существует, и обращение к члену на нём — ошибка времени выполнения.
  4. Отдельная диагностика. Обращение к члену на возможном Неопределено — это не «неизвестный член», а «возможно неинициализированное значение»; вынести в своё правило со своим ключом и настройкой.

Соображение в пользу того, чтобы не гасить совсем: набор с Неопределено — это результат расчёта по потоку, а не незнание типа. Он прямо говорит, что есть путь выполнения, на котором значения нет.

Откуда взялось

Обнаружено при сверке с методической рекомендацией «Типизация кода»: по ней переменная, объявленная записью Перем и без иных сведений о типе, содержит Неопределено. Реализация — #4348, там же цифры по SSL.

Оговорка про измерение

Число срабатываний UnknownMember от прогона к прогону плавает: на develop 31362 / 31397 / 31373 / 31395 (88 находок появляются и исчезают), с правками из #4348 — 30256 / 30272 / 30274 / 30262 (36 плавающих). Поэтому сравнивались не сырые числа, а пересечение четырёх прогонов. Сама недетерминированность — отдельная тема, к обсуждаемому здесь вопросу отношения не имеет и на develop присутствует.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions