联合数组的别名
这是此问题的后续问题。
以下代码位于编译器资源管理器上。
#include <stddef.h>
#include <stdint.h>
union my_type
{
uint8_t m8[8];
uint16_t m16[4];
uint32_t m32[2];
uint64_t m64;
};
void my_copy(uint32_t volatile *restrict dst, uint32_t const *restrict src, size_t const count)
{
for (size_t i = 0; i < count / 8; ++i)
{
*dst++ = *src++;
*dst++ = *src++;
}
}
int main(int argc, char *argv[])
{
union my_type src[100];
union my_type dst[200];
my_copy(dst[42].m32, src[10].m32, sizeof(union my_type) * 60);
return 0;
}
虽然 my_copy 看起来很人为,但访问模式是由硬件强制的(必须对连续对齐的位置进行 2x 32 位写入)。其余的丑陋之处是由相隔几年的不同开发人员编写的几段代码的交集造成的。
问题是,传递给 my_copy
的参数有问题吗?如果这只是复制一个union my_type
,我相信就可以了。不过,我不知道复制数组是否有效。
This is a follow-up question to this question.
The following code is on Compiler Explorer.
#include <stddef.h>
#include <stdint.h>
union my_type
{
uint8_t m8[8];
uint16_t m16[4];
uint32_t m32[2];
uint64_t m64;
};
void my_copy(uint32_t volatile *restrict dst, uint32_t const *restrict src, size_t const count)
{
for (size_t i = 0; i < count / 8; ++i)
{
*dst++ = *src++;
*dst++ = *src++;
}
}
int main(int argc, char *argv[])
{
union my_type src[100];
union my_type dst[200];
my_copy(dst[42].m32, src[10].m32, sizeof(union my_type) * 60);
return 0;
}
While my_copy
looks contrived, the access pattern is forced by hardware (must have 2x 32-bit writes to consecutive aligned locations). The rest of the ugliness is due to the intersection of a couple of sections of code that were written by different developers a couple of years apart.
The question is, are the arguments passed to my_copy
an issue? If this was just to copy a single union my_type
, I believe that it would be ok. I don't know if that is valid to copy an array, though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定是否将其归咎于参数,确切地说,但是您传递从两个数组派生的指针,然后使用它们来超出这些数组的边界。未定义的行为结果。由此访问的存储可以被认为保留在
main()
的src
和dst
数组的范围内,这在形式上并不重要。在实践中,程序的行为可能如您所期望的那样,尽管我发现特定的调用习惯非常晦涩。为什么要涉及
sizeof(union mytype)
?为什么相应的参数名为count
,而它实际上是循环迭代次数的八倍?我想我已经弄清楚了,但我不应该对此感到不确定。如果您想使用示例的 2x32 位访问模式在两个不相交的
union my_type
数组之间进行复制,那么我会这样写:这与您所呈现的并没有太大不同,而且它避免了数组溢出问题。如果您想保留 sizeof(union my_type) ,那么与 my_copy() 的前两个参数的修订类型结合起来,即使这样也会更有意义。
I'm not sure whether to blame it on the arguments, exactly, but you pass pointers derived from two arrays, and then use them to overrun the bounds of those arrays. Undefined behavior results. That the storage thereby accessed can be considered to stay within the bounds
main()
'ssrc
anddst
arrays does not formally matter.In practice, the program probably behaves as you expect, though I find the particular calling idiom extremely obscure. Why is
sizeof(union mytype)
involved? Why is the corresponding parameter namedcount
, when it is actually eight times the number of loop iterations? I think I have figured it out, but I shouldn't have to be uncertain about that.If you want to copy between two disjoint arrays of
union my_type
, using the 2x32-bit access pattern of the example, then I would write it like this:That's not too different from what you present, and it avoids the array-overrun issue. And if you want to keep
sizeof(union my_type)
then even that would make a bit more sense in conjunction with the revised types of the first two parameters tomy_copy()
.