473,386 Members | 1,715 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Operator Precence Issue/Question

Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
// Code
}

0x03==0x03 always equates to TRUE. Therefore my code equates to

if (P8 & TRUE) {
// code
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.

(I fully expect the answer to be "It depends on the compiler")

Thanks

Steven (who usually uses the strongly typed VHDL)

Jul 4 '06 #1
14 1824
mo****@yahoo.co.uk said:
Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}
Simplifying, without loss of generality: if(x & y == z)

Yes, it's a nasty one, that; dmr acknowledges that it was a mistake which
ought to have been fixed at an early stage. Too late now, of course.
>
There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
Yes. More simply:

if(x & (y == z))
// Code
}

0x03==0x03 always equates to TRUE.
Well, it is either true or false. If it were false, it would yield 0. Since
it is true, it yields 1. (All conditional expressions behave in this way.)
Therefore my code equates to

if (P8 & TRUE) {
// code
More precisely, and using my generalisation:

if(x & 1)
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.
The statement that succeeds the if() will be executed if the low bit of your
first value is set - i.e. if(x & 1) evaluates to 1.
(I fully expect the answer to be "It depends on the compiler")
For a mercy, it actually doesn't depend on the compiler on this occasion!
The operators == != < <= = always yield either 0 or 1 as their result,
and that is guaranteed by the Standard:
6.5.8 [...] Each of the operators < (less than), (greater than),
<= (less than or equal to), and >= (greater than or equal
to) shall yield 1 if the specified relation is true and 0 if
it is false.80) The result has type int.

6.5.9 [...] Each of the operators yields 1 if the
specified relation is true and 0 if it is false. The result
has type int.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 4 '06 #2
Richard,

Thank you for the full and detailed response.

And as luck would have it, it's also the answer I wanted (by which I
mean I can work around without anyone knowing :-) )

Steven

Richard Heathfield wrote:
mo****@yahoo.co.uk said:
Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

Simplifying, without loss of generality: if(x & y == z)

Yes, it's a nasty one, that; dmr acknowledges that it was a mistake which
ought to have been fixed at an early stage. Too late now, of course.

There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {

Yes. More simply:

if(x & (y == z))
// Code
}

0x03==0x03 always equates to TRUE.

Well, it is either true or false. If it were false, it would yield 0. Since
it is true, it yields 1. (All conditional expressions behave in this way.)
Therefore my code equates to

if (P8 & TRUE) {
// code

More precisely, and using my generalisation:

if(x & 1)
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.

The statement that succeeds the if() will be executed if the low bit of your
first value is set - i.e. if(x & 1) evaluates to 1.
(I fully expect the answer to be "It depends on the compiler")

For a mercy, it actually doesn't depend on the compiler on this occasion!
The operators == != < <= = always yield either 0 or 1 as their result,
and that is guaranteed by the Standard:
6.5.8 [...] Each of the operators < (less than), (greater than),
<= (less than or equal to), and >= (greater than or equal
to) shall yield 1 if the specified relation is true and 0 if
it is false.80) The result has type int.

6.5.9 [...] Each of the operators yields 1 if the
specified relation is true and 0 if it is false. The result
has type int.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 4 '06 #3
mo****@yahoo.co.uk wrote:
Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}
What is uint8? Standard C has no such type, but has uint8_t.
There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
// Code
}

0x03==0x03 always equates to TRUE. Therefore my code equates to

if (P8 & TRUE) {
// code
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.
In C, the relational operators always return 1 for true and 0 for
false, so in your case P8 would be bitwise and'ed with 0x01. So the IF
will evaluate to true if the Least Significant Bit of P8 is set, in
which case the statements inside the IF block will execute, otherwise
control will transfer to the statement after the IF block, (maybe an
ELSE?).
(I fully expect the answer to be "It depends on the compiler")
I don't know for sure, but I don't believe compilers will differ over
this. The Standard guarentees that relational expressions will yield
either 1 or 0, so conforming compilers, (compiling in a conforming
mode), should all behave the same.

Whether the IF evaluates true or not depends on the bit representation
of P8, (i.e. it's vaue), which only you know.

Jul 4 '06 #4
mo****@yahoo.co.uk wrote:
Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. [...]
Some compilers and some "lint" programs will issue
warnings for perfectly valid C that likely doesn't mean
what was intended. Check the documentation for your
compiler and/or lint to see whether you can make them
more sensitive to this sort of thing, so as to avoid such
errors in the future.

Even if you ultimately use Frobozz Magic C to compile
your programs, it might be worth while to run additional
compilations with gcc, say, just for the diagnostics.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 4 '06 #5

Eric Sosman wrote:
mo****@yahoo.co.uk wrote:
Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. [...]

Some compilers and some "lint" programs will issue
warnings for perfectly valid C that likely doesn't mean
what was intended.
.... snip ...

By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).

Jul 4 '06 #6
santosh wrote:
Eric Sosman wrote:
>>mo****@yahoo.co.uk wrote:
>>>Experts,

I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. [...]

Some compilers and some "lint" programs will issue
warnings for perfectly valid C that likely doesn't mean
what was intended.

... snip ...

By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).
Yes, and I'm also saying that some compilers will issue
warnings for "perfectly valid but quite possibly erroneous C."
Do you doubt this?

By encouraging his compilers and other tools to emit such
warnings and by paying attention to what they tell him, he
may be able to increase the likelihood that such semantic
errors will be caught before they become embarrassing.

--
Eric Sosman
es*****@acm-dot-org.invalid

Jul 4 '06 #7
Eric Sosman wrote:
santosh wrote:
Eric Sosman wrote:
>mo****@yahoo.co.uk wrote:
.... snip ...
>>There is a mistake in this code in that equality is higher precedence
than bitwise and. [...]

Some compilers and some "lint" programs will issue
warnings for perfectly valid C that likely doesn't mean
what was intended.
... snip ...

By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).

Yes, and I'm also saying that some compilers will issue
warnings for "perfectly valid but quite possibly erroneous C."
Do you doubt this?
No. I failed to grasp what you meant the first time around. I
understand now, though, in my limited experience, I've yet come across
a compiler that smart, but then again, I've only used about five
different compilers. I've found splint to be more suited for this.
By encouraging his compilers and other tools to emit such
warnings and by paying attention to what they tell him, he
may be able to increase the likelihood that such semantic
errors will be caught before they become embarrassing.
Absolutely, though these tools should not be a replacement for a C
textbook.

Jul 4 '06 #8
santosh wrote:
Eric Sosman wrote:
>>santosh wrote:
>>>By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).

Yes, and I'm also saying that some compilers will issue
warnings for "perfectly valid but quite possibly erroneous C."
Do you doubt this?

No. I failed to grasp what you meant the first time around. I
understand now, though, in my limited experience, I've yet come across
a compiler that smart, but then again, I've only used about five
different compilers. I've found splint to be more suited for this.
You should make a point of becoming acquainted with gcc.
Many things good and bad can be and have been said of it, but
IMHO it has the best diagnostics of any compiler I've encountered.
(If properly propitiated, of course: "-Wall -W -ansi -pedantic"
is a good starting point, possibly with "-std=something_else"
instead of "-ansi".)

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 4 '06 #9
On 2006-07-04, Eric Sosman <es*****@acm-dot-org.invalidwrote:
santosh wrote:
>Eric Sosman wrote:
>>>santosh wrote:

By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).

Yes, and I'm also saying that some compilers will issue
warnings for "perfectly valid but quite possibly erroneous C."
Do you doubt this?

No. I failed to grasp what you meant the first time around. I
understand now, though, in my limited experience, I've yet come across
a compiler that smart, but then again, I've only used about five
different compilers. I've found splint to be more suited for this.

You should make a point of becoming acquainted with gcc.
Many things good and bad can be and have been said of it, but
IMHO it has the best diagnostics of any compiler I've encountered.
(If properly propitiated, of course: "-Wall -W -ansi -pedantic"
is a good starting point, possibly with "-std=something_else"
instead of "-ansi".)
Agreed.

For example, I once used the construct (ch[1] == ch[2] == '-') to check
for a comment in an XML document (it was already known that ch[0] was '<').
I likely would have had a very difficult time noticing that bug on my own,
because the construct "a = b = c" /is/ correct. (This is an interesting
variant on the =/== typo that isn't mentioned in any books I've read).

Anyway, gcc gave me the following message (paraphrased):
warning: expressions of the form (a <= b <= c) do not have their
mathematical meaning.

and saved me several potential hours of debugging.

--
Andrew Poelstra <http://www.wpsoftware.net/blog>
To email me, use "apoelstra" at the above address.
"You people hate mathematics." -- James Harris
Jul 4 '06 #10
Eric Sosman wrote:
santosh wrote:
Eric Sosman wrote:
>santosh wrote:

By saying there is a mistake in his code, the OP is talking about a
semantic error on his part, not that the code was rejected by the
compiler, (since as you say, it's perfectly valid C).

Yes, and I'm also saying that some compilers will issue
warnings for "perfectly valid but quite possibly erroneous C."
Do you doubt this?
No. I failed to grasp what you meant the first time around. I
understand now, though, in my limited experience, I've yet come across
a compiler that smart, but then again, I've only used about five
different compilers. I've found splint to be more suited for this.

You should make a point of becoming acquainted with gcc.
Though gcc is what I use 90 % of the time, I haven't really explored
it's options in depth. I really should though.
Many things good and bad can be and have been said of it, but
IMHO it has the best diagnostics of any compiler I've encountered.
I agree and I would probably place Borland's compiler second in this
regard.
(If properly propitiated, of course: "-Wall -W -ansi -pedantic"
is a good starting point, possibly with "-std=something_else"
instead of "-ansi".)
Exactly what I use for all my programs, (with std=c99 for the
ocassional one that needs it). Recently I've started trying the
exhaustive set of diagnostics switches Richard Heathfield posted. It's
made me reconsider quite a number of constructs, (plus the excellent
knowledge of this group of course).

Jul 4 '06 #11
Richard Heathfield <in*****@invalid.invalidwrites:
mo****@yahoo.co.uk said:
[...]
>0x03==0x03 always equates to TRUE.

Well, it is either true or false. If it were false, it would yield 0. Since
it is true, it yields 1. (All conditional expressions behave in this way.)
More precisely, all conditional *operators* behave in this way. The
language guarantees that the relational, equality, "&&", "||", and "!"
operators yield 1 for true and 0 for false. Other things that you
might think of as conditional expressions (e.g., a call to isdigit())
don't have this guarantee.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 4 '06 #12

mo****@yahoo.co.uk wrote:
I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
// Code
}

0x03==0x03 always equates to TRUE. Therefore my code equates to

if (P8 & TRUE) {
// code
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.

(I fully expect the answer to be "It depends on the compiler")
Is following the lines of code what you want,

int l2bs(int i)
{
const unsigned char MASK = 0x03; /*0000 0011*/
if ((i & MASK) == MASK)
i = 1; /*last 2 bits are set*/
else
i = 0; /*last 2 bits are not set*/
return i;
}

lovecreatesbeauty

Jul 5 '06 #13
All,

Thanks for the advice and observations.

I will certainly look into the pendantic warnings options within GCC to
try an catch this type bug in future.

Steven

lovecreatesbeauty wrote:
mo****@yahoo.co.uk wrote:
I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
// Code
}

0x03==0x03 always equates to TRUE. Therefore my code equates to

if (P8 & TRUE) {
// code
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.

(I fully expect the answer to be "It depends on the compiler")

Is following the lines of code what you want,

int l2bs(int i)
{
const unsigned char MASK = 0x03; /*0000 0011*/
if ((i & MASK) == MASK)
i = 1; /*last 2 bits are set*/
else
i = 0; /*last 2 bits are not set*/
return i;
}

lovecreatesbeauty
Jul 5 '06 #14
On 2006-07-05, lovecreatesbeauty <lo***************@gmail.comwrote:
>
mo****@yahoo.co.uk wrote:
>I have written (and delivered :-( ) some code. I wanted to check that
the bottom two bits of P8 were set, and so I produced:

if (P8 & (uint8)0x03 == (uint8)0x03) {
// Code
}

There is a mistake in this code in that equality is higher precedence
than bitwise and. Therefore my code behaves as:

if (P8 & ((uint8)0x03 == (uint8)0x03)) {
// Code
}

0x03==0x03 always equates to TRUE. Therefore my code equates to

if (P8 & TRUE) {
// code
}

So my question is, how is TRUE likely to be represented, and when will
the code be run.

(I fully expect the answer to be "It depends on the compiler")

Is following the lines of code what you want,

int l2bs(int i)
{
const unsigned char MASK = 0x03; /*0000 0011*/
if ((i & MASK) == MASK)
i = 1; /*last 2 bits are set*/
else
i = 0; /*last 2 bits are not set*/
return i;
}
That function could be replaced with

int l2bs (int i)
{
return (i & 0x03) == 0x03
}

Or a macro:
#define #L2BS(n) ((n) & 3 == 3)

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>
To email me, use "apoelstra" at the above address.
"You people hate mathematics." -- James Harris
Jul 5 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Piotr Wyderski | last post by:
Hello, is it possible to reuse a friend operator which is defined inside a class? I'd like to obtain the following behaviour: class integer { integer operator +(signed long int v) const...
5
by: James Angi | last post by:
I have a question on operator overloading that I can't find an answer to in several guides (even google has failed me). I'm currently making my way through several C++ guides, trying to become...
4
by: Mark Stijnman | last post by:
A while ago I posted a question about how to get operator behave differently for reading and writing. I basically wanted to make a vector that can be queried about whether it is modified recently...
4
by: mux | last post by:
Hi I found out that the following piece of code throws an error. 1 #include "stdio.h" 2 3 int main() 4 { 5 int a,b; 6 a= 10;
17
by: ma740988 | last post by:
Consider: # include <iostream> # include <algorithm> # include <vector> # include <string> using namespace std; class msg { std::string someStr;
0
by: erik.erikson | last post by:
I am getting a compiler error that I can't well explain or even understand the origin of (though I boiled it down close...). Below is a bare-bones example. What I am doing is defining the...
8
by: pauldepstein | last post by:
The following code was written by a colleague -- to preserve confidentiality, the name of the class is changed: HisClass operator+ (const HisClass & h1, const HisClass & h2) { // some code here}...
14
by: Hunk | last post by:
Hi I ws wondering if there is a way to implement operator+ in case of virtual classes. Here's the problem. I have to have a base string class from which two classes (normal char string and a...
30
by: Angel Tsankov | last post by:
Hello! Does the C++ standard define what happens when the size argument of void* operator new(size_t size) cannot represent the total number of bytes to be allocated? For example: struct S {...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.