Недопустимые макросы потока символов

Следующий макрос препроцессора:

#define _VARIANT_BOOL /##/

на самом деле недействителен C; грубо говоря, причина в том, что препроцессор определен как работающий с потоком токенов, тогда как вышеприведенное предполагает, что он работает с потоком символов.

С другой стороны, к сожалению, приведенное выше на самом деле происходит в заголовочном файле Microsoft, поэтому мне все равно приходится с этим справляться. (Я работаю над реализацией препроцессора.)

С какими другими случаями люди сталкивались в дикой природе, будь то в унаследованном коде, каким бы старым он ни был, пока этот код все еще используется, с макросами препроцессора, которые на самом деле недействительны, но все равно работают, потому что они были написаны для компиляторов, которые используют символ ориентированная реализация препроцессора?

(Обоснование: я пытаюсь заранее понять, сколько особых случаев мне придется взломать, если я напишу правильную чистую, соответствующую стандарту реализацию, ориентированную на токен.)


person rwallace    schedule 15.10.2011    source источник
comment
Почему вы должны справиться с этим? Тот факт, что у Microsoft есть нестандартный препроцессор и нестандартные заголовочные файлы, которые используют его преимущества, не означает, что вам нужно с этим справиться.   -  person CB Bailey    schedule 15.10.2011
comment
Ну, цель состоит в том, чтобы создать инструменты, которые могут делать полезные вещи с существующим кодом. Инструменты, которые не могут читать файлы заголовков Microsoft, даже если они имеют моральное превосходство в соответствии со стандартом, будут менее полезными.   -  person rwallace    schedule 15.10.2011
comment
В таком случае я не думаю, что ваш вопрос имеет окончательный ответ. То, что вам нужно поддерживать, полностью зависит от вашего целевого рынка. Если вы пишете препроцессор, совместимый со стандартами, это одно, в противном случае расширения, которые вы должны поддерживать, зависят от того, в каких средах вы собираетесь использовать свой продукт, и это полностью зависит от вас (или полностью открыто).   -  person CB Bailey    schedule 15.10.2011
comment
Я стремлюсь как можно ближе подойти к «любому коду C, который все еще используется в любой среде».   -  person rwallace    schedule 15.10.2011
comment
любой код C, который все еще используется в любой среде. Ты точно шутишь? Это просто огромное количество кода, и вы никогда не получите доступ к 99,99% этого кода, а из оставшейся части лишь незначительное количество проектов когда-либо рассмотрит возможность использования нового инструмента с новым препроцессором.   -  person CB Bailey    schedule 15.10.2011
comment
Я сказал любой, а не все. Конечно, любой данный новый инструмент будет запускаться только на крошечной части кода C, но нет никакого способа узнать заранее, какая часть, и нет причин априори исключать такие куски, как «ничего, что включает заголовки Microsoft».   -  person rwallace    schedule 15.10.2011
comment
Итак, проблема в том, что при склеивании // не является допустимым pp-token?   -  person caf    schedule 16.10.2011
comment
Правильно. Недействительный токен pp, но все равно должен работать.   -  person rwallace    schedule 16.10.2011


Ответы (1)


В соответствующей части стандарта (§6.10.3.3 The ## operator) говорится:

Если результат не является допустимым токеном предварительной обработки, поведение не определено.

Это означает, что ваш препроцессор может делать все, что ему заблагорассудится, и при этом соответствовать стандарту, включая эмуляцию общего поведения.

Я думаю, что вы все еще можете иметь реализацию «на основе токенов» и поддерживать это поведение, указав, что, когда результат оператора ## не является допустимым токеном предварительной обработки, результатом являются два неизмененных токена операнда. Вы также можете захотеть, чтобы ваш препроцессор выдавал предупреждение о недопустимом коде.

person caf    schedule 17.10.2011