Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > C++ > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Здесь нужно купить рекламу за 25 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru

Ответ
 
Опции темы
Старый 15.04.2013, 14:42   #11
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Код:
{ Arg arg = 10;  int val = arg;  cout<<"val = "<<val<<endl; }
{ int src = 20; Arg arg = &src;  int *ptr = arg;  cout<<"src = "<<*ptr<<endl; }
Раздел 8.5.3, пункты 5 и 6, подразумевают, что ссылки на POD-типы в части времени их жизни оговариваются теми же правилами, что и ссылки на объекты классов.
Раздел 12.2, пункт 5:
Цитата:
The temporary to which the reference is bound or
the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the
reference except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2)
persists until the constructor exits.
В обоих случаях создаётся временный объект, время жизни которого заканчивается сразу после инициализации arg. Далее, в соответствии с разделом 3.8 выделенная под временный объект память может быть reused. После того, как это произойдёт, *arg.mAddr можно будет использовать только в качестве lvalue (раздел 3.8, пункт 6):
Цитата:
Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated
or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any
lvalue which refers to the original object may be used but only in limited ways. Such an lvalue refers to allocated storage
(3.7.3.2), and using the properties of the lvalue which do not depend on its value is well-defined. If an lvalue-to-rvalue
conversion (4.1) is applied to such an lvalue, the program has undefined behavior
По-моему, как-то так.
Abstraction вне форума   Ответить с цитированием
Старый 15.04.2013, 14:58   #12
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 5,941
По умолчанию

Вспылил, был неправ:
Arg arg = 10;
по стандарту еквивалентно
Arg arg; arg = Arg(10);

Тогда как в MSVC будет напрямую:
Arg arg(10);

Вот вам код, который прокатит в MSVC 2010- и завалит GCC (в 2012 вроде пофикшено):
Код:
class CTest
{
public:
    CTest( int )    { }
private:
    CTest(const CTest&) { }
};
int main()
{
    CTest a(10);
    CTest b = 10;
    return 0;
}

Последний раз редактировалось waleri; 15.04.2013 в 15:03.
waleri вне форума   Ответить с цитированием
Старый 15.04.2013, 15:04   #13
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,325
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Да, данный код некорректен. Не зря его GCC не берет.

Далее, ваш код позволяет из const объекта сделать не-const, что тоже не очень хорошо.
1. Выше указанная ссылка с примером это вообще то как раз таки последняя версия gcc 4.8.0.

Там есть возможность выбирать разные версии компиляторов. Можете по-эскперементировать - этот код работает.

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

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

В действительности, Arg - это аргумент функции.
Изначально,я создал его для того, что бы имитировать шаблонные виртуальные функции:

Код:
//потомки смогут работать с любыми типами данных
virtual Arg Func(const Arg a)=0;
И можно понять, почему в боевом проекте баг не проявился:

Код:
void Foo(const Arg arg);
...

Foo(10); //пока функция не отработает, временный объект жив
//поэтому Arg содержит валидные данные.

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

Учитывает константность объектов. Умеет работать с любыми типами данных, включая массивы.

3. В действительности, ещё раз глянул тесты: релиз студии провалился на тесте, где Arg был использован вне пределов функции.

И поломался на временном объекте.

Резюмируя: использование Arg безопасно только если его использовать по назначению: внутри функций. И чревато если использовать снаружи функций...

Сейчас я подумываю о том, что возможно стоит запретить времени компиляции подсовывать временные объекты. Это сузит область применения Arg, и снизит удобство его использования, но увеличит безопасность....

Вот только знать бы как это вообще можно такой статический ассерт то вляпать...

Последний раз редактировалось _Bers; 15.04.2013 в 15:21.
_Bers вне форума   Ответить с цитированием
Старый 15.04.2013, 15:10   #14
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 5,941
По умолчанию

Сделайте конструктор explicit - возможно поможет
waleri вне форума   Ответить с цитированием
Старый 15.04.2013, 15:13   #15
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,325
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение

Вот вам код, который прокатит в MSVC 2010- и завалит GCC (в 2012 вроде пофикшено):
Код:
class CTest
{
public:
    CTest( int )    { }
private:
    CTest(const CTest&) { }
};
int main()
{
    CTest a(10);
    CTest b = 10;
    return 0;
}
http://liveworkspace.org/code/O7CSz$2

Вообще, понятия не имею, за каким макаром, гцц докалебался до приватного копирующего конструктора
_Bers вне форума   Ответить с цитированием
Старый 16.04.2013, 17:33   #16
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
http://liveworkspace.org/code/O7CSz$2

Вообще, понятия не имею, за каким макаром, гцц докалебался до приватного копирующего конструктора
Потому что
Код:
CTest b = 10;
// это
CTest b(CTest(10));
// а не
CTest b; b = CTest(10);
Somebody вне форума   Ответить с цитированием
Старый 16.04.2013, 18:20   #17
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
Потому что
Неверно. Обратите внимание на вывод. Если бы Вы были правы, выводилось бы COPY (оптимизация этого не должна изменять, ибо наблюдаемое поведение).
Abstraction вне форума   Ответить с цитированием
Старый 16.04.2013, 19:55   #18
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
(оптимизация этого не должна изменять, ибо наблюдаемое поведение)
Почему это?
C++11 12.8.31
Цитата:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization. This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
...
when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
Somebody вне форума   Ответить с цитированием
Старый 16.04.2013, 20:55   #19
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Н-да. Нехорошо (с моей стороны). Может, подскажете, где лежат заведомо корректные стандарты 2003 и 2011?
Abstraction вне форума   Ответить с цитированием
Старый 16.04.2013, 21:43   #20
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Заведомо корректные стандарты за деньги продаются :-(
А так
http://cs.nyu.edu/courses/spring13/C...ard%202003.pdf
http://www.open-std.org/jtc1/sc22/wg...2012/n3376.pdf
Somebody вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
релиз собирается дебаг нет. veshiyoleg Visual C++ 2 07.10.2011 20:12
Релиз программы! Нужен совет. DimOn4Ik Свободное общение 4 25.06.2010 13:19
Посоветуйте релиз TreeView KWN, lnc Общие вопросы Delphi 4 12.05.2009 02:55
Релиз ViceCity Манжосов Денис :) Gamedev - cоздание игр: Unity, OpenGL, DirectX 13 05.02.2008 15:18


23:05.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.