Valor de retorno desde el ámbito local?

Me topé con un código como este en nuestra base de códigos … lo que me preocupó.

int foo(int a); // Forward declaration. int baz() { int result = { int a = dosomestuff(); foo(a); } ? 0 : -1; return result; } 
  1. ¿Está bien definido el comportamiento de este código?
  2. ¿Funcionará realmente, esa variable de result se carga con 0 o -1 dependiendo del valor de retorno de foo(a) ?

Para interés: el código no se escribió así originalmente; sin embargo, es lo que imagino que esta macro de apariencia inocente se desplegará en …

 int foo(int a); // Forward declaration. #define BAR() { int a = dosomestuff(); foo(a); } int baz() { int result = BAR() ? 0 : -1; return result; } 

Esta es una extensión de GCC a C llamada ‘expresiones de statement’: http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

La clave es que una expresión de statement devuelve lo último que hace como el valor de la expresión:

Lo último en la statement compuesta debe ser una expresión seguida de un punto y coma; el valor de esta subexpresión sirve como el valor de toda la construcción.

En tu ejemplo, eso sería lo que foo(a) devuelva.

Sin embargo, el bloque se debe incluir entre paréntesis para que GCC acepte la syntax.

 int foo(); // Forward declaration. int baz() { int result = ({ int a = dosomestuff(); foo(a); }) ? 0 : -1; return result; } 

No conozco ningún otro comstackdor que soporte esto.

Tendrías que consultar la documentación de tu comstackdor. Esta construcción no está permitida en el estándar C o el estándar C ++.

Es trivial para limpiar esto sin embargo, por ejemplo

 int baz() { int result; { int a = dosomestuff(); result = foo(a)? 0: -1; } return result; } 

No sé de un solo comstackdor que acepte eso. Además, sería mejor hacer esto:

 int foo(); int dosomestuff(); int baz() { int result = foo(dosomestuff()) ? 0 : -1; return result; } 

No es estándar C ++.

En el estándar C ++, escriba

 bool baz() { return !foo( dosomestuff() ); } 

Eso es.

Debido a que es un tipo simple sin puntero, se devolverá el valor exacto y se definirá el comportamiento de retorno. Ese bloque es … realmente extraño, y me sorprende que haya un comstackdor de C que no se ahogue con eso.

Con C ++ 11 puedes acercarte bastante:

 int foo(int a); // Forward declaration. int baz() { int result = []{ int a = dosomestuff(); return foo(a); }() ? 0 : -1; return result; }