versiones guia español actualizar objective-c objective-c-blocks

objective c - guia - Tener problemas con el tipo de retorno BOOL en bloques Objective-C



qgis español (3)

Como han dicho otros, la razón por la que está recibiendo el error es que e0 || e1 e0 || e1 devuelve un int independientemente de los tipos de e0 y e1 . Dado que el compilador infiere el tipo de retorno de bloque basado en la (s) declaración (es) de return , tiene un bloque que devuelve int y está intentando asignarlo a una variable de bloque cuyo tipo de retorno de bloque es BOOL .

Personalmente prefiero esta sintaxis:

BoolBlock bar = ^BOOL { return YES || NO };

para evitar el error, dejando en claro que el tipo de retorno de bloque es BOOL . El rvalue, un bloque literal, se entiende como un bloque cuyo tipo de retorno es BOOL y el compilador aplica las conversiones C habituales.

En cuanto a por qué sucede esto, es una decisión de diseño, aunque no parece estar explícitamente documentada. 1 Los bloques son una nueva característica de idioma. Los diseñadores del compilador 2 han decidido que deberían tener una semántica más estricta en los bloques, es decir, la asignación de los tipos de punteros de bloque deben tener tipos estrictamente coincidentes, y aplican esta semántica más estricta cuando asignan un bloque a una variable de bloque, independientemente de que el valor sea un bloque puntero o un bloque literal.

Como no hay bloques de cobertura estándar ISO / IEC en C o C ++, los diseñadores de compiladores son libres de tomar estas decisiones. Apple ha enviado bloques a ISO / IEC JTC1 / SC22 / WG14 como WG14/N1370 y WG14/N1451 y, si lo aceptan, este comportamiento (o alguna variante) debería estandarizarse y documentarse.

1 El código fuente de Clang tiene un comentario que indica que la asignación de punteros de bloque es más estricta que la asignación de punteros de función.

2 Les he preguntado personalmente sobre esto.

Me topé con un curioso problema con el tipo de retorno BOOL en bloques. Teniendo la siguiente definición:

typedef BOOL (^BoolBlock)(void);

... este código pasa:

BoolBlock foo = ^{ return YES; };

... pero esto no se compila:

BoolBlock bar = ^{ return YES || NO; };

Con el siguiente mensaje de error:

Tipos de punteros de bloque incompatibles que inicializan ''BoolBlock'' (también conocido como ''BOOL (^) (void)'') con una expresión de tipo ''int (^) (void)''

Puedo resolver el problema utilizando un reparto explícito, pero ¿no debería funcionar esto sin él? ¿Hay una solución mejor?


Probablemente estás pensando en el || Operador trabaja en idiomas como Ruby y Python, donde regresa en el primer operando que es verdadero. En C, devuelve 1 si cualquiera de los operandos es verdadero y 0 de lo contrario, por eso cree que está devolviendo un entero.


|| El operador devuelve el tipo int como dijo Chuck.

BoolBlock bar = ^{ return (BOOL)(YES || NO); };

o

BoolBlock bar = ^BOOL (void){ return YES || NO; }; BoolBlock bar = ^BOOL (){ return YES || NO; }; // warns in gcc, ok with clang