2010-11-27 3 views
9

Я не понимаю, выхода следующей программы:Когда начинается новый запуск __LINE__?

#include <iostream> 

#define FOO std::cout << __LINE__ << ' ' \ 
         << __LINE__ << '\n'; 
int main() 
{ 
    FOO 

    std::cout << __LINE__ << ' ' \ 
       << __LINE__ << '\n'; 
} 

Первый выход 7 и 7, что свидетельствует о том, что расширение FOO представляет собой один логические линии, а второй выход 9 и 10, указывая две различные логические линии. Почему существует разница?

ответ

5

Поскольку

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'; 
} 

Это не правильный код, но он показывает, как работают вещи. Примените обычные правила расширения макросов, и вы получите полученный результат.

+0

+1, очень четкое описание – 2010-11-27 11:27:58

2

вызывают то, что вы определяете в инструкции #define, которая всегда оценивалась как одна строка. Однако второй случай - это действительно две строки кода.

3

Потому что #define расширение содержит хакерство, чтобы убедиться, что __LINE__ - это тот, где макрос «вызывается». В противном случае много сообщений об ошибках не имеет смысла для пользователя.

+2

Это не хакерство. Он ведет себя как любой другой макрос, который вы `# define` перед расширением` FOO` и используете внутри `FOO`. Единственная особенность с `__LINE__` заключается в том, что она автоматически обновляется в начале каждой строки. – ybungalobill 2010-11-27 11:07:16

0

Замещение Foo требует оценки предопределенной директивы _ _LINE _ _. Это, как я понимаю, потому, что нет второго прохода предварительной обработки для оценки _ _LINE _ _.

Отсюда _ _ _ _LINE оценивается на основе линии, на которой Foo в настоящее время expaned, который линия 7.

Использование _ _ _ _LINE в последующей строке в коде действительно оценивается во время фаза предварительной обработки на основе точного номера строки, который он показывает в исходном коде в блоке перевода.

Смежные вопросы