Как я могу определить функцию, которая гарантирует не изменять свой аргумент, даже если аргумент не является константным? - PullRequest
1 голос
/ 29 февраля 2020

Это своего рода продолжение до этого вопроса

Рассмотрим следующий фрагмент

void f(int const &); // f "guarantees" not to change its parameter

int main()
{
  int const a = 42;  // a is not modifiable
  f(a); // so f definitely can't modify a 
        // (at least not without invoking UB), that's great

  int b = 42; // b is modifiable
  f(b); // but f could modify b legally? huh? not so great
}

Мое понимание: f can only измените b, и он должен использовать const_cast для этого. Кроме того, это вообще плохая идея, и ее не следует делать. Кроме того, существуют причины, по которым в языке существует механизм игнорирования const.

Если мое понимание верно, то мой вопрос в том, есть ли способ написать функцию, которая гарантируется не изменять свой аргумент. то есть есть ли способ сделать следующее

void f(int const_really &); // f *guarantees* not to change its parameter

int main()
{
  int b = 42; // even if b is modifiable
  f(b); // f is not allowed to modify b legally
        // (or is UB if it does)
}

Редактировать: Одной из причин для этого было бы позволить компилятору выполнять оптимизацию. В настоящее время функция, которая принимает аргумент по const-reference, имеет значение , а не , позволяющее предположить, что биты аргумента не будут изменены функцией. Это связано с тем, что функция может выполнять допустимое const_cast или тип аргумента может иметь изменяемые члены.

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

Может ли это быть что-то, что можно добавить в язык?

Если нет, есть ли какая-то причина, почему это никогда не может быть сделано?

Ответы [ 2 ]

4 голосов
/ 29 февраля 2020

Ключевое слово для этого - const. Он уже предлагает такую ​​же сильную гарантию, какую когда-либо дает С ++ - это не так, если разработчик функции выберет ее так. вы делаете.

C ++ - это язык, который всегда позволяет вам отбрасывать что-либо, так или иначе. Поэтому, какое бы новое ключевое слово const_really вы ни вводили, оно останется там, где сейчас находится const - бессильно, если программист решит игнорировать его и выполнить кучу приведений. Запретить это будет go против ядра t enet C ++ - абсолютный контроль, если это понадобится программисту. Нет необходимости в новом ключевом слове, потому что нечего его получить.

0 голосов
/ 29 февраля 2020

const - лучшее, что вы можете иметь.

Если вы беспокоитесь, что какая-то внешняя программа все еще может волшебным образом изменить параметр b, это может произойти, даже если вы используете другой язык, такой как C#, Java и др. c. Если у вас есть gr asp адрес b случайно / преднамеренно и вы указали доступ, как в режиме ядра или const_cast, вы можете изменить его. Все может быть изменено внутри.

Вы просто должны сосредоточиться внутри своей функции. Добавление const достаточно. Если ВЫ не изменили b внутри ВАШЕЙ функции, этого достаточно для доказательства того, что b не будет изменен, даже если все еще может быть изменен взломанным способом. Вы знаете полный лог c внутри функции. Вы можете видеть, что b не будет изменен.

Кроме того, const_cast имеет полезную цель. В моем случае у меня есть получатели большого объекта, которые я должен вернуть как const, поэтому большинство переменных и методов-членов не будут изменены или доступны. Но я должен установить специальные методы, чтобы добавлять вещи в этот большой объект. Это как категоризация доступа. Я надеюсь, что когда-нибудь они добавят его в c ++.

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