在调试我们的一些代码(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]
的文档,我找不到任何文档,说明您可以将逗号分隔的值列表传递给它以及它将如何处理它。
答案 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.aspx或http://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
完全有效。