Browse Source

preparser_serializer: json: fix anonymous struct in for-loop initializer

The json_array_foreach_ref macro declares an anonymous struct type
inside a for-loop initializer:

    for (struct { size_t i; const struct json_array *a; } idx = ...

C11 6.8.5p3 constrains the for-loop initializer to only declare
objects with auto or register storage class — in other words, it is
only meant to create loop variables, not to define new types. However,
writing `struct { ... } x = ...;` does two things at once: it defines
a new type (the anonymous struct) and declares a variable.

In C11 standard 6.2.1, struct tags declared inside a for-loop
initializer get block scope of the enclosing block, so the type
definition escapes the for-loop, violating the "only objects"
constraint.

Extract the anonymous struct into a named struct json_array_iter
defined before the macro, so the for-loop initializer only declares a
plain object of an already-existing type.

Clang on armv7 iOS (via xcode-cross) enforces this constraint strictly
and rejects the original code with "declaration of non-local variable in
'for' loop".
pull/199/head
Alexandre Janniaux 6 months ago
committed by Jean-Baptiste Kempf
parent
commit
ff8f491bc4
  1. 7
      modules/misc/preparser_serializer/json/fromjson.c

7
modules/misc/preparser_serializer/json/fromjson.c

@ -360,11 +360,16 @@ static inline bool json_object_to_boolean(const struct json_object *obj,
* Macro definition
*/
struct json_array_iter {
size_t i;
const struct json_array *a;
};
/* Get the array with `name` as a key, if there is not array with this key set
* `error` to true and don't start the loop, else iterate over the array and
* set `item` to the current value each round. */
#define json_array_foreach_ref(obj, name, item, error) \
for (struct { size_t i; const struct json_array *a; } \
for (struct json_array_iter \
idx_##item = { 0, json_get_array(obj, name) }; \
((idx_##item.a != NULL || (*(error) = true, false)) && \
idx_##item.i < idx_##item.a->size && \

Loading…
Cancel
Save