Yes, it's entirely possible.
For example, you can define the language as requiring at least a minimal degree of dead-code elimination, so (for example) something like:
const bool debug = false;
...requires that not only is
whatever() not called, but that it produce code that does not refer to
whatever at all.
This gives roughly the same effect as something like:
...would in C or C++. The only obvious difference is that by including the capability in the language, you typically require that the contents of the condition be syntactically correct for the target programming language (whereas C and C++ allow an
#ifdef block to contain code that isn't syntactically correct C or C++, as long as the preprocessor can still detect the matching
Now, in some cases it's easy to require things that nobody knows how to do, thus producing a specification that nobody can implement. That would not be the case here though: compilers that can do the optimization above already exist.
Ada, for one example, includes a great deal of ability to tailor code to a specific platform without using a preprocessor like C and C++ do. In fact, it (Ada) arguably supports quite a bit more than C and C++ do in this regard.