нестандартное поведение препроцессора msvc 2010

Тема в разделе "LANGS.C", создана пользователем jabocrack, 23 янв 2011.

  1. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    ну ето конечно баян. Тока я уже задолбался копать в гугле.
    хочу узнать в каком порядке и в какую последовательность раскроется вызов макроса __drv_functionClass, если используется msvc.
    Код (Text):
    1. #define __drv_functionClass(x) __drv_out(__drv_declspec("SAL_functionClass(\""#x"\")"))
    2. #define __drv_out(annotes) __post __$drv_group(##__drv_nop(annotes))
    3. #define __drv_declspec(x) __declspec(x)
    вот например:
    "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinNT.h" , line 1202
    __drv_functionClass(EXCEPTION_ROUTINE)

    по стандарту процесс идет примерно в такой последовательности(если ниче не путаю):

    1.замещение макроса __drv_functionClass
    2.обрабатываем оператор # __drv_out(__drv_declspec("SAL_functionClass(\"EXCEPTION_ROUTINE\")"))
    3. раскрываем макрос __drv_out
    __post __$drv_group(##__drv_nop(annotes))
    здесь встречается оператор склеивания, но рядом с ним нет параметра для склеивания. Вот здесь и спотыкаются левые препроцессоры( если честно, они спотыкаются и на знаке $). Обычно они выдают ошибку, что (__drv_nop не является preprocessing token.
     
  2. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    Код (Text):
    1. #define __drv_nop(x) x
    2. #define __$drv_group(annotes) __drv_declspec("SAL_begin") annotes __drv_declspec("SAL_end")
    соответсвенно.
     
  3. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    По ходу дела возник след вопрос. Относится ли пример из предыдущего поста к правилу из стандарта 9899:1999 6.10.3.11 "If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined."
     
  4. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    сам себе отвечу:) Не является, так как ## - это не директива препроцессора. а оператор в макроподстановке.
     
  5. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    как я понимаю, такая чехарда с предварительной подготовкой исходного текста для компиляции (preprocessing), связана с тем, что не соблюдаются шаги трансляции. в стандарте определена след последовательность.
    1. нормализуется буквенное отображение исходного текста ( убираются триграфы и тп)
    2. соединяются логические строки текста.
    3. текст разбирается на единицы (pp tokens) и нули(whitespaces). Комментарии замещаются нуликом. Знаки конца строки сохраняются.
    4. обрабатываются директивы препроцессора, выполняются макроподстановки. в конце етой фазы директивы и макросы удаляются.
    Ост фазы я пропускаю. Итак в лучшем варианте все ето должно происходить последовательно в несколько проходов. Но в действительности все ети шаги выполняются за 1 проход по исходному тексту.
    ---------------
    Еще раз акцентирую внимание, что 4 фаза принимает на вход разобранный на единицы препроцессора текст, а не сырую последовательность букв.
    Препроцессор воспринимает на входе след.:
    - имя заголовочного файла
    - идентификатор
    - буква-константа
    - число
    - строка
    - знаки препинания
    - и все ост. в виде отдельного буквенного знака
     
  6. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    В свете информации из предыдущего поста.
    После слияния ( и __drv_nop получаем (__drv_nop, который не является единицей препроцессора. 6.10.3.3.3 гласит, что "If the result is not a valid preprocessing token, the behavior is undefined."
    Получается, что препроцессор msvc в нестандартном режиме воспринимает на вход не только pp_tokens, но и сырой неразобранный текст.
    Остялось тока выяснить, pp msvc выполняет вызов __drv_nop до или после выполнения оператора ##.
     
  7. jabocrack

    jabocrack New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    96
    Сейчас уже не нужно. Вопрос остался, но я обошел его другим путем.