The preprocessor hack does not compile to code that would decompile back to an if() statement. The i/1000 code does not compile to code that would decompile back to an if() statement. The ctor hack does not compile to code that would decompile back to a loop and an if statement. The i<1000 code, on the other hand, does compile down to code that decompiles back up to an if() statement; that's because it's just a compact way of writing an if() statement.
Well, neither C nor C++ are assembly, and vice versa. That's my usual response to this kind of "arguments", in every such question; boy do they come up a lot.
Regardless, I'll repeat it; maybe it'll stick this time:
i < 0
is a conditional expression,
if (i < 0) {}
is a conditional statement.
Also, while the above could be (mis)taken for C code;
cmp eax, 0
jl foo
this one surely wouldn't.
And at this point I'll stop beating this particular horse.
I'm not being a "language lawyer".