Debido
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__
expande a líneas físicas, líneas no lógicos:
El número línea de la línea de fuente de corriente es uno mayor que el número de la nueva línea de caracteres leídos o introducido en la fase de traducción 1 (2.2) mientras se procesa el archivo fuente al token actual.
Mientras que las líneas que terminaron por \
se concatenan en fase de traducción 2.
La otra aplicación lógico sería imprimir 3 y 4 para la invocación de FOO, pero eso no parece muy útil.
También puede ver esto de la siguiente manera: __LINE__
no es diferente de cualquier otra macro. Se acaba de actualizar automáticamente por el compilador al comienzo de cada línea. Así que el código es una especie de interpretarse de esta manera:
#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';
}
Esto no es un código válido, pero demuestra cómo funcionan las cosas. Aplique las reglas de expansión macro habituales y obtendrá la salida que tiene.
+1, descripción muy clara –
¿Y esto está garantizado por la norma? ¡Eso seria genial! Tengo algunas macros bastante grandes que contienen múltiples tokens '__LINE__', y realmente me gustaría dividirlas con barras diagonales inversas, aunque deben ceder la misma línea cuando se expanden. – fredoverflow
@FredOverflow Sí. – ybungalobill