SomeWhere\WhyDoesItCompile\WhyDoesItCompile.ino: In function 'void setup()':
SomeWhere\WhyDoesItCompile\WhyDoesItCompile.ino:7:9: warning: invalid conversion from 'int' to 'int*' [-fpermissive]
test(i);
^
SomeWhere\WhyDoesItCompile\WhyDoesItCompile.ino:1:6: note: initializing argument 1 of 'void test(int*)'
void test(int * p) {
^
SomeWhere\WhyDoesItCompile\WhyDoesItCompile.ino:7:9: warning: 'i' is used uninitialized in this function [-Wuninitialized]
test(i);
^
JohnGaby:
Can someone explain why this program compiles without errors.
Probably because -fpermissive is specified on the commandline of the compiler.
I am not sure what you mean when you say that you 'remove all warnings'. Do you mean that you always fix warnings? If so, I am in complete agreement with that and always do the same. However when I compile this code with the default options for version 1.8.1 of the Arduino software, I get neither warnings nor errors. It tells me that everything is fine, when it is clearly not.
Yes, I did not expect that. I really did not think that the default settings would be such that this code would compile at all, much less without warnings.
Yes, one of the whole points of modern languages is to do type checking (the stricter the better) and to turn all of that off by default makes little sense to me. However, now that I have turned it back on, I can see why they might have done that. Many of the libraries that I am using generate a copious amounts of warnings and they probably didn't want people to see all of that.
The compiler probably optimized this to an empty function and then removed it since it doesn't actually do anything. Hence it compiles with no problems.
It's not optimization, but an implicit conversion between types int and int*. This produces a warning (due to the -fpermissive flag already mentioned) which is hidden unless you turn on verbose compilation.
Jiggy-Ninja:
It's not optimization, but an implicit conversion between types int and int*. This produces a warning (due to the -fpermissive flag already mentioned) which is hidden unless you turn on verbose compilation.
It flags the warning when parsing the code, but also likely optimizes it completely away, later in the compilation process, as the code, overall, does nothing with any side-effects, as the code sets a variable, but that variable is then never read. If it were declared volatile, perhaps it would not be optimized out, but as it is, I'd guess it would be.
RayLivingston:
It flags the warning when parsing the code, but also likely optimizes it completely away, later in the compilation process, as the code, overall, does nothing with any side-effects, as the code sets a variable, but that variable is then never read. If it were declared volatile, perhaps it would not be optimized out, but as it is, I'd guess it would be.
Regards,
Ray L.
No, it's writing 0 to a dereferenced pointer (note the *). I can't imagine any reason for a compiler optimizer to decide to remove that.
Jiggy-Ninja:
No, it's writing 0 to a dereferenced pointer (note the *). I can't imagine any reason for a compiler optimizer to decide to remove that.
Well, whether you can imagine any reason or not, it does. The sketch in the OP compiles to 444 bytes. A completely empty sketch also compiles to 444 bytes. Modern compilers are very smart about optimization...
The compiler probably optimized this to an empty function and then removed it since it doesn't actually do anything. Hence it compiles with no problems.
This is most certainly not an empty function.
At a guess, the compiler permits test(i) because on the AVR int values and pointers are both 16 bit.
PaulS:
Then, they should fix the libraries, not turn a blind eye to all the problems.
No kidding. I have never used a C++ setup before that hides so many issues by default. Personally, I usually have most warnings turned on and have the compiler set to treat warnings as errors so I am forced to fix them. And I certainly don't enable an option which turns off type checking (i.e. -fpermissive).
And yes, I am aware that you can, under the right circumstances, copy a pointer into an integer and back to a pointer and have it work. However, you should be forced to use casts to tell the compiler that you actually know what you are doing (hopefully you do). Lacking the casts, that kind of code should always be flagged as an error, not a warning.