Лучший способ избежать предупреждения «управление достигает конца непустой функции» в режиме выпуска

У меня есть класс (здесь MyObject) с функцией, возвращающей имя по ссылке в зависимости от внутреннего типа объекта. Более того, эту функцию можно вызывать только для некоторых значений внутреннего типа.

/**
 * \brief Return the name depending of the internal type
 * \pre   The internal type must be 1 or 2
 */
inline
const std::string& MyObject::getName() const
{
  switch(this->type)
  {
    case 1:
      return this->type1->getName();
      break;
    case 2:
      return this->type2->getName();
      break;
    default:
      assert(false && "PRE: Invalid type for this operation");
  }
}

Затем, когда я компилирую в режиме Release, я получаю это предупреждение:

предупреждение: управление достигает конца непустой функции

Как лучше всего избежать этого предупреждения в этом случае? Я не могу вернуть пустую строку, потому что это приведет к ссылке на временный объект, а затем к другому предупреждению. Я предпочитаю не генерировать исключение в этом контексте, потому что это только для устранения предупреждения. Если выполнение вызывает часть по умолчанию, это ошибка программирования, она будет обнаружена в режиме отладки в предварительном выпуске с утверждением. Обычно выполнение никогда не вызывает его в режиме Release, и в этом случае допустимо неопределенное поведение.


person Caduchon    schedule 05.06.2015    source источник
comment
Я не вижу веских причин не генерировать исключение.   -  person juanchopanza    schedule 05.06.2015
comment
Обратите внимание, что неопределенное поведение не является случайным поведением — его наличие делает всю программу неопределенной, и очень агрессивный оптимизатор может предположить, что this->type никогда не имеет значения, отличного от 1 или 2.   -  person molbdnilo    schedule 05.06.2015
comment
exception или abort() или изменить дизайн, чтобы избежать случая переключения.   -  person Jarod42    schedule 05.06.2015
comment
@juanchopanza: мне не нужно исключение для этой функции, потому что она вызывается в деструкторе.   -  person Caduchon    schedule 05.06.2015


Ответы (2)


Вы можете вернуть ссылку на статическую переменную:

/**
 * \brief Return the name depending of the internal type
 * \pre   The internal type must be 1 or 2
 */
inline
const std::string& MyObject::getName() const
{
  switch(this->type)
  {
    case 1:
      return this->type1->getName();
      break;
    case 2:
      return this->type2->getName();
      break;
    default:
      assert(false && "PRE: Invalid type for this operation");
  }

  static std::string hack("");
  return hack;
}
person Thomas Sparber    schedule 05.06.2015
comment
В данном случае это, вероятно, хорошее решение. Если, к сожалению, ошибка все еще присутствует в режиме выпуска, я предпочитаю, чтобы она вернула неправильное имя, чем останавливала программу. - person Caduchon; 05.06.2015
comment
Я тоже так думаю. Я считаю, что внутренняя обработка ошибки лучше, чем прерывание программы. - person Thomas Sparber; 05.06.2015

«... в этом случае допустимо случайное поведение».

Это может быть приемлемо, но зачем вам это? Просто добавьте exit(1); после assert, и вы не будете тратить время на это, или напишите макрос, чтобы добавить и assert, и exit.

Отдельно не нужно break от case, что return.

person Tony Delroy    schedule 05.06.2015
comment
Да, break - хорошая практика. Это довольно распространенная сложная ошибка, которую нужно решить, если вы забыли одну из них. - person Caduchon; 05.06.2015
comment
@Caduchon: я совершенно не согласен ... это запутывает return, который уже был адекватным, и вызывает неправильные рассуждения, такие как я уберу этот break и позволю case X провалиться - но этого не произойдет, потому что это уже returnред. - person Tony Delroy; 05.06.2015