"Condition is Always False" Question

B

Brian

I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.

<snip>
td.expMon = trk2[9] * 10 + trk2[10];

// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {
err = TKT_INVALID_MONTH;
}
</snip>

<snip>
td.expDay = trk2[11] * 10 + trk2[12];

// Borland says this is always false, though the condition is
fine.
if ((td.expDay < 0) || (td.expDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>

<snip>
td.eftvDay = trk2[28] * 10 + trk2[29];
// Borland says this is always false, though the condition is
fine.
if ((td.eftvDay < 0) || (td.eftvDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>
 
V

Victor Bazarov

Brian said:
I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.

See below.
<snip>
td.expMon = trk2[9] * 10 + trk2[10];

// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {

What's the type of 'expMon'? If it's unsigned, it cannot be less
that 0, so the first expression is always false.
err = TKT_INVALID_MONTH;
}
</snip>

<snip>
td.expDay = trk2[11] * 10 + trk2[12];

// Borland says this is always false, though the condition is
fine.
if ((td.expDay < 0) || (td.expDay > 31)) {

Same here. How is 'expDay' declared? If it's unsigned, it cannot
be less than 0, so the first condition will always be false.
err = TKT_INVALID_DAY;
}
</snip>

<snip>
td.eftvDay = trk2[28] * 10 + trk2[29];
// Borland says this is always false, though the condition is
fine.
if ((td.eftvDay < 0) || (td.eftvDay > 31)) {

Same here.
err = TKT_INVALID_DAY;
}
</snip>

HTH

V
 
A

Andre Kostur

I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.

<snip>
td.expMon = trk2[9] * 10 + trk2[10];

// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {
err = TKT_INVALID_MONTH;
}
</snip>

<snip>
td.expDay = trk2[11] * 10 + trk2[12];

// Borland says this is always false, though the condition is
fine.
if ((td.expDay < 0) || (td.expDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>

<snip>
td.eftvDay = trk2[28] * 10 + trk2[29];
// Borland says this is always false, though the condition is
fine.
if ((td.eftvDay < 0) || (td.eftvDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>

We're not mind-readers.... you haven't told us what the types of expMon,
expDay, or eftwDay are. But my first guess would be that they are all
of some sort of unsigned type, thus all of your "< 0" comparisions will
always be false.
 
B

Brian

@q2g2000cwa.googlegroups.com:




I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.
<snip>
td.expMon = trk2[9] * 10 + trk2[10];
// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {
err = TKT_INVALID_MONTH;
}
</snip>
<snip>
td.expDay = trk2[11] * 10 + trk2[12];
// Borland says this is always false, though the condition is
fine.
if ((td.expDay < 0) || (td.expDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>
<snip>
td.eftvDay = trk2[28] * 10 + trk2[29];
// Borland says this is always false, though the condition is
fine.
if ((td.eftvDay < 0) || (td.eftvDay > 31)) {
err = TKT_INVALID_DAY;
}
</snip>

We're not mind-readers.... you haven't told us what the types of expMon,
expDay, or eftwDay are. But my first guess would be that they are all
of some sort of unsigned type, thus all of your "< 0" comparisions will
always be false.- Hide quoted text -

- Show quoted text -

Ok, yep that is what it was. They are all ushort. Makes total sense
now. I'll clarify better next time I ask a question.
 
P

peter koch

@q2g2000cwa.googlegroups.com:




I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.
<snip>
td.expMon = trk2[9] * 10 + trk2[10];
// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {
err = TKT_INVALID_MONTH;
}
[snips]


We're not mind-readers.... you haven't told us what the types of expMon,
expDay, or eftwDay are. But my first guess would be that they are all
of some sort of unsigned type, thus all of your "< 0" comparisions will
always be false.
I might have a blind spot here, but this would still leave the other
part of the condition, e.g. (td.expMon > 12) above.
Ahhh... perhaps the compiler complains about part of a boolean
expression? That would make sense (sort of).

/Peter
 
B

Brian

@q2g2000cwa.googlegroups.com:
I am using Borland C++ Builder 5 for my application. When I build my
application, it states that I have several if-statements that will
always be false. The statements appear correct, so could someone
please enlighten me as to how C++ Builder may think that the
conditions will always be false. See below. Thanks.
<snip>
td.expMon = trk2[9] * 10 + trk2[10];
// Borland says this is always false, though the condition is
fine.
if ((td.expMon < 0) || (td.expMon > 12)) {
err = TKT_INVALID_MONTH;
}
[snips]



We're not mind-readers.... you haven't told us what the types of expMon,
expDay, or eftwDay are. But my first guess would be that they are all
of some sort of unsigned type, thus all of your "< 0" comparisions will
always be false.

I might have a blind spot here, but this would still leave the other
part of the condition, e.g. (td.expMon > 12) above.
Ahhh... perhaps the compiler complains about part of a boolean
expression? That would make sense (sort of).

/Peter- Hide quoted text -

- Show quoted text -

Correct me if I'm wrong, but if I also try to assign a negative number
to this variable, the negative number will be assessed as the unsigned
value. So if I tried to assign -1, it should be assessed as the
unsigned value of 65,535.
 
V

Victor Bazarov

Brian said:
[..]
Correct me if I'm wrong, but if I also try to assign a negative number
to this variable, the negative number will be assessed as the unsigned
value. So if I tried to assign -1, it should be assessed as the
unsigned value of 65,535.

Seems right if your 'unsigned short' is 16 bits long.

V
 
R

Rolf Magnus

Victor said:
Brian said:
[..]
Correct me if I'm wrong, but if I also try to assign a negative number
to this variable, the negative number will be assessed as the unsigned
value. So if I tried to assign -1, it should be assessed as the
unsigned value of 65,535.

Seems right if your 'unsigned short' is 16 bits long.

.... and the signed one is stored in 2's complement.
 
V

Victor Bazarov

Rolf said:
Victor said:
Brian said:
[..]
Correct me if I'm wrong, but if I also try to assign a negative
number to this variable, the negative number will be assessed as
the unsigned value. So if I tried to assign -1, it should be
assessed as the unsigned value of 65,535.

Seems right if your 'unsigned short' is 16 bits long.

... and the signed one is stored in 2's complement.

Actually, that doesn't matter. The standard guarantees the 'modulo
2^n' operation regardless of the representation. The bit pattern
doesn't change for 2's complement (it does for the other two reps).

V
 
C

Clark S. Cox III

Rolf said:
Victor said:
Brian said:
[..]
Correct me if I'm wrong, but if I also try to assign a negative number
to this variable, the negative number will be assessed as the unsigned
value. So if I tried to assign -1, it should be assessed as the
unsigned value of 65,535.
Seems right if your 'unsigned short' is 16 bits long.

.... and the signed one is stored in 2's complement.

That is irrelevant. On *any* C implementation (regardless of the
representation of signed integers), the value (-1), when converted to an
unsigned type will be converted to the maximum value representable by
that type. Period.
 
R

Rolf Magnus

Victor said:
Rolf said:
Victor said:
Brian wrote:
[..]
Correct me if I'm wrong, but if I also try to assign a negative
number to this variable, the negative number will be assessed as
the unsigned value. So if I tried to assign -1, it should be
assessed as the unsigned value of 65,535.

Seems right if your 'unsigned short' is 16 bits long.

... and the signed one is stored in 2's complement.

Actually, that doesn't matter. The standard guarantees the 'modulo
2^n' operation regardless of the representation. The bit pattern doesn't
change for 2's complement (it does for the other two reps).

Hmm, the exact wording in the standard is "If the destination type is
unsigned, the resulting value is the least unsigned integer congruent to
the source integer (modulo 2 n where n is the number of bits used to
represent the unsigned type) [Note: In a two’s complement representation,
this conversion is conceptual and there is no change in the bit pattern (if
there is no truncation). ]". It doesn't say what it means by "congruent".
The modulo part seems only to matter if you are converting from a bigger to
a smaller type, and basically just means that the extra bits are cut off.
The note talks about two's complement, but it doesn't say what happens to
other representations or why the conversion is "conceptiual" for two's
complement. Basically, I don't understand anything. I'm not sure if that is
due to the standard's wording or due to some lack of understanding English
on my side.
 
C

Clark S. Cox III

Rolf said:
Victor said:
Rolf said:
Victor Bazarov wrote:

Brian wrote:
[..]
Correct me if I'm wrong, but if I also try to assign a negative
number to this variable, the negative number will be assessed as
the unsigned value. So if I tried to assign -1, it should be
assessed as the unsigned value of 65,535.
Seems right if your 'unsigned short' is 16 bits long.
... and the signed one is stored in 2's complement.
Actually, that doesn't matter. The standard guarantees the 'modulo
2^n' operation regardless of the representation. The bit pattern doesn't
change for 2's complement (it does for the other two reps).

Hmm, the exact wording in the standard is "If the destination type is
unsigned, the resulting value is the least unsigned integer congruent to
the source integer (modulo 2 n where n is the number of bits used to
represent the unsigned type)

This says it all. Conceptually, the conversion from int to an unsigned
int looks like this (assume that 'big' is a signed integer type with an
infinite range):

unsigned Convert(int i)
{
big temp = i;
while(temp > numeric_limits<unsigned>::max())
{
temp -= big(numeric_limits<unsigned>::max())+1;
}

while(temp < 0)
{
temp += big(numeric_limits<unsigned>::max())+1;
}

return unsigned(temp);
}

[Note: In a two’s complement representation,
this conversion is conceptual and there is no change in the bit pattern (if
there is no truncation). ]". It doesn't say what it means by "congruent".

"coinciding when superimposed"
The modulo part seems only to matter if you are converting from a bigger to
a smaller type, and basically just means that the extra bits are cut off.

No, it applies whenever a value outside of the range of the unsigned
type is converted to that type.
The note talks about two's complement, but it doesn't say what happens to
other representations or why the conversion is "conceptiual" for two's
complement.

It only says that for two's compliment representations, this conversion
is basically a no-op. Nothing in that note contradicts anything
previously said in the section, it serves only to clarify.
 
C

Clark S. Cox III

Clark said:
Rolf said:
Victor said:
Brian wrote:
[..]
Correct me if I'm wrong, but if I also try to assign a negative number
to this variable, the negative number will be assessed as the unsigned
value. So if I tried to assign -1, it should be assessed as the
unsigned value of 65,535.
Seems right if your 'unsigned short' is 16 bits long.
.... and the signed one is stored in 2's complement.

That is irrelevant. On *any* C implementation [snip]

Oops, wrong group, but this happens to apply equally well to any C++
implementation. :)
 
P

Pete Becker

Rolf said:
Victor said:
Rolf said:
Victor Bazarov wrote:

Brian wrote:
[..]
Correct me if I'm wrong, but if I also try to assign a negative
number to this variable, the negative number will be assessed as
the unsigned value. So if I tried to assign -1, it should be
assessed as the unsigned value of 65,535.
Seems right if your 'unsigned short' is 16 bits long.
... and the signed one is stored in 2's complement.
Actually, that doesn't matter. The standard guarantees the 'modulo
2^n' operation regardless of the representation. The bit pattern doesn't
change for 2's complement (it does for the other two reps).

Hmm, the exact wording in the standard is "If the destination type is
unsigned, the resulting value is the least unsigned integer congruent to
the source integer (modulo 2 n where n is the number of bits used to
represent the unsigned type) [Note: In a two’s complement representation,
this conversion is conceptual and there is no change in the bit pattern (if
there is no truncation). ]". It doesn't say what it means by "congruent".
The modulo part seems only to matter if you are converting from a bigger to
a smaller type, and basically just means that the extra bits are cut off.
The note talks about two's complement, but it doesn't say what happens to
other representations or why the conversion is "conceptiual" for two's
complement. Basically, I don't understand anything. I'm not sure if that is
due to the standard's wording or due to some lack of understanding English
on my side.

x is congruent to y modulo m means that the remainder of x divided by m
is equal to the remainder of y divided by m (where division rounds
toward negative infinity). So 3 is congruent to 8 modulo 5, as is -2. In
general, -1 is congruent to m-1 modulo m, -2 is congruent to m-2, etc. A
machine that uses n bits to represent an integral type can hold unsigned
values from 0 up to and including (2^n)-1. When you're dealing with
values outside that range, they'll generally be reduced modulo 2^n, that
is, replaced by their remainder (rounding toward negaitve infinity) when
divided by 2^n. Thus, the original value is replaced by a value in the
range 0 to (2^n)-1 that is congruent to the original value modulo 2^n.

A simpler way to think of it informally is what I mentioned earlier: -1
becomes (2^n)-1, -2 becomes (2^n)-2, etc. And (2^n)-1 is UINT_MAX.

The note is specifically about twos-complement representation. Notes
aren't normative (they don't create requirements), and if you don't do
assembly programming, it's at best confusing. So ignore it.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
V

Victor Bazarov

Rolf said:
Victor said:
Rolf said:
Victor Bazarov wrote:

Brian wrote:
[..]
Correct me if I'm wrong, but if I also try to assign a negative
number to this variable, the negative number will be assessed as
the unsigned value. So if I tried to assign -1, it should be
assessed as the unsigned value of 65,535.

Seems right if your 'unsigned short' is 16 bits long.

... and the signed one is stored in 2's complement.

Actually, that doesn't matter. The standard guarantees the 'modulo
2^n' operation regardless of the representation. The bit pattern
doesn't change for 2's complement (it does for the other two reps).

Hmm, the exact wording in the standard is "If the destination type is
unsigned, the resulting value is the least unsigned integer congruent
to the source integer (modulo 2 n where n is the number of bits used
to represent the unsigned type) [Note: In a two's complement
representation, this conversion is conceptual and there is no change
in the bit pattern (if there is no truncation). ]". It doesn't say
what it means by "congruent". The modulo part seems only to matter if

http://en.wikipedia.org/wiki/Congruence_relation

A and B are congruent modulo N if (A-B) is divisible by N exactly.
So, if B is -1 and A is the number we seek (i.e. what it will be
if it's unsigned), and N=2^k where k is the number of bits in the
representation of 'A', then we get a simple equation:

A - (-1) = 2^(sizeof(A) * CHAR_BIT)

in our case:

A + 1 = 65536

which gives

A = 65535

(note that no particular hardware representation is involved here)
you are converting from a bigger to a smaller type, and basically
just means that the extra bits are cut off. The note talks about
two's complement, but it doesn't say what happens to other
representations or why the conversion is "conceptiual" for two's
complement.

It's conceptual because the bit pattern doesn't change and no
arithmetic operation is actually performed.
Basically, I don't understand anything. I'm not sure if
that is due to the standard's wording or due to some lack of
understanding English on my side.

You were just misreading it and I couldn't explain it right.

V
 
G

Grizlyk

Brian said:
Correct me if I'm wrong, but if I also try to assign a negative number
to this variable

On x86 CPU yes, but it seems to me, that C++ does not require that MSB is
always sign bit, so representaion of "-1" in theory can be any (not only in
complementary binary code, where "-a == (~a)+1" , for example "-1" can be
"0xfffe", not "0xffff".
 
V

Victor Bazarov

Grizlyk said:
On x86 CPU yes, but it seems to me, that C++ does not require that
MSB is always sign bit, so representaion of "-1" in theory can be any
(not only in complementary binary code, where "-a == (~a)+1" , for
example "-1" can be "0xfffe", not "0xffff".

C++ supports three representations at this time: 2's complement, 1's
complement and signed magnitude. All of them have the MSB as the sign
bit, but I am not sure how this is relevant here.

V
 
G

Grizlyk

Victor said:
C++ supports three representations at this time: 2's complement, 1's
complement and signed magnitude. All of them have the MSB as the sign
bit, but I am not sure how this is relevant here.

I do not know what is differences between "2's complement, 1's complement
and signed magnitude", but think befor it, that C++ save internal CPU data
representation, that can be (in theory) any, so passing "int" to "unsigned"
can require "_i2u" internal converter for hosted C++ compiler to set correct
bits.

I always write -1 if I need UINT_MAX, but think it is not portable.

Or C++ have "C++ virtual machine" with signed implemented as complementary
binary, hiding internal CPU representation?
 
V

Victor Bazarov

Grizlyk said:
I do not know what is differences between "2's complement, 1's
complement and signed magnitude"

The difference is in the way negative numbers are represented. GIYF.
, but think befor it, that C++ save
internal CPU data representation, that can be (in theory) any, so
passing "int" to "unsigned" can require "_i2u" internal converter for
hosted C++ compiler to set correct bits.

I always write -1 if I need UINT_MAX, but think it is not portable.

'unsigned int' and 'int' are required to have the same size. The
requirement is that a negative int 'a' when converted to unsigned
int produces (2^n + a) (where 'n' is the size in bits of the types).
Defining UINT_MAX as _different from_ (2^n - 1) is not possible if
we intend to satisfy the requirement that unsigned types behave the
way 3.9.1/4 requires ("obey the laws of arithmetic modulo 2^n").

So, AFA C++ is concerned, -1 converted to 'unsigned int' yields
'UINT_MAX' in any implementation.
Or C++ have "C++ virtual machine" with signed implemented as
complementary binary, hiding internal CPU representation?

Huh?

V
 
K

Kai-Uwe Bux

Grizlyk said:
I do not know what is differences between "2's complement, 1's complement
and signed magnitude", but think befor it, that C++ save internal CPU data
representation, that can be (in theory) any, so passing "int" to
"unsigned" can require "_i2u" internal converter for hosted C++ compiler
to set correct bits.
Yes.


I always write -1 if I need UINT_MAX, but think it is not portable.

It is portable. The standard demands that conversion from -1 to any unsigned
integral type yields 2^n - 1 where n is the number of bits in the target
type. More precisely, any value x is converted to the unique integral value
in the interval [0,2^n) congruent to x mod 2^n. See [4.7/2].

Or C++ have "C++ virtual machine" with signed implemented as complementary
binary, hiding internal CPU representation?

No. However, that does not change the requirements of the standard about
conversion.


Best

Kai-Uwe Bux
 

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,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top