Ответ 1
Почему
\?
один из символов escape-последовательности?
Поскольку он является особенным, ответ приводит к Trigraph, препроцессор C/С++ заменяет следующую трехсимвольную последовательность на соответствующий одиночный знак. (C11 §5.2.1.1 и С++ 11 §2.3)
Trigraph: ??( ??) ??< ??> ??= ??/ ??' ??! ??-
Replacement: [ ] { } # \ ^ | ~
Trigraph теперь почти бесполезен, в основном используется для запутанных целей, некоторые примеры можно увидеть в IOCCC.
gcc по умолчанию не поддерживает триграф и будет предупреждать вас, если в коде есть триграф, если только опция -trigraphs
3 включен. В опции -trigraphs
второй \?
полезен в следующем примере:
printf("\?\?!\n");
Вывод будет |
, если ?
не экранирован.
Для получения дополнительной информации о триграфе см. Cryptic line "??!??!" в устаревшем коде
Почему не выполняется экранирование
?
работает нормально, там даже не предупреждение.
Потому что ?
(и двойная кавычка "
) могут быть представлены сами по себе стандартом:
C11 §6.4.4.4 Символьные константы Раздел 4
Двойная кавычка
"
и вопросительный знак?
представляются либо сами по себе, либо escape-последовательностями\"
и\?
, соответственно, но одинарная кавычка'
и обратная косая черта\
должны быть представлены соответственно управляющими последовательностями\'
и\\
.
Аналогично в С++:
С++ 11 §2.13.2 Символьные литералы Раздел 3
Некоторые неграфические символы, одинарная кавычка
’
, двойная кавычка"
, вопросительный знак?
и обратная косая черта\
, могут быть представлены в соответствии с таблицей 6. Двойная кавычка"
и знак вопроса?
, могут быть представлены как сами или управляющие последовательности\"
и\?
соответственно, но одинарная кавычка’
и обратная косая черта\
должны быть представлены escape-последовательностями\’
и\\
соответственно. Если символ, следующий за обратным слэшем, не является одним из указанных, поведение undefined. Управляющая последовательность задает один символ.