weird 'C' warning - can you solve this?

R

Ross

I'm compiling some code over and over with no problems. The only
differences between the versions is slightly different constants that
are specific to various embedded devices that are getting loaded.
Suddenly I notice a certain value generates a warning. Here's the
low-down:

The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

with some experimenting, -50000, and -40000 are also not liked


All these other versions will compile fine
const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine


a work around (I think) is to explicitly put an L in place to denote a
long - but why that would work, who knows?

const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine


The warning is specifically:

[warning] unsigned operand of unary -

Can anyone explain why this is happening. If -60000 were beyond the
valid range of a signed long, then surely -70000 or -80000 would
generate a warning too.

Thx. Ross.
 
P

Peter Pichler

Ross said:
I'm compiling some code over and over with no problems. The only
differences between the versions is slightly different constants that
are specific to various embedded devices that are getting loaded.
Suddenly I notice a certain value generates a warning. Here's the
low-down:

The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

with some experimenting, -50000, and -40000 are also not liked

All these other versions will compile fine
const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine

a work around (I think) is to explicitly put an L in place to denote a
long - but why that would work, who knows?

const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine

The warning is specifically:

[warning] unsigned operand of unary -

Can anyone explain why this is happening. If -60000 were beyond the
valid range of a signed long, then surely -70000 or -80000 would
generate a warning too.

It's obvious actually. int is 16 bits wide on your system, so anything over
32767 is considered unsigned. Appending an explicit L after the number makes
it long. To prove that, you could try any number between 32768 and 65535
inclusive, all of them should give you the warning. Numbers smaller or
bigger than that would appear to be OK. The correct way is of course using
L.

Peter
 
L

lawrence.jones

Ross said:
The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad [...]
[warning] unsigned operand of unary -

Can anyone explain why this is happening.

Because your compiler is broken. It appears to be treating unsuffixed
decimal constants between INT_MAX and UINT_MAX as having type unsigned
int, but the C Standard requires them to have type long int (unlike
octal and hex constants, decimal constants are *never* interpreted as
unsigned without an explicit u or U suffix).

-Larry Jones

The surgeon general should issue a warning about playing with girls. -- Calvin
 
N

Nejat AYDIN

Peter said:
Ross said:
I'm compiling some code over and over with no problems. The only
differences between the versions is slightly different constants that
are specific to various embedded devices that are getting loaded.
Suddenly I notice a certain value generates a warning. Here's the
low-down:

The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

with some experimenting, -50000, and -40000 are also not liked

All these other versions will compile fine
const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine

a work around (I think) is to explicitly put an L in place to denote a
long - but why that would work, who knows?

const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine

The warning is specifically:

[warning] unsigned operand of unary -

Can anyone explain why this is happening. If -60000 were beyond the
valid range of a signed long, then surely -70000 or -80000 would
generate a warning too.

It's obvious actually. int is 16 bits wide on your system, so anything over
32767 is considered unsigned.

Then the compiler is broken. The unsuffixed decimal constants over 32767 must be
considered ``long int'' if it is less than LONG_MAX, assuming an implementation
where INT_MAX is 32767.
 
M

Mark F. Haigh

Ross said:
The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

[warning] unsigned operand of unary -

Can anyone explain why this is happening.

Because your compiler is broken. It appears to be treating unsuffixed
decimal constants between INT_MAX and UINT_MAX as having type unsigned
int, but the C Standard requires them to have type long int (unlike
octal and hex constants, decimal constants are *never* interpreted as
unsigned without an explicit u or U suffix).

-Larry Jones

Not quite. Before long long came along, a decimal constant higher than
LONG_MAX would result in an unsigned long type. See 3.1.3.2 of C90.

I agree with your diagnosis, however.

Mark F. Haigh
(e-mail address removed)
 
D

Dan Pop

In said:
Not quite. Before long long came along, a decimal constant higher than
LONG_MAX would result in an unsigned long type. See 3.1.3.2 of C90.
^^^^^^^^^^^^^^
No such thing. It's 3.1.3.2 of C89. The most important contribution of
ISO to the ANSI C standard was screwing its section numbering.

Dan
 
P

Peter Pichler

Nejat AYDIN said:
Then the compiler is broken. The unsuffixed decimal constants over 32767 must be
considered ``long int'' if it is less than LONG_MAX, assuming an implementation
where INT_MAX is 32767.

I never said otherwise :)

About 5 years ago, when I was working on embedded projects, such compilers
were quite common. I don't know what the situation is now.

ITYM assuming an implementation where INT_MAX < LONG_MAX, BTW.
 
D

Dan Pop

In said:
I never said otherwise :)

Then, what did you mean by:

The correct way is of course using L.
^^^^^^^ ^^^^^^^^^
What exactly is *incorrect* if L is omitted, apart from the broken
compiler's behaviour?
About 5 years ago, when I was working on embedded projects, such compilers
were quite common. I don't know what the situation is now.

ITYM assuming an implementation where INT_MAX < LONG_MAX, BTW.

If int is 16-bit, which is already explicitly assumed in your original
post, INT_MAX *must* be lower than LONG_MAX, unless the implementation
is *severely* broken.

Dan
 
P

Peter Pichler

Dan Pop said:
In <[email protected]> "Peter Pichler"

Then, what did you mean by:

The correct way is of course using L.
^^^^^^^ ^^^^^^^^^

An advice how to solve the OP's problem.
What exactly is *incorrect* if L is omitted, apart from the broken
compiler's behaviour?

Failing to say A does not mean implying !A.

I know how futile it is to argue with you, so I will shut up now.
I prefer being happy to being right :)

Peter
 
D

Dan Pop

In said:
An advice how to solve the OP's problem.

It's a lot more than that. It's *also* an implication that the OP's
way was incorrect. And a strong clue that you believed the OP's code
to be incorrect.

A properly phrased advice would have been something along the lines:
"you can shut up the bogus warning by using the L suffix".

Dan
 
P

Peter Pichler

Dan Pop said:
In <[email protected]> "Peter Pichler"

It's a lot more than that. It's *also* an implication that the OP's
way was incorrect. And a strong clue that you believed the OP's code
to be incorrect.

A properly phrased advice would have been something along the lines:
"you can shut up the bogus warning by using the L suffix".

On the second thought, I think you're right. Sorry about (potentially)
misleading the OP.
 
R

Ross

Thanks for the replies and discussion.

The explanation makes sense regarding the bit length of INT versus
Long - and it did indeed seem like a bug in the compiler.

The compiler (for those interested) is ImageCraft - within the
Cypress tools.

(Not so much to diss either of those co's, but just in case someone
else is searching to explain the same problem later)

Thanks again,

Ross.

The 'L' suffix appears to be the best work around.

Ross said:
The specific instance of the "-6" in this phrase generates a warning:

const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad [...]
[warning] unsigned operand of unary -

Can anyone explain why this is happening.

Because your compiler is broken. It appears to be treating unsuffixed
decimal constants between INT_MAX and UINT_MAX as having type unsigned
int, but the C Standard requires them to have type long int (unlike
octal and hex constants, decimal constants are *never* interpreted as
unsigned without an explicit u or U suffix).

-Larry Jones

The surgeon general should issue a warning about playing with girls. -- Calvin
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top