Сообщение Re[18]: Когда это наконец станет defined behavior? от 29.04.2023 10:04
Изменено 29.04.2023 10:13 rg45
Re[18]: Когда это наконец станет defined behavior?
Здравствуйте, netch80, Вы писали:
TB>
N>А вот что меня таки смущает — почему это происходит при том, что в аргументе было "const int& a", а не "int& a". Clang — точно так же. Это значит, что константность для них действует одинаково как "мы не имеем права это менять", но не действует как "это не может поменять кто-то снаружи", несмотря на то, что формально это const.
Так ясно почему — константность ссылки не гарантирует константности объекта. Один и тот же объект можно привязать одновременно к множеству разных ссылок, как константных, так и неконстантных. Ниже один из возможных примеров.
http://coliru.stacked-crooked.com/a/5197fe8b39464268
TB>
TB>int bar();
TB>int foo(const int& a) {
TB> int ll = a;
TB> int l = ll + bar();
TB> return l + a;
TB>}
TB>N>А вот что меня таки смущает — почему это происходит при том, что в аргументе было "const int& a", а не "int& a". Clang — точно так же. Это значит, что константность для них действует одинаково как "мы не имеем права это менять", но не действует как "это не может поменять кто-то снаружи", несмотря на то, что формально это const.
Так ясно почему — константность ссылки не гарантирует константности объекта. Один и тот же объект можно привязать одновременно к множеству разных ссылок, как константных, так и неконстантных. Ниже один из возможных примеров.
http://coliru.stacked-crooked.com/a/5197fe8b39464268
////////////////////////////////////////////////////////
// main.cpp
#include <iostream>
int bar();
int foo(const int& a) {
int ll = a;
int l = ll + bar();
return l + a;
}
int main()
{
extern int x;
std::cout << x << std::endl;
std::cout << foo(x) << std::endl;
std::cout << x << std::endl;
}
////////////////////////////////////////////////////////
// bar.cpp
int x = 42;
int bar() {
return ++x;
}Re[18]: Когда это наконец станет defined behavior?
Здравствуйте, netch80, Вы писали:
TB>
N>А вот что меня таки смущает — почему это происходит при том, что в аргументе было "const int& a", а не "int& a". Clang — точно так же. Это значит, что константность для них действует одинаково как "мы не имеем права это менять", но не действует как "это не может поменять кто-то снаружи", несмотря на то, что формально это const.
Так ясно почему — константность ссылки не гарантирует константности объекта. Один и тот же объект можно привязать одновременно к множеству разных ссылок, как константных, так и неконстантных. А функция bar может может иметь непостредственный доступ к объекту, помимо той ссылки, которая передается в функцию foo:
http://coliru.stacked-crooked.com/a/5197fe8b39464268
TB>
TB>int bar();
TB>int foo(const int& a) {
TB> int ll = a;
TB> int l = ll + bar();
TB> return l + a;
TB>}
TB>N>А вот что меня таки смущает — почему это происходит при том, что в аргументе было "const int& a", а не "int& a". Clang — точно так же. Это значит, что константность для них действует одинаково как "мы не имеем права это менять", но не действует как "это не может поменять кто-то снаружи", несмотря на то, что формально это const.
Так ясно почему — константность ссылки не гарантирует константности объекта. Один и тот же объект можно привязать одновременно к множеству разных ссылок, как константных, так и неконстантных. А функция bar может может иметь непостредственный доступ к объекту, помимо той ссылки, которая передается в функцию foo:
http://coliru.stacked-crooked.com/a/5197fe8b39464268
////////////////////////////////////////////////////////
// main.cpp
#include <iostream>
int bar();
int foo(const int& a) {
int ll = a;
int l = ll + bar();
return l + a;
}
int main()
{
extern int x;
std::cout << x << std::endl;
std::cout << foo(x) << std::endl;
std::cout << x << std::endl;
}
////////////////////////////////////////////////////////
// bar.cpp
int x = 42;
int bar() {
return ++x;
}