Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Критерий - использование == для сравнения строк #13

Closed
AndrewGavril opened this issue Dec 29, 2023 · 3 comments · Fixed by #28
Closed

Comments

@AndrewGavril
Copy link

В некоторых случаях оператор == будет давать корректный результат (если в переменную записывается указатель на константную строку, а потом сравнивается с этой константной строкой), но в общем смысле это неизбежно приведет к ошибке

@jcdkiki
Copy link
Collaborator

jcdkiki commented Feb 10, 2024

В OCLint уже есть такой критерий, но он отлавливает далеко не все такие случаи. Отлавливает только сравнения с константными строковыми литералами, т.е.

"Hello" == "World"
"Hello" == str
str == "World"
// И аналогичные с '!='

Мое решение также отлавливает сравнение переменной с переменной:

str1 == str2
// И даже
char **arr;
arr[1] == arr[2]
// И аналогичные с '!='

В общем, оно отлавливает сравнение любых выражений, имеющих тип "char*" или подобный.

Код лежит в rules/StringCompareRule.cpp
Пример лежит в examples/ex-string-compare/main.c

Коммит: 84c7ef1

@jcdkiki
Copy link
Collaborator

jcdkiki commented Feb 11, 2024

UPD:
В OCLint такого критерия нет. Это он выдавал варнинги clang'а result of comparison against a string literal is unspecified (use an explicit string comparison function instead)

Для проверки типа я использую метод isAnyCharacterType(). Но он почему-то не распознает wchar_t. Разберусь с этим позже.

Скорее всего, потому что wchar_t определен где-то как typedef unsigned short wchar_t;, но я не уверен.

@jcdkiki
Copy link
Collaborator

jcdkiki commented Feb 21, 2024

На моем ноуте, в моей системе, с моим компиляторам широкие строковые литералы имеют тип int * . Это не символьный тип, и это плохо.

В последнем коммите написал решение, как по мне, немного грязное, зато рабочее. Единственные случаи, которые оно не отлавливает -- это сравнение двух широких строковых литералов. В глазах oclint'а это получается сравнение двух значений типа int *, то есть не имеет к строкам никакого отношения. Но, я уверен, никто в своих лабораторных и курсовых так (L"Hello" == L"World") не пишет, поэтому это не проблема.

@jcdkiki jcdkiki linked a pull request Jul 25, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants