900624-它是错误吗? [英] 900624 - Is it a bug?!

查看:67
本文介绍了900624-它是错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨 在以下代码中:

 //  t4.cpp:定义控制台应用程序的入口点.
//  

#include   "  stdafx.h"

结构 S
{
联盟
{
结构
{
浮动 f1;
布尔 b;
};
结构
{
布尔 b;
字符 c;
 float  f2;
};
};
};

 int  _tmain( int  argc,_TCHAR * argv [])
{
s;
s.b =  true ;
s.f2 =  1 . 00 ;
返回  0 ;
} 


当s.f2初始化时,s.b变为false!
这是一个错误吗?我尝试了VS2008和VS2010,而这两种情况都发生了.
有什么问题?
thx

解决方案

也许您需要查看实际使用的并集:
http://www.cplusplus.com/doc/tutorial/other_data_types/ [ 结构 S { int utype; 联盟 { 结构 { 布尔 b; 浮动 f1; } s1; 结构 { float f2; int i; 布尔 b; } s2; } } int main(){ S my_s; // 现在插入一些值: my_s.utype = 1 ; // 立即使用s1 my_s.s1.b = true ; my_s.s1.f1 = 3 . 14 ; // 现在所做的事情完全不同 // ... 现在,// 从您的结构中读取,但首先检查它的当前用法: 布尔 my_b; 浮动 my_f; 如果(my_s.utype == 1 ){ // 好.使用s1: my_b = my_s.s1.b; my_f = my_s.s1.f1; } 其他 { // 同时有人将用法更改为s2!因此,现在使用s2: my_b = my_s.s2.b; my_f = my_s.s2.f2; } }


尽管这比以前的代码安全得多,但是仍然总是必须特别指出或查询正在使用的联合的哪一部分仍然很尴尬.在一些get和set函数中使用类和继承会容易得多.


在两个联合结构中都有一个bool b,因此对S.b的任何引用都将引用第一个结构中的那个.然后对第二个结构进行的更改可能(将)破坏它.在每个结构中选择不同的名称,或为每个结构命名以避免歧义;类似的东西:

 结构 S
{
    联盟
    {
        结构
        {
            浮动 f1;
            布尔 b;
        } s1;
        结构
        {
            布尔 b;
            字符 c;
             float  f2;
        } s2;
    };
};
 
 int  _tmain( int  argc,_TCHAR * argv [])
{
s;
s.s2.b =  true ;
s.s2.f2 =  1 . 00 ;
返回  0 ;
} 


hi in the following code:

// t4.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

struct S
{
	union
	{
		struct
		{
			float f1;
			bool b;
		};
		struct
		{
			bool b;
			char c;
			float f2;
		};
	};
};

int _tmain(int argc, _TCHAR* argv[])
{
	S s;
	s.b = true;
	s.f2 = 1.00;
	return 0;
}


when s.f2 is initialized, s.b becomes false!
is it a bug?! i tried VS2008 and VS2010 and this happens in both.
what''s the problem?
thx

Perhaps you need to look up what unions are actually used for:
http://www.cplusplus.com/doc/tutorial/other_data_types/[^]

They''re used for sharing the same memory with different data types. Since you''re sharing the same memory space, changing the second structure is of course affecting the first.


1. You''ve used the tag C++ for this question, yet you are using outdated C-Syntax. union is an unsafe construct from the C language that is only still available in C++ for compatibility reasons. C++ provides safe alternate means to implement anything that you would otherwise use a union for, such as class hierarchies, and inheritance.

2. There is a reason for rule 1. above: unions are unsafe. After your own experience you should recognize why. You and you alone are responsible for correctly accessing your union - neither the compiler nor the runtime can do that for you! If at one point you enter values into s1, then any accesses to s2 become invalid!
It is your responsibility to ensure that you always acces the correct struct - the one that was last initialized.

3. As Richard already pointed out, it isn''t exactly helpful to use unnamed structs. This is yet another remnant of C Syntax that should best be forgotten! See Solution 2.

4. While I''ve pointed out in 1. that you shouldn''t be using union in the first place, if you choose to ignore that advice, at the very least add one attribute to your struct S that indicates the struct that is currently being used. E. g. something like this:

struct S {
   int utype;
   union {
      struct {
          bool b;
          float f1;
      } s1;
      struct {
          float f2;
          int i;
          bool b;
      } s2;
   }
}
int main() {
   S my_s;
   // now insert some values:
   my_s.utype = 1; // using s1 now
   my_s.s1.b = true;
   my_s.s1.f1 = 3.14;
   // now do something completely different 
   // ...
   // now read from your struct, but check it's current usage first:
   bool my_b;
   float my_f;
   if (my_s.utype == 1) {
      // Ok. Using s1:
      my_b = my_s.s1.b;
      my_f = my_s.s1.f1;
   }
   else {
      // someone changed the usage to s2 in the meantime! So use s2 now:
      my_b = my_s.s2.b;
      my_f = my_s.s2.f2;
   }
}


While this is much safer than your previous code, it''s still awkward that you always have to specifically point out or inquire what part of the union you are using. Using classes and inheritance with a few get and set functions would be a lot easier.


You have a bool b in both structures of the union so any reference to S.b will refer to the one in the first structure. Changes then made to the second structure may (will) corrupt it. Choose different names in each structure, or give each structure a name to avoid ambiguity; something like:

struct S
{
    union
    {
        struct
        {
            float f1;
            bool b;
        } s1;
        struct
        {
            bool b;
            char c;
            float f2;
        } s2;
    };
};
 
int _tmain(int argc, _TCHAR* argv[])
{
	S s;
	s.s2.b = true;
	s.s2.f2 = 1.00;
	return 0;
}


这篇关于900624-它是错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆