gpt4 book ai didi

C++ 严格别名问题 --- 让我抓狂

转载 作者:太空宇宙 更新时间:2023-11-04 14:21:28 24 4
gpt4 key购买 nike

好吧......我有点绝望地试图让这段代码在开启严格别名(和-O3)的情况下工作。
我无法缩短代码(对不起...)所以它相当长 ~170 行...

struct S
{
enum
{
leaf,
node
} type; // the type of the structure. leaf means has a value. node has vector.

union
{
int value;
std::vector<struct S*> *v;
} data; // the data. only one is active dependant on the type
};

//compares two structs
bool cmpStructs( const struct S *s1, const struct S *s2 );
//compares the 'top levels' i.e. type and if leaves then also the value
bool cmpStructs1( const struct S *s1, const struct S *s2 );

int main( void )
{
// Create the structure: s1 = [1,2] s2 = [1,3]. Just some random stuff
struct S *s1 = new struct S;
struct S *s2 = new struct S;

s1->type = s2->type = S::node;

s1->data.v = new std::vector<struct S*>( 2U );
s2->data.v = new std::vector<struct S*>( 2U );

struct S *t = new struct S;
t->type = S::leaf;
t->data.value = 1;
s1->data.v->front() = t;

t = new struct S;
t->type = S::leaf;
t->data.value = 2;
s1->data.v->back() = t;

t = new struct S;
t->type = S::leaf;
t->data.value = 1;
s2->data.v->front() = t;

t = new struct S;
t->type = S::leaf;
t->data.value = 3;
s2->data.v->back() = t;

//compare s1 and s2. Note: the result is actually not important. the problem is the crash.
if( cmpStructs( s1, s2 ) )
std::cout << "equal" << std::endl;
else
std::cout << "not equal" << std::endl;

return 0;
}

bool cmpStructs( const struct S *s1, const struct S *s2 )
{
// compare 'top-level'
if( cmpStructs1( s1, s2 ) == false )
return false;
// i.e. s1->type == s2->type and s1->value == s2->value
if( s1->type != S::node )
return true;
// different vector sizes don't compare the same
if( s1->data.v->size() != s2->data.v->size() )
return false;
// used to iterate over all elements in the tree structure of struct S
struct const_iteratorList
{
std::vector<struct S*>::const_iterator it, end;
struct const_iteratorList *next, *previous;
} l1, l2, *c1, *c2;

c1 = &l1;
c2 = &l2;

bool equal = true;

c1->it = s1->data.v->begin();
c1->end = s1->data.v->end();

c2->it = s2->data.v->begin();
c2->end = s2->data.v->end();

c1->previous = c2->previous = c1->next = c2->next = NULL;

do
{
while( c1->it != c1->end )
{// This is where it crashes. Though basically the same stuff as above
if( cmpStructs1( *(c1->it), *(c2->it) ) == false )
{
equal = false;
break;
}

if( (*(c1->it))->type != S::node )
{
++(c1->it);
++(c2->it);
continue;
}

if( (*(c1->it))->data.v->size() != (*(c2->it))->data.v->size() )
{
equal = false;
break;
}
// since *(c1->it) is not a leaf we need to look into its subnodes
c1->next = new struct const_iteratorList;
c2->next = new struct const_iteratorList;

c1->next->it = (*(c1->it))->data.v->begin();
c1->next->end = (*(c1->it))->data.v->end();

c2->next->it = (*(c2->it))->data.v->begin();
c2->next->end = (*(c2->it))->data.v->end();

c1->next->previous = c1;
c2->next->previous = c2;
c1 = c1->next;
c2 = c2->next;

c1->next = c2->next = NULL;
}

if( c1->previous != NULL )
{
c1 = c1->previous;
c2 = c2->previous;

delete c1->next;
delete c2->next;

++(c1->it);
++(c2->it);
} else
break;
} while( equal == true );

while( c1->previous != NULL )
{
c1 = c1->previous;
c2 = c2->previous;

delete c1->next;
delete c2->next;
}

return equal;
}

bool cmpStructs1( const struct S *s1, const struct S *s2 )
{
if( s1->type == S::node )
{
if( s2->type == S::node )
return true;
} else
{
if( s2->type == S::node )
return false;

if( s1->data.value == s2->data.value )
return true;
}

return false;
}

这个问题很容易描述:它在没有 -fstrict-aliasing 的情况下工作,并在它的情况下中断。
“休息”是指“崩溃”。请帮助我让它在这两种情况下都能正常工作:P
谢谢!!!提前(我已经尝试了几个小时......)

编辑:
它崩溃了。
基本上我不知道可能出了什么问题,所以我试图通过删除代码路径并重试来缩小范围……但它并没有带我到任何地方。

编辑:添加了一些评论

最佳答案

这里有一个问题:为什么要放置一个 int和一个 vector<int>*在 union ?这使得 union 的两个成员共享相同的内存(即更新 value 覆盖 v 反之亦然)。

在我看来您更愿意使用结构:

struct
{
int value;
std::vector<struct S*> *v;
} data;

这会将对象按顺序放置在内存中(即 v 现在是 value ,而不是“在” value 之上)。

此外,在这种情况下,您可能希望只使用法线 vector ,因为您不再受并集的限制:

struct
{
int value;
std::vector<struct S*> v;
}

但这取决于你。

编辑

根据 Billy 的评论,您还可以让事情变得更简单,并使结构更漂亮、更扁平:

struct S
{
enum
{
leaf,
node
} type;

int value;
vector<S*> *v
};

关于C++ 严格别名问题 --- 让我抓狂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7323441/

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