Removing "if (a = b)" warning

S

Stephen

writes


God, this is so broken, it is not funny anymore.

Oh for goodness sake. It's NOT broken (or at least the slightly improved
version) in the exactly/only circumstances in which it is being used.
On the ancient compilers that I know where incrementing a pointer past a
64 KB boundary didn't work, this code would _definitely_ not work.

Hint: On an x86 in 16 bit mode, the difference between one legal segment
and the next one is not one, but eight.

I'm not using x86. I believe I made it perfectly clear that this
particular instance of the macro was directly targeted at a specific
platform to get around a specific problem.

You can take your "must be ANSI C compliant" mentality too far when you
forget to engage your brain.
 
O

Old Wolf

Stephen said:
Any other suggestions for how to stop the warning on: "if (a = b)" ?

1) Read your compiler documentation and find a switch that does it.
2) Pass the compiler output through 'grep' and remove the warnings
you don't like.
3) Don't use your macro inside an 'if' statement:
FARPTR_INC(p);
if (p)
{ ...etc
Keil C51 for extended memory architecture 8051s.

IMHO, you should avoid creating objects that cross 64KB boundaries.
Then you would not have any of these problems.
Does the system documentation on the "extended memory architecture"
include any suggestions along these lines?
I've seen shorts at 8, 16 or 32 bit and now completely hate the
word short :)

An 8-bit short would not conform to the C standard.
 
S

Stephen

Old said:
3) Don't use your macro inside an 'if' statement:
FARPTR_INC(p);
if (p)

Yes, I've considered using that if I need it.

However, having spent more time today fiddling with macros across
various platforms I've now reached the state where there isn't a problem
any more. The only platform where I need to use this particular horrible
kludge inside an 'if' or 'while' is one that doesn't seem to issue
warnings anyway. It doesn't even issue a warning at 'if (a = b)' which
is a bit disconcerting. Good job the code is multi-platform, you sort of
get the benefits of all of the platforms put together so if I make such
a mistake and one compiler lets me away with it then one of the other
compilers won't.
IMHO, you should avoid creating objects that cross 64KB boundaries.

Oh I agree, C allocated objects never cross 64KB boundaries. But in this
case it isn't an "object" in the C sense, because the same problem
occurs on native pointer support (I use pointers to large data areas
that the compiler has no direct knowledge of).
Does the system documentation on the "extended memory architecture"
include any suggestions along these lines?

Sure.

It was one of their macros that I borrowed the cast to ULONG from :)

But they admit issues with 64KB boundaries for now.
An 8-bit short would not conform to the C standard.

Nor would half the other stuff I regularly have to deal with in embedded
compilers. See the fun us embedded guys have? Must be terrible only ever
being able to write strict ANSI C code ;-)

Although, seriously, I do admire the depth of knowledge encountered in
here from the C purists. Can someone give me a hyperlink to the official
C standard? It would make a good read from time to time...
 
K

Keith Thompson

Stephen said:
Although, seriously, I do admire the depth of knowledge encountered in
here from the C purists. Can someone give me a hyperlink to the official
C standard? It would make a good read from time to time...

The standard itself is available as a PDF for $18 from ANSI (I don't
have the URL).

A committee draft, n1124.pdf, is freely available; Google will find
it. It includes the C99 standard with some more recent corrections
merged in (and marked with change bars).
 
O

Old Wolf

Stephen said:
Oh I agree, C allocated objects never cross 64KB boundaries. But in
this case it isn't an "object" in the C sense, because the same
problem occurs on native pointer support (I use pointers to large
data areas that the compiler has no direct knowledge of).

You must be using some sort of structure withing these large data
areas -- perhaps you can organize that structure so that you
never need to do pointer arithmetic across a boundary.

(Note that the C compiler is actually conforming to the C standard,
as it is undefined behaviour to use pointers to areas that the
compiler has no direct knowledge of).
Nor would half the other stuff I regularly have to deal with in
embedded compilers. See the fun us embedded guys have? Must be
terrible only ever being able to write strict ANSI C code ;-)

This is different. Usually, embedded compilers support ANSI C
and add their own extensions (such as far pointers, in your case).
An embedded system should be able to compile and run any
strictly conforming ANSI C program.

However, 8-bit short is not an "extension", it would actually
break strictly conforming code.
It would make a good read sometime

Trust me, it is painful to read:)
Try reading the newsgroup FAQ, you can learn most of the points
that come up regularly in this newsgroup (funnily enough).
 
J

Jordan Abel

This is different. Usually, embedded compilers support ANSI C
and add their own extensions (such as far pointers, in your case).
An embedded system should be able to compile and run any
strictly conforming ANSI C program.

What about one that uses "far" as an identifier? To support those,
the compiler would need to require a header that includes #define
far __far to follow the standard.

Stephen, an explanation of _why_ an 8-bit short would be illegal -
short is required to represent at least the range -32767..32767 -
thus it must be at least 16 bits.
 
T

Tim Rentsch

Stephen said:
Is there a standard way to remove the warning that a C compiler might
produce from the statement:

if (a = b) {}

I don't want to do:

if ((a = b) != 0) {}

Because my "a = b" is actually contained in a macro that might be used
as a statement or as an expression within (for example) an "if"
statement.

If it makes any difference, here's exactly what I'm trying to do. In
order to get around a limitation of a particular C compiler that will
not allow p++ (or any other pointer arithmetic) to work correctly across
64KB boundaries, I have come up with a few macros, one of which is:

#define FARPTR_INC(p) p=(void far *)(((ULONG)(p))+sizeof(*(p)))

Now I can do:

UBYTE far *pb;
UWORD far *pw;
ULONG far *pl;
FARPTR_INC(pb); // Replacement for: pb++; (adds 1 to address)
FARPTR_INC(pw); // Replacement for: pw++; (adds 2 to address)
FARPTR_INC(pl); // Replacement for: pl++; (adds 4 to address)

I can also do:

func(FARPTR_INC(p)); // Replacement for: func(p++);

But if I do:

if (FARPTR_INC(p)) {}

Then I get a warning since the compiler is justifiably taking the view
that I might have missed an equals sign and accidentally turned an
equality comparison into an assignment.

The comment says FARPTR_INC(p) is a replacement for p++, but
the way the macro definition is written, FARPTR_INC(p) looks
more like ++p. Presumably the macro definition is what's
actually desired, in which case the comment should be changed.
Also INC_FARPTR() might be a better name than FARPTR_INC() for
the pre-increment semantics.

Usually it's good to enclose macro definitions (when intended
to serve as expressions) in parentheses. The macro FARPTR_INC
is supposed to be usable as an expression or sub-expression,
so its definition should be enclosed in parentheses. If this
is done then

if( FARPTR_INC(p) != 0 ) ...

will work just fine.


And now, what everyone has been waiting for: the Top 10 List
of ways to avoid warnings for 'if( a = b )'...

(...drum roll...)


10. a = b;
if( a ) ...


9. if( (a = b) ) ...


8. #define NONZERO(x) ((x) != 0)
if( NONZERO( a = b ) ) ...


7. if( a = b, a ) ...


6. if( !! (a = b) ) ...


5. #define ASSIGN(a,b) ((a) = (b))
if( ASSIGN(a,b) ) ...


4. if( (_Bool) (a = b) ) ...


3. if( 0 || (a = b) ) ...


2. if( 1? a = b :0 ) ...


And now the number 1 way to avoid warnings on 'if( a = b )'...

1. #define if(x) if( (x) )
if( a = b ) ...
 
C

Christopher Benson-Manica

Stephen said:
You can take your "must be ANSI C compliant" mentality too far when you
forget to engage your brain.

Are you the ghost of Dan Pop? What have you done with him?
 
P

pete

Martin said:
No *standard* way, since compilers are free to issue whatever warnings
they want. There is a *common* way:
if ((a = b)) { }


I'm sure some others can parse that and make sense of it, but it's
beyond me.

I can't.

if (A)
means exactly the same thing as
if ((A) != 0)

for any and all possible meanings of A, including funky macros.
 
B

Ben Pfaff

pete said:
if (A)
means exactly the same thing as
if ((A) != 0)

for any and all possible meanings of A, including funky macros.

Here's an interesting funky macro to go along with that
observation:
#define if(expr) if ((expr) != 0)
(Does it break anything?)
 
S

Stephen

[/QUOTE]
if (A)
means exactly the same thing as
if ((A) != 0)

for any and all possible meanings of A, including funky macros.

You've missed the point:

if ((a = b) != 0)

will kill the warning generated by:

if (a = b)
 
P

Peter Nilsson

Ben said:
Here's an interesting funky macro to go along with that
observation:
#define if(expr) if ((expr) != 0)
(Does it break anything?)

It can if you include a standard header after the macro
definition. Also, if A is an expression that includes a non-
parenthesised comma, then there is a problem since the macro
only takes one parameter.
 
P

pete

Stephen said:
[QUOTE="pete said:
Stephen wrote:
Is there a standard way to remove
the warning that a C compiler might
produce from the statement:

if (a = b) {}

I don't want to do:

if ((a = b) != 0) {}
if (A)
means exactly the same thing as
if ((A) != 0)

for any and all possible meanings of A, including funky macros.

You've missed the point:[/QUOTE]

That happens more often than I like.
if ((a = b) != 0)

will kill the warning generated by:

if (a = b)

I thought that you wanted to kill the warning.

if ((a = b) != 0) {}
kills the warning very nicely
without changing the meaning of the code.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top