Как `int main (int argc, char * argv <::>)` действительная подпись main?
Я видел на сайте, что int main(int argc, char* argv<::>)
также может использоваться как подпись main
. Удивительно, Следующая программа:
int main(int argc, char* argv<::>)
{
return 0;
}
компилирует все предупреждения в GCC, а также clang. Он также компилируется в С++.
Итак, как получилось, что int main(int argc, char* argv<::>)
является допустимой сигнатурой main
?
Ответы
Ответ 1
char* argv<::>
эквивалентен char* argv[]
. <:
и :>
, используемые здесь, являются орграфами.
C11: 6.4.6 (p3):
Во всех аспектах языка шесть токенов 79)
<: :> <% %> %: %:%:
ведут себя соответственно так же, как шесть токенов
[ ] { } # ##
за исключением их правописания. 80)
Примечание для нот:
79). Эти жетоны иногда называют "орграфами".
80) Таким образом, [
и <:
ведут себя по-разному, когда "строятся" (см. 6.10.3.2), но в противном случае могут свободно меняться.
Пример:
%: define stringize(a) printf("Digraph \"%s\" retains its spelling in case of stringization.\n", %:a)
Вызов макроса
stringize( %:);
напечатает
Digraph "%:" retains its spelling in case of stringization.
Ответ 2
<:
и :>
являются орграфами; они эквивалентны соответственно [
и ]
.
Я считаю, что их единственное использование в реальной жизни - это создание запутанного кода, такого как тот, который вы представляете, но они являются частью стандарта C99, предназначенного для замены еще более неуклюжих триграфов, которые были на C почти навсегда.
Первоначальное намерение состояло в том, чтобы помочь программистам, работающим с национальными наборами символов, которым не хватало определенных знаков препинания. Поскольку в настоящее время довольно редко встречается среда, которая не поддерживает (по крайней мере) восьмибитные наборы символов, позволяя таким символам, как Ä, сосуществовать с [, проблема в основном спорная. Но обратная совместимость по-прежнему считается необходимой.