0

I have a string char str[] (lets assume its not empty)

When I perform the iteration:

for(int i = 0; i<strlen(str);i++)
    {
        if((!isalpha(str[i]))&&((!isdigit[i])))
        {
            printf("something");

        }
    }

I get the following marking:

Clang-Tidy: Use of a signed integer operand with a binary bitwise operator

Why is it occuring? and how can I fix it?

Arammm
  • 11
  • What is the operator the compiler refers to? There is no binary bitwise operator in the presented code. – Vlad from Moscow Apr 08 '20 at 10:06
  • 1
    I don't see and bitwise operator in your code. – Jabberwocky Apr 08 '20 at 10:07
  • 5
    `isdigit[i]` --> `isdigit(str[i])`, but with a cast `isdigit((unsigned char)str[i])`, see why the cast: https://stackoverflow.com/questions/17975913/does-ctype-h-still-require-unsigned-char – David Ranieri Apr 08 '20 at 10:08
  • 4
    `isdigit[i]` is just plain wrong! You need an argument list for `isdigit` and you *probably* want to pass `str[i]` rather than `i`. – Adrian Mole Apr 08 '20 at 10:10
  • @AdrianMole So why does it give me a clang tidy marking? this hits my OCD real hard. – Arammm Apr 08 '20 at 10:19
  • @VladfromMoscow: The character classification macros are often implemented with macros which contain bitwise operators. If you voted down based on the lack of visible bitwise operators in the question, then you voted in error. – Eric Postpischil Apr 08 '20 at 10:19
  • There are *at least* three syntax errors in your `if` statement, so I guess Clang Tidy gets a bit confused ... I certainly did! – Adrian Mole Apr 08 '20 at 10:21
  • @AdrianMole: There is only one error in the `if` statement that might be described as a syntax error. That is the use of brackets instead of parentheses with `isdigit`. But, from the compiler’s perspective, that is syntactically okay; it is a semantic error, not a syntax error. – Eric Postpischil Apr 08 '20 at 10:32
  • Show a [mre]. There is some question about the actual code producing this message. Also state precisely which C implementation you are using—preferably the full name and version of the C compiler and standard C library, but the name and version of the compiler at least. – Eric Postpischil Apr 08 '20 at 10:35
  • @EricPostpischil A good point - I was actually seeing other errors due to missing header files. See my answer, below - which may not have a very long lifetime! – Adrian Mole Apr 08 '20 at 10:36
  • @EricPostpischil good point thanks – Jabberwocky Apr 08 '20 at 10:52
  • @EricPostpischil Funnily, if I define `ISDIGIT(X)` as a macro, then modifying the OP's code **only** to change `isdigit` to uppercase (to invoke the macro) fails because it has no parameter list ... and, as such, is not recognized as the same macro. – Adrian Mole Apr 08 '20 at 11:02
  • "how can I fix it?" --> `if((!isalpha(str[i]))&&((!isdigit[i])))` --> `if(!isalnum((unsigned char) str[i]))` – chux - Reinstate Monica Apr 08 '20 at 11:16

1 Answers1

0

When I compile your code with clang-cl, it reports the following error on the line with the if statement:

error : subscript of pointer to function type 'int (int)'

As to why you see the "binary bitwise operator" error message - the comment provided by Eric Postpischil may well explain that (isdigit is not implemented as a macro on the system I am using, BTW).

This and other errors can be resolved by simply 'moving' one opening bracket. The code below shows your line (with spaces added for alignment) with a corrected version (I've also made the assumption that you actually want to test str[i] for being a digit, rather than i itself):

int main()
{
    char str[] = "a-bc-de-fg=12=345";
    for (int i = 0; i < strlen(str); i++) {
 //     if ( ( !isalpha(str[i]) ) && ((!isdigit  [i]  ) ) ) { // Original code
        if ( ( !isalpha(str[i]) ) && ( !isdigit(str[i]) ) ) { // Corrected code
            printf("something");
        }
    }
    return 0;
}

I hope this helps you clear up your problems!

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 2
    They should cast the arguments to `unsigned char` before passing them to the character classification functions. – Eric Postpischil Apr 08 '20 at 10:37
  • What C implementation are you using, and how do you know it is not using macros for these functions? – Eric Postpischil Apr 08 '20 at 10:37
  • I tested it using `clang-cl` and, when I right-click on `isdigit` and go to its definition, I see this: `_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isdigit(_In_ int _C);` – Adrian Mole Apr 08 '20 at 10:38
  • @EricPostpischil Not necessarily, these functions are designed to accept `EOF` as valid input. – Lundin Apr 08 '20 at 10:43
  • @EricPostpischil While I absolutely agree that casting to `unsigned char` (i.e. to prevent sign-extension when the argument is promoted to `int`) is *definitely* best practice, I didn't consider it relevant to this problem. – Adrian Mole Apr 08 '20 at 10:46
  • @Lundin: That is not relevant. If OP had an `int` that contained either an `unsigned char` value or `EOF`, I would not have made that comment. But they do not, they have elements from an array of `char`. If any of those are negative, the behavior is not defined by the C standard. Casting to `unsigned char` is a fix for that. If they had an `int` that might contain either a `char` value or `EOF`, it would not be a fix, but they do not. – Eric Postpischil Apr 08 '20 at 10:48