unused<T>
От: remark Россия http://www.1024cores.net/
Дата: 13.08.10 11:41
Оценка: 39 (3) -1
Из той же оперы, что и auto_value&lt;&gt;
Автор: Кодт
Дата: 16.01.03
.

Иногда приходится писать код типа:
DWORD err = GetLastError();
(void)err;

BOOL res = CloseHandle(f);
assert(res);
(void)res;


Дабы сократить 1 строчку, подумалось:
template<typename T>
class unused
{
public:
    unused(T v) : v(v) {}
    unused(unused const& v) : v(v.v) {}
    operator T () const {return v;}
private:
    void operator = (unused const&);
    T volatile const v;
};

unused<DWORD> err = GetLastError();

unused<BOOL> res = CloseHandle(fout);
assert(res);


З.ы. volatile важен, т.к. обычно его забываешь ставить, и потом в релизе до истины уже не докапаешься.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: unused<T>
От: Erop Россия  
Дата: 13.08.10 11:52
Оценка:
Здравствуйте, remark, Вы писали:

R>
R>    unused(unused const& v) : v(v.v) {}
R>private:
R>    void operator = (unused const&);
R>


Зачем это всё? Зачем свой конструктор копии и зачем запрет присваивания?
Или фишка в том, что нельзя поменять? Тогда, по идее, нужен не operator T, а operator const T&

R>З.ы. volatile важен, т.к. обычно его забываешь ставить, и потом в релизе до истины уже не докапаешься.

Ну и название мне не нравится, конечно. Фраза
unused<DWORD> res = GetLastError();
checkError( res );
нифига не читабельная. Может как-то типа debug_variable назвать, например?

R>

Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: unused<T>
От: Erop Россия  
Дата: 13.08.10 11:53
Оценка:
Здравствуйте, remark, Вы писали:


R>Дабы сократить 1 строчку, подумалось:


А вообще, конечно, цель сократить одну строчку ложная.
Другое дело, что волотайл может быть в тему.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: unused<T>
От: night beast СССР  
Дата: 13.08.10 11:57
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>
R>>    unused(unused const& v) : v(v.v) {}
R>>private:
R>>    void operator = (unused const&);
R>>


E>Зачем это всё? Зачем свой конструктор копии и зачем запрет присваивания?

E>Или фишка в том, что нельзя поменять? Тогда, по идее, нужен не operator T, а operator const T&

думаю, чтобы подавить варнинг неиспользуемой переменной в релизе.
Re[3]: unused<T>
От: Erop Россия  
Дата: 13.08.10 12:05
Оценка:
Здравствуйте, night beast, Вы писали:

NB>думаю, чтобы подавить варнинг неиспользуемой переменной в релизе.

Как-то это ненадёжно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: unused<T>
От: night beast СССР  
Дата: 13.08.10 12:06
Оценка:
Здравствуйте, Erop, Вы писали:

NB>>думаю, чтобы подавить варнинг неиспользуемой переменной в релизе.

E>Как-то это ненадёжно.

почему?
Re: unused<T>
От: uzhas Ниоткуда  
Дата: 13.08.10 12:13
Оценка:
Здравствуйте, remark, Вы писали:

Аналогичные вопросы обсуждались здесь
http://rsdn.ru/forum/cpp/3655065.flat.aspx
Автор: remark
Дата: 28.12.09

http://rsdn.ru/forum/cpp/3787064.flat.aspx
Автор: uzhas
Дата: 26.04.10


R>unused<BOOL> res = CloseHandle(fout);

R>assert(res);
а так сможете?
unused<std::string> res = FetchName(db);
assert(!res.empty());
Re: unused<T>
От: Кодт Россия  
Дата: 13.08.10 12:14
Оценка:
Здравствуйте, remark, Вы писали:

Всё-таки, unused — это write-only. Ассерт — это уже не совсем unused
Можно так
template<class T>
class unused : noncopyable
{
#ifdef _DEBUG

  T data;
public:
  unused(const T& v) : data(v) {}
  operator const T& () const { return data; }

#else

public:
  unused(const T& v) {}
  operator const T& () const { PANIC(); }

#endif
};


В чём прикол с volatile, не понял. И почему нельзя по месту писать unused<volatile T>, если известно, что функция возвращает volatile?
Перекуём баги на фичи!
Re[2]: unused<T>
От: remark Россия http://www.1024cores.net/
Дата: 13.08.10 12:18
Оценка:
Здравствуйте, Erop, Вы писали:

E>А вообще, конечно, цель сократить одну строчку ложная.


А что делать, если надо обернуть кучу WinAPI/POSIX, и таких мест дофига?
В паре месте написать лишнюю строчку нормально, но в десятках тоже как-то не очень имвхо...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: unused<T>
От: remark Россия http://www.1024cores.net/
Дата: 13.08.10 12:20
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, remark, Вы писали:


U>Аналогичные вопросы обсуждались здесь

U>http://rsdn.ru/forum/cpp/3655065.flat.aspx
Автор: remark
Дата: 28.12.09

U>http://rsdn.ru/forum/cpp/3787064.flat.aspx
Автор: uzhas
Дата: 26.04.10



Для параметров это немного другое получается.
Тут идея как бы совместить переменную и unused.


R>>unused<BOOL> res = CloseHandle(fout);

R>>assert(res);
U>а так сможете?
U>
U>unused<std::string> res = FetchName(db);
U>assert(!res.empty());
U>


Ну... можно перегрузить operator->(), тогда будет:
assert(!res->empty());



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: unused<T>
От: superlexx  
Дата: 13.08.10 12:21
Оценка: +1
Здравствуйте, remark, Вы писали:

R>template<typename T> class unused


Проще надо быть:
VERIFY(CloseHandle(x));
Если на результаты хочется посмотреть, то найдёте их в регистрах. GetLastError -- $err,hr в Watch
verify
Re[2]: unused<T>
От: remark Россия http://www.1024cores.net/
Дата: 13.08.10 12:24
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Всё-таки, unused — это write-only. Ассерт — это уже не совсем unused

К>Можно так
К>
К>template<class T>
К>class unused : noncopyable
К>{
К>#ifdef _DEBUG
К>  T data;
К>public:
К>  unused(const T& v) : data(v) {}
К>  operator const T& () const { return data; }
К>#else
К>public:
К>  unused(const T& v) {}
К>  operator const T& () const { PANIC(); }
К>#endif
К>};
К>


В релизе переменная тоже нужна, что бы видеть в отладчике или в дампе.


К>В чём прикол с volatile, не понял. И почему нельзя по месту писать unused<volatile T>, если известно, что функция возвращает volatile?


Если переменная используется только в assert'е, или вообще не используется (просто хочется видеть значение в отладчике/дампе), то в релизе её либо вообще не будет, либо она будет замешана где-то в регистрах.
Если же объявлять как:
DWORD volatile err = GetLastError();


То она в релизе не только останется, но даже и отладчик скорее всего будет показывать корректное значение.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: unused<T>
От: remark Россия http://www.1024cores.net/
Дата: 13.08.10 12:29
Оценка:
Здравствуйте, superlexx, Вы писали:

R>>template<typename T> class unused


S>Проще надо быть:
VERIFY(CloseHandle(x));
Если на результаты хочется посмотреть, то найдёте их в регистрах. GetLastError -- $err,hr в Watch


Это не то.
VERIFY не везде есть.
VERIFY выдаёт мессаджбокс.
В регистрах искать не очень круто при прочих равных.
В регистре значение будет очень не долго, а в дампе его вообще не будет.
Иногда со значением вообще ничего не надо делать, просто что бы было. $err надо успеть сделать, и вообще его надо делать.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: unused<T>
От: Кодт Россия  
Дата: 13.08.10 18:42
Оценка: 11 (1)
Здравствуйте, remark, Вы писали:

R>Это не то.

R>VERIFY не везде есть.
#define REMARK_VERIFY

R>VERIFY выдаёт мессаджбокс.

#define REMARK_VERIFY

R>В регистрах искать не очень круто при прочих равных.

R>В регистре значение будет очень не долго, а в дампе его вообще не будет.
#define REMARK_VERIFY(x) LBRACE auto tmp = x; assert(x); RBRACE

#define LBRACE do {
#define RBRACE } while(false)


R>Иногда со значением вообще ничего не надо делать, просто что бы было. $err надо успеть сделать, и вообще его надо делать.


Для пущей навороченности:
struct errors
{
  UINT m_lasterror;
  error_t m_errno, m_doserrno;

  errors() : m_lasterror(GetLastError()), m_errno(::errno), m_doserrno(::_doserrno) {}

  operator bool() const { return m_lasterror||m_errno||m_doserrno; }
};

template<class Value, class Assertion = Pofigu>
struct unused
{
  Value m_value;
  errors m_errors;

  unused(Value v) : m_value(v) { Assertion::assert(v, m_errors); }
};

struct Pofigu         { template<class Value> static void assert(Value v,   errors const& e) {               } };
struct AssertNoErrors { template<class Value> static void assert(Value v,   errors const& e) { ::assert(!e); } };
struct AssertNonZero  { template<class Value> static void assert(Value v,   errors const& e) { ::assert(v);  } };
struct AssertZero     { template<class Value> static void assert(Value v,   errors const& e) { ::assert(!v); } };
struct AssertHResult  {                       static void assert(HRESULT v, errors const& e) { ::assert(SUCCEEDED(hr)); } };
Перекуём баги на фичи!
Re: unused<T>
От: Vamp Россия  
Дата: 13.08.10 19:22
Оценка:
R>Иногда приходится писать код типа:
Я уже всю голову сломал, но так и не понял, зачем такой код приходится писать?

DWORD err = GetLastError();
(void)err;

Чтоза поведение обеспечивается?
Да здравствует мыло душистое и веревка пушистая.
Re[2]: unused<T>
От: Вертер  
Дата: 13.08.10 21:09
Оценка:
Здравствуйте, Vamp, Вы писали:

R>>Иногда приходится писать код типа:

V>Я уже всю голову сломал, но так и не понял, зачем такой код приходится писать?

V>Чтоза поведение обеспечивается?


чтобы Visual Studio не выдавал warning когда включен Level 4. Предупреждение будет, типа: «локальная переменная объявлена но не используется»
Re[3]: unused<T>
От: Vamp Россия  
Дата: 13.08.10 21:12
Оценка:
В>чтобы Visual Studio не выдавал warning когда включен Level 4. Предупреждение будет, типа: «локальная переменная объявлена но не используется»
А, спасибо, понял. Я бы правда скорее подавил предупреждение.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: unused<T>
От: Вертер  
Дата: 13.08.10 21:22
Оценка:
В>>чтобы Visual Studio не выдавал warning когда включен Level 4. Предупреждение будет, типа: «локальная переменная объявлена но не используется»
V>А, спасибо, понял. Я бы правда скорее подавил предупреждение.

лучше этого не делать с помощью всяких подавителей иногда можно так и (логическую) ошибку пропустить.
Re[3]: unused<T>
От: minorlogic Украина  
Дата: 15.08.10 06:50
Оценка:
Здравствуйте, remark, Вы писали:

R>А что делать, если надо обернуть кучу WinAPI/POSIX, и таких мест дофига?


Первое что приходит в голову, враперы ?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: unused<T>
От: SleepyDrago Украина  
Дата: 15.08.10 15:52
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

R>З.ы. volatile важен, т.к. обычно его забываешь ставить, и потом в релизе до истины уже не докапаешься.


Идея сохранить удобства дебага в релизе с помощью volatile прикольная — все равно syscall штука недешевая так что запись в переменную считай бесплатно.

Идея не обрабатывать ошибки в релизе достойна порки.
Я не настаиваю на месадж боксах тк пишу и под линупс без гуя но альтернативы всегда есть — логи и тп. Даже если не собираетесь падать эта инфо может быть очень важна.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.