Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
|
[C++] от слова к делу 08.10.08 06:44 Число просмотров: 3018
Автор: void <Grebnev Valery> Статус: Elderman
|
Сегодня предложил тим-лидам высказаться о возможности использовать это в наших проектах.
1) Реакция разная. 99% всего кода компании это C++ std-based код, и возникает вопрос зачем это нужно если мы используем const std::string& parameter, std::vector, map и т.д. (утрирую). С дугой стороны, если учесть, что внури С++ кода есть тонны мест, где торчат уши достаточно низкоуровневых прямых вызовы RTL/API, где есть тонны мелких функций обработки буферов стреамов, строк, шаред мемори стораджей, и т.д. - вопрос о нужности SAL для меня однозначный. Я скорее всего буду использовать везде в коде С++, где это уместно (если начальство не запретит).
2)Есть вопрос - насколько это портабельно. Действительно сложно предположить возможность портить миллионы строк кода для Windows на другую платформу. Здесь возразить нечего. Хотя я вообще не сторонник создания портабельного кода для Windows/MAC/.......
3)Есть также вопрос - как указано в http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx это работает только на "...that can help static analysis tools, such as the /analyze switch in Visual Studio 2005 Team System and Visual Studio 2005 Team Edition for Developers..."
Действительно, этонеработает, например, на Express edition 2005:
1>Compiling...
1>cl : Command line warning D9040 : ignoring option '/analyze'; Code Analysis warnings are not available in this edition of the compiler
Но вот если собрать проект в VC++ 2008 даже Express Edition с опцией '/analyze':
#include "stdafx.h"
#include <windows.h>
void FillString(
__out_ecount(cchBuf) TCHAR* buf,
size_t cchBuf,
char ch) {
for (size_t i = 0; i < cchBuf; i++) {
buf[i] = ch;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR buf[100];
FillString( buf, 102, 0);
FillString( NULL, 102, 0);
return 0;
}
---
то получим следующие варнинги (что и нужно):
1>c:\users\val\documents\visual studio 2008\projects\sal\test1\test1.cpp(21) : warning C6202: Buffer overrun for 'buf', which is possibly stack allocated, in call to 'FillString': length '204' exceeds buffer size '200'
1>c:\users\val\documents\visual studio 2008\projects\sal\test1\test1.cpp(22) : warning C6309: Argument '1' is null: this does not adhere to function specification of 'FillString'
|
<programming>
|
[C++] кто использует MS SAL аннотации в коде? 04.10.08 19:36
Автор: void <Grebnev Valery> Статус: Elderman
|
В принципе удобно в определениях:
void f(__in int a)
{
}
...
...
...
но так же удобно и где-то в коде: f(__in 10); Для IDL - так вообще это норма.
|
|
[C++] от слова к делу 08.10.08 06:44
Автор: void <Grebnev Valery> Статус: Elderman
|
Сегодня предложил тим-лидам высказаться о возможности использовать это в наших проектах.
1) Реакция разная. 99% всего кода компании это C++ std-based код, и возникает вопрос зачем это нужно если мы используем const std::string& parameter, std::vector, map и т.д. (утрирую). С дугой стороны, если учесть, что внури С++ кода есть тонны мест, где торчат уши достаточно низкоуровневых прямых вызовы RTL/API, где есть тонны мелких функций обработки буферов стреамов, строк, шаред мемори стораджей, и т.д. - вопрос о нужности SAL для меня однозначный. Я скорее всего буду использовать везде в коде С++, где это уместно (если начальство не запретит).
2)Есть вопрос - насколько это портабельно. Действительно сложно предположить возможность портить миллионы строк кода для Windows на другую платформу. Здесь возразить нечего. Хотя я вообще не сторонник создания портабельного кода для Windows/MAC/.......
3)Есть также вопрос - как указано в http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx это работает только на "...that can help static analysis tools, such as the /analyze switch in Visual Studio 2005 Team System and Visual Studio 2005 Team Edition for Developers..."
Действительно, этонеработает, например, на Express edition 2005:
1>Compiling...
1>cl : Command line warning D9040 : ignoring option '/analyze'; Code Analysis warnings are not available in this edition of the compiler
Но вот если собрать проект в VC++ 2008 даже Express Edition с опцией '/analyze':
#include "stdafx.h"
#include <windows.h>
void FillString(
__out_ecount(cchBuf) TCHAR* buf,
size_t cchBuf,
char ch) {
for (size_t i = 0; i < cchBuf; i++) {
buf[i] = ch;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR buf[100];
FillString( buf, 102, 0);
FillString( NULL, 102, 0);
return 0;
}
---
то получим следующие варнинги (что и нужно):
1>c:\users\val\documents\visual studio 2008\projects\sal\test1\test1.cpp(21) : warning C6202: Buffer overrun for 'buf', which is possibly stack allocated, in call to 'FillString': length '204' exceeds buffer size '200'
1>c:\users\val\documents\visual studio 2008\projects\sal\test1\test1.cpp(22) : warning C6309: Argument '1' is null: this does not adhere to function specification of 'FillString'
|
| |
А портирование данной конкретной фичи достигается путем вырезания всего SAL препроцессором 08.10.08 07:59
Автор: amirul <Serge> Статус: The Elderman
|
|
| | |
You are right, but it is up to the management to decide what... 08.10.08 17:07
Автор: void <Grebnev Valery> Статус: Elderman
|
You are right, but it is up to the management to decide what is good for the company with respect to “porting”. Yesterday, I told the same (as you are saying) to ours team leads. Will see. I personally find new MS features very useful especially for the issues discussed: calls of RTL/WinAPI, and low level programming.
|
|
сорри, а для чего ??? 06.10.08 16:18
Автор: PS <PS> Статус: Elderman
|
> В принципе удобно в определениях: > void f(__in int a) > { > } > > ... > ... > ... > но так же удобно и где-то в коде: f(__in 10); Для IDL - так > вообще это норма.
void f( int a ) - IN.
void f( const int& a ) - IN.
void f( int& a ) - OUT.
Все прекрасно описывается средствами языка. Зачем втаскивать в текст дублирующие конструкции ?
|
| |
SAL не ограничивается in и out 06.10.08 22:24
Автор: amirul <Serge> Статус: The Elderman
|
> void f( int a ) - IN. > void f( const int& a ) - IN. > void f( int& a ) - OUT.
Что делать в C?
Что делать с IN OUT параметрами? Что делать с OPTIONAL параметрами (в C)? Что делать со всякими __out_ecount (который позволяет находить переполнения буфера)? И т.д..
> Все прекрасно описывается средствами языка. Зачем > втаскивать в текст дублирующие конструкции ? Не все, не прекрасно и не дублирующие :-)
|
| | |
Все равно не понятно 07.10.08 13:19
Автор: PS <PS> Статус: Elderman Отредактировано 07.10.08 13:23 Количество правок: 1
|
> > void f( int a ) - IN. > > void f( const int& a ) - IN. > > void f( int& a ) - OUT. > > Что делать в C? > Что делать с IN OUT параметрами? Что делать с OPTIONAL > параметрами (в C)? Что делать со всякими __out_ecount > (который позволяет находить переполнения буфера)? И т.д.. > > > Все прекрасно описывается средствами языка. Зачем > > втаскивать в текст дублирующие конструкции ? > Не все, не прекрасно и не дублирующие :-)
1. А что делать в ALGOL, LISP и других языках ? (это к вопросу о "C")
2.
void f( __out_encount(n) char* b, int n )
{
memset( b, 0, 2*n );
}
Скомпилится ? С варнингами - да. А можно и без варнингов. Запустится - да. Отработает - да. Память порушит - да.
И х. тогда было огород городить ?
/*!
@param out_str out строка заполненая n ASCII нулями
@param n in количество ASCII нулей для заполнения
*/
void f( std::string& out_str, int n )
{
out_str.append( n, '0' );
}
Память порушит - нет. Что in, что out видно ? да. SAL использован ? нет.
В каком то языке(компиляторе), то ли в VB, то ли в дельфи есть возможность при компиляции устанавливать: передаются параметры по значению или по ссылке.
И один и тот же код
function integer f( integer a){ a = 9; }
при разных ключах компиляции будет вести себя по разному.
Тут действительно SAL необходим ;)
|
| | | |
VS не поддерживает ни алгол ни лисп 07.10.08 23:17
Автор: amirul <Serge> Статус: The Elderman
|
> 1. А что делать в ALGOL, LISP и других языках ? (это к
VS не поддерживает ни алгол ни лисп
> вопросу о "C")
А вот C - поддерживает.
> 2. > void f( __out_encount(n) char* b, int n ) > { > memset( b, 0, 2*n ); > } > > Скомпилится ? С варнингами - да. А можно и без варнингов. > Запустится - да. Отработает - да. Память порушит - да. > И х. тогда было огород городить ?
Если с ворнингами - то этого достаточно. Вон ядерный код вообще компилируется с treat warning as errors. И все - не скомпилится. Если же человек увидел ворнинг и вместо того, чтобы разобраться в проблеме просто подавил его ключами - что ж сам идиот.
Вот здесь есть пример того, как это работает.
http://blogs.msdn.com/michael_howard/archive/2006/05/19/602077.aspx
> /*! > @param out_str out строка заполненая n ASCII нулями > @param n in количество ASCII нулей для заполнения > */ > void f( std::string& out_str, int n ) > { > out_str.append( n, '0' ); > } > > Память порушит - нет. Что in, что out видно ? да. SAL > использован ? нет.
Плюсовые обертки это конечно хорошо, но к примеру в C их нет. Да и при стыковке с WinAPI все равно надо разворачивать и вытаскивать наружу указатели и счетчики символов.
|
| | | | |
Т.е. SAL хорошо только для C ? 08.10.08 00:59
Автор: PS <PS> Статус: Elderman
|
> > 1. А что делать в ALGOL, LISP и других языках ? (это к > > VS не поддерживает ни алгол ни лисп > > > вопросу о "C") > > А вот C - поддерживает. > > Плюсовые обертки это конечно хорошо, но к примеру в C их > нет. Да и при стыковке с WinAPI все равно надо > разворачивать и вытаскивать наружу указатели и счетчики > символов.
По твоему выходит, что C - это краеугольный камень. Не буду спорить. Для меня C - такой же мамонт как алгол ;) Трахайтесь дальше со своими указателями, буферами и городите огороды в виде SAL ;)
А вот нахрена SAL нужен в C++ - не ясно. "Чую дело бесовское, а обосновать не могу" - всмысле, что вроде как и что-то полезное (судя по редким восторженным репликам), но куда это воткнуть, и главное - для чего, фантазии не хватает.
|
| | | | | |
Не только, но в общем да, наиболее полезен он именно в C 08.10.08 01:35
Автор: amirul <Serge> Статус: The Elderman
|
> По твоему выходит, что C - это краеугольный камень. Не буду > спорить. Для меня C - такой же мамонт как алгол ;) > Трахайтесь дальше со своими указателями, буферами и > городите огороды в виде SAL ;)
Только для того, чтобы не трахаться с указателями и буферами это не к плюсам, а жабам-додиезам.
> А вот нахрена SAL нужен в C++ - не ясно. "Чую дело
Ну вот неконстантная ссылка это out или inout? Кроме того, плюсы с гораздо бОльшими проблемами биндятся к другим языкам, чем C (тут тебе и собственные схемы мангляния у каждого компилятора, и собственная BPI для виртуальных таблиц, виртуального и множественного наследования,и невозможность заэнфорсить конктрукцию/деструкцию в других языках, и несовместимость обработки исключений и много чего еще). Именно поэтому API, которые предполагается использовать с другими языками/компиляторами делаются обычными PlainC-функциями (и при желании чуть выше заворачиваются в плюсовые обертки). Вон весь WinAPI - заSALен и это хорошо. Даже при вызове WinAPI из C++ кода хорошо.
> бесовское, а обосновать не могу" - всмысле, что вроде как и > что-то полезное (судя по редким восторженным репликам), но > куда это воткнуть, и главное - для чего, фантазии не > хватает. Да в общем повышает избыточность кода, что позволяет находить чуть больше ошибок статически. Ровно для тех же целей существует статическая типизация. Чуваки, более склонные к динамической типизации тоже ни хрена не понимают, почему это они не могут (без дополнительных извращений типа boost::any) в одном векторе хранить и строки, и инты, и лямбды.
|
| |
It does not duplicate the existing semantics. 06.10.08 21:48
Автор: void <Grebnev Valery> Статус: Elderman
|
|
|
[C++] Я пользовался в kernel-коде 04.10.08 21:54
Автор: amirul <Serge> Статус: The Elderman
|
> В принципе удобно в определениях: > void f(__in int a) > { > } > > ... > ... > ... > но так же удобно и где-то в коде: f(__in 10); Для IDL - так > вообще это норма.
IN, OUT, OPTIONAL. Раньше они были пустыми дефайнами, сейчас вроде компилятор МОЖЕТ извлечь какую то информацию (к примеру выдать ворнинги или соптимизировать чего-то), так что сейчас это не только удобно, но еще и МОЖЕТ привести к более правильными результатам
|
| |
По полной программе (т.е. не может, но "a must") это... 05.10.08 07:56
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 05.10.08 16:54 Количество правок: 1
|
> IN, OUT, OPTIONAL. Раньше они были пустыми дефайнами, > сейчас вроде компилятор МОЖЕТ извлечь какую то информацию > (к примеру выдать ворнинги или соптимизировать чего-то), > так что сейчас это не только удобно, но еще и МОЖЕТ > привести к более правильными результатам
По полной программе (т.е. не МОЖЕТ, но "a must") это реализовано только для "managed" кода, например C#. Причём, для managed кода это работает не только на уровне определения, но и вызовов (т.е. нельзя в определении фунции написать "ref", а при вызове функции опустиить "ref")... Жаль что этого нет в С++ (имею ввиду в non-managed С++).
|
|
|