2010-10-31 22 views
5

Bastante claro en el título, creo. No estoy del todo seguro sobre esto, y no puedo encontrar una buena respuesta a través de los Googles (por desgracia, no he comprometido con el arte de las normas-fu), por lo que pido:Es "int i = x ++, j = x ++;" ¿legal?

int i = x++, j = x++; 

¿Esto está definido? Estoy bastante seguro de que i = x++, j = x++; como comportamiento normal sería indefinido es el operador de coma, que es un punto de secuencia y sería legal, pero ninguna fuente es bastante clara sobre si un inicializador finaliza en el punto y coma o una vez la siguiente variable comienza a declararse, y como ese no es el operador de coma en uso, no puedo encontrar una respuesta clara. Por lo tanto, a) la coma termina el inicializador, es un punto de secuencia y funciona, o b) no. ¿Cuál es?

Y para impedir, sé que debería simplificar el dolor de cabeza y simplemente escribir como:

int i = x++; 
int j = x++; 

y garantizar que se define. Estoy pidiendo más por curiosidad.

Respuesta

11

El final de un inicializador es un punto de secuencia por lo que el ejemplo en el título es legal.

El operador de coma también es un punto de secuencia para que su "declaración normal" sea también legal y bien definida.

The wikipedia article has a list of the C and C++ sequence points.

Para dar seguimiento a un comentario más abajo, he aquí una demostración del poder temible del operador coma, como se conserva en stdio.h de FreeBSD (bajo ifndef __GNUC__):

/* 
* This has been tuned to generate reasonable code on the vax using pcc. 
*/ 
#define __sputc(c, p) \ 
     (--(p)->_w < 0 ? \ 
       (p)->_w >= (p)->_lbfsize ? \ 
         (*(p)->_p = (c)), *(p)->_p != '\n' ? \ 
           (int)*(p)->_p++ : \ 
           __swbuf('\n', p) : \ 
         __swbuf((int)(c), p) : \ 
       (*(p)->_p = (c), (int)*(p)->_p++)) 
#endif 
+0

Leí el artículo de la wiki, pero no lo suficiente como para registrar el bit del operador de coma. (Inconsistencias malditas.) De todos modos, GCC nunca me hizo ninguna advertencia y siempre funcionó, así que de alguna manera asumí que sí. –

+0

Antes de la extensión de expresión de sentencia de GCC ('({declaraciones ...; valor})' el operador de coma era la principal forma de crear macros realmente complejas (por ejemplo, putc de stdio). –

+0

No me gustaría ver 'putc()' definido de esa manera. Ese camino solo puede conducir a la locura. –

-5

eso es una pregunta capciosa. si hubiera escrito:

int i = 0, j = 0, x = 10; 
i = x++, j = x++; 

yo hubiera dicho: es indefinido. (Varios C y C++ normas que mantienen undfined)

Pero en un inicializador no estoy seguro; D OFC que había llegado a la conclusión que es allí indefinido así, pero quién sabe ...

Angelo

+0

I era incorrecto: el operador de coma es un punto de secuencia. (¿Para qué lo usaríamos si 'f(), g()' donde 'f()' y 'g()' son ambos 'puts (__ FUNC __)' no definidos ¿comportamiento?) Mi pregunta sigue en pie, pero me hacen creer que es incorrecta. –

+3

-1 para una respuesta incorrecta. El operador de coma es un punto de secuencia. –

+0

¿Por qué motivo se moderó mi respuesta? ¡Eso es injusto! Después de todo, no dije que ES ASÍ, pero dio mis "pensamientos" y proceso de pensamiento. Suspiro ... –

Cuestiones relacionadas