De hecho , depende de su interpretación del estándar de idioma. Por ejemplo, bajo mCPP, una implementación del preprocesador que se ajusta estrictamente al texto de la lengua estándar, los segundos rendimientos CAT(x, y);
así como [nuevas líneas adicionales se han eliminado a partir del resultado]:
C:\dev>mcpp -W0 stubby.cpp
#line 1 "C:/dev/stubby.cpp"
CAT(x, y) ;
CAT(x, y) ;
C:\dev>
Hay a known inconsistency en el C++ Especificación del lenguaje (la misma incoherencia está presente en la especificación C, aunque no sé dónde está la lista de defectos para C). La especificación establece que el CAT(x, y)
final no se debe reemplazar en macro. La intención puede haber sido que debería ser macro-reemplazado.
citar el informe de defectos vinculados:
Ya en la década de 1980 se entiende por varios WG14 personas que no eran pequeñas diferencias entre la verborrea "no sustitución" y los intentos de producir pseudo-código.
La decisión del comité fue que ningún programa realista "en la naturaleza" se aventuraría en esta área, y tratar de reducir las incertidumbres no justifica el riesgo de cambiar el estado de cumplimiento de las implementaciones o programas.
Entonces, ¿por qué obtenemos un comportamiento diferente para M(0)
N(0)
que para la mayoría de las implementaciones del preprocesador comunes? En la sustitución de M
, la segunda invocación de CAT
consiste enteramente de tokens resultantes de la primera invocación de CAT
:
M(0)
CAT(M_, 0)
CAT_I(M_, 0)
M_0
CAT(x, y)
Si M_0
lugar se definió para ser sustituido por CAT(M, 0)
, la sustitución sería recurse infinitamente. La especificación del preprocesador prohíbe explícitamente esta sustitución "estrictamente recursiva" al detener la sustitución de macro, por lo que CAT(x, y)
no se reemplaza macro.
Sin embargo, en la sustitución de N
, la segunda invocación de CAT
consiste sólo parcialmente de tokens resultantes de la primera invocación de CAT
:
N(0)
CAT(N_, 0) ()
CAT_I(N_, 0) ()
N_0 ()
CAT(x, y)
CAT_I(x, y)
xy
Aquí la segunda invocación de CAT
se forma parcialmente a partir de tokens resultante de la primera invocación de CAT
y parcialmente de otros tokens, a saber, el ()
de la lista de reemplazo de N
. El reemplazo no es estrictamente recursivo y, por lo tanto, cuando se reemplaza la segunda invocación de CAT
, no puede producir recursión infinita.
Uhhh ... ¿qué es exactamente lo que está tratando de lograr aquí ... y con qué propósito? – t0mm13b
Realmente no quiero lograr nada, solo noté esto mientras trabajaba en algo, y tengo curiosidad sobre las razones. Me molesta cuando no entiendo algo :). – imre