代码之家  ›  专栏  ›  技术社区  ›  seaotternerd

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

  •  1
  • seaotternerd  · 技术社区  · 9 年前

    我试图在EM_ASM-style宏中声明一个多元素数组。当我只使用普通的旧EM_ASM时,这很好:

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

    然而,在任何返回值的EM_ASM-style宏中执行此操作似乎会混淆编译器。

    例如:

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

    给我这些错误:

    错误:为类似宏的函数提供的参数太多 调用

    测验cc:4:3:注意:不能在宏参数的开头使用初始值设定项列表

    测验cc:4:3:error:使用未声明的标识符“EM_ASM_INT_V”

    这同样适用于 EM_ASM_INT , EM_ASM_DOUBLE EM_ASM_DOUBLE_V (无论我是否给他们适当的参数和返回)。如果我声明一个单元素数组:

     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页面的相关问题,但找不到任何问题。我是做错了什么,还是这是个bug?有人有更好的解决方法吗?

    1 回复  |  直到 9 年前
        1
  •  1
  •   Charles Ofria    9 年前

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

    我没有看过EM_ASM的定义,但由于它只需要一个参数,我的猜测是,如果它得到了多个参数,它会自动用逗号将它们粘在一起。然而,其他EM_ASM_*宏不知道需要多少参数,因此它们无法做到这一点。

    对于修复,通常可以包含额外的括号。例如,您应该能够使用:

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

    括号不会伤害任何东西,但会将宏参数正确地粘在一起(有时不那么容易,但通常是这样)。

    我知道在预处理器规范中修复这个问题已经是很长一段时间的话题了——希望有一天会这样。当在宏调用中包含模板时,这会变得特别烦人,因为在这种情况下,没有简单的方法将所有内容都括在括号中。

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