VC9, std::exception, спецификации исключений
От: igna Россия  
Дата: 05.01.10 11:52
Оценка: 13 (2)
На основании чего VC9 определяет функции-члены класса std::exception без спецификаций исключений, ведь стандарт требует их:

18.6.1 Class exception

class exception {
public:
  exception() throw();
  exception(const exception&) throw();
  exception& operator=(const exception&) throw();
  virtual ˜exception() throw();
  virtual const char* what() const throw();
}

Re: VC9, std::exception, спецификации исключений
От: Кодт Россия  
Дата: 06.01.10 19:55
Оценка: 1 (1) :)
Здравствуйте, igna, Вы писали:

I>На основании чего VC9 определяет функции-члены класса std::exception без спецификаций исключений, ведь стандарт требует их:


1) На основании кривых рук?

2) На основании того, что
— компиляцию это не сломает,
— авторы реализации STL и без того поклялись не кидать исключение из конструктора std::exception,
— какая разница, рухнет программа предсказуемо, с terminate(), если они всё-таки нарушат клятву, или возникнет какое-то неопределённое поведение
— а если разницы нет, то зачем платить за проверку — неявный catch(...){terminate();} в определении функций, помеченных как throw()
То есть, это такая оптимизация.
Перекуём баги на фичи!
Re[2]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 06.01.10 20:47
Оценка:
Здравствуйте, Кодт, Вы писали:

К>2) На основании того, что

К>- компиляцию это не сломает,

Ну, при желании можно написать код, который об это сломается.

Реально, можно в переопределённом в what забыть про throw, и сломается уже на другом компиляторе.

К>То есть, это такая оптимизация.


у VC вроде напротив, throw() не то, что д.б. по стандарту, а как __declspec(nothrow), т.е. throw() как раз таки является оптимизацией.
Русский военный корабль идёт ко дну!
Re[3]: VC9, std::exception, спецификации исключений
От: Кодт Россия  
Дата: 06.01.10 21:17
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Ну, при желании можно написать код, который об это сломается.

AG>Реально, можно в переопределённом в what забыть про throw, и сломается уже на другом компиляторе.

Что-то туплю, как можно сломаться об это?
Перекуём баги на фичи!
Re[4]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 06.01.10 21:38
Оценка: 31 (1)
Здравствуйте, Кодт, Вы писали:

К>Что-то туплю, как можно сломаться об это?


1. Сломать на других компиляторах, просмотрев из-за отсутсвия контроля со сотроны MSVC


class SomeException : public std::exception
{
public:
  char const * what(); // будет работать в MSVC, но сломается на других конпиляторах
}



2. Думаю, теоретически можно написать код, который бы был правлиьным по стандарту, но сломался бы в MSVC.
Была такая идея, но MSVC почему-то это компилирует:
#include <stdexcept>

int main()
{
  char const * (std::exception::* f)() const throw() 
  = &std::exception::what;
}
Русский военный корабль идёт ко дну!
Re[5]: VC9, std::exception, спецификации исключений
От: igna Россия  
Дата: 07.01.10 08:43
Оценка: 11 (2)
Здравствуйте, Alexander G, Вы писали:

AG>class SomeException : public std::exception
AG>{
AG>public:
AG>  char const * what(); // будет работать в MSVC, но сломается на других конпиляторах
AG>}


Здесь между прочим ошибка, what должна быть константной, иначе она скрывает exception::what, причем VC9 предупреждения не выдает. Но это так, по ходу дела, я собственно о другом хотел написать, а именно, что даже если добавить спецификацию исключения, аналогичная проблема, то есть то, что будет работать в MSVC, но сломается на других компиляторах, может возникнуть, если класс будет иметь члены с деструктором без спецификации исключения или со спецификацией исключения отличной от throw(), а деструктор будет генерироваться компилятором. Тогда спецификация исключений сгенерированного деструктора будет несовместима со спецификацией исключений деструктора std::exception:

class SomeException : public std::exception
{
  std::string what_;
public:
  char const * what() const throw();
};


"ComeauTest.c", line 4: error: exception specification for implicitly declared
virtual function "SomeException::~SomeException" is incompatible
with that of overridden function "std::exception::~exception"
class SomeException : public std::exception
^


То есть нужно определить деструктор самому:

class SomeException : public std::exception
{
  std::string what_;
public:
  ~SomeException() throw() {}
  char const * what() const throw();
};
Re[6]: VC9, std::exception, спецификации исключений
От: _nn_  
Дата: 07.01.10 08:52
Оценка: 5 (1)
Здравствуйте, igna, Вы писали:

I>Здесь между прочим ошибка, what должна быть константной, иначе она скрывает exception::what, причем VC9 предупреждения не выдает.


Для этого случая есть особый ключик /Wall
Автор: Flamer
Дата: 28.12.09
.
И предупреждение C4263

// C4263.cpp
// compile with: /W4
#pragma warning(default:4263)
#pragma warning(default:4264)
class B {
public:
   virtual void func();
};

class D : public B {
   void func(int);   // C4263
};

int main() {
}


http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: VC9, std::exception, спецификации исключений
От: igna Россия  
Дата: 07.01.10 09:07
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Для этого случая есть особый ключик /Wall
Автор: Flamer
Дата: 28.12.09
.


Спасибо, это интересно. Полезность однако весьма ограниченная, компилируем например такое:

#include <exception>
#include <string>

class SomeException : public std::exception
{
  std::string what_;
public:
  ~SomeException() throw() {}
  char const * what() throw();
};


И получаем 37 предупреждений, относящихся в основном к стандартным заголовочным файлам:

------ Build started: Project: test, Configuration: Debug Win32 ------
Compiling...
test.cpp
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(114) : warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::attrib'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(119) : warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::name'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(123) : warning C4820: '_wfinddata64_t' : '4' bytes padding added after data member '_wfinddata64_t::attrib'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(493) : warning C4820: '_stat32' : '2' bytes padding added after data member '_stat32::st_gid'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(509) : warning C4820: 'stat' : '2' bytes padding added after data member 'stat::st_gid'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(525) : warning C4820: '_stat32i64' : '2' bytes padding added after data member '_stat32i64::st_gid'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(526) : warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_rdev'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(530) : warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_ctime'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(539) : warning C4820: '_stat64i32' : '2' bytes padding added after data member '_stat64i32::st_gid'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(553) : warning C4820: '_stat64' : '2' bytes padding added after data member '_stat64::st_gid'
c:\programme\microsoft visual studio 9.0\vc\include\wchar.h(554) : warning C4820: '_stat64' : '4' bytes padding added after data member '_stat64::st_rdev'
c:\programme\microsoft visual studio 9.0\vc\include\typeinfo(58) : warning C4820: 'type_info' : '3' bytes padding added after data member 'type_info::_m_d_name'
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(1865) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(1890) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(2137) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(2172) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(2420) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(2454) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\dokumente und einstellungen\igor (user)\eigene dateien\visual studio 2008\projects\test\test\test.cpp(9) : warning C4263: 'const char *SomeException::what(void) throw()' : member function does not override any base class virtual member function
c:\dokumente und einstellungen\igor (user)\eigene dateien\visual studio 2008\projects\test\test\test.cpp(10) : warning C4264: 'const char *std::exception::what(void) const' : no override available for virtual member function from base 'std::exception'; function is hidden
c:\programme\microsoft visual studio 9.0\vc\include\exception(201) : see declaration of 'std::exception::what'
c:\programme\microsoft visual studio 9.0\vc\include\exception(95) : see declaration of 'std::exception'
c:\programme\microsoft visual studio 9.0\vc\include\xstring(1566) : warning C4548: expression before comma has no effect; expected expression with side-effect
c:\programme\microsoft visual studio 9.0\vc\include\xstring(1557) : while compiling class template member function 'char &std::basic_string<_Elem,_Traits,_Ax>::operator [](unsigned int)'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xstring(2221) : see reference to class template instantiation 'std::basic_string<_Elem,_Traits,_Ax>' being compiled
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::_DebugHeapString::operator std::string(void) const' : function not inlined
c:\programme\microsoft visual studio 9.0\vc\include\xdebug(138) : see declaration of 'std::_DebugHeapString::operator std::string'
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::_Locinfo::_Getname(void) const' : function not inlined
c:\programme\microsoft visual studio 9.0\vc\include\xlocinfo(112) : see declaration of 'std::_Locinfo::_Getname'
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::locale::name(void) const' : function not inlined
c:\programme\microsoft visual studio 9.0\vc\include\xlocale(406) : see declaration of 'std::locale::name'
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::locale std::ios_base::getloc(void) const' : function not inlined
c:\programme\microsoft visual studio 9.0\vc\include\xiosbase(429) : see declaration of 'std::ios_base::getloc'
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(173) : see declaration of 'std::numpunct<_Elem>::do_grouping'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(178) : see declaration of 'std::numpunct<_Elem>::do_falsename'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(183) : see declaration of 'std::numpunct<_Elem>::do_truename'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(173) : see declaration of 'std::numpunct<_Elem>::do_grouping'
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined
with
[
_Elem=wchar_t,
_Traits=std::char_traits<wchar_t>,
_Ax=std::allocator<wchar_t>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(178) : see declaration of 'std::numpunct<_Elem>::do_falsename'
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined
with
[
_Elem=wchar_t,
_Traits=std::char_traits<wchar_t>,
_Ax=std::allocator<wchar_t>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(183) : see declaration of 'std::numpunct<_Elem>::do_truename'
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(83) : see declaration of 'std::numpunct<_Elem>::falsename'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(88) : see declaration of 'std::numpunct<_Elem>::truename'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined
with
[
_Elem=wchar_t,
_Traits=std::char_traits<wchar_t>,
_Ax=std::allocator<wchar_t>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(83) : see declaration of 'std::numpunct<_Elem>::falsename'
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined
with
[
_Elem=wchar_t,
_Traits=std::char_traits<wchar_t>,
_Ax=std::allocator<wchar_t>
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(88) : see declaration of 'std::numpunct<_Elem>::truename'
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(78) : see declaration of 'std::numpunct<_Elem>::grouping'
with
[
_Elem=char
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(135) : warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined
with
[
_Elem=wchar_t
]
c:\programme\microsoft visual studio 9.0\vc\include\xlocnum(78) : see declaration of 'std::numpunct<_Elem>::grouping'
with
[
_Elem=wchar_t
]
Build log was saved at "file://c:\Dokumente und Einstellungen\Igor (user)\Eigene Dateien\Visual Studio 2008\Projects\test\test\Debug\BuildLog.htm"
test — 0 error(s), 37 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Re[8]: VC9, std::exception, спецификации исключений
От: _nn_  
Дата: 07.01.10 09:36
Оценка:
Здравствуйте, igna, Вы писали:

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


__>>Для этого случая есть особый ключик /Wall
Автор: Flamer
Дата: 28.12.09
.


I>Спасибо, это интересно. Полезность однако весьма ограниченная, компилируем например такое:


К сожалению, включаются довольно неинтересные предупреждения.
У себя в проекте я выбрал из списка то что действительно нужно.
Например, C4265.


Ссылкой я ошибся..
Вот правильная /Wall
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 07.01.10 11:30
Оценка:
Здравствуйте, igna, Вы писали:

I>И получаем 37 предупреждений, относящихся в основном к стандартным заголовочным файлам:


такой хак
Автор: Alexander G
Дата: 14.09.08
может помочь.
Русский военный корабль идёт ко дну!
Re: VC9, std::exception, спецификации исключений
От: gear nuke  
Дата: 12.01.10 11:21
Оценка:
Здравствуйте, igna, Вы писали:

I>На основании чего VC9 определяет функции-члены класса std::exception без спецификаций исключений


Для оптимизации. Разницу в сгенерированном коде видно, если указать ключ /d1ESrt.

??0exception@std@@QAE@XZ PROC                ; std::exception::exception, COMDAT
; _this$ = ecx

; 44   :     exception()  {}

    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx
    mov    eax, DWORD PTR _this$[ebp]
    mov    DWORD PTR [eax], OFFSET ??_7exception@std@@6B@
    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0
??0exception@std@@QAE@XZ ENDP                ; std::exception::exception


??0exception@std@@QAE@XZ PROC                ; std::exception::exception, COMDAT
; _this$ = ecx

; 44   :     exception() throw() {}

    push    ebp
    mov    ebp, esp
    push    -1
    push    __ehhandler$??0exception@std@@QAE@XZ
    mov    eax, DWORD PTR fs:0
    push    eax
    mov    DWORD PTR fs:0, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx
    mov    eax, DWORD PTR _this$[ebp]
    mov    DWORD PTR [eax], OFFSET ??_7exception@std@@6B@
    mov    eax, DWORD PTR _this$[ebp]
    mov    ecx, DWORD PTR __$EHRec$[ebp]
    mov    DWORD PTR fs:0, ecx
    mov    esp, ebp
    pop    ebp
    ret    0
_TEXT    ENDS
В последнем варианте приходится как-то различать откуда исключение — из конструктора exception, или нет.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 12.01.10 12:00
Оценка:
Здравствуйте, gear nuke, Вы писали:

I>>На основании чего VC9 определяет функции-члены класса std::exception без спецификаций исключений


GN>Для оптимизации. Разницу в сгенерированном коде видно, если указать ключ /d1ESrt.


Этот ключ даже не документирован и вряд ли кем-то используется в продакшн, а без него скорее код с пустой спецификацией исключений будет лучше оптимизирован.
Русский военный корабль идёт ко дну!
Re[3]: VC9, std::exception, спецификации исключений
От: gear nuke  
Дата: 12.01.10 14:38
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Этот ключ даже не документирован и вряд ли кем-то используется в продакшн


Это не имеет отношения к делу.

AG>а без него скорее код с пустой спецификацией исключений будет лучше оптимизирован.


Какие для этого есть предпосылки, хотя бы в теории?

И я ведь мог написать — мы тоже используем exception без спецификаторов исключений, потому что это дает более оптимальный код. Но я не Саттер, много кто поверит?

Поэтому я воспроизвел "лишний код" самым простым способом. /d1ESrt в данном случае используется для отключения некоторых оптимизаций (на самом деле он еще добавляет таблицы с данными, не связанные с exception(); ).

"Лишний код" в листинге не несет ничего, чем его можно связать с /d1ESrt. Это выполнение конструктора "в как-бы try блоке". Дополнительный SEH фрейм нужен, что бы диспетчер исключений понял, бросил ли конструктор.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 12.01.10 15:11
Оценка:
Здравствуйте, gear nuke, Вы писали:

AG>>а без него скорее код с пустой спецификацией исключений будет лучше оптимизирован.


GN>Какие для этого есть предпосылки, хотя бы в теории?


__declspec(nothrow) позволяет компилятору предположить, что функция никогда не бросает исключения.
С /EHs — исключениями это может существенно уменьшить сгенерированный код.

Пустая спецификация исключений, именно пустая (и именно по умолчанию, а не с /d1-ключами) эквивалентна __declspec(nothrow)

см. http://msdn.microsoft.com/en-us/library/49147z04(VS.71).aspx
Русский военный корабль идёт ко дну!
Re[5]: VC9, std::exception, спецификации исключений
От: gear nuke  
Дата: 12.01.10 16:27
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>__declspec(nothrow) позволяет компилятору предположить, что функция никогда не бросает исключения.

AG>С /EHs — исключениями это может существенно уменьшить сгенерированный код.

За счет чего /EHs может уменьшить код мне понятно, хоть ты и не указал. И это не имеет отношения к теме. Компилятор не генериреут некоторые фреймы, т.к. видит поток управления и уверен что там не возникнут исключения. Он может использовать jmp вместо длинной цепочки _CxxThrowException --> __CxxFrameHandler3

Вот примерно такие теоретические умозаключения я и хочу увидеть в подтверждение твоей теории. Без них она совсем ничего не стоит.

AG>Пустая спецификация исключений, именно пустая (и именно по умолчанию, а не с /d1-ключами) эквивалентна __declspec(nothrow)


Я видел код аналогичный приведённому и без /d1ESrt (не надо цепляться к /d1 ключам, это всего лишь ключи для фронтенда С++). Я его не могу привести сейчас, сходу, на минимальном примере. Но в проекте по-больше было видно что общий размер кода увеличивается.

Почему появляется дополнительный код — потому что нужно знать, где было исключение в функции или вне. Теория согласуется с практикой. Я не знаю, почему у MS именно так, но здесь std::exception такой именно по этой причине.

AG>см. http://msdn.microsoft.com/en-us/library/49147z04(VS.71).aspx


Дык сам и смотри:

Using void declspec(nothrow) stdcall f2(); has the advantage that you can use an API definition, such as that illustrated by the #define statement, to easily specify nothrow on a set of functions. The third declaration, void stdcall f3() throw(); is the syntax defined by the C++ standard.

Это одно и тоже. Помедитируй еще над C4290. В библиотечном коде нестандартное и правда удобнее использовать.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[5]: VC9, std::exception, спецификации исключений
От: gear nuke  
Дата: 12.01.10 16:33
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Пустая спецификация исключений, именно пустая (и именно по умолчанию, а не с /d1-ключами) эквивалентна __declspec(nothrow)


Сорри, выше я что-то переборщил с аргументами, ты пишешь тоже самое.

Теперь посмотрим на 2 ситуации:
1. функция без спецификации — бросит, не бросит — диспетчер исключений это не волнует. Он поймает исключение и вызовет подходящий catch, если сможет.
2. функция с throw(). Она как бы не может бросить, так думает автор кода. Но диспетчер исключений не может быть уверен, что автор не ошибся. Он должен различить ситуацию, когда функция все-таки что-то бросила, что бы вызвать unexpected(). Потому такой вариант требует допонительный код. Если компилятор способен проследить поток управления и убедиться что там нет подозрительных мест, он не будет генерировать SEH фреймы и/или изменение exception state в них.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: VC9, std::exception, спецификации исключений
От: Alexander G Украина  
Дата: 12.01.10 16:45
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Сорри, выше я что-то переборщил с аргументами, ты пишешь тоже самое.


GN>Теперь посмотрим на 2 ситуации:

GN>1. функция без спецификации — бросит, не бросит — диспетчер исключений это не волнует. Он поймает исключение и вызовет подходящий catch, если сможет.
+

GN>2. функция с throw(). Она как бы не может бросить, так думает автор кода. Но диспетчер исключений не может быть уверен, что автор не ошибся. Он должен различить ситуацию, когда функция все-таки что-то бросила, что бы вызвать unexpected(). Потому такой вариант требует допонительный код. Если компилятор способен проследить поток управления и убедиться что там нет подозрительных мест, он не будет генерировать SEH фреймы и/или изменение exception state в них.


Насколько я понимаю, без хитрых ключей вроде /d1ESrt — даже код, вызывающий unexpected, сгенерирован не будет, иначе не было бы по моей ссылке в самом начале:

This attribute tells the compiler that the declared function and the functions it calls never throw an exception. With the synchronous exception handling model, now the default, the compiler can eliminate the mechanics of tracking the lifetime of certain unwindable objects in such a function, and significantly reduce the code size.


Насколько я помню, Саттер тоже упоминал, что пустая спецификация в MSVC не вызывает unexpected.
Русский военный корабль идёт ко дну!
Re[7]: У Саттера
От: Alexander G Украина  
Дата: 12.01.10 16:54
Оценка:
AG>Насколько я помню, Саттер тоже упоминал, что пустая спецификация в MSVC не вызывает unexpected.

По приведенной тобой ссылке
http://www.gotw.ca/publications/mill22.htm

It’s actually even a bit worse than that in practice, because it turns out that popular implementations vary in how they actually handle exception specifications. At least one popular C++ compiler (Microsoft’s, up to version 7.x) parses exception specifications but does not actually enforce them, reducing the exception specifications to glorified comments. But, on the other hand, there are legal optimizations a compiler can perform outside a function, and which the Microsoft 7.x compiler does perform, that rely on the ES enforcement being done inside each function -- the idea is that if the function did try to throw something it shouldn’t the internal handler would stop the program and control would never return to the caller, so since control did return to the caller the calling code can assume nothing was thrown and do things like eliminate external try/catch blocks. So on that compiler, because the checking is not done but the legal optimization that relies on it is done, the meaning of “throw()” changes from the standard “check me on this, stop me if I inadvertently throw” to a “trust me on this, assume I’ll never throw and optimize away.” So beware: If you do choose to use even an empty throw-specification, read your compiler’s documentation and check to see what it will really do with it. You might just be surprised. Be aware, drive with care.


Под "internal handler" подразумевается явно написанный обработчик, т.к. про неявный чётко сказано, что его нет.

Оно же "Новые сложные задачи на С++", с. 92.
Русский военный корабль идёт ко дну!
Re[7]: VC9, std::exception, спецификации исключений
От: gear nuke  
Дата: 13.01.10 07:33
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Насколько я понимаю, без хитрых ключей вроде /d1ESrt — даже код, вызывающий unexpected, сгенерирован не будет


/d1ESrt гененирует только "List of expected exceptions" (см. здесь). Код, вызывающий unexpected (а так же код, проверяющий списки ожидаемых исключений) безусловно находится в CRT и линкуется к каждому приложению (использующему этот рантайм).

AG>, иначе не было бы по моей ссылке в самом начале:


[]

Не вижу там про связь между /EHs и /d1ESrt. Однако общее у этих ключей есть — заставляют компилятор не делать некоторые допущения, отсюда он не может "eliminate" некоторый код. Вот только поэтому я и использовал /d1ESrt, в других случаях для этого пишу volatile.

Вот прицепился то к ключу Это, конечно, совершенно понятно: агрументов в защиту твоей теории нет
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: У Саттера
От: gear nuke  
Дата: 13.01.10 07:42
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>

the idea is that if the function did try to throw something it shouldn’t the internal handler would stop the program and control would never return to the caller


AG>Под "internal handler" подразумевается явно написанный обработчик, т.к. про неявный чётко сказано, что его нет.


Если внимательно изучить исходники диспетчера исключений, то окажется, что под этим понимается внутренний обработчик в CRT, а именно __CxxFrameHandler3 котрый вызывает далее __InternalCxxFrameHandler
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.