Discussion:
про статические проверки чужого-кода
(слишком старое сообщение для ответа)
Nickita A Startcev
2014-01-31 17:27:56 UTC
Permalink
Привет, All !

А какие есть проверяльщики кода, которые аккуратно ругнутся на потерю точности
при присваиваниях или при неявном приведении 'простых' типов в выражениях?
gcc/g++ при самых жестких настройках проверяет только сравнение знакового с
беззнаковым.

примеры плохого кода:

char foo( int a, int b)
{
return a+b; // int урезается до char
}

unsigned int bar1(int a, int b)
{
return a+b; // знаковое урезается до беззнакового. при отрицательном будут
проблемы
}

long long bar3(int a, int b)
{
return a*b; // возможна потеря точности
}

. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev
... вендоры игрушек и прочие NVidia съели его мозг
Semen Panevin
2014-01-31 20:50:32 UTC
Permalink
Доброго здоровьица тебе, Nickita!

Friday January 31 2014 21:27, Nickita A Startcev писал All:

NAS> А какие есть проверяльщики кода, которые аккуратно ругнутся на потерю
NAS> точности при присваиваниях или при неявном приведении 'простых' типов
NAS> в выражениях? gcc/g++ при самых жестких настройках проверяет только
NAS> сравнение знакового с беззнаковым.
Поскольку на конкретный язык программирования указания довольно косвенные,
рискну предположить - mono?

С наилучшими пожеланиями, Семён.

... В гостях хорошо, а дома хуже...
Serguei E. Leontiev
2014-02-01 12:49:59 UTC
Permalink
Привет Nickita,

От 31 января 2014 г., 21:27:56 в fido7.ru.unix.prog ты писал:
NS> А какие есть проверяльщики кода, которые аккуратно ругнутся на
NS> потерю точности при присваиваниях или при неявном приведении
NS> 'простых' типов в выражениях? ??gcc/g++ при самых жестких

Hу, GNU-тое не есть прямое, давно уже его не люблю :)

NS> настройках проверяет только сравнение знакового с беззнаковым.
NS>
NS> примеры плохого кода:
NS>
NS> char foo( int a, int b)
NS> {
NS> return a+b; // int урезается до char
NS> }
NS>
NS> unsigned int bar1(int a, int b)
NS> {
NS> return a+b; // знаковое урезается до беззнакового. при
NS> отрицательном будут проблемы
NS> }

А вот BSD отличилось в этом упражнении. :)

http://clang.llvm.org/docs/UsersManual.html#options-to-control-error-and-warning-messages

leom:tmp leo$ cc --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.2
Thread model: posix
leom:tmp leo$ cc -c -Weverything -Werror chk.c
chk.c:8:15: error: implicit conversion loses integer precision: 'int' to
'char'
[-Werror,-Wconversion]
return a+b; // int урезается до char
~~~~~~ ~^~
chk.c:13:15: error: implicit conversion changes signedness: 'int' to
'unsigned int' [-Werror,-Wsign-conversion]
return a+b; // знаковое урезается до беззнакового. при отрицательн...
~~~~~~ ~^~
2 errors generated.


NS> long long bar3(int a, int b)
NS> {
NS> return a*b; // возможна потеря точности

А вот это не является потерей точности. Это возможность переполнения при
вычислении целочисленных выражений, но эта возможность есть всегда.

int bar3(int a, int b)
{
return a*b; // возможно переполнение

или даже

return a+1; // возможно переполнение

А если объявить плохим стилем приведение целого выражения меньшего ранга
к целочисленному типу большего ранга, то будешь погребён под ошибочными
предупреждениями второго рода.

По сути оно же на типичных LP64 платформах не отличается от весьма и
весьма распространённого:

char *bar4(char *p, int a, int b)
{
return p+a*b; // возможно переполнение
}

Хотя если "гнобить" только тип "long long" и только для старых добрых ILP32.

--
Успехов, Сергей Леонтьев. E-mail: ***@CryptoPro.ru
Valentin Nechayev
2014-02-01 12:58:02 UTC
Permalink
SEL> leom:tmp leo$ cc -c -Weverything -Werror chk.c
~~~~~~~~~~~
О, ключевое слово! -Wall -Wextra ему недостаточно.

NS>> long long bar3(int a, int b)
NS>> {
NS>> return a*b; // возможна потеря точности

SEL> А вот это не является потерей точности. Это возможность переполнения при
SEL> вычислении целочисленных выражений, но эта возможность есть всегда.

Угу. Это уже проблема определения умножения. В процессорах обычно при
умножении двух значений в N бит результат получается 2N бит, но в Си
такое не делается (на этой операции).

SEL> А если объявить плохим стилем приведение целого выражения меньшего ранга
SEL> к целочисленному типу большего ранга, то будешь погребён под ошибочными
SEL> предупреждениями второго рода.

Я бы удовлетворился для >99% случаев заданием checked контекста на нужных
операциях, как в C#.


--netch--
Serguei E. Leontiev
2014-02-01 13:31:38 UTC
Permalink
Привет Valentin,

От 1 февраля 2014 г., 16:58:02 в fido7.ru.unix.prog ты писал:
SEL>> А если объявить плохим стилем приведение целого выражения
SEL>> меньшего ранга к целочисленному типу большего ранга, то
SEL>> будешь погребён под ошибочными предупреждениями второго
SEL>> рода.
VN> Я бы удовлетворился для >99% случаев заданием checked
VN> контекста на нужных операциях, как в C#.

Hе тот случай, всё равно накроет.

--
Успехов, Сергей Леонтьев. E-mail: ***@CryptoPro.ru
Serguei E. Leontiev
2014-02-01 18:09:17 UTC
Permalink
P.S.

От 1 февраля 2014 г., 16:49:59 в fido7.ru.unix.prog ты писал:> По сути
оно же на типичных LP64 платформах не отличается от весьма и
Post by Serguei E. Leontiev
char *bar4(char *p, int a, int b)
{
return p+a*b; // возможно переполнение
}
Подумалось, это ж наверное прикольная засада, на типичных 64-бит
компьютерах при нормальном объёме памяти (в случае переполнения):

void *bar5(void *pv, unsigned a, unsigned b)
{
char *pc = pv;
return pc+a*b; // возможно переполнение
}

double *pd;

&pd[idx] != bar5(pd, sizeof(*pd), idx)

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

--
Успехов, Сергей Леонтьев. E-mail: ***@CryptoPro.ru
Nickita A Startcev
2014-02-01 21:29:10 UTC
Permalink
Привет, Serguei !


01 Feb 14 , 22:09 Serguei E. Leontiev писал к Serguei E. Leontiev:

SEL> От 1 февраля 2014 г., 16:49:59 в fido7.ru.unix.prog ты писал:> По сути
SEL> оно же на типичных LP64 платформах не отличается от весьма и
Post by Serguei E. Leontiev
char *bar4(char *p, int a, int b)
{
return p+a*b; // возможно переполнение
}
SEL> Подумалось, это ж наверное прикольная засада, на типичных 64-бит
SEL> компьютерах при нормальном объёме памяти (в случае переполнения):

на 16-битках тоже бывают нежданчики, когда размеры не те или вдруг какие-то
размеры перестают совпадать.

кстати, на некоторых 64-битных платформах инт 32 бита, а на некоторых 64. Hо на
всех есть костыль типа 'uintptr'


. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev
... Мужчина, разбрасывающий носки метит свою территорию?
Nickita A Startcev
2014-02-01 18:49:04 UTC
Permalink
Привет, Serguei !


01 Feb 14 , 16:49 Serguei E. Leontiev писал к Nickita A Startcev:

[..]

NS>> long long bar3(int a, int b)
NS>> {
NS>> return a*b; // возможна потеря точности

SEL> А вот это не является потерей точности.

вопрос мутный: надо ли автоматически расширять разрядность выражения по типу
результата, или можно и по минимальному/среднему/максимальному в правой+левой
или только в правой части.

то есть, надо ли писать

long long bar3(int a, int b)
{
return (long long)a * (long long)b;
}

или компилятор должен сам уширить ширину до ширины результата.

SEL> А если объявить плохим стилем приведение целого выражения меньшего
SEL> ранга к целочисленному типу большего ранга, то будешь погребён под
SEL> ошибочными предупреждениями второго рода.

SEL> По сути оно же на типичных LP64 платформах не отличается от весьма и
SEL> весьма распространённого:

у меня 16-битная платформа, там радости в обратную сторону, особенно при
портировании части кода с 32-битных платформ:

sz_bool = 1
sz_short = 2
sz_int = 2
sz_long = 4
sz_long_long = 8
sz_float = 4
sz_double = 4
sz_long_double = 4
sz_size_t = 2
sz_pointer = 2



. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev
... купается с круглыми утками
Peter Irich
2014-02-01 17:21:40 UTC
Permalink
Post by Nickita A Startcev
Привет, All !
А какие есть проверяльщики кода, которые аккуратно ругнутся на потерю точности
при присваиваниях или при неявном приведении 'простых' типов в выражениях?
gcc/g++ при самых жестких настройках проверяет только сравнение знакового с
беззнаковым.
Вроде бы "g++ -Wall" сообщает об этом, но, кажется,
не во всех случаях.
У меня с -Wall компилируются Qt-программы.
-Wextra никогда не пробовал.

Пётр.
Nickita A Startcev
2014-02-01 20:49:54 UTC
Permalink
Привет, Peter !
Post by Nickita A Startcev
А какие есть проверяльщики кода, которые аккуратно ругнутся на
потерю точности при присваиваниях или при неявном приведении
'простых' типов в выражениях? gcc/g++ при самых жестких настройках
проверяет только сравнение знакового с беззнаковым.
PI> Вроде бы "g++ -Wall" сообщает об этом, но, кажется,
PI> не во всех случаях.
PI> У меня с -Wall компилируются Qt-программы.
PI> -Wextra никогда не пробовал.

нет. "-Wall" не включает в себя

-Wconversion -Wdouble-promotion -Wfloat-equal -Wignored-qualifiers
-Wno-pointer-to-int-cast -Wreturn-type -Wsign-compare
-Wsign-conversion -Weverything

. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev
... в начищеных до блеска трусах
Loading...