首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类型双关将对象分解为单词

使用类型双关将对象分解为单词
EN

Stack Overflow用户
提问于 2019-08-12 07:24:50
回答 5查看 153关注 0票数 3

看看下面的代码,它将对象分解为单词,以便使用只接受一个单词的API将(对词对齐)对象写入内存:

代码语言:javascript
复制
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标准的方式来执行,这样就不会违反严格的混叠规则。代码实现了这个目标吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-08-12 07:52:21

它看起来不错,但您可以简化很多:

代码语言:javascript
复制
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完成了这项工作。

我怀疑如果您更改函数以接受对象的地址,效果会更好,在这种情况下,您可能也希望传递一个数组长度。

票数 3
EN

Stack Overflow用户

发布于 2019-08-12 08:23:18

首先,如果类型是大的,也许您应该通过指针传递它。

如果(而且只有当)该结构已经像您所说的那样正确地对齐,则可以将指向结构和uint32_t数组的联合的指针转换为。

代码语言:javascript
复制
#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中的单词:

  1. 对象的存储值只能由具有下列类型之一的lvalue表达式访问:
代码语言:javascript
复制
- 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. 

票数 1
EN

Stack Overflow用户

发布于 2019-08-12 08:42:40

你可能想得有点过头了。以下代码并不违反严格的混叠规则。

代码语言:javascript
复制
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);
    }
}

它也独立于对象的类型,并且不进行任何大的堆栈分配。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57457095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档