Могу ли добавить дополнительную функциональность для ограничения квалификации (если компиляция прошла нормально)?
Как я пытаюсь применить const-correctness для своего собственного кода, мне часто приходится добавлять квалификацию const
к определениям функций в других модулях (написанных другими программистами), чтобы использовать эти функции в моем собственном коде. (см. здесь, как исправление контр-исправления)
Я всегда думал, что если все компилируется нормально, это может привести к нарушению функциональности, поскольку const
метки имеют значение только во время компиляции.
Однако на днях один из моих коллег настоял на том, чтобы я повторно запустил все автоматические тесты, прежде чем совершить код с добавленными метками const
, где я думал, что достаточно, чтобы этот код скомпилировался.
Есть ли у него точка? Есть ли способ, которым применение const-correctness может нарушить существующую функциональность?
Изменить: Возможно, важно отметить, что, как правило, я должен делать это только для параметров указателей функций (например, Something getSomething(Object* pObj)
- Something getSomething(const Object* pObj)
). Я не меняю типы возврата или метод const, поскольку это не проблема для клиентского кода.
Ответы
Ответ 1
Поскольку метод const может отличаться от не const one
class C
{
public:
int& get() { return i; }
int get() const { return i; }
private:
int i = 42;
};
у вас может быть другое поведение:
C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // true
тогда
const C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // not true.
Ответ 2
У них действительно есть точка.
-
Если вы отбросили const
от переменной, которая изначально была const
, тогда поведение программы undefined. Вы рискуете ввести это в свой код, если добавите квалификацию const
.
-
Вы можете непреднамеренно переключить перегрузку функции для переопределения функции.
-
Определяется переход анонимного временного объекта к функции, которая принимает ссылку const
, но если функция принимает ссылку const
, то поведение undefined. Многие компиляторы допускают не const
(возможно, случайно, хотя некоторые даже доходят до того, что называют это расширением). Якобы, вы все помогаете в этом, но вы можете удалить конструкцию undefined -behaviour, на которую полагаются во время выполнения.
-
В стандарте С++ не утверждают, что sizeof(T*) == sizeof(const T*)
. Макет v-table вашего класса может отличаться при создании параметра const
to const
. Конечно, это маловероятно, но вы должны проверить.
Итак, вы должны проверить эти изменения.
Ответ 3
Да.
Возможна следующая проблема с добавлением const
поведения undefined при изменении переменной позже (в ситуации, когда компилятор больше не может ее предотвратить).
Что, если f здесь const?
float f = 1.0;
//do something with f
readFromBinaryFile((char *)(&f), sizeof(f));
//do another something with f
//...
void readFromBinaryFile(char *c, size_t s)
{
//... fill c
}