if(a=b) is not if(a==b) could IDE check this b4 upload?

Guys,
I see this request come up a lot
and lots of bashing back and forth between the novices wanting
the tools to catch their mistakes and the purists saying
just learn how to better use the tools.

Because "arduino" is not a language, and the IDE simply passes
the sketch to gcc for C++ parsing, it is the compiler that must check
for this condition.

Good news is that there is already a compiler option to do this.
(Has been for like 20+ years in gcc.....)

Currently, it is -Wparentheses

If you simply use this option to the compiler, then if you do something like:

if( a = 50)

vs

if (a == 50)

or even with dual variables like

if( a = b)

You will get a warning like:

bs.cpp:25: warning: suggest parentheses around assignment used as truth value

If you really need to do the assignment inside the if, you can avoid the warning by
simply using:

if( (a = 50) )

instead.
To me this actually emphasizes the assignment,
which seems like a good thing for clarity.

===

Now if the Arduino guys would just let you set the compiler flags.......
(but thats another issue)

Now for the really bad news. Nobody and and I mean nobody has seen a warning
from the compiler using the IDE. The IDE explicitly disables ALL warnings from the compiler!!
(again you'll have to ask the arduino team why they decided to do this)

For now, you can go in and hack the IDE java code and rebuild
the IDE yourself: (the beauty of open source)
It is in app/src/processing/app/debug/Compiler.java around line #443

You will need to remove the -w option which suppresses all warnings and
replace it with -Wparentheses and rebuild the IDE.

It does work. I've tested it.

But be prepared to get many warnings because none of the code has been built
with warnings enabled for quite some time now,
So you will see that lots of the code out there (including some of the core arduino code) has slight
issues that generate warnings.

But you will actually get a warning for the dreaded "accidental" assignment
inside an if statement.

--- bill

Probably just a lot easier to put a posit-it note on your screen, reminding you to watch for
if (x=y)

if your code !

haughtonomous:
Well, C was written to help write an operating system (UNIX), where you are hitting the hardware and want to be able to do pretty much anything.

And now I'll duck. :slight_smile:

Heh. Where do you hide, I'll need to hide after this. My turn. One thing which irritates me in C is: I started with assembly programming a long time ago. There you had to know exactly what was a address and what was data in that address. And how to mix and handle both. Exactly. In C a variable is sometimes data and sometime address. I hate that a lot. Please note I like (valid)pointers.

It feels like C was designed by an idiot(s) who didn't understand indirect addressing.

LMI:

haughtonomous:
Well, C was written to help write an operating system (UNIX), where you are hitting the hardware and want to be able to do pretty much anything.

And now I'll duck. :slight_smile:

Heh. Where do you hide, I'll need to hide after this. My turn. One thing which irritates me in C is: I started with assembly programming a long time ago. There you had to know exactly what was a address and what was data in that address. And how to mix and handle both. Exactly. In C a variable is sometimes data and sometime address. I hate that a lot. Please note I like (valid)pointers.

It feels like C was designed by an idiot(s) who didn't understand indirect addressing.
[/quote]

Still, I don't think any company today could afford the time and costs to write a complete modern graphical OS in assembly language. C/C++ can be used to write such an OS. How many other higher level languagues (higher then asm) can make that claim?

Lefty

LMI:

haughtonomous:
Well, C was written to help write an operating system (UNIX), where you are hitting the hardware and want to be able to do pretty much anything.

And now I'll duck. :slight_smile:

Heh. Where do you hide, I'll need to hide after this. My turn. One thing which irritates me in C is: I started with assembly programming a long time ago. There you had to know exactly what was a address and what was data in that address. And how to mix and handle both. Exactly. In C a variable is sometimes data and sometime address. I hate that a lot. Please note I like (valid)pointers.

It feels like C was designed by an idiot(s) who didn't understand indirect addressing.
[/quote]

Can you give a specific C (not C++) example of how the same variable referenced the same way
is sometimes data and sometimes a pointer?
I'm kind of struggling with that comment.

How is the difference between "data" and "pointer" in a variable in C any different than the
contents of a register or memory location in assembler?

In assembler you have the same problem. If you look at the contents of a register that was passed
to a routine, how do you know if it is the data or an address that points to data?
You don't. It is only because you know (because it was defined somewhere)
what the register is supposed to contain that you know how to use it.
Same is true for a memory location. The memory location can be the actual data or a pointer
to the real data.

C is exactly the same way.
The only difference is that C allows you to easily declare how the "register" is used
and create as many "registers" as you like.
In C the way the "register"/variable/memory-location is declared determines how it is used and how the data
is referenced and the compiler will ensure that the code treats the variable consistently according
to its definition.

vs in Assembler there is no such declaration nor any sanity checking
and the actual code must be hard-coded to be consistent.
In a complex system that becomes very difficult especially on projects that involve many
team members.

And I think the designers of C very much understood indirect addressing and used
it accordingly.

Now I'll agree that to many novice C coders there may be some perhaps strange/non-obvious
things that happen when calling functions. Things like the address of the first
element of an array being passed vs the entire array.
But those are well defined and are very logical.

--- bill

Can you give a specific C (not C++) example of how the same variable referenced the same way
is sometimes data and sometimes a pointer?

There's the example from another recent thread. An array as a parameter is a pointer, but as a local or global variable is a sized array (and sizeof(x) is different.)

#include <stdio.h>

void func(int x[10])
{
    int y[10];

    printf("sizeof x=%d, sizeof y=%d\n", sizeof(x), sizeof(y));
}

int main()
{
    int z[10];
    func(z);
}

It's also somewhat annoying that structs are passed by value by default, but arrays are passed by reference by default. You get used to it...

In assembler you have the same problem.

I agree completely with that. And sometimes you do extensive math on an address before you use it as a pointer. Just recently I was writing:    a = (a + ps) & ~(ps-1);

bperrybap:
Now for the really bad news. Nobody and and I mean nobody has seen a warning
from the compiler using the IDE. The IDE explicitly disables ALL warnings from the compiler!!
(again you'll have to ask the arduino team why they decided to do this)

I agree with Bill on this one. In fact I thought I had the solution, after some Googling I found this:

#pragma GCC diagnostic warning "-Wall"

That is, with a pragma, enable all warnings. Even saw that code inside some Arduino library.

But no dice. The problem "if" statement does not produce warnings.

Now I can understand the Arduino developers thinking "We won't confuse all those newbies with warning messages they don't understand". But what they have substituted is program behaviour, even crashes, that they don't understand. So instead of spending 10 minutes eliminating warnings, you spend days puzzling over why your code isn't working as you expect.

And, look! The compiler, as distributed, does support it (the parenthesis warnings). Look at this test case:

$ avr-gcc -Wall test.cpp
test.cpp: In function 'int main()':
test.cpp:4: warning: suggest parentheses around assignment used as truth value
$

Interestingly though, the avr-gcc compiler does not honour the pragma. Did they deliberately compile it to accept the pragma but do nothing? Seems like a lot of work to go through to stop people, who really want them, from getting warnings.

Nick,
I don't think it is as nefarious as you think.
I think you have stumbled on a legitimate compiler bug or at least something that
needs clarification in the gcc documentation.
I was unaware of the pragmas to alter the diagnostic messages (I seldom use pragmas as they are so unportable)
However, if this worked it would be exactly what the OP was looking for.

According to the gcc documentation:

The pragmas are supposed to override any command line options. (from the current documentation):

Note that these pragmas override any command-line options.

In this case, the offending commandline option is "-w" (set by the Arduino IDE) which disables all warnings.
See documentation: Warning Options (Using the GNU Compiler Collection (GCC))

What wasn't clear in the gcc documentation is that "-w" cannot be overridden by the pragmas.
While I believe that the overriding of -w with pragmas could be argued either way,
(personally I think pragmas should be allowed to override -w)
the way it currently works (you can't override it with a #pragma),
definitely could use a comment about this in the section about the diagnostic pragmas
indicating that no warnings can be enabled if the -w command line option was used
to disable all warnings.

Note: The pragma does work if the -w command line option is not used.
(at least in avr-gcc version 4.3.4 which is what I'm using on linux)
Windows may be running an older version and if so, the pragmas may not be supported.

But unfortunately, currently the only way to get rid of the -w command line option
being passed to gcc from the IDE is to patch the java code and rebuild the IDE.

What would be nice is if the Arduino guys would update the IDE to allow overriding the commandline options.
As an alternative they could remove the -w option from the compiler commandline
and use a pragma to disable warnings in WProgram.h

That way users that want/need to see warnings could turn them back on by simply inserting
a pragma in their code.

It would be the best of all worlds. Naive users never get warnings and more advanced users
could easily turn them back on.

--- bill

bperrybap:
What would be nice is if the Arduino guys would update the IDE to allow overriding the commandline options.
As an alternative they could remove the -w option from the compiler commandline
and use a pragma to disable warnings in WProgram.h

Bill,

I agree with you 100%.

Suppressing warnings is just shifting the problem. For example, if your car was running out of petrol, you might be annoyed by flashing "low fuel" message, but you will be even more annoyed when you run out of gas on a lonely country road.

However, to the test case. I have a program here:

#pragma GCC diagnostic warning "-Wall"

int main ()
  {
  int a;
  if (a = 1)
    {};  // do something
  return 0;
  }

If I compile that without any -w flag, it still does not raise a warning.

$ avr-gcc test.cpp
$

However with -Wall it does.

$ avr-gcc test.cpp -Wall
test.cpp: In function 'int main()':
test.cpp:6: warning: suggest parentheses around assignment used as truth value
$

So the -w flag is not suppressing warnings. Something else is. Or the pragma just doesn't work.

Interesting. I was testing using -Wparentheses not -Wall
(what version of the Compiler are you using)

What is very interesting for me on is that on avr-gcc version 4.3.4
#pragma GCC diagnostic warning "-Wall"
will not output the warning while:
#pragma GCC diagnostic warning "-Wparentheses"

will turn on the warning. (but only if -w is not used on the commandline).

Either one on the commandline will turn on the warning.

It seems like a bug to me that -Wall on the command line behaves differently
than
#pragma GCC diagnostic warning "-Wall"

--- bill

#pragma GCC diagnostic warning "-Wall"

Does #pragma GCC diagnostic warning "-Wparen" work? It wouldn't surprise me if Wall is a special case.

One reason that -Wall isn't turned on by default is that it tends to result in a lot of relatively confusing warnings for mostly-non-issues (for example, comparison between a signed and unsigned int.)

Another reason is that there is currently a G++ bug that causes a bogus warning for initialized PROGMEM variables.

A third reason is that the Arduino "core" and official libraries are not "warning free."

westfw:

#pragma GCC diagnostic warning "-Wall"

Does #pragma GCC diagnostic warning "-Wparen" work? It wouldn't surprise me if Wall is a special case.

One reason that -Wall isn't turned on by default is that it tends to result in a lot of relatively confusing warnings for mostly-non-issues (for example, comparison between a signed and unsigned int.)

Another reason is that there is currently a G++ bug that causes a bogus warning for initialized PROGMEM variables.

A third reason is that the Arduino "core" and official libraries are not "warning free."

#pragma GCC diagnostic warning "-Wparen"

does not work. However, as I mentioned above:

#pragma GCC diagnostic warning "-Wparentheses"

does work if you don't use -w on the command line.
-w seems to disable all warnings even if pragmas attempt to turn them back on.

Yep I saw the wierd errors for progmem constants. I hadn't tracked that down yet.

Still seems to like it would be logical that

#pragma GCC diagnostic warning "-Wall"

should behave the same as -Wall on the commandline though.

(I started a thread over on the AVRfreaks gcc forum about it)

--- bill

Yep I saw the wierd errors for progmem constants. I hadn't tracked that down yet.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
Not getting fixed very quickly...

bperrybap:
Interesting. I was testing using -Wparentheses not -Wall
(what version of the Compiler are you using)

What is very interesting for me on is that on avr-gcc version 4.3.4
#pragma GCC diagnostic warning "-Wall"
will not output the warning while:
#pragma GCC diagnostic warning "-Wparentheses"

will turn on the warning. (but only if -w is not used on the commandline).

$ avr-gcc --version
avr-gcc (GCC) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Ah yes, confirmed. The specific pragma works, but not if you use -w.

However this (the -Wall part) is contradicted by "man gcc":

 -Wparentheses
           Warn if parentheses are omitted in certain contexts, such as when there is an assignment in a context where a truth value is expected, ...

           This warning is enabled by -Wall.

Yep I saw the wierd errors for progmem constants. I hadn't tracked that down yet.

I still would like to enable -Wparentheses. Cancelling all warnings is like throwing out the baby with the bathwater. Or something.

Is not cancelling all warnings akin to clapping your hands over your ears, screwing your eyes tightly shut, and loudly chanting "la la la la la...."?

:slight_smile:

haughtonomous:
Is not cancelling all warnings akin to clapping your hands over your ears, screwing your eyes tightly shut, and loudly chanting "la la la la la...."?

:slight_smile:

If I had to guess I'd say the problem is that Arduino recompiles all the libraries on each compilation. My bet is the libraries produce loads of warnings. Not a very elegant solution though.

If I had to guess I'd say the problem is that Arduino recompiles all the libraries on each compilation. My bet is the libraries produce loads of warnings. Not a very elegant solution though.

Several (4-5?) versions ago of the IDE, it use to look to see if there were any precompiled .o files and would use them, if not it would recompile from source. Then they changed it to always force a complete compile. Not sure of the reason for that change, however there were always problems with people forgetting to delete a .o file, after making changes to a library source file(s) and not seeing any change in behaviour. :wink:

Not competent enough to pass judgment on suppression of warning messages, I have enough challenge just trying to get all the fatal compilation errors to go away. Plus I already have a wife, the ultimate warning message machine. :wink:

Lefty

Wife aggro, huh?

As for the libraries, I don't see why you can't compile libraries suppressing warnings, but keep them for the "user" code. Or alternatively, huh, fix the libraries. I think there is a pragma that suppresses warnings, so I would rather go through and "knowingly" suppress a warning I know to be benign, than have them all suppressed.

See this thread for a very nice solution to this issue.
It allows advanced users to set their own compiler and linker options.

It would be really nice if this would make it into the next Arduino release.
(seems like a no brainer to me)

http://arduino.cc/forum/index.php/topic,54456.0.html

--- bill