我有一个C库(我在C++中使用它),它定义了一个结构和一个函数来对其进行操作。
struct s {
type1 x1;
type2 x2;
type3 x3;
type4 x4;
type5 x5;
};
void f(s* x);我知道f不做任何涉及s::x4或s::x5的事情。由于它们对我的目的都是无用的,而且我有很多s实例,所以我希望将它们分配到一个数组中,这样s[n+1]就可以在s[n].x3之后立即启动。会执行类似的操作,导致未定义的行为?假设从未使用x4和x5。
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的实例之外,我还想在其中添加其他东西。
发布于 2018-05-18 19:08:57
如果您避免任何与对齐相关的问题,您的代码将属于程序类别,标准的作者可能期望高质量的实现能够有效地处理,但是标准的N1570 6.5p7节允许以任意的方式处理实现。请注意,C标准的编写方式,甚至类似于:
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都对这种可能性故意视而不见,但使用该标志将使它们表现得像高质量的编译器。
发布于 2018-05-18 05:16:35
只要函数f不处理x4和x5,那么您就可以安全地将结构复制到一个没有符号的字符数组中,并将其传递给function.Sample程序,如下所示:
#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;
}https://stackoverflow.com/questions/50403804
复制相似问题