1

I have defined a function called checkrow, which reads a given element of a char array (fed to it by a pointer to char) and determines if it is equal to certain characters. When I compile my overall program, the compiler tells me that line 67, which is (if(*pInput == (' ' || '\t' || '\n'))) will never execute. Why? The logic makes sense to me. Below is the code.

#include <stdio.h>
#include <stdlib.h>

int checkRow(char *pArray);

int main (void){

    char c = 0;
    int high = 0;
    int low = 9;
    int checksum = 0;
    char input[3000];
    char *pInput = input;
    FILE *pFile = NULL;

    pFile = fopen("foo.txt", "r");
    if (pFile == NULL){
        printf("failed to open file\n");
        return (-1);
    }

    while((c = fgetc(pFile)) != EOF){
        *pInput = c;
        ++pInput;
    }

    fclose(pFile);
    pFile = NULL;
    pInput = input; //point pInput back to the address of the first element of input
    //printf("the checksum is %d\n", checksum(pInput));
    while(*pInput){

        if(checkRow(pInput) == 0){
            checksum += (high - low);
            ++pInput;
            continue;
        }
        else{
            if((*pInput - '0') > high && (*pInput - '0') < low){
            high = *pInput - '0';
            low = *pInput - '0';
            ++pInput;
            continue;
            }
            else if (*pInput - '0' > high){
            high = *pInput - '0';
            ++pInput;
            continue;
            }
            else if(*pInput - '0' < low){
            low = *pInput - '0';
            ++pInput;
            }
        }

    }

    printf("this is the checksum %d\n", checksum);
    getchar();
    return 0;
}

int checkRow(char *pInput){

    int in = 0;

    if(*pInput == (' ' || '\t' || '\n'))
        in = 0;
    else
        in = 1;
    return in;
}
MFisherKDX
  • 2,840
  • 3
  • 14
  • 25
  • 4
    `*pInput == (' ' || '\t' || '\n')` doesn't do at all what you think. You should look up what these operators do. – lurker Mar 13 '19 at 17:02
  • 1
    `||` is going between logical expressions, not between constants you want to compare to. – Eugene Sh. Mar 13 '19 at 17:02
  • 1
    @EugeneSh True, but how come the line never gets executed? Compiler knows that pointer can never be (probably) 1? That would keep the **next** line from execution... – Yunnosch Mar 13 '19 at 17:04
  • 1
    Right way to do is `if ( (*pInput == ' ') || (*pInput == '\t') || (*pInput == '\') ) { .. }` – Sunil Bojanapally Mar 13 '19 at 17:06
  • 1
    @Yunnosch I think the OP have somehow distorted the original warning. – Eugene Sh. Mar 13 '19 at 17:06
  • @EugeneSh. Possible. – Yunnosch Mar 13 '19 at 17:07
  • What compiler are you using and how are you compiling? I'm not getting a warning as written. (Although others are correct regarding the *intent* of the statement is written incorrectly). – MFisherKDX Mar 13 '19 at 17:08
  • Seems like the function `isspace()` in `` would be useful for you – Govind Parmar Mar 13 '19 at 17:17
  • OT: for ease of readability and understanding: 1) please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: `for` `if` `else` `while` `do...while` `switch` `case` `default` via a single blank line. 3) separate functions by 2 or 3 blank lines (be consistent) – user3629249 Mar 13 '19 at 17:21
  • 1
    regarding: `while((c = fgetc(pFile)) != EOF){` the function: `fgetc()` returns an `int` and `EOF` is an `int`. so the variable `c` should be declared as an `int`, not as a `char`. When compiling, always enable the warnings, then fix those warnings. ( for `gcc`, at a minimum use: `-Wall -Wextra -Wconversion -pedantic -std=gnu11` ) Note: other compilers use different options to produce the same thing – user3629249 Mar 13 '19 at 17:24
  • OT: regarding: `printf("failed to open file\n");` error messages should be output to `stderr`, not `stdout` and when the error is from a C library function, then should also output (to `stderr`) the text reason the system thinks the error occurred. The function: `perror()` correctly handles both the above operations – user3629249 Mar 13 '19 at 17:34

2 Answers2

4

It's not saying that the statement will not be executed, just specific expressions within it. The warning message looks like this:

testcompare.c:67:35: warning: code will never be executed [-Wunreachable-code]
    if(*pInput == (' ' || '\t' || '\n'))
                                  ^~~~
testcompare.c:67:27: warning: code will never be executed [-Wunreachable-code]
    if(*pInput == (' ' || '\t' || '\n'))
                          ^~~~

Notice the arrows pointing to '\n' and '\t', those are what it's saying will never be executed.

The || operator is a short-circuiting operator, it only executes the right operand if the left operand is falsey.

In this case, since the ' ' is a constant, and it's known to be truthy (any char other than '\0' is truthy), the other two operands do not need to be executed to determine the result.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

You would need to rewrite the expression:

if(*pInput == (' ' || '\t' || '\n'))

as

if(*pInput ==' ' || *pInput =='\t' || *pInput =='\n'))

or

if ( strchr(" \t\n" , *pInput) != NULL)
stacker
  • 68,052
  • 28
  • 140
  • 210