Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PVS-Studio: анализируем код операционной системы ReactOS, Проверив код ReactOS, я смог исполнить с 
:(
    Опции темы
Thunderbolt
Дата 16.9.2011, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


DevRel
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 7.11.2007
Где: Тула

Репутация: 10
Всего: 16



user posted image

Аннотация

Проверив код ReactOS, я смог исполнить сразу три своих желания. Во-первых, давно хотелось написать статью об обыкновенном проекте. Не интересно проверять код таких проектов, как Chromium. Он слишком качественен и, на поддержание этого качества тратятся ресурсы, недоступные в обыкновенных проектах. Во-вторых, появился хороший пример, на котором можно показать, как необходим статический анализ в большом проекте, особенно если он разрабатывается разнородным распределенным коллективом. В-третьих, я получил подтверждение, что PVS-Studio становится всё лучше и полезнее.

PVS-Studio становится все лучше и лучше

Начну с последнего момента, по поводу пользы инструмента PVS-Studio. ReactOS косвенно подтверждает, что PVS-Studio развивается в правильном направлении. Вот новость о проверке ReactOS с помощью такого тяжеловеса, как  Coverity - "Статический анализ в Coverity" [1]. Я, конечно, знаю и понимаю, что до возможностей Coverity нам далеко. Но, тем не менее, там, где благодаря Coverity "было найдено несколько новых ошибок", PVS-Studio находит их целый вагон и маленькую тележку. При этом никакой код никуда отправлять не надо. Можно просто взять и проверить проект. Значит мы на верном пути.

Что такое ReactOS?

ReactOS - это современная, свободная и открытая операционная система, основанная на архитектуре Windows XP/2003. Система была написана с нуля и имеет своей целью повторение архитектуры Windows-NT, созданной Microsoft, от аппаратного до прикладного уровня. Объем исходного кода на языке Си, Си++ и ассемблере составляет порядка 220 мегабайт.

Различные ссылки:

Ошибки в ReactOS

Теперь поговорим о вагоне ошибок, которые повстречались мне в коде ReactOS. Конечно, все они в статью не войдут. Здесь я выложил текстовый файл с описанием ошибок, которые я заметил в ходе анализа. Файл содержит диагностические сообщения с именами файлов и номерами строк. Также я выделил ошибки в короткий код и дал некоторые комментарии. Поэтому тем, кто захочет сделать правки в ReactOS, лучше руководствоваться этим файлом, а не статьёй.

А еще лучше скачать и самим проверить проект с помощью PVS-Studio. Ведь я не знаком с проектом и выписывал только те ошибки, которые мне понятны. По поводу многих фрагментов кода я не знаю, содержат они ошибки или нет. Так что мой анализ достаточно поверхностен. Ключ для проверки выделим.

Ошибки, которые можно встретить в ReactOS разнообразнейшие. Просто зоопарк. Есть опечатки из одного символа.

Код
BOOL WINAPI GetMenuItemInfoA(...)
{
  ...
  mii->cch = mii->cch;
  ...
}


На самом деле должно быть написано вот так: "mii->cch = miiW->cch;". Потеряли букву 'W'. Как результат, программы уже не могут доверять функции GetMenuItemInfoA.

А вот другая опечатка в один символ. В этот раз некорректно работает сравнение двух имён.

Код
static void _Stl_loc_combine_names(_Locale_impl* L,
  const char* name1, const char* name2,
  locale::category c)
{
  if ((c & locale::all) == 0 || strcmp(name1, name1) == 0)
  ...
}


Есть путаница между оператором && и &. Очень распространенная ошибка. Встречаю практически в каждом проекте, где работают с битами или атрибутами файлов.

Код
static LRESULT APIENTRY ACEditSubclassProc()
{
  ...
  if ((This->options && ACO_AUTOSUGGEST) &&
      ((HWND)wParam != This->hwndListBox))
  ...
}


Корректный код должен выглядеть так "(This->options & ACO_AUTOSUGGEST)". Пример ниже содержит родственную ей ошибку, из-за которой всё условие всегда ложно.

Код
void adns__querysend_tcp(adns_query qu, struct timeval now) {
  ...
    if (!(errno == EAGAIN || EWOULDBLOCK || errno == EINTR ||
        errno == ENOSPC || errno == ENOBUFS || errno == ENOMEM)) {
  ...
}


Если присмотреться, то можно заметить коварный фрагмент: "|| EWOULDBLOCK ||".

Кстати, в ReactOS нашлось достаточно много условий, которые всегда истинны или ложны. Некоторые нестрашные, так как, например, располагаются в макросе assert(). Но есть, на мой взгляд, и критичные.

Код
INT WSAAPI
connect(IN SOCKET s,
        IN CONST struct sockaddr *name,
        IN INT namelen)
{
  ...
  /* Check if error code was due to the host not being found */
  if ((Status == SOCKET_ERROR) &&
      (ErrorCode == WSAEHOSTUNREACH) &&
      (ErrorCode == WSAENETUNREACH))
  {
  ...
}


Согласитесь, что реализация таких функций как "connect" должна быть протестирована максимально полно. А здесь мы имеем условие, которое всегда ложно. Быстро заметить дефект не так просто, поэтому выделю суть ошибки:

Код
(ErrorCode == 10065) && (ErrorCode == 10051)


Кстати, часть, связанная с сокетами, вообще выглядит сырой. Возможно, это связано с тем, что в Linux мире SOCKET принято объявлять как знаковый тип. А в Windows он беззнаковый:

Код
typedef UINT_PTR SOCKET;


Как результат имеем разнообразные ошибки в операциях сравнения:

Код
void adns_finish(adns_state ads) {
  ...
  if (ads->tcpsocket >= 0) adns_socket_close(ads->tcpsocket);
  ...
}


Выражение "ads->tcpsocket >= 0" не имеет смысла, так как всегда истинно.

Встречаются просто странные фрагменты. Скорее всего, это недописанные и забытые участки кода.

Код
if (ERROR_SUCCESS == hres)
{
  Names[count] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue) + 1);
  if (Names[count])
     strcmpW(Names[count], szValue);
}


Зачем вызывать "strcmpW", если результат никак не используется?

Имеются ошибки, связанные с приоритетом операций.

Код
VOID NTAPI
AtapiDmaInit(...)
{
  ...
  ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
  ...
}


Я расставлю скобки, чтобы стало ясно, как работает это выражение на самом деле:

Код
ULONG treg = (0x54 + (dev < 3)) ? (dev << 1) : 7;


Следующая ошибка обязательно встречается в любом большом проекте. Есть парочка и в ReactOS. Речь идет о лишней точке с запятой - ';'. 

Код
BOOLEAN
CTEScheduleEvent(PCTE_DELAYED_EVENT Event,
                 PVOID Context)
{
  ...
  if (!Event->Queued);
  {
    Event->Queued = TRUE;
    Event->Context = Context;
    ExQueueWorkItem(&Event->WorkItem, CriticalWorkQueue);
  }
  ...
}


Ещё мне нравятся ошибки с инициализацией элементов массива. Не знаю почему. Они трогательны. Возможно, я вспоминаю свои первые эксперименты с массивами на языке Basic.

Код
HPALETTE CardWindow::CreateCardPalette()
{
  ...
  //include button text colours
  cols[0] = RGB(0, 0, 0);
  cols[1] = RGB(255, 255, 255);

  //include the base background colour
  cols[1] = crBackgnd;

  //include the standard button colours...
  cols[3] = CardButton::GetHighlight(crBackgnd);
  cols[4] = CardButton::GetShadow(crBackgnd);
  ...
}


Можно продолжать приводить разные интересные участки кода. К сожалению, тогда статья станет слишком длинной и нужно останавливаться. Напомню, что посмотреть на другие ошибки, найденные мной в ReactOS, можно вот в этом файле. На сладкое только приведу вот этот кусочек кода:

Код
#define SWAP(a,b,c)  c = a;\
                     a = b;\
                     a = c


Пример использования:

Код
BOOL FASTCALL
IntEngGradientFillTriangle(...)
{
  ...
  SWAP(v2,v3,t);
  ...
}


Это – шедевр. 

Статический анализ кода

Я считаю ReactOS очень хорошим примером проекта, где регулярный статический анализ кода просто необходим. И дело здесь не в квалификации разработчиков. Проект большой и содержит разнообразные подсистемы. Это значит, что над таким проектом всегда трудится большое количество людей. А в большом коллективе всегда кто-то программирует хуже, кто-то лучше. Кто-то использует один стиль, кто-то другой. Но никто не застрахован от ошибок. Вот смотрите.

Один человек взял и написал в ReactOS вот так:

Код
if ((res = setsockopt(....) == -1))


Код делает не то, что хочется. Корректный вариант: if ((res = setsockopt(....)) == -1). Если придерживаться практики писать константу в начале, то случайно никогда не сделаешь ошибочное присваивание внутри оператора "if". У нас здесь другой тип ошибки. Но если писать код по приведенному правилу, то не получится сделать ошибку и в рассматриваемом выражении: "if (-1 == res = setsockopt(....))".

Вот только знание этой практики не мешает другому человеку ошибиться альтернативным способом.

Код
static DWORD CALLBACK
RegistrationProc(LPVOID Parameter)
{
  ...
  if (0 == LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
                        UnknownError,
                        sizeof(UnknownError) /
                        sizeof(UnknownError[0] - 20)))
  ...
}


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

К чему я все эти примеры? А к тому, что никто из нас программистов не идеален. И ни стандарт кодирования, ни технологии программирования, ни самоконтроль не гарантируют отсутствие ошибок в коде.

В крупных проектах просто необходимы такие вспомогательные технологии, как динамический и статический анализ. Подчеркну:

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

Поясню своё утверждение. В подобных системах невозможно  приблизиться к 100% покрытию кода при тестировании с помощью юнит-тестов или регрессионных тестов. Немного уточню. Можно конечно, но затраты на создание и поддержание таких тестов становятся недопустимо высоки.

Причина в том, что уж очень велико количество возможных состояний системы и возможных путей выполнения ветвей кода. Некоторые ветви крайне редко получают управление, но от этого не становятся ненужными. Именно здесь и получается увидеть преимущество, которым обладает статический анализ. Он проверяет весь код, в независимости от того, как часто он получает управление в процессе работы программы.

Пример проверки кода, редко получающего управление:

Код
static HRESULT STDMETHODCALLTYPE
CBindStatusCallback_OnProgress(...)
{
  ...
  if (This->szMimeType[0] != _T('\0'))
    _tprintf(_T("Length: %I64u [%s]\n"), This->Size, 
             This->szMimeType);
  else
    _tprintf(_T("Length: %ull\n"), This->Size);
  ...
}


Скорее всего, изначально код был написан неправильно. Потом кто-то заметил, что сообщение формируется неправильно и внес исправление, написав "%I64u". А вот на код по соседству он не обратил внимание. И там по-прежнему имеется некорректный формат "%ull".  Видимо ветка вызывается крайне редко. Статический анализ такое не пропустит. Собственно он и не пропустил, раз я могу продемонстрировать этот пример.

Другим хорошим примером может служить большое количество ошибок очистки памяти, которые я увидел ReactOS. Почему их так много, мне понятно. Никто не тестирует, заполнилась память или нет. Во-первых, сложно осознать, что в этих простых местах можно ошибиться. А во-вторых, не так просто проверить очистился внутри функции какой-то временный буфер или нет. Здесь статический анализ вновь на высоте. Приведу только пару примеров. На самом деле я насчитал как минимум 13 ошибок заполнения массивов константным значением.

Код
#define MEMSET_BZERO(p,l) memset((p), 0, (l))

char *SHA384_End(SHA384_CTX* context, char buffer[]) {
  ...
  MEMSET_BZERO(context, sizeof(context));
  ...
}


Очищаем только первые байты массива, так как sizeof(context) возвращает размер указателя, а не структуры.

Код
#define RtlFillMemory(Destination, Length, Fill) \
  memset(Destination, Fill, Length)

#define IOPM_FULL_SIZE          8196

HalpRestoreIopm(VOID)
{
  ...
  RtlFillMemory(HalpSavedIoMap, 0xFF, IOPM_FULL_SIZE);
  ...
}


Перепутаны аргументы при использовании макроса RtlFillMemory. Вызов должен быть таким:

Код
RtlFillMemory(HalpSavedIoMap, IOPM_FULL_SIZE, 0xFF);


Снова о табуляциях и пробелах

Заранее хочу попросить не начинать в комментариях новую бурную дискуссию на эту тему. Я просто выскажу своё мнение. С ним можно быть согласным или нет. Но обсуждать не стоит. 

Есть два непримиримых лагеря. Одни за использование табуляции в коде, так как это позволяет подстраивать отображение кода под себя [2]. Другие говорят, что это всё равно не работает и, что нет разумных причин использовать символы табуляции. От табуляции только вред и разъезжающееся форматирование. К их числу отношусь и я [3].

Можно сколько угодно говорить о том, что табуляции надо использовать правильно и тогда всё будет хорошо. К сожалению, это говорят те, кто работает замкнуто над одним проектом и не сталкиваются с внешним миром. В любом открытом или просто большом проекте, не удаётся достичь нормального оформления кода, если разрешить использовать табуляцию в любом виде.

Я не буду заниматься абстрактными рассуждениями. В этот раз я просто приведу своим оппонентам наглядный пример. Сейчас таким примером станет код ReactOS.

В стандарте кодирования ReactOS [4] написано хорошее правило с теоретической точки зрения:

Generic note about TABs usage: Don't use TABs for formatting; use TABs for indenting only and use only spaces for formatting.

Код
Example: 
NTSTATUS
SomeApi(IN Type Param1,
[spaces]IN Type Param2)
{
[TAB]ULONG MyVar;
[TAB]MyVar = 0;
[TAB]if ((MyVar == 3) &&
[TAB][sp](Param1 == TRUE))
[TAB]{
[TAB][TAB]CallSomeFunc();
...


Поклонники табуляции довольны. Однако я открываю исходные коды ReactOS и наблюдаю во многих местах испорченное форматирование. Почему?

user posted image

user posted image

user posted image

Ответ конечно очевиден. Потому, что это сложно помнить, где надо нажать TAB, а где поставить несколько пробелов,  если это не единственный проект, с которым работаешь. Вот люди постоянно и ошибаются. А раз так, нечего быть теоретиками, а надо быть практиками. Надо взять и запретить использовать табуляцию вообще. И тогда всё у всех будет одинаково, а виновника, кто начинает использовать табуляцию, легко найти и сделать ему внушение.

Это не шаг назад в оформлении кода! Это шаг вперёд! Это следующий уровень осознания. Теоретическая красота настраиваемых отступов не сочетается с практикой. В первую очередь важно обеспечить однозначное представление кода и легкость разработки в большой команде. В компании Google это понимают. И в их стандарте для форматирования используются только пробелы [5]. Тем, кто ратует за использование табуляции, еще раз рекомендую задумываться, почему распределенная команда высококлассных профессионалов, которые разрабатывают Chromium, выбрала именно пробелы.

И еще раз. Теоретическая красота настраиваемых отступов не сочетается с практикой. Неважно, как красиво звучит теория, если она не работает. А именно так и обстоит дело в  ReactOS.

Рекомендую команде разрабатывающей ReactOS модифицировать их стандарт и отказаться от использования табуляции. Любая табуляция должна расцениваться, как ошибка и быть устранена из кода.

Кстати, подобная практика позволит находить вот такие вот безобразия в коде ReactOS:

Код
BOOLEAN
KdInitSystem(IN ULONG BootPhase,
             IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
  ...
  /* Check if this is a comma, a space or a tab */
  if ((*DebugOptionEnd == ',') ||
      (*DebugOptionEnd == ' ') ||
      (*DebugOptionEnd == ' '))
  ...
}


Последнее сравнение, это сравнение с символом табуляции, а не с пробелом, как может показаться. Нормальный код должен выглядеть так: "(*DebugOptionEnd == '\t')". 

Примечание для сторонников табуляции. Не надо мне вновь рассказывать, как правильно использовать табуляции. И это не мой код. Смотрите, вот есть вполне конкретный проект ReactOS. В нем есть плохо отформатированный код. Подумайте, какие действия позволят сделать так, чтобы новый программист мог открыть код проекта и не гадать, какой размер символа табуляции ему необходимо установить в настройках редактора. Мысли в духе "нужно сразу было писать правильно" практической ценности не имеют.

Библиографический список
  1. Выпуск новостей ReactOS N79. Статический анализ в Coverity. http://www.viva64.com/go.php?url=722
  2. Пора завязывать использовать пробелы вместо табуляции в коде. http://www.viva64.com/go.php?url=725
  3. Пора завязывать использовать символы табуляции в коде. http://www.viva64.com/go.php?url=726
  4. ReactOS. Coding Style. http://www.viva64.com/go.php?url=724
  5. Google C++ Style Guide. http://www.viva64.com/go.php?url=679

--------------------
Карпов Андрей, DevRel в PVS-Studio.
PM MAIL WWW   Вверх
borisbn
Дата 18.9.2011, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(Thunderbolt @  16.9.2011,  19:25 Найти цитируемый пост)
Если придерживаться практики писать константу в начале, то случайно никогда не сделаешь ошибочное присваивание внутри оператора "if"

Это-то, конечно, так, но IMHO придерживаться этого правила всегда и везде - глупо. В простых случаях
Код
if ( count == 0 )

"читается" как "Если count равен нулю, то ...". Обратная же запись "не читаема". А на ошибку типа
Код
if ( count = 0 )

ругнётся компилятор.

А по поводу пробелов и табуляции - полностью и безоговорочно согласен. Своим падаванам по рукам даю за табуляцию.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
alexvs11
Дата 18.9.2011, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(borisbn @  18.9.2011,  11:06 Найти цитируемый пост)
Обратная же запись "не читаема".

не стоит недооценивать свои силы - запись будет вполне читаема
PM MAIL   Вверх
fish9370
Дата 18.9.2011, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: -1
Всего: 1



Цитата(Thunderbolt @ 16.9.2011,  19:25)
Другим хорошим примером может служить большое количество ошибок очистки памяти, которые я увидел ReactOS. Почему их так много, мне понятно

если у них не будет таких ошибок, то какой же это будет windows?

а по поводу табуляций, я придерживаюсь спецификации Kernighan & Ritchie, где рекомендуется использовать табуляцию шириной 8 символов - прекрасный стиль, применяется в ядре линукса, в астериске, и в тысячах других програм..
пробелы вместо табуляций появляются не потому-что, кто-то лепит их вместо табуляций, а потому-что используется копи-паст, это и порождает пробелы.. - что легко исправляется с помощью утилиты indent.
А редактаровать код с пробелами вместо табуляций - адское занятие,  если это не какой-то специальный редактор, который воспринимает пробелы как табуляцию..

писать константу впереди - это маразм - как тут уже правильно заметили, читать такой код невозможно..

Добавлено через 7 минут и 41 секунду
Цитата(borisbn @  18.9.2011,  11:06 Найти цитируемый пост)
if ( count = 0 );
ругнётся компилятор.


gcc на это ругнется, только если будет опция -Wall, что и рекомендую включать..



--------------------
undefined
PM MAIL WWW ICQ   Вверх
volatile
Дата 18.9.2011, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Слегка придирусь чтоли, если позволите...
Цитата(Thunderbolt @ 16.9.2011,  19:25)
Один человек взял и написал в ReactOS вот так:
Код
if ((res = setsockopt(....) == -1))

Код делает не то, что хочется. Корректный вариант: if ((res = setsockopt(....)) == -1). 

В обоих случаях условие абсолютно одинаково.
там и там сравнивается возвращаемое значение функции setsockopt() с минус единицей.
Разница лишь в значении которое присваивается переменной res, а чему оно должно быть равно, из приведенного отрывка абсолютно не очевидно.
Цитата(Thunderbolt @ 16.9.2011,  19:25)
Если придерживаться практики писать константу в начале, то случайно никогда не сделаешь ошибочное присваивание внутри оператора "if". У нас здесь другой тип ошибки. Но если писать код по приведенному правилу, то не получится сделать ошибку и в рассматриваемом выражении: "if (-1 == res = setsockopt(....))".

Как не меняй местами, а у оператора "== " приоритет всегда выше чем у оператора "="
Так что рекомендуемый вами код, будет интерпретирован как ((-1 == res) = setsockopt(....))"
То есть сначала вычислится булева переменная (-1 == res), а потом ей присвоится значение функции setsockopt();
Что смысла вообще не имеет...
PM MAIL   Вверх
alexvs11
Дата 18.9.2011, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(volatile @  18.9.2011,  15:12 Найти цитируемый пост)
Так что рекомендуемый вами код, будет интерпретирован как ((-1 == res) = setsockopt(....))"То есть сначала вычислится булева переменная (-1 == res), а потом ей присвоится значение функции setsockopt();Что смысла вообще не имеет...

Код

if (-1 == (res = setsockopt(....)))
{

}

PM MAIL   Вверх
fish9370
Дата 18.9.2011, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: -1
Всего: 1



Цитата(alexvs11 @  18.9.2011,  15:57 Найти цитируемый пост)
if (-1 == (res = setsockopt(....)))


отсюда вывод - скобки нужно правильно ставить, этот метод лишь маскирует проблему..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
volatile
Дата 18.9.2011, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(alexvs11 @  18.9.2011,  15:57 Найти цитируемый пост)
if (-1 == (res = setsockopt(....)))

ну это-то понятно. smile 

А почему бы не сделать просто.
Код

res = setsockopt(....);
if (res == -1)
{ ...

Имхо, ясней не бывает.
PM MAIL   Вверх
Thunderbolt
Дата 19.9.2011, 09:56 (ссылка)  | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


DevRel
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 7.11.2007
Где: Тула

Репутация: 10
Всего: 16



Цитата(volatile @ 18.9.2011,  15:12)
Как не меняй местами, а у оператора "==" приоритет всегда выше чем у оператора "="
Так что рекомендуемый вами код, будет интерпретирован как ((-1 == res) = setsockopt(....))"
То есть сначала вычислится булева переменная (-1 == res), а потом ей присвоится значение функции setsockopt();
Что смысла вообще не имеет...

Код

  int setsockopt() { return 1; }
  void foo(int res) {
    if (-1 == res = setsockopt())
    {}
  }


Ох уж мне эти сказочники....

error C2106: '=' : left operand must be l-value
--------------------
Карпов Андрей, DevRel в PVS-Studio.
PM MAIL WWW   Вверх
volatile
Дата 19.9.2011, 11:03 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Thunderbolt @  19.9.2011,  09:56 Найти цитируемый пост)
left operand must be l-value 

Ну дык, я об этом и говорю. smile 
PM MAIL   Вверх
volatile
Дата 19.9.2011, 11:19 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



К томуже, почему вы решили что ?
Цитата(Thunderbolt @  16.9.2011,  19:25 Найти цитируемый пост)
if ((res = setsockopt(....) == -1))
Код делает не то, что хочется.


А может так и задумывалось?
т.е.:
Код

bool res = setsockopt(....) == -1;
if (res) 
{ ...
Из приведенного отрывка вовсе не вытекает, что там хочется а что не хочется...

Ну да ладно, завязываю..

PM MAIL   Вверх
Thunderbolt
Дата 19.9.2011, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


DevRel
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 7.11.2007
Где: Тула

Репутация: 10
Всего: 16



Цитата(volatile @ 19.9.2011,  11:19)

Из приведенного отрывка вовсе не вытекает, что там хочется а что не хочется...


Вытекает. Но не приводить же везде простыню кода.

Это сообщение отредактировал(а) Thunderbolt - 19.9.2011, 14:00
--------------------
Карпов Андрей, DevRel в PVS-Studio.
PM MAIL WWW   Вверх
volatile
Дата 19.9.2011, 18:19 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Thunderbolt @  19.9.2011,  14:00 Найти цитируемый пост)
Но не приводить же везде простыню кода.

Ну раз вы отобрали только очевидные факты, то имхо, и должны предоставить достаточное основание в ошибочности.
Ибо иначе, можно вообще постить каждую строку любого кода, и говорить что оно "ошибочно", но почему сам знаю.

Цитата(Thunderbolt @  16.9.2011,  19:25 Найти цитируемый пост)
if ((res = setsockopt(....) == -1))

В этом коде я, например, не вижу ничего ненормального, разве что лишние скобки.
Не мудрено что
Цитата(Thunderbolt @  16.9.2011,  19:25 Найти цитируемый пост)
там, где благодаря Coverity "было найдено несколько новых ошибок", PVS-Studio находит их целый вагон и маленькую тележку.


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


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1002 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.