首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包装修整C结构

包装修整C结构
EN

Stack Overflow用户
提问于 2018-05-18 04:28:08
回答 2查看 101关注 0票数 1

我有一个C库(我在C++中使用它),它定义了一个结构和一个函数来对其进行操作。

代码语言:javascript
复制
struct s {
  type1 x1;
  type2 x2;
  type3 x3;
  type4 x4;
  type5 x5;
};

void f(s* x);

我知道f不做任何涉及s::x4s::x5的事情。由于它们对我的目的都是无用的,而且我有很多s实例,所以我希望将它们分配到一个数组中,这样s[n+1]就可以在s[n].x3之后立即启动。会执行类似的操作,导致未定义的行为?假设从未使用x4x5

代码语言:javascript
复制
struct s_trimmed {
  type1 x1;
  type2 x2;
  type3 x3;
};

size_t num_s = 1000;
char *mem = new char[stuff_before + num_s*sizeof(s_trimmed) + stuff_after];

for (size_t i=0; i<nums; ++i)
  f((s*)(mem + stuff_before + i*sizeof(s_trimmed)));

mem是一个char数组,因为它只是一个内存块,除了s的实例之外,我还想在其中添加其他东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-18 19:08:57

如果您避免任何与对齐相关的问题,您的代码将属于程序类别,标准的作者可能期望高质量的实现能够有效地处理,但是标准的N1570 6.5p7节允许以任意的方式处理实现。请注意,C标准的编写方式,甚至类似于:

代码语言:javascript
复制
struct foo {int x;} s = {0};
s.x = 1;

属于同一类别,因为标准没有描述int类型的lvalue可用于影响struct foo类型对象的任何情况,其lvalue的定义也不适应lvalue可能具有int类型但与其他类型有6.5p7关联的想法。

没有理由让任何高质量的编译器都难以认识到,将T1*转换为T2*并将其传递给作用于T2*的函数的代码可能会访问类型为T1*的对象。在没有-fno-strict-aliasing标志的情况下,gcc和clang都对这种可能性故意视而不见,但使用该标志将使它们表现得像高质量的编译器。

票数 1
EN

Stack Overflow用户

发布于 2018-05-18 05:16:35

只要函数f不处理x4和x5,那么您就可以安全地将结构复制到一个没有符号的字符数组中,并将其传递给function.Sample程序,如下所示:

代码语言:javascript
复制
#include <iostream>
#include <memory.h>
struct s {
  double x1;
  float x2;
  long long x3;
  int x4;
  int x5;
};
struct s_trimmed {
  double x1;
  float x2;
  long long x3;
};
void f(s* x)
{
  std::cout<<x->x1<<std::endl;
  std::cout<<x->x2<<std::endl;
  std::cout<<x->x3<<std::endl;
}
int main() {
  size_t nums = 2;
  unsigned char *mem = new unsigned char[nums*sizeof(s_trimmed)];
  unsigned int start = 0;
  for(int i=0;i<nums;i++)
  {
    s* s_obj = new s;
    s_obj->x1 = 10.5;
    s_obj->x2 = 89.98;
    s_obj->x3=28765;
    s_obj->x4=1;
    s_obj->x5=5;
    memcpy(mem+start,s_obj,sizeof(s_trimmed));
    start = start + sizeof(s_trimmed);
    delete s_obj;
    s_obj = nullptr;
  }
  start = 0;
  for(int i=0;i<nums;i++)
  {
    unsigned char *memf = new unsigned char[sizeof(s_trimmed)];
    memcpy(memf,mem+start,sizeof(s_trimmed));    
    f((s*)memf);    

  }
  delete[] mem;
  mem=nullptr;
  return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50403804

复制
相关文章

相似问题

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