Library tutorials & articles
Typical errors of porting C++ code on the 64-bit platform
- Introduction
- Off-warnings
- Use of the functions with a variable number of arguments
- Magic numbers
- Bit shifting operations
- Storing of pointer addresses
- Memsize types in unions
- Change of an array type
- Virtual functions with arguments of memsize type
- Serialization and data exchange
- Pointer address arithmetic
- Arrays indexing
- Mixed use of simple integer types and memsize types
- Implicit type conversions while using functions
- Overload functions
- Data alignment
- The use of outdated functions and predefined constants
- Explicit type conversions
- Error diagnosis
- Unit test
- Code review
- Built-in means of compilers
- Static analyzers
- Conclusion
- Resources
Memsize types in unions
The peculiarity of a union is that for all members of the union the same memory area is allocated that is they overlap. Although the access to this memory area is possible with the use of any of the elements the element for this aim should be chosen so that the result won’t be senseless.
One should pay attention to the unions which contain pointers and other members of memsize type.
When there is a necessity to work with a pointer as an integer sometimes it is convenient to use the union as it is shown in the example, and work with the number form of the type without using explicit conversions.
union PtrNumUnion { char *m_p; unsigned m_n; } u; u.m_p = str; u.m_n += delta; |
This code is correct on 32-bit systems and is incorrect on 64-bit ones. Changing member m_n on the 64-bit system we work only with a part of the m_p. We should use the type which will correspond to the pointer size.
union PtrNumUnion { char *m_p; size_t m_n; //type fixed } u; |
Another frequent use of the union is in the presentation of one member as an addition of other smaller ones. For example, we may need to split the value size_t type into bytes to carry out the table algorithm of calculation of the number of zero bits in a byte.
union SizetToBytesUnion { size_t value; struct { unsigned char b0, b1, b2, b3; } bytes; } u; SizetToBytesUnion u; u.value = value; size_t zeroBitsN = TranslateTable[u.bytes.b0] + TranslateTable[u.bytes.b1] + TranslateTable[u.bytes.b2] + TranslateTable[u.bytes.b3]; |
Here it is a fundamental algorithmic error which consists in the supposition that size_t type consists of 4 bytes. The possibility of the automatic search of algorithmic errors is hardly possible but we can provide the search of all the unions and check the presence of memsize types in them. Having found such a union we can find an algorithmic error and overwrite the code in the following way.
union SizetToBytesUnion { size_t value; unsigned char bytes[sizeof(value)]; } u; SizetToBytesUnion u; u.value = value; size_t zeroBitsN = 0; for (size_t i = 0; i != sizeof(bytes); ++i) zeroBitsN += TranslateTable[bytes[i]]; |
Related articles
Related discussion
-
WinGDB - Linux debugging under Visual Studio
by WinGDB (0 replies)
-
Regarding Serial port communication
by raghu550 (0 replies)
-
VS2005 app's won't run on another machine
by ted4444 (0 replies)
-
VB.NET: Hide and show table using radio buttons
by converter2009 (1 replies)
-
Convert C++ code to VB6
by mawcot (4 replies)
Related podcasts
-
Interview with Shawn Burke on Microsoft's .NET Source Code Release
Scott and Carl talk with Shawn Burke on the culmination of his many-year-old plan to get parts of the source of the .NET Framework released. With Visual Studio 2008, a simple process will allow developers to STEP INTO the .NET Framework Source from the IDE. This'll be a great debugging and learni...
This thread is for discussions of Typical errors of porting C++ code on the 64-bit platform.