看看下面的代码,它将对象分解为单词,以便使用只接受一个单词的API将(对词对齐)对象写入内存:
void func(some_type obj /*obj is word aligned*/, unsigned int size_of_obj_in_words)
{
union punning{
unsigned char bytes[4]; /* assume 4 bytes in word in my system */
uint32_t word;
};
union punning pun;
unsigned char *legal_aliasing_by_char_pointer;
for (int i=0; i < size_of_obj_in_words; i++)
{
for (int j=0; j<4; j++)
{
legal_aliasing_by_char_pointer = (unsigned char *)&obj + j + i*4;
pun.byte[j] = *legal_aliasing_by_char_pointer;
}
/* finally, using word aliasing to decompose object to words */
/* endianity is not important */
write_word_to_hw_by_word(pun.word)
}
} 我试图以符合c标准的方式来执行,这样就不会违反严格的混叠规则。代码实现了这个目标吗?
发布于 2019-08-12 07:52:21
它看起来不错,但您可以简化很多:
void func(some_type obj)
{
uint32_t word;
for (int i=0; i < sizeof obj / sizeof word; i++)
{
memcpy(&word, (char *)&obj + i * sizeof word, sizeof word);
write_word(word);
}
}obj的对齐并不重要。而且,您不需要传递大小,因为sizeof完成了这项工作。
我怀疑如果您更改函数以接受对象的地址,效果会更好,在这种情况下,您可能也希望传递一个数组长度。
发布于 2019-08-12 08:23:18
首先,如果类型是大的,也许您应该通过指针传递它。
如果(而且只有当)该结构已经像您所说的那样正确地对齐,则可以将指向结构和uint32_t数组的联合的指针转换为。
#include <stdlib.h>
#include <stdint.h>
typedef struct some_type {
uint32_t a;
uint32_t b;
} some_type;
void write_word_to_hw_by_word(uint32_t word);
void func(some_type *obj)
{
union punning {
uint32_t words[sizeof (some_type) / sizeof (uint32_t)];
some_type obj;
} *pun_ptr;
pun_ptr = (union punning *)obj;
for (size_t i = 0; i < sizeof (some_type) / sizeof (uint32_t); i++)
{
write_word_to_hw_by_word(pun_ptr->words[i]);
}
}在这里,我们使用lvalue表达式*pun_ptr通过依赖C11 6.5p7来访问obj中的单词:
- a type compatible with the effective type of the object,
- a qualified version of a type compatible with the effective type of the object,
- a type that is the signed or unsigned type corresponding to the effective type of the object,
- a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
- **an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or**
- a character type.
发布于 2019-08-12 08:42:40
你可能想得有点过头了。以下代码并不违反严格的混叠规则。
void func(void *obj, size_t size_of_obj) // Passing address and size of object
{
for (size_t i = 0; i < size_of_obj; i += sizeof(word_type))
{
word_type word;
memcpy(&word, obj, sizeof(word_type));
write_word_to_hw_by_word(word);
obj = (char *)obj + sizeof(word_type);
}
}它也独立于对象的类型,并且不进行任何大的堆栈分配。
https://stackoverflow.com/questions/57457095
复制相似问题