Defining keyword-like macros just for improving code readablity
I think its acceptable. But like Marco said, its fairly subjective.
I think an example of a macro enhancing readability is C++ and NOTHROW. Oddly, specifying throw() means a function does not throw; and opposed to throw (SomeException), which means a function could throw an exception. There's nothing intuitive about declaring something throw() when it does not throw.
Lots of chatter about it on Stack Overflow:
Microsoft defines IN, OUT and INOUT to help with readability and usability. The macros decorate function parameters and are defined to nothing. For example, you might see (I don't have a specific Microsoft example handy):
// Process foo. Reuse baz if possible; reallocate if needed and return size.
// Return TRUE/FALSE as success/failure. Return an error code if result is FALSE.
int FooBarBaz(IN char* foo, IN int flen, INOUT char** baz, INOUT int* blen, OUT int* err);
Related: macros are helpful to abstract platform differences. For example, exporting a function from a shared object (Unix and knock-offs) or dynamic link libraries (Windows).
Related: macros are helpful to abstract configuration differences. For example, the meaning or implementation of ASSERT in debug and release configurations.
Related: hijacking keywords can be helpful. For example, re-defining C++'s protected and private to public can be helpful during testing so a test case can be written against methods that aren't normally accessible.