M.W. berechnet der Präprozesor nur die Ausdrücke in den #if- und
#elif-Direktiven. In allen anderen Fällen macht er lediglich Text-
ersetzung (Expansion) und das auch nur außerhalb von Präprozessor-
direktiven (also im normalen C-Code).
Was der Compiler im #warning-Text ersetzt, ist Compiler-spezifisch, da
die #warning-Direktive nicht zum Standard gehört. Bei der verwandten
(und standardisierten) #error-Direktive wird nichts expandiert, schon
gar nicht, wenn Anführungszeichen wie in deinem Beispiel verwendet
werden.
Dass beim C18-Compiler das "Error" in der #warning expandiert wird, ist
also schon verwunderlich. Dass der Ausdruck auch noch ausgewertet wird,
ist einfach zuviel verlangt ;-)
Es sei denn, der C18-Compiler hat ein spezielles Feature, das dies
erlaubt. Das sollte dann aber im Handbuch beschreiben sein.