parentheses question

Z

Zach

I don't understand this warning. From what I've read in K&R this is
valid C:

ll14.c: In function 'process_tokens':
ll14.c:156: warning: suggest parentheses around '&&' within '||'

Relevant code:

if ((((c[0] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[1]) || islower(c[1])))
&& (c[2] == '-')
&& (c[3] == '>'))
&& ((c[4] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[5]) || islower(c[5]))
|| ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
|| ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
|| ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
|| ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))

Line 156 is:
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))

Also I don't understand why it complains only about that line and not
the others. Weird.

Zach
 
Z

Zach

Zach said:
I don't understand this warning. From what I've read in K&R this is
valid C:
ll14.c: In function 'process_tokens':
ll14.c:156: warning: suggest parentheses around '&&' within '||'
Relevant code:
  if ((((c[0] == 'F' || 'R' || 'O' || 'K')
        && (isdigit(c[1]) || islower(c[1])))
       && (c[2] == '-')
       && (c[3] == '>'))
      && ((c[4] == 'F' || 'R' || 'O' || 'K')
          && (isdigit(c[5]) || islower(c[5]))
      || ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
      || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
      || ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
      || ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
          || ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))
Line 156 is:
      || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
Also I don't understand why it complains only about that line and not
the others. Weird.

Regardless of the value of (X),
(X == 'F' || 'R' || 'O' || 'K') is always equal to (1).

That has nothing to do with the warning. Thanks but I already knew
that. The code works fine, the problem is why that warning is
generated. And why it is generated for only that 1 line.

Zach
 
Z

Zach

Zach said:
Zach wrote:
I don't understand this warning. From what I've read in K&R this is
valid C:
ll14.c: In function 'process_tokens':
ll14.c:156: warning: suggest parentheses around '&&' within '||'
Relevant code:
  if ((((c[0] == 'F' || 'R' || 'O' || 'K')
        && (isdigit(c[1]) || islower(c[1])))
       && (c[2] == '-')
       && (c[3] == '>'))
      && ((c[4] == 'F' || 'R' || 'O' || 'K')
          && (isdigit(c[5]) || islower(c[5]))
      || ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
      || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
      || ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
      || ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
          || ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))
Line 156 is:
      || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
Also I don't understand why it complains only about that line and not
the others. Weird.
Regardless of the value of (X),
(X == 'F' || 'R' || 'O' || 'K') is always equal to (1).
That has nothing to do with the warning.

Don't forget that your premise
is that you don't know what is causing the warning.
Thanks but I already knew
that. The code works fine, the problem is why that warning is
generated. And why it is generated for only that 1 line.

When I removed those expressions and their associated (&&) operators,
I got a program which runs and compiles without warnings.

/* BEGIN new.c */

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char c[] = "123456789";

    if ((((isdigit(c[1]) || islower(c[1])))
       && (c[2] == '-')
       && (c[3] == '>'))
      && ((isdigit(c[5]) || islower(c[5]))
      || ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
      || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
      || ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
      || ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
          || ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))
    {
        puts(c + 1);
    } else {
        puts(c);
    }
    return 0;

}

/* END new.c */

Hi Pete,

Yes, but I needed the other code to test for whether I wanted that
token. For example a log file with line:

10:10:10 F2->R4 hello

I need this code to to test the "F2->R4" token:

((c[0] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[1]) || islower(c[1])))

I only want to further process lines for which this is true.

Zach
 
W

Willem

Zach wrote:
) 10:10:10 F2->R4 hello
)
) I need this code to to test the "F2->R4" token:
)
) ((c[0] == 'F' || 'R' || 'O' || 'K')
) && (isdigit(c[1]) || islower(c[1])))
)
) I only want to further process lines for which this is true.

That test will also be true for this line:
10:10:10 X2->R4 hello


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Z

Zach

That test will also be true for this line:
10:10:10 X2->R4 hello

Why? X is not specified as a conditional in the code. It should only
match for 'F','R','O','K'.

Zach
 
Z

Zach

That test will also be true for this line:
10:10:10 X2->R4 hello

I just did a test and you're correct. How can I have it be true ONLY
IF c[0] matches either 'F','R','O','K'?

Zach
 
K

Kenny McCormack

Why? X is not specified as a conditional in the code. It should only
match for 'F','R','O','K'.

Zach

People are dancing around telling you directly what's wrong, presumably
because they don't want to risk hurting your feelings.

But the point is that when you write:

(c[0] == 'F' || 'R' || 'O' || 'K')

You are checking to see if any of the following conditions are true:

c[0] == 'F'
'R'
'O'
'K'

Now, the first one in my list might be true or might not be (depending
on the value of c[0]). But the rest of them are all true regardless of
anything, since they are constants.

You probably meant:

(c[0] == 'F' ||
c[0] == 'R' ||
c[0] == 'O' ||
c[0] == 'K')
 
B

BartC

Zach said:
That test will also be true for this line:
10:10:10 X2->R4 hello

I just did a test and you're correct. How can I have it be true ONLY
IF c[0] matches either 'F','R','O','K'?

(c[0] == 'F' ||c[0]== 'R' ||c[0]== 'O' ||c[0]== 'K')
 
Z

Zach

People are dancing around telling you directly what's wrong, presumably
because they don't want to risk hurting your feelings.

Hi Kenny,

If I was worried about hurting a frail ego and was psychologically so
insecure I wouldn't have even bothered posting. :)
Now, the first one in my list might be true or might not be (depending
on the value of c[0]).  But the rest of them are all true regardless of
anything, since they are constants.

You probably meant:

(c[0] == 'F' ||
 c[0] == 'R' ||
 c[0] == 'O' ||
 c[0] == 'K')

Yes, my mistake was thinking that the way I wrote it was equivalent to
this. Lesson learned. BTW I still get the warning:

ll15.c: In function 'process_tokens':
ll15.c:156: warning: suggest parentheses around '&&' within '||'

Line 156:
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))

Any idea how to clear this up and why it only is triggered for that
specific line and not similar ones?

Zach
 
W

Willem

Zach wrote:
) ll15.c: In function 'process_tokens':
) ll15.c:156: warning: suggest parentheses around '&&' within '||'
)
) Line 156:
) || ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
)
) Any idea how to clear this up and why it only is triggered for that
) specific line and not similar ones?

Have you considered the possibility that the compiler is a bit imprecise
in locating the exact line on which the error is ? Especially with
multi-line expression like this it's very difficult for a compiler to
pinpoint exactly where the error lies, especially if it's an error
like this one.

I'd guess it's a few lines up.



SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Z

Zach

Have you considered the possibility that the compiler is a bit imprecise
in locating the exact line on which the error is ?  Especially with
multi-line expression like this it's very difficult for a compiler to
pinpoint exactly where the error lies, especially if it's an error
like this one.

I'd guess it's a few lines up.

Thanks for the suggestion.

Zach
 
J

Jens Thoms Toerring

Zach said:
I don't understand this warning. From what I've read in K&R this is
valid C:
ll14.c: In function 'process_tokens':
ll14.c:156: warning: suggest parentheses around '&&' within '||'
Relevant code:
if ((((c[0] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[1]) || islower(c[1])))
&& (c[2] == '-')
&& (c[3] == '>'))
&& ((c[4] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[5]) || islower(c[5]))
|| ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
|| ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
|| ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
|| ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))
Line 156 is:
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
Also I don't understand why it complains only about that line and not
the others. Weird.

Because you've got here (when indentated correctly)

((c[4] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[5]) || islower(c[5]))
|| ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
|| ...

So it's

A && B || C || ...

just as the compiler tells you.

Others have already pointed out that

( c[4] == 'F' || 'R' || 'O' || 'K' )

doesn't make sense since it's always true. I guess you meant
to ask if c[4] is either F, R, O or K, didn't you?

And why make it rather difficult to understand if there are
function that can do the job for parts of what you want? If
I'm not mistaken

if ( strchr( "FROK", c[ 0 ] )
&& ( isdigit( c[ 1 ] ) || islower( c[ 1 ] ) )
&& ! strncmp( c + 2, "->", 2 )
&& ( ( strchr( "FROK", c[ 4 ] )
&& ( isdigit( c[ 5 ] ) || islower( c[ 5 ] ) ) )
|| ! strncpm( c + 4, "ALL", 3 )
|| ! strncmp( c + 4, "FED", 3 )
|| ! strncmp( c + 4, "ROM", 3 )
|| ! strncmp( c + 4, "ORI", 3 )
|| ! strncmp( c + 4, "KLI", 3 ) ) )

would do the same (if my assumption about what you really in-
tended in that broken line(s) is correct) and I would consider
it to be a bit easier to grasp. I might even go a step further
and define a few helper functions like

bool
is_FROK_token( const char *s )
{
return strchr( "FROK", s[ 0 ] )
&& ( isdigit( s[ 1 ] ) || islower( s[ 1 ] ) );
}

bool
is_pointing( const char * s )
{
return ! strncmp( s, "->", 2 );
}

bool
is_word( const char * s )
{
return ! strncpm( s, "ALL", 3 )
|| ! strncmp( s, "FED", 3 )
|| ! strncmp( s, "ROM", 3 )
|| ! strncmp( s, "ORI", 3 )
|| ! strncmp( s, "KLI", 3 );
}

Then you could write

if ( is_FROK_TOKEN( c )
&& is_pointing( c + 2 )
&& ( is_FROK_token( c + 4 )
|| is_word( c + 4 ) ) )

to make your intensions even clearer.

BTW, instead of writing a parser by hand you might find having
a look at tools like flex and bison beneficial - they take a bit
of time getting used to but then can make analysing/parsing struc-
tured data a lot easier and more fun.

Regards, Jens
 
Z

Zach

BTW, instead of writing a parser by hand you might find having
a look at tools like flex and bison beneficial - they take a bit
of time getting used to but then can make analysing/parsing struc-
tured data a lot easier and more fun.

Hallo Jens,

Interesting. Thanks for the ideas. I will look into it.

Zach
 
K

Keith Thompson

Zach said:
I don't understand this warning. From what I've read in K&R this is
valid C:

ll14.c: In function 'process_tokens':
ll14.c:156: warning: suggest parentheses around '&&' within '||'

Relevant code:

if ((((c[0] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[1]) || islower(c[1])))
&& (c[2] == '-')
&& (c[3] == '>'))
&& ((c[4] == 'F' || 'R' || 'O' || 'K')
&& (isdigit(c[5]) || islower(c[5]))
|| ((c[4] == 'A') && (c[5] == 'L') && (c[6] == 'L'))
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))
|| ((c[4] == 'R') && (c[5] == 'O') && (c[6] == 'M'))
|| ((c[4] == 'O') && (c[5] == 'R') && (c[6] == 'I'))
|| ((c[4] == 'K') && (c[5] == 'L') && (c[6] == 'I'))))

Line 156 is:
|| ((c[4] == 'F') && (c[5] == 'E') && (c[6] == 'D'))

Also I don't understand why it complains only about that line and not
the others. Weird.

Here's a code fragment that produces the same warning:

int a = 1, b = 1, c = 1;
int d = a || b && c;

The expression
a || b && c
is equivalent to
a || (b && c)
because "&&" has higher precedence than "||". The compiler is
suggestinging that depending on this rule tends to make code unclear.
Reading the expression, it's hard to tell whether the author really
meant that, or
(a || b) && c
Adding parentheses around "b && c), while not changing the meaning
of the expression, would make it clearer.

Yes, the original code is valid; that's why you got a warning, not an
error message.
 
Z

Zach

The expression
    a || b && c
is equivalent to
    a || (b && c)
because "&&" has higher precedence than "||".  The compiler is
suggestinging that depending on this rule tends to make code unclear.
Reading the expression, it's hard to tell whether the author really
meant that, or
    (a || b) && c
Adding parentheses around "b && c), while not changing the meaning
of the expression, would make it clearer.

Yes, the original code is valid; that's why you got a warning, not an
error message.

I see. Thanks for explaining Keith.

Zach
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top