BUG: Array of Unnamed Union Does Not Initialize Correctly

ID: Q126843

1.00 1.50 1.51 1.52 WINDOWS kbtool kbbuglist

The information in this article applies to:

SYMPTOMS

Structures that include unnamed unions do not get initialized correctly in C++ code.

CAUSE

The compiler inserts an extra block of data equal to the size of the union after each object. Therefore, every other initialized object will apparently be skipped. See the sample output in SAMPLE 1 below in the MORE INFORMATION section.

RESOLUTION

This problem can be worked around using one of the following methods:

1. Named unions instead of unnamed unions.

   - or -

2. Define constructors for the structure.

More detailed information is provided in sample code SAMPLE 2, found below.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

The following sample code SAMPLE 1 reproduces the problem. Use SAMPLE 2 to work around the problem. Both samples should be .CPP applications.

Sample Code

SAMPLE 1 :

/* Compile options needed: none.
*/ 

#include <stdio.h>

struct MyStruct {
  union {
     char c[8];
     struct {
        unsigned long uL1, uL2;
       };
    };
};

MyStruct ms[] = {

  {"Z000"},
  {"Z001"},
  {"Z002"},
  {"Z003"},
  {"Z004"}
};

void main()
{
  for ( int i=0; i<=4; i++ )
   printf("ms[%d] = %s\n",i,ms[i].c );
}

Output :

ms[0] = Z000 ms[1] = ms[2] = Z001 ms[3] = ms[4] = Z002

SAMPLE 2 :

/* Compile options needed: none
*/ 

#include <stdio.h>

// Define CASE1 or CASE2 here.

#ifdef CASE1 struct MyStruct {
  union {
     char c[8];
     struct {
        unsigned long uL1, uL2;
     };
  } t;  // Name the union here.
}; #endif

#ifdef CASE2

#include <string.h>

struct MyStruct {
  union {
     char c[8];
     struct {
        unsigned long uL1, uL2;
     };
  };
  MyStruct(unsigned long l1, unsigned long l2) {
      uL1 = l1;
      uL2 = l2;
  }             // Constructor
  MyStruct(char *lpz) {
      strcpy(c, lpz);
  }             // Constructor
  MyStruct(){}  // Constructor
}; #endif

MyStruct ms[] = {

  {"Z000"},
  {"Z001"},
  {"Z002"},
  {"Z003"},
  {"Z004"}
};

void main()
{ #ifdef CASE1
   for ( int i=0; i<=4; i++ )
     printf("ms[%d] = %s\n",i,ms[i].t.c );
#endif

#ifdef CASE2

   for ( int i=0; i<=4; i++ )
     printf("ms[%d] = %s\n",i,ms[i].c );
#endif }

Output :

ms[0] = Z000 ms[1] = Z001 ms[2] = Z002 ms[3] = Z003 ms[4] = Z004

Additional reference words: CPP nameless 8.00 8.00c 1.00 1.50 1.51 1.52 KBCategory: kbtool kbbuglist KBSubCategory: CPPIss Keywords : kb16bitonly

Last Reviewed: July 23, 1997