Реализация C не заменяет макрос A()
до тех пор, пока не увидит закрывающий )
. Это )
появляется в строке 8, так что это точка, в которой происходит замена макроса.
Особенности __LINE__
в отношении замены макросов не очень хорошо определены стандартом C. Вы, вероятно, не должны полагаться на конкретное поведение здесь. Конечно, реализация C не может заменить макрос A()
, пока он читает только до строки 7, поскольку еще не знает, что будет. Как только он увидит закрывающий )
, тогда, когда он заменяет макрос, он может считать, что замещающие токены встречаются в строке 7, в строке 8 или в некоторой смеси - стандарт C не является специфическим в этом отношении; Номера строк в значительной степени не имеют отношения к семантике C на данном этапе, и макрос __LINE__
в значительной степени удобен для отладки и других разработок, а не для производственных программ (хотя он может иметь некоторое использование для них).
В printf
реализация C распознает макрос __LINE__
, как только видит конец строки. (На самом деле, синтаксический анализ более сложен; входные данные были токенизированы, но эффект заключается в том, что токен __LINE__
распознается при проверке символа конца строки.) Он находится в строке 9, поэтому он заменяется на 9
. То, что это аргумент printf
, не имеет значения. Реализация C не имеет процесса printf
для замены токена __LINE__
, который появляется в строке 9; они не взаимодействуют.