This simple function using the digitalWriteFast library would give me an 'else' without a previous 'if' error. I was confused, because that should compile with a normal function.
It turns out that digitalWriteFast() is a #define, with its own nested if/else structure. When it gets substituted, the result fails. Adding braces fixes the problem.
It's possible to set up macro-based, multi-line "functions" to always parse as single "statements", so that they won't cause errors like this. Apparently the one you are using doesn't do that. (I'd consider this a bug worth reporting...)
if it has a if / else structure then you should be fine. if it's just an if then indeed it might become an issue as your else would not be attached to the right if.
which library are you using and on which platform?
Not when some of the offending code is hidden by a macro.
It's not THAT obvious. My first impression was that the if statement that the fast macro expands to IS a single statement, and it ought to work.
That's a shame. The correct way to write this structure in C++ is
#define digitalWriteFast(P, V) \
do { \
if (__builtin_constant_p(P)) { \
BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
} else { \
digitalWrite((P), (V)); \
} \
} while (0)
This way it behaves like an ordinary C++ statement and works fine whether or not there is a brace around an else block.
I would make a pull request but the last edit to the repo was 8 years ago and I guess there would be all kinds of latent defects uncovered if you changed it now. For example, you can currently write digitalWriteFast(...) // Note omitted semicolon and that will work. If you fixed the code, that would cease to compile.
FWIW, all of this is possibly irrelevant if the core you're using defines all these functions as static inline in the relevant headers. If that is the case, the compiler will often inline and elide any constants. Unfortunately, the core I use, the esp32 core, does not. But fortunately it has other ways to program digital outputs to switch at higher frequencies that don't involve using the CPU.
Oh, I think you're right. The second else would attach to the first if in that case. The semicolon just separates it from the first if, causing an "else without if" error.
(Of course, I'm not suggesting the solution is to omit the semicolons. The solution is to update the library code as has been done already.)