while switch sentencia que programacion lenguaje else ejemplos c gcc standards expression

que - sentencia switch en c++



¿Las sentencias compuestas(bloques) están rodeadas de expresiones parens en ANSI C? (2)

Al examinar las fuentes del kernel de Linux, encontré un fragmento de código donde un bloque de enunciados rodeados de paréntesis se trata como una expresión a la lisp (o ML), es decir, una expresión cuyo valor es el valor de la última declaración.

Por ejemplo:

int a = ({ int i; int t = 1; for (i = 2; i<5; i++) { t*=i; } t; });

He estado mirando la gramática de ANSI C tratando de descubrir cómo esta parte del código cabría en el árbol de análisis sintáctico, pero no he tenido éxito.

Entonces, ¿alguien sabe si este comportamiento es obligatorio por el estándar o es solo una peculiaridad de GCC?

Actualización: lo he intentado con el flag-kendic y el compilador ahora me da una advertencia:

warning: ISO C forbids braced-groups within expressions


Esta es una extensión gcc llamada expresiones de declaración , aquí puede encontrar la lista completa de extensiones C. Esta es en realidad una de las muchas extensiones de gcc utilizadas en el kernel de Linux y parece que clang también lo admite y aunque no se menciona explícitamente en el documento.

Como observó que la última expresión sirve como el valor de la expresión, el documento dice (el énfasis es mío ):

Lo último en la declaración compuesta debe ser una expresión seguida de un punto y coma; el valor de esta subexpresión sirve como el valor de la construcción completa . (Si usa algún otro tipo de instrucción al final dentro de las llaves, la construcción tiene tipo vacío, y por lo tanto, no tiene valor).

Uno de los principales beneficios sería crear macros seguros que evitarían múltiples evaluaciones de argumentos con efectos secundarios. El ejemplo dado utiliza esta macro insegura:

#define max(a,b) ((a) > (b) ? (a) : (b))

que evalúa ya sea a o b dos veces y puede reescribirse para eliminar este problema utilizando expresiones de declaración de la siguiente manera:

#define maxint(a,b) / ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

Tenga en cuenta que es necesario utilizar explícitamente int que puede Typeof utilizando otra extensión de gcc Typeof :

#define max(a,b) / ({ typeof (a) _a = (a), _b = (b); _a > _b ? _a : _b; })

Tenga en cuenta que clang también es compatible con typeof .


Se llama "grupo arrinconado dentro de la expresión".

No está permitido por ANSI / ISO C ni C ++, pero gcc lo admite.