Константы и оптимизация компилятора в C ++ - PullRequest
49 голосов
/ 17 октября 2008

Я прочитал все советы о правильности констант в C ++ и о том, что это важно (частично), потому что это помогает компилятору оптимизировать ваш код. То, что я никогда не видел, является хорошим объяснением того, как компилятор использует эту информацию для оптимизации кода, даже хорошие книги не объясняют, что происходит за кулисами.

Например, как компилятор оптимизирует метод, который объявлен как const, по сравнению с тем, который не является, но должен быть. Что происходит, когда вы вводите изменяемые переменные? Они влияют на эти оптимизации const методов?

Ответы [ 12 ]

0 голосов
/ 17 октября 2008

Этот код,

class Test
{
public:
  Test (int value) : m_value (value)
  {
  }

  void SetValue (int value) const
  {
    const_cast <Test&>(*this).MySetValue (value);
  }

  int Value () const
  {
    return m_value;
  }

private:
  void MySetValue (int value)
  {
    m_value = value;
  }

  int
    m_value;
};

void modify (const Test &test, int value) 
{
  test.SetValue (value);
}

void main ()
{
  const Test
    test (100);

  cout << test.Value () << endl;
  modify (test, 50);
  cout << test.Value () << endl;
}

выходы:

100
50

, что означает, что объявленный const объект был изменен в функции-члене const. Наличие const_cast (и ключевое слово mutable) в языке C ++ означает, что ключевое слово const не может помочь компилятору в создании оптимизированного кода. И, как я указывал в моих предыдущих постах, это может даже привести к неожиданным результатам.

Как правило:

const! = Оптимизация

Фактически, это допустимый модификатор C ++:

volatile const
0 голосов
/ 17 октября 2008

Наиболее очевидный момент, когда const - это прямая оптимизация, - это передача аргументов функции. Часто важно убедиться, что функция не изменяет данные, поэтому единственными реальными вариантами выбора сигнатуры функции являются:

void f(Type dont_modify); // or
void f(Type const& dont_modify);

Конечно, настоящая магия здесь - передача ссылки, а не создание (дорогой) копии объекта. Но если ссылка не была помечена как const, это ослабило бы семантику этой функции и привело бы к отрицательным эффектам (таким как усложнение отслеживания ошибок). Следовательно, const разрешает оптимизацию здесь.

/ EDIT: на самом деле, хороший компилятор может проанализировать поток управления функции, определить, что он не изменяет аргумент, и выполнить оптимизацию (передавая ссылку, а не копию). const здесь просто помощь компилятору. Однако, поскольку C ++ имеет довольно сложную семантику и такой анализ потока управления может быть очень дорогим для больших функций, мы, вероятно, не должны полагаться на компиляторы для этого. У кого-нибудь есть данные, чтобы поддержать меня / доказать, что я не прав?

/ EDIT2: и да, как только в игру вступают пользовательские конструкторы копирования, это становится еще сложнее, потому что компиляторы, к сожалению, не могут их вызывать в этой ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...