А>icc выругался, что "const" бесполезен здесь, А>почему?
Хмм... А почему и как он может быть полезен? Эта функция возвращает rvalue типа 'Msg*'. Квалификатор 'const' не имеет смысла применять к rvalue не-класс типов. Rvalue не-класс типов и так не являются изменяемыми. Поэтому хоть прилепляй к ним 'const' хоть не прилепляй — разницы никакой не будет.
А>>icc выругался, что "const" бесполезен здесь, А>>почему?
АТ>Хмм... А почему и как он может быть полезен? Эта функция возвращает rvalue типа 'Msg*'. Квалификатор 'const' не имеет смысла применять к rvalue не-класс типов. Rvalue не-класс типов и так не являются изменяемыми. Поэтому хоть прилепляй к ним 'const' хоть не прилепляй — разницы никакой не будет.
После ответа(спасибо), я понял что хотел спросить,
цель не дать модифицировать адресс:
int a;
int * const p = &a;
++p;//<-ошибка компиляции
Почему такое можно
int a;
int * const p = &a;
int *v = p;//<- не ошибка
Re[3]: type qualifier on return type is meaningless
А>>>icc выругался, что "const" бесполезен здесь, А>>>почему?
АТ>>Хмм... А почему и как он может быть полезен? Эта функция возвращает rvalue типа 'Msg*'. Квалификатор 'const' не имеет смысла применять к rvalue не-класс типов. Rvalue не-класс типов и так не являются изменяемыми. Поэтому хоть прилепляй к ним 'const' хоть не прилепляй — разницы никакой не будет.
А>После ответа(спасибо), я понял что хотел спросить, А>цель не дать модифицировать адресс:
А>
А> int a;
А> int * const p = &a;
А> ++p;//<-ошибка компиляции
А>
А>Почему такое можно А>
А> int a;
А> int * const p = &a;
А> int *v = p;//<- не ошибка
А>
Потому что в последнем случае у тебя есть конкретный объект по имени 'p'. Этот объект является lvalue, т.е. он располалается где-то в памяти. Вот если ты его объявил как 'const', этот объект по имени 'p' становится константным, т.е. то ты больше не имеешь права изменять объект 'p' и компилятор будет стараться не допустить никаких попыток изменения. Ключевым моментом тут является наличие отдельного объекта — lvalue по имени 'p'.
Когла же речь идет о возвращаемом значении функции типа 'указатель', ситуация получается принципиально другая. Возвращаемое значение функции — это временное значение. Оно не является lvalue, т.е. оно не имеет никакого места в памяти. Такое значение невозможно поменять. Просто напросто не существует синтаксиса, который пытался бы менять это возвращаемое значение. Поэтому пытаться квалифицировать такое значение как 'const' не имеет никакого смысла. (Мне не понятно, что имеешь в виду под "цель не дать модифицировать адресс". Как ты собираешься его "модифицировать"?).
Например, возмем результат выражения '5 + 1'. Этот результат — это rvalue '6' типа 'int'. Будет ли разница, если мы решим, что результат этого выражения имеет тип 'const int'? Нет, не будет. Результат выражения '5 + 1' невозможно "поменять". Языки С/С++ поэтому сразу говорят, что к rvalue (не-класс типов в случае С++) константная квалификация (т..е квалификатор 'const') примениять нет никакого смысла. Это просто ничего не даст.
А>Нет, хотелось дать возможность модифицировать объект, А>но не давать возможности изменять указатель на него.
В С/С++ можно запретить изменять указатель
int a;
int * const p = &a;
++p;//<-ошибка компиляции
но как только ты создал неконстантную копию этого указателя
int *v = p;
эту копию можно менять сколько угодно
++v; // не ошибка
Не существует способа запретить изменять неконстантные копии константного значения.
В С/С++ модификатор 'const' защищает от изменения объект, а не значение в нем содержащееся. Как только ты скопировал это значение в "незащищенный" объект, ты можешь менять эту копию сколько угодно.
Best regards,
Андрей Тарасевич
Re[3]: type qualifier on return type is meaningless
Здравствуйте, <Аноним>, Вы писали:
А>Почему такое можно А>
А> int a;
А> int * const p = &a;
А> int *v = p;//<- не ошибка
А>
Потому что p объявлен как константный указатель на неконстантные данные, т.е. нельзя перенаправить p на другой адрес (или обнулить), а сами данные, на которые он указывает доступны для модификации, соответственно не запрещено на эти же данные направить другой указатель такого же типа. Может быть сказанное станет более очевидным, если твой пример переписать так:
typedef int* IntPtr;
int a;
const IntPtr p = &a; //константный указатель на неконстантные данные
IntPtr v = p; //неконстантный указатель инициализируем константным
//Адресуемые данные доступны для модификации через оба указателя:
*p = 4;
*v = 3;
Присваивание v = p вызвало бы ошибку, если бы p был объявлен как неконстантный указатель на константные данные: const int* p, или как константный указатель на константные данные: const int* const p;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: type qualifier on return type is meaningless
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Не существует способа запретить изменять неконстантные копии константного значения.
Но можно написать обёртку с таким запретом.
Скажем, умный указатель, для которого не реализована или подавлена адресная арифметика.
А то и вообще подавлено присваивание, либо сделано как-то очень явно.
CoolValue foo();
CoolValue x = foo(); // инициализация
x = bar(); // изменение: запрещено!
x.reset( bar() ); // явное изменение: можно
simple_value y = x; // можно