在 EM_ASM_INT 内声明多元素数组会中断编译

Declaring multi-element array within EM_ASM_INT breaks compilation

我正在尝试在 EM_ASM-style 宏中声明一个多元素数组。当我只使用普通的旧 EM_ASM:

时,这很好用
EM_ASM({var a = [1,2];});

但是,在任何 EM_ASM-style 宏中执行此操作 return 一个值似乎会使编译器感到困惑。

例如:

 EM_ASM_INT_V({var a = [1,2]; return 1;});

给我这些错误:

error: too many arguments provided to function-like macro invocation

test.cc:4:3: note: cannot use initializer list at the beginning of a macro argument

test.cc:4:3: error: use of undeclared identifier 'EM_ASM_INT_V'

EM_ASM_INTEM_ASM_DOUBLEEM_ASM_DOUBLE_V也是如此(不管我是否给他们适当的参数和return)。如果我声明一个 1 元素数组:

 EM_ASM_INT_V({var a = [1]; return 1;});

一切都很好。这也发生在大括号括起来的 Javascript 对象中——单个元素(例如 {val1: 1})很好,但超过那个(例如 {val1: 1, val2: 2})会给我同样的错误。

我当前的解决方法是单独将其他元素推送到数组:

 EM_ASM_INT_V({var a = [1];
               a.push(2); 
               return 1;});

这行得通,但是很笨重。

我检查了 Emscripten github 页面的相关问题,但没有找到。我做错了什么,或者这是一个错误?谁有更好的解决方法?

我认为问题与宏调用中的逗号有关。括号内的逗号会被忽略,但大括号、方括号或尖括号内的逗号不会被忽略,因此它将您的第一个参数分成两个:{var a = [12]; return 1;},这显然是有问题的。

我没有看过 EM_ASM 的定义,但由于它只需要一个参数,我的猜测是如果它有多个参数,它会自动用逗号将它们粘在一起。然而,其他 EM_ASM_* 宏不知道期望有多少个参数,所以他们不能这样做。

至于修复,您通常可以添加额外的括号。对于您的示例,您应该能够使用:

EM_ASM_INT_V({var a = ([1,2]); return 1;});

圆括号不会在那里造成任何伤害,但会使宏参数正确地粘合在一起(有时不是那么容易,但通常是这样)。

我知道在预处理器规范中解决这个问题已经讨论了很长时间——希望有一天会实现。在宏调用中包含模板时,这变得特别烦人,因为在这些情况下没有简单的方法将所有内容括在括号中。

编辑:我检查了 EM_ASM 定义,实际上它是一个可变参数宏,将参数粘合在一起。