Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


4.10.5  Sentencias de expresiones con coma

§1  Sinopsis

En ocasiones las sentencias contienen expresiones con coma, que describimos a continuación; convirtiéndose así en bloques de código, ya que cada subexpresión de la expresión con coma se ejecuta como una entidad separada.

§2  Expresiones con coma

Las expresiones con coma son conjuntos de subexpresiones separadas por coma, que aquí es un operador ( 4.9.5), y agrupadas por paréntesis. Cada subexpresión se evalúa una a continuación de otra empezando por la izquierda, el resultado es el valor de la última.

Ejemplos

sum = (i = 3, i++, i++);    // sum = 4, i = 5
func(i, (j = 1, j + 4), k); // llama func con 3 argumentos (i,5,k) no 4
func(i, j);                 // llama func con dos argumentos
func((exp1, exp2), (exp3, exp4, exp5)); // ídem con dos argumentos


Los siguientes pares de expresiones son equivalentes:

(a, b) += 12;
(a, b += 12);
 
&(a, b);
(a, &b);

Nota: no deben confundirse la expresiones con coma, de las que separan los parámetros de las funciones (donde la coma se usa como puntuador 3.2.6). Aunque es legal mezclar ambos usos, para evitar ambigüedades, es necesario emplear paréntesis, como en los ejemplos anteriores.

§3  Comentario

Como una pincelada de los usos que pueden darse a estas expresiones, a continuación mostramos un ejemplo tomado de un caso real, encontrado en un programa Windows de un reconocido autor.  En el fuente leemos las siguientes sentencias (sin ninguna explicación adicional):

case WM_DESTROY:     // Window is being destroyed
     return HANDLE_WM_DESTROY (hwnd, wParam, lParam, mainFrame_OnDestroy);

aquí los valores hwnd, wParam y lParam están perfectamente identificados (son frecuentísimos en los programas que utiliza la API de Windows), pero la expresión en sí misma resulta un tanto extraña, ya que aparenta ser la invocación de una función cuyo nombre es inusual (parece una constante), y en principio HANDLE_WM_DESTROY no aparece en ninguna otra parte del fuente ni en la documentación de la API de Windows. Por su parte, mainFrame_OnDestroy es una función cuya definición en el mismo fuente, tiene el siguiente aspecto:

static void mainFrame_OnDestroy (HWND hwnd) {
  /* ... */
}

Una búsqueda más concienzuda nos muestra que HANDLE_WM_DESTROY es un define situado en el fichero de cabecera windowsx.h:

#define HANDLE_WM_DESTROY(hwnd, wParam, lParam, fn) ((fn)(hwnd), 0L)

En consecuencia, una vez que el pre-procesador ha realizado las sustituciones oportunas, las sentencias originales se traducen en:

case WM_DESTROY:     // Window is being destroyed
     return (mainFrame_OnDestroy(hwnd), 0L);

La segunda línea es una expresión con coma, cuya primera subexpresión es una invocación a mainFrame_OnDestroy, y la segunda es un long de valor cero (0L), que es el resultado (el valor realmente devuelto). Así pues, las sentencias originales equivalen a lo siguiente:

case WM_DESTROY:     // Window is being destroyed
     mainFrame_OnDestroy (hwnd);
     return 0L;