Поскольку
1: #include <iostream>
2:
3: #define FOO std::cout << __LINE__ << ' ' \
4: << __LINE__ << '\n';
5: int main()
6: {
7: FOO // the first two __LINE__s come from here, that's one line of code
8:
9: std::cout << __LINE__ << ' ' \ // 3rd __LINE__ comes from here
10: << __LINE__ << '\n'; // 4th __LINE__ comes from here
11: }
__LINE__
расширяется до физических строк, а не логических строк:
номер строки текущей строки источника равен единицебольше, чем число символов новой строки, прочитанных или введенных на этапе 1 (2.2) перевода при обработке исходного файла в текущий токен.
В то время как строки, заканчивающиеся на \
, объединяются в переводеФаза 2.
Другой единственной логической реализацией было бы напечатать 3 и 4 для вызова FOO, но это кажется не очень полезным.
Вы также можете посмотреть на это следующим образом:__LINE__
ничем не отличается от любого другого макроса.Он просто автоматически обновляется компилятором в начале каждой строки.Таким образом, код как бы интерпретируется следующим образом:
#include <iostream>
#define __LINE__ 3
#define FOO std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
int main()
{
#define __LINE__ 7
FOO
#define __LINE__ 9
std::cout << __LINE__ << ' ' \ // Yeah, you're right
#define __LINE__ 10
<< __LINE__ << '\n';
}
Это неверный код, но он демонстрирует, как все работает.Примените обычные правила расширения макросов, и вы получите полученный результат.