0

В моем понимании, lvalue - это просто местоположение, а его соответствующее значение r - это значение, хранящееся в этом месте. например:Определены ли значения во время компиляции?

int x; 
x = 0; /* the compiler will replace x with the location where 0 will be stored */ 
int y = x; /* x works as an rvalue here, its content is unknown until run time */ 

Может компилятор известен во время компиляции, что значение х находится в третьей строке 0, так что она может инициализировать у со значением 0 напрямую (а не ждать, пока время работы, и в время запуска сначала получает значение x, а затем дает это значение y)?

int *p = &x; 
*p = 3; 

Здесь * p во второй строке является lvalue (местоположение x). Начиная с & x известно во время компиляции, поэтому * p также известно во время компиляции, правильно?

Будет ли компилятор просто заменить * p на местоположение x, или он будет генерировать код, который сначала получит адрес, сохраненный в p, а затем назначить 3 на этот адрес?

+1

Посмотрите на сборку производства. – chris

+1

В обоих случаях компилятор, скорее всего, просто выкинет как можно больше ненужного промежуточного мусора и значительно сварит код. В первом случае, если 'x' не используется в другом месте, я был бы удивлен, если бы он был * в * конечных бит. Аналогично с 'p' во втором. Подумайте об этом, а затем просмотрите комментарий Криса. – WhozCraig

+5

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

ответ

-2

Я бы не сказал, что в выражении int y = x переменная x является r-значением. Тот факт, что он находится в правой части, не означает, что он является r-значением.

По определению значение l представляет собой объект, который занимает некоторое идентифицируемое местоположение в памяти, например x; r-значения - это просто объекты, которые не являются значениями l.

Так, если выражение было int y = x1 + x2, то да, временный x1 + x2 будет г-значение, но в вашем случае, и в течение срока службы области, в которой x определен, x имеет идентифицируемое местоположение в памяти и, следовательно, является l-значением.

+0

rvalues ​​также имеют место в памяти. Вот почему вы можете брать ссылки и указатели на них. – Pubby

+1

x - это значение lvalue и rvalue. Преобразование lvalue в rvalue является неявным, что означает, что при добавлении кода в 'x' это выражение lvalue может стать операндом неявного выражения преобразования. Только контекст говорит вам, есть ли у вас todo с rvalue. Вы не можете выбирать чисто на основе контекстных символов 'x'. –

+0

Суть этого, я думаю, в том, что могут быть несколько выражений, которые имеют одинаковое лексическое представление. –

2

Я не уверен, что вы хотите иметь отношение к lvalues ​​или rvalues. Исправьте меня, если я ошибаюсь, но я чувствую, что вы хотите сделать некоторые «ручные оптимизации», гарантируя, грубо говоря, что вещи, которые определены во время компиляции, не принимают никаких вычислений во время выполнения. Есть много способов сделать это, некоторые более сложные, чем другие.

Из двух приведенных вами примеров я бы посоветовал вам проявить интерес к константным и статическим классификаторам и новому ключевому слову constexpr в C++ 11. Вообще говоря, никогда не забывайте писать const, когда можете; это действительно помогает компилятору во время оптимизации. Для static это еще одна история; он оказывается более безопасным для всех, если вы используете его только в том случае, если вы уже достаточно опытны в программировании, только в некоторых конкретных случаях, а некоторые из них религиозно не используют его вообще ...

Если вы хотите немного узнать подробнее об оптимизации, я бы порекомендовал this website, и, конечно же, есть template-meta-programming, что может помочь сделать некоторые вычисления во время компиляции.

Чтобы вернуться к вашему примеру, зачем вы пишете такую ​​вещь и ожидаете, что компилятор выполнит эту работу за вас? Если вы знаете y 0, почему бы не написать его самостоятельно? Если значение y изменится позже, как бы вы сделали иначе, чем выделить пространство для y в памяти и скопировать значение 0 в этом месте, когда ваш код «начнет» с его помощью (т.е. во время выполнения)? Что делать, если значение y было установлено в зависимости от состояния, которое может быть разрешено только во время выполнения? И т. Д.

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

«Другие грехи вычислительными совершаются во имя эффективности (не обязательно его достижения), чем какой-либо другой причине. - в том числе слепой глупости», W.A. Вульф

Смежные вопросы