reinterpret_cast strangeness(逗号分隔表达式)

时间:2013-08-16 09:09:24

标签: c++

在调试我们的一些代码(C ++)时,我发现了这个:

inline std::string BufferToStr(
    const unsigned char* buffer,
    int index,
    size_t length)
{
   std::string retValue(reinterpret_cast<const char*>(&buffer[index], length));
   return retValue;
}

此代码的问题(忽略缺少指针和字符串长度检查)是reinterpret_cast的右括号已经放在length之后,它应该在{{1}之后。 }。起初我认为这是编译器的一个问题(使用VS2013),但在使用VS2012和gcc 4.6.3成功编译之后,我得出结论,这是出于某种原因允许的。代码不能在Windows或Linux上运行,因为length参数用作指针。

所以我的问题是为什么要编译?查看&buffer[index]的文档,我找不到任何文档,说明您可以将逗号分隔的值列表传递给它以及它将如何处理它。

5 个答案:

答案 0 :(得分:12)

reinterpret_cast接受expression。括号中的内容是一个表达式 - "," operator有两个子表达式,它们将计算出最后一个子表达式的结果。

答案 1 :(得分:7)

这是由于c / c ++中的comma operator。代码(表达式):

(&buffer[index], length)

相当于(&amp; buffer [index]不起作用):

(length)

所以你的代码相当于:

inline std::string BufferToStr(const unsigned char* buffer, int index, size_t length)
{
   std::string retValue(reinterpret_cast<const char*>(length));
   return retValue;
}

答案 2 :(得分:4)

它是comma operator。它评估逗号两边的表达式,但返回右侧表达式的结果。

编译器没有抱怨的原因是因为你简单告诉编译器表达式(类型size_t)的结果应该被视为const char*表达式。这就是reinterpret_cast的作用,它允许几乎任何类型的几乎任何类型的转换,无论它多么愚蠢。

答案 3 :(得分:3)

reinterpret_cast < new_type > ( expression )        

reinterpret_cast接受expression。这里有一个逗号运算符,它可以计算两边的表达式并返回正手表达式。

事实上,(&buffer[index], length)这个词在这里等同于(length)

请参阅:http://msdn.microsoft.com/en-us/library/zs06xbxh.aspxhttp://en.wikipedia.org/wiki/Comma_operator以获取逗号运算符说明。

总而言之,在这里,您要告诉编译器将size_t(表达式的结果)转换为const char*并且它可以执行此操作。

答案 4 :(得分:2)

这是为什么启用警告很重要的原因之一,它可能会帮助您自己解决这个问题。使用gcc并与-Wall一起运行,这是我收到的警告:

 warning: left operand of comma operator has no effect [-Wunused-value]
 std::string retValue(reinterpret_cast<const char*>(&buffer[index], length));
                                                                  ^

您可以看到live example

警告告诉我们,我们首先使用comma operator这可能有点令人费解,但reinterpret_cast不是函数调用,如果不使用括号,这将无法工作,我们可以看到{ {3}},但是表达式和C ++标准草案的5.2 Postfix表达式 postfix-expression 的语法包含:

postfix-expression:
   ...
   reinterpret_cast < type-id > ( expression )
   ...

我们可以在参数中使用expression,因此comma operator完全有效。