I am writing a small code to enable a buzzer when a sensor reading is above certain threshold. To enable the buzzer for one second, I gave a delay of 1000ms by calling this function : delay(1000)
. However, I randomly typed delay+(1000)
and it compiles well. Is this function call syntactically correct?
I have tried this code on Arduino IDE. It compiles but the same is not true for avr-gcc or avr-g++ or gcc/g++.
I expect delay+(1000) to not compile as it does not seem to be valid c/c++ syntax.
Update 1:
Compiled and uploaded the following code snippet to Arduino UNO using Arduino IDE :
void setup()
{
Serial.begin(9600);
}
void loop()
{
int x = delay+(1000);
Serial.println(x);
}
It continuously prints a random number 1132 without any delay. (So, 1132 => Function pointer address + 100 ?)
I also observed that delay+(1000)
and delay-(1000)
compiles but the same is not true for delay*(1000)
and delay/(1000)
. The compiler gives the following error:
sketch_jun09a:8: error: invalid operands of types 'void(long unsigned int)' and >'int' to binary 'operator*'
delay*(1000); ^
However, this int t = (int)delay*(1000);
compiles well.
Update 2:
Based on the answers below, delay<operator>(x)
just performs function pointer arithmetic (either using unary or binary operators) and does not execute the function itself.
I have used the following code snippet:
void setup()
{
Serial.begin(9600);
}
int custom()
{
Serial.println("hello");
return 0;
}
void loop()
{
custom+(1000);
delay+(1000);
}
It compiles well and outputs nothing.
Update 3:
I changed the Compiler Warnings level to "ALL" under Preferences in Arduino IDE. On compilation of this snippet,
void setup()
{
delay+(1000);
}
void loop() {}
Following warnings are obtained :
sketch_jun09a.ino: In function 'void setup()': sketch_jun09a.ino:3:14: warning: pointer to a function used in arithmetic [-Wpointer-arith]
delay+(1000); ^
sketch_jun09a.ino:3:8: warning: statement has no effect [-Wunused-value]
delay+(1000); ^
So there's two things going on here.
delay+(1000)
is syntax for adding 1000 to the function pointer delay. Which of course is completely senseless, but why did it compile at all. Normally you can add integers to pointers, but this would not apply to void *
pointers and function pointers. gcc
however has an extension that makes adding to void *
and void(*)()
work by giving the types void
and void()
size 1. So, adding integers to functions works (uselessly).
It turns out that adding integers to void *
pointers is occasionally something you actually want to do and the extension gets rid of a few annoying extra local variables, but function pointers almost never work like that. I guess somebody was building up asm code awhile ago, as it's the only use case I can imagine. Hint: on some architectures, function pointers don't point to function code but to descriptors.