gpt4 book ai didi

c++ - 平凡可复制总是伪标准布局?

转载 作者:行者123 更新时间:2023-11-28 03:39:32 25 4
gpt4 key购买 nike

是否有任何编译器对标准布局类型的布局要求不适用于普通可复制类型?特别是,关键规则是指向该类型的指针是指向其第一个成员的指针(其中基类将被视为先于派生类)。也就是说,类型的地址与其基类型的地址相同。

在代码中,是否存在以下实际上不起作用的通用编译器。这对我来说似乎是常见的做法,因此我很惊讶它没有在 C++11 中标准化。

struct base { int a; /* is a trivial class*/ };
struct derived : public base { int b; /*still a trivial class*/ }

void copy( base * a, base * b, size_t len )
{
memcpy( a, b, len );
}

...
derived d1, d2;
copy( &d1, &d2, sizeof(derived) );

我确信这在 GCC 中有效,我相信它在 MSVC 中有效(尽管我可能错了)。在哪个非历史编译器中,上述内容不会按预期工作?


扩展示例

上面的例子展示了根本问题,但可能没有展示解决问题的意图。这是一个稍微冗长的示例。基本上任何人都可以调用“发送”,这会将消息排队,然后通过转换回其真实类型来发送每条消息。

struct header { int len, id; }
struct derived : public header { int other, fields; }

void send( header * msg )
{
char * buffer = get_suitably_aligned_buffer( msg->len );
memcpy( buffer, msg, msg->len );
}

void dispatch( char * buffer )
{
header * msg = static_cast<header*>(buffer);
if( msg->id == derived_id )
handle_derived( static_cast<derived*>(msg) );
}


derived d;
d.len = sizeof(d);
d.id = deirved_id;
send( &d );

...
char * buffer = get_the_buffer_again();
dispatch( buffer );

还是省略了很多方面,但是关键部分都显示出来了。

最佳答案

是的,自从单继承存在以来,人们就一直在用 C++ 这样做。是的,本质上是合理的。不,标准不支持它。它是否得到普遍支持?可能吧,但你似乎已经知道这不是重点。这种问题才是标准化应该解决的问题。

无论好坏,C++ 确实为这个问题提供了解决方案,尽管明显不那么优雅。

问题是派生类中的非静态数据成员在基类成员之后不一定遵循相同的填充,就好像它们直接拼接到基类中一样。

但具有共同初始序列(有意避免继承)的标准布局结构的 union 确实获得此保证。

struct header { int len, id; }

union derived {
struct {
header h;
int payload;
} fmt1;

struct {
header h; // repetitive
double payload;
} fmt2;

// etc for all message types
};

当多次包含空基类时,布局实际上可能会有所不同,尤其是当第一个非静态数据成员与空基类的类型相同时。继承(仍然)不能这样做的原因可能是他们厌倦了编写关于空基的特殊情况。

关于c++ - 平凡可复制总是伪标准布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9752055/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com