volatile uint8_t m;
uint8_t getNumber() {
return 1;
}
void setup() {
uint8_t n = getNumber;
m = n; // prevent optimizing away
}
void loop() {
// put your main code here, to run repeatedly:
}
In output:
C:\Users\hanss\AppData\Local\Temp\.arduinoIDE-unsaved20251117-41564-18hm0vg.rt8p\sketch_dec17a\sketch_dec17a.ino: In function 'void setup()':
C:\Users\hanss\AppData\Local\Temp\.arduinoIDE-unsaved20251117-41564-18hm0vg.rt8p\sketch_dec17a\sketch_dec17a.ino:7:15: warning: invalid conversion from 'uint8_t (*)() {aka unsigned char (*)()}' to 'uint8_t {aka unsigned char}' [-fpermissive]
// put your main code here, to run repeatedly:
^~~~~~~~~
@alto777 actually won the race. I removed the duplicate content from my post once I noticed it had already been posted, but left in the unique explanation re: the unfortunate warning content mismatch caused by having an unsaved sketch.
I assumed that you were referring to the irrelevant line of the sketch code being referenced by the warning:
Note that the correct line of code is now shown in the warning:
I suppose the somewhat cryptic "invalid conversion from 'uint8_t (*)() {aka unsigned char (*)()}' to 'uint8_t {aka unsigned char}' [-fpermissive]" warning itself might also be described as "weird".
More weirdness: according to the disassembled program, the value 0x48 is stored in the only RAM location used.
Apparently a compiler warning doesn't mean "I got the meaning anyway." but "You probably won't get what you wanted."
Absolutely. The compiler’s really saying “I did what you told me because it’s not invalid to do so, but history says that’s unlikely to be what you wanted - so go reread your code and think about it!”
it's actually very clear and not weird if you understand types in C++...
In C++, the name of a function is actually a pointer to that function.
When you write
uint8_t n = getNumber;
you are assigning the address of the function getNumber to a variable n of type uint8_t.
The type of the function getNumber itself is uint8_t(), which means “a function taking no arguments and returning a uint8_t.”
When you use the function name without parentheses, it decays to a pointer to the function, so the type is uint8_t (*)().
this is why you see
warning: invalid conversion from uint8_t (*)() to 'uint8_t
This is technically a type mismatch, but C++ allows it by truncating the pointer (an address in memory) to fit into the single byte. Since the compiler can do it (edit: only because of the -fpermissive flag) , it is not an error, only a warning, because the resulting value is almost certainly meaningless but the code is still valid C++ syntax.
The flag exists for backward compatibility and pragmatism. Large amounts of old C and non-conforming C++ code rely on implicit or invalid conversions that were accepted by older compilers or by C but are illegal in C++. Rejecting all of that code would make migration very costly.
-fpermissive lets the compiler keep compiling such code by turning some errors into warnings, so developers can get a build, run tests, and then fix the code incrementally. It is not meant to make the code legitimate or correct, only to keep legacy or sloppy code compiling.