C++ 使用泛型运算符->*作为右值
汇编过程如下:C++ 使用泛型运算符->*作为右值,c++,templates,arm,iar,C++,Templates,Arm,Iar,汇编过程如下: template <typename T> T GetMember(const T STRUCT_T::* member) { STRUCT_T* pStruct = GetStruct(); ... // read value T retVal = pStruct->*member; // compiler assertion here ReleaseStruct(); return retVal; } 与
template <typename T> T GetMember(const T STRUCT_T::* member)
{
STRUCT_T* pStruct = GetStruct();
...
// read value
T retVal = pStruct->*member; // compiler assertion here
ReleaseStruct();
return retVal;
}
与非基本类型T一起使用时,由于编译器断言而结束:
template <typename T> void SetMember(T STRUCT_T::* member, const T& value)
{
STRUCT_T* pStruct = GetStruct();
...
// write value
pStruct->*member = value; // no compiler assertion here
ReleaseStruct();
}
刀具内部错误:
内部错误:[前端]:断言在以下位置失败:
....\Translator\compiler\u core\src\parser\edg\lower\u il.c,第13411行
IAR编译器的lower_il.c至少有13411行,其中非一行是正确的泛型运算符->*,这一事实让我感到震惊,我发现以下函数使用非基本类型T编译更为奇怪:
template <typename T> void SetMember(T STRUCT_T::* member, const T& value)
{
STRUCT_T* pStruct = GetStruct();
...
// write value
pStruct->*member = value; // no compiler assertion here
ReleaseStruct();
}
我猜泛型运算符的结果可以作为左值,但不能作为右值。取消对参数的约束没有帮助
有什么原因和解决方案吗?我们可以从edg\lower_il.c看出,这是edg前端,而不是专有的IAR解析器。EDG得到了很好的维护和尊重,您可以随时使用更新的版本。从编译器菜单中选择ICC
文件名表明它正在处理较低级别的中间表示,而不是构建初始AST。将指向成员访问的指针转换为更基本的操作可能会出现问题。或者标志可能出现在错误的行上。内部错误并不总是精确的。一个更好。IAR service pack 6.70.2解决了这个问题。除了升级编译器,没有解决内部编译器错误的方法。您在这里所能期望的最好的解决方法是,这看起来像是一个解析器错误。尝试使用不同的语法执行相同的操作,例如T retValpStruct->*成员、T&retVal=pStruct->*成员或const T retValPtr*=&pStruct->*成员。简言之,请采取措施诱使编译器采用不同的代码路径,避免断言。T retVal=*&pDbAppDynamic->*成员起作用@dasblinkenlight非常感谢你。我仍然对如何发生这种情况感兴趣。C++编译器非常复杂,对于C++编译器来说,13K行不是很多。和大多数大型程序一样,编译器也有bug,这一点也不奇怪。你只是碰巧找到了其中一个。如果你可以构建一个小型测试用例来公开它,那么就把它通过电子邮件发送给编译器制造商:考虑到你已经找到了一个解决方法,这应该是一个简单的修复方法。现在手工维护解析器文件是非常罕见的:解析器生成器已经成为大约四十年的标准。解析器代码生成器生成大量代码——我看到了从10:1到25:1的比率,也就是说,对于每行lex/yacc/antlr/javacc代码,您可以得到10到25行生成的C/Java/C/等代码。但是,生成的代码都不是手工维护的:而是修改解析器源代码,然后再次运行生成器。