Может ли компилятор определить, является ли переменная const самой?

Я знаю, что для этой функции это будет просто:

int foo(int a, int b){
    return a + b;
}

Но мой вопрос: не может ли компилятор автоматически обнаружить, что это то же самое, что:

int foo(const int a, const int b){
    return a + b;
}

И поскольку это может быть обнаружено, зачем мне вводить const где угодно? Я знаю, что ключевое слово inline устарело из-за прогресса компилятора. Разве не время, чтобы const сделать то же самое?

Ответ 1

Да, компилятор может доказать свою силу в вашем примере.

Нет, это было бы бесполезно: -).

Обновление: Херб Саттер посвятил одну из своих проблем в тему (http://www.gotw.ca/gotw/081.htm). Краткое описание:

  • const помогает большинству, заставляя компилятор и компоновщик выбирать функции для объектов const, включая константные функции-члены, которые могут быть закодированы для повышения эффективности.
  • const не помогает с обычной моделью единицы перевода [отличается от того, что я предполагал]; компилятор должен увидеть всю программу для проверки фактической консистенции (которую просто не декларирует декларация) и ее использования, а также доказать отсутствие псевдонимов...
  • ... и когда компилятор может видеть всю программу и может доказать фактическую константу, на самом деле это, конечно, не нуждается в объявлении const больше! Это может доказать это. Duh.
  • Единственное место, где const имеет большое значение, - это определение, потому что компилятор может хранить объект в постоянной памяти.

Статья, конечно, стоит прочитать.

В отношении всей оптимизации/перевода программы, которая обычно необходима для использования константы cf. комментарии ниже от amdn и Angew.

Ответ 2

Вы не ставите const в результате не изменяя переменную. Вы используете const, чтобы вы не изменяли его. Без const вы можете изменить значение. С const компилятор будет жаловаться.

Это вопрос семантики. Если значение не должно быть изменчивым, используйте const, и компилятор выполнит это намерение.

Ответ 3

не может компилятор просто автоматически обнаружить, что это то же самое, что...

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

Ответ 4

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

То, что компилятор никогда не знает, - это то, что вы хотели сделать.

Если вы хотите, чтобы переменная оставалась постоянной, но случайно изменила ее позже в коде, компилятор может только уловить эту ошибку, если вы сообщите компилятору, что вы хотели.

Это ключевое слово const.

Ответ 5

struct bar {
  const int* x;
};

bar make_bar(const int& x){
  return {&x};
}

std::map<int,bar> data;

shuffle(data);

зная, что bar никогда не будет изменять x (или заставить его изменять) в течение своей жизни требует понимания каждого использования bar в программе или, например, создания x указателя на const.

Даже при идеальной оптимизации всей программы (которая не может существовать: машины turing не совсем понятны), динамическое связывание означает, что во время компиляции вы не можете знать, как будут использоваться данные. const является обещанием, и нарушение этого обещания (в определенных контекстах) может быть UB. Компилятор может использовать этот UB для оптимизации способами, которые игнорируют сломанное обещание.

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

const упрощает определенные оптимизации (что может сделать их возможным), и накладывает на программиста вещи (что помогает программисту) и может изменить код (const перегрузка).

Ответ 6

Возможно, он мог, но утверждение const также относится к вам. Если вы установите переменную как const и попытаетесь присвоить новое значение, вы получите сообщение об ошибке. Если компилятор сам сделает var из него, это не сработает.

Ответ 7

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

Переменная может быть действительно const (это означает, что она записывается в месте только для чтения, следовательно, оптимизация компилятора), если она const во время ее объявления.

Вы можете предоставить свою вторую переменную non const, которая станет "const" внутри области функций.

Или альтернативно вы можете обходить const путем кастинга, поэтому компилятор не может проанализировать весь ваш код, пытаясь выяснить, будет ли значение изменено или нет внутри области функций.

Учитывая, что конструкторы const в основном предназначены для обеспечения кода и что компиляторы будут генерировать один и тот же код в 99% случаев, если переменная const или non const, тогда NO, компилятор не должен автоматически обнаруживать константу.

Ответ 8

Короткий ответ: потому что не все проблемы такие простые.

Дольше ответ: вы не можете предположить, что подход, который работает с простой проблемой, также работает со сложной задачей

Точный ответ: const - это намерение. Основная цель const - предотвратить случайное выполнение вами каких-либо действий. Если компилятор автоматически добавит const, он просто увидит, что этот подход НЕ является const и оставляет его на нем. Использование ключевого слова const приведет к возникновению ошибки.