473,388 Members | 1,408 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

An int that is 4 bytes in native, and 12 bytes in .NET? Huh?

Posted this to comp.lang.c++, where I was informed this was an
implementation issue/concern/problem.

Why is it that VS 2005, VC++.NET needs 12 bytes to store an int, when
it can be done natively with 4? Mind you, even on 64-bit systems the
int is still supposed to be 4 bytes. An yes, the _pointer_ will be 8
bytes on a 64 bit system versus 4 bytes on a 32 bit one.

So what gives?

Consider:

The two listings below came from compiling the following console
application with VS6.0 and VS2005 on a/the same 32 bit system:

1. void main(){
2. int x=2;
3. int y=5;
4. int z=0;
5. z=x+y;
6. }

Looking below, the first listing shows each int being stored at 4 byte
intervals on the stack. Whereas the second listing shows x being
stored 8 bytes into the stack, y 12 bytes further in, and z another 12
bytes further.

But as you can see from the immediate data in the instructions and the
use of the 32 bit registers that receive the data when fetched, only 4
bytes is being used for the data. So it appears that the second
program is wasting 4 bytes for the storage of x and 8 bytes each for y
and z.

Source code, generated offsets, machine code, and assembly language
generated by VS6.0:

1: void main(){
00401010 55 push ebp
00401011 8B EC mov ebp,esp
00401013 83 EC 4C sub esp,4Ch
00401016 53 push ebx
00401017 56 push esi
00401018 57 push edi
00401019 8D 7D B4 lea edi,[ebp-4Ch]
0040101C B9 13 00 00 00 mov ecx,13h
00401021 B8 CC CC CC CC mov eax,0CCCCCCCCh
00401026 F3 AB rep stos dword ptr [edi]
2: int x=2;
00401028 C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2
3: int y=5;
0040102F C7 45 F8 05 00 00 00 mov dword ptr [ebp-8],5
4: int z=0;
00401036 C7 45 F4 00 00 00 00 mov dword ptr [ebp-0Ch],0
5: z=x+y;
0040103D 8B 45 FC mov eax,dword ptr [ebp-4]
00401040 03 45 F8 add eax,dword ptr [ebp-8]
00401043 89 45 F4 mov dword ptr [ebp-0Ch],eax
6: }
00401046 5F pop edi
00401047 5E pop esi
00401048 5B pop ebx
00401049 8B E5 mov esp,ebp
0040104B 5D pop ebp
0040104C C3 ret

Source code, generated offsets, machine code, and assembly language
generated by VS2005:

1: void main(){

00411360 55 push ebp
00411361 8B EC mov ebp,esp
00411363 81 EC E4 00 00 00 sub esp,0E4h
00411369 53 push ebx
0041136A 56 push esi
0041136B 57 push edi
0041136C 8D BD 1C FF FF FF lea edi,[ebp+FFFFFF1Ch]
00411372 B9 39 00 00 00 mov ecx,39h
00411377 B8 CC CC CC CC mov eax,0CCCCCCCCh
0041137C F3 AB rep stos dword ptr es:[edi]
2: int x=2;
0041137E C7 45 F8 02 00 00 00 mov dword ptr [ebp-8],2
3: int y=5;
00411385 C7 45 EC 05 00 00 00 mov dword ptr [ebp-14h],5
4: int z=0;
0041138C C7 45 E0 00 00 00 00 mov dword ptr [ebp-20h],0
5: z=x+y;
00411393 8B 45 F8 mov eax,dword ptr [ebp-8]
00411396 03 45 EC add eax,dword ptr [ebp-14h]
00411399 89 45 E0 mov dword ptr [ebp-20h],eax
6: }
0041139C 33 C0 xor eax,eax
0041139E 5F pop edi
0041139F 5E pop esi
004113A0 5B pop ebx
004113A1 8B E5 mov esp,ebp
004113A3 5D pop ebp
004113A4 C3 ret

WTF???

BogusException

Feb 3 '07 #1
8 1153
On 3 Feb 2007 15:37:38 -0800, "BogusException" <bo************@gmail.com>
wrote:
>Posted this to comp.lang.c++, where I was informed this was an
implementation issue/concern/problem.

Why is it that VS 2005, VC++.NET needs 12 bytes to store an int, when
it can be done natively with 4? Mind you, even on 64-bit systems the
int is still supposed to be 4 bytes. An yes, the _pointer_ will be 8
bytes on a 64 bit system versus 4 bytes on a 32 bit one.

So what gives?

Consider:

The two listings below came from compiling the following console
application with VS6.0 and VS2005 on a/the same 32 bit system:

1. void main(){
2. int x=2;
3. int y=5;
4. int z=0;
5. z=x+y;
6. }

Looking below, the first listing shows each int being stored at 4 byte
intervals on the stack. Whereas the second listing shows x being
stored 8 bytes into the stack, y 12 bytes further in, and z another 12
bytes further.

But as you can see from the immediate data in the instructions and the
use of the 32 bit registers that receive the data when fetched, only 4
bytes is being used for the data. So it appears that the second
program is wasting 4 bytes for the storage of x and 8 bytes each for y
and z.

Source code, generated offsets, machine code, and assembly language
generated by VS6.0:

1: void main(){
00401010 55 push ebp
00401011 8B EC mov ebp,esp
00401013 83 EC 4C sub esp,4Ch
00401016 53 push ebx
00401017 56 push esi
00401018 57 push edi
00401019 8D 7D B4 lea edi,[ebp-4Ch]
0040101C B9 13 00 00 00 mov ecx,13h
00401021 B8 CC CC CC CC mov eax,0CCCCCCCCh
00401026 F3 AB rep stos dword ptr [edi]
2: int x=2;
00401028 C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2
3: int y=5;
0040102F C7 45 F8 05 00 00 00 mov dword ptr [ebp-8],5
4: int z=0;
00401036 C7 45 F4 00 00 00 00 mov dword ptr [ebp-0Ch],0
5: z=x+y;
0040103D 8B 45 FC mov eax,dword ptr [ebp-4]
00401040 03 45 F8 add eax,dword ptr [ebp-8]
00401043 89 45 F4 mov dword ptr [ebp-0Ch],eax
6: }
00401046 5F pop edi
00401047 5E pop esi
00401048 5B pop ebx
00401049 8B E5 mov esp,ebp
0040104B 5D pop ebp
0040104C C3 ret

Source code, generated offsets, machine code, and assembly language
generated by VS2005:

1: void main(){

00411360 55 push ebp
00411361 8B EC mov ebp,esp
00411363 81 EC E4 00 00 00 sub esp,0E4h
00411369 53 push ebx
0041136A 56 push esi
0041136B 57 push edi
0041136C 8D BD 1C FF FF FF lea edi,[ebp+FFFFFF1Ch]
00411372 B9 39 00 00 00 mov ecx,39h
00411377 B8 CC CC CC CC mov eax,0CCCCCCCCh
0041137C F3 AB rep stos dword ptr es:[edi]
2: int x=2;
0041137E C7 45 F8 02 00 00 00 mov dword ptr [ebp-8],2
3: int y=5;
00411385 C7 45 EC 05 00 00 00 mov dword ptr [ebp-14h],5
4: int z=0;
0041138C C7 45 E0 00 00 00 00 mov dword ptr [ebp-20h],0
5: z=x+y;
00411393 8B 45 F8 mov eax,dword ptr [ebp-8]
00411396 03 45 EC add eax,dword ptr [ebp-14h]
00411399 89 45 E0 mov dword ptr [ebp-20h],eax
6: }
0041139C 33 C0 xor eax,eax
0041139E 5F pop edi
0041139F 5E pop esi
004113A0 5B pop ebx
004113A1 8B E5 mov esp,ebp
004113A3 5D pop ebp
004113A4 C3 ret

WTF???

BogusException
What compiler options did you use?

--
Doug Harrison
Visual C++ MVP
Feb 4 '07 #2
Doug,

Thanks for writing. Do the defaults create this output? Are there
compiler options that are more efficient in this regard?

Thanks!

BogusException

On Feb 3, 7:23 pm, "Doug Harrison [MVP]" <d...@mvps.orgwrote:
What compiler options did you use?

--
Doug Harrison
Visual C++ MVP

Feb 4 '07 #3
In article <11**********************@v33g2000cwv.googlegroups .com>,
BogusException <bo************@gmail.comwrote:
>Thanks for writing. Do the defaults create this output? Are there
compiler options that are more efficient in this regard?
You really do need to provide more information. Is this a debug
or optimized build? (Debug errs on the side of safety and information,
versus size/speed. Release tends to do the opposite).

Nathan Mates
--
<*Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
Feb 4 '07 #4
On 3 Feb 2007 16:36:50 -0800, "BogusException" <bo************@gmail.com>
wrote:
>Doug,

Thanks for writing. Do the defaults create this output? Are there
compiler options that are more efficient in this regard?

Thanks!

BogusException
Apparently, you were compiling for a debug build using the /RTC1 and /ZI
options. At least that combination produces for me the code you posted. You
should look up those options to determine what they do. Then compile for
release mode and verify the code doesn't contain all the debug mode,
runtime checking stuff.

--
Doug Harrison
Visual C++ MVP
Feb 4 '07 #5
Nathan and Doug,

Thank you both very much for writing. Thanks to you I was able to
figure out a way to get the code trimmed down. See below...

On Feb 3, 9:05 pm, "Doug Harrison [MVP]" <d...@mvps.orgwrote:
Apparently, you were compiling for a debug build using the /RTC1 and /ZI
options. At least that combination produces for me the code you posted. You
should look up those options to determine what they do. Then compile for
release mode and verify the code doesn't contain all the debug mode,
runtime checking stuff.
It wasn't the /Zi or /RTC1 switch. It was simply the /Os optimization
switch which favors small code. Check it out:

1: void main(){
00411235 55 push ebp
00411236 8B EC mov ebp,esp
00411238 83 EC 4C sub esp,4Ch
0041123B 53 push ebx
0041123C 56 push esi
0041123D 57 push edi
2: int x=2;
0041123E C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2
3: int y=5;
00411245 C7 45 F8 05 00 00 00 mov dword ptr [ebp-8],5
4: int z=0;
0041124C 83 65 F4 00 and dword ptr [ebp-0Ch],0
5: z=x+y;
00411250 8B 45 FC mov eax,dword ptr [ebp-4]
00411253 03 45 F8 add eax,dword ptr [ebp-8]
00411256 89 45 F4 mov dword ptr [ebp-0Ch],eax
6: }
00411259 33 C0 xor eax,eax
0041125B 5F pop edi
0041125C 5E pop esi
0041125D 5B pop ebx
0041125E C9 leave
0041125F C3 ret

Thanks again or the insight!

Bogus Exception

Feb 4 '07 #6
On 4 Feb 2007 08:33:18 -0800, "BogusException" <bo************@gmail.com>
wrote:
>Nathan and Doug,

Thank you both very much for writing. Thanks to you I was able to
figure out a way to get the code trimmed down. See below...

On Feb 3, 9:05 pm, "Doug Harrison [MVP]" <d...@mvps.orgwrote:
>Apparently, you were compiling for a debug build using the /RTC1 and /ZI
options. At least that combination produces for me the code you posted. You
should look up those options to determine what they do. Then compile for
release mode and verify the code doesn't contain all the debug mode,
runtime checking stuff.

It wasn't the /Zi or /RTC1 switch. It was simply the /Os optimization
switch which favors small code. Check it out:

1: void main(){
00411235 55 push ebp
00411236 8B EC mov ebp,esp
00411238 83 EC 4C sub esp,4Ch
0041123B 53 push ebx
0041123C 56 push esi
0041123D 57 push edi
2: int x=2;
0041123E C7 45 FC 02 00 00 00 mov dword ptr [ebp-4],2
3: int y=5;
00411245 C7 45 F8 05 00 00 00 mov dword ptr [ebp-8],5
4: int z=0;
0041124C 83 65 F4 00 and dword ptr [ebp-0Ch],0
5: z=x+y;
00411250 8B 45 FC mov eax,dword ptr [ebp-4]
00411253 03 45 F8 add eax,dword ptr [ebp-8]
00411256 89 45 F4 mov dword ptr [ebp-0Ch],eax
6: }
00411259 33 C0 xor eax,eax
0041125B 5F pop edi
0041125C 5E pop esi
0041125D 5B pop ebx
0041125E C9 leave
0041125F C3 ret

Thanks again or the insight!

Bogus Exception
You seem to have concluded that using /Os gives you the desired result.
This is not the case, because you'll get the same output WRT the stack
offsets if you use no compiler options at all. It was the use of /ZI and
/RTC1 together that caused the crazy stack offsets. HTH.

--
Doug Harrison
Visual C++ MVP
Feb 5 '07 #7
On Sun, 04 Feb 2007 22:54:23 -0600, "Doug Harrison [MVP]" <ds*@mvps.org>
wrote:
You seem to have concluded that using /Os gives you the desired result.
This is not the case, because you'll get the same output WRT the stack
offsets if you use no compiler options at all. It was the use of /ZI and
/RTC1 together that caused the crazy stack offsets. HTH.
I didn't try to find out what exact switch[es] is/are responsible, but in a
default debug build they're spaced at 12 bytes, so I suppose that's what
the OP was talking about.
I used this code:

void DoIt(int a, int b)
{
int x, y, z;
x = a;
y = b;
z = a + b;
printf("%d + %d = %d\n", x, y, z);
}

int _tmain(int argc, _TCHAR* argv[])
{
DoIt(1, 2);
return 0;
}
In a debug build, the offsets are declared to be:

_TEXT SEGMENT
_z$ = -32 ; size = 4
_y$ = -20 ; size = 4
_x$ = -8 ; size = 4
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
In a release build everything is optimized away, only the printf call
remains with the results pre-computed and pushed onto the stack as
constants.
To my surprise, it even optimizes away the call to DoIt() !

; 17 : DoIt(1, 2);

00000 6a 03 push 3
00002 6a 02 push 2
00004 6a 01 push 1
00006 68 00 00 00 00 push OFFSET
??_C@_0O@FDJKEPMC@?$CFd?5?$CL?5?$CFd?5?$DN?5?$CFd? 6?$AA@
0000b ff 15 00 00 00
00 call DWORD PTR __imp__printf
00011 83 c4 10 add esp, 16 ; 00000010H

; 18 : return 0;

00014 33 c0 xor eax, eax

; 19 : }

Feb 7 '07 #8
On Feb 4, 11:54 pm, "Doug Harrison [MVP]" <d...@mvps.orgwrote:
You seem to have concluded that using /Os gives you the desired result.
This is not the case, because you'll get the same output WRT the stack
offsets if you use no compiler options at all. It was the use of /ZI and
/RTC1 together that caused the crazy stack offsets. HTH.
Doug,

I stand corrected. It wasn't the /Os switch.

In playing with switch combinations, I inadvertently changed /ZI to /
Zi and ended up with /Zi, /RTC1, and /Os. I didn't even notice the
case difference. Both switches, /ZI and /Zi, give the debugger a
database to retrieve program source code info from such as variable
names but /ZI gives the debugger an edit and continue capability as
well.

It turns out that /Zi together with /RTC1 without /Os does the trick.
The run time check switch /RTC1 is equivalent to using both /RTCs and /
RTCu which is for stack frame and uninitialized variable run time
checks.

I was able to get the 4 byte storage with the follow combinations of
debugger and run time check switches: (/Zi, /RTC1), (/ZI, /RTCu), (/
Zd, /RTC1), and (/Z7, /RTC1). It looks like it's the combo of /ZI
with /RTCs that's causing the extra memory.

Thanks!

Bogus Exception

Feb 7 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: David Kantowitz | last post by:
I am trying to wrap a native-C++ DLL in managed C++, to use in a .NET project. The native code is compiled into a DLL, and I have created a .def file that exports the mangled names of the...
7
by: Bob | last post by:
Hi, I am trying to use BULK INSERT with format file. All of our data has few bytes of header in the data file which I would like to skip before doing BULK INSERT. Is it possible to write...
19
by: James Harris | last post by:
My K&R 2nd ed has in the Reference Manual appendix, A7.4.8 sizeof yields the number of BYTES required to store an object of the type of its operand. What happens if C is running on a machine that...
8
by: ranjeet.gupta | last post by:
Dear All I am not able o understand the exact number of bytes allocation done by the two fucntion given below, It is said that the fuction Condition_String1 allocates the 240 bytes while...
6
by: Alexander Hunziker | last post by:
Hello group, I have a program that reads data from a binary file. I know that at some known position in the file there are 12 4 bytes long floating point numbers. Here's how I read them now: ...
1
by: dln | last post by:
Hey all. I'm a bit new to the language and I'm trying to figure out how to have my c# application interact with native code that is exported via a dll. I've run into a problem interfacing with a...
0
by: fergaloc | last post by:
Hi there. Our .net framework 1.1 application is a complex media player that plays back video, flash, web, TV and pictures full screen. It runs on Windows XP SP2. It has 12 DLLs and runs to about...
7
by: BogusException | last post by:
Why is it that VS 2005, VC++.NET needs 12 bytes to store an int, when it can be done natively with 4? Mind you, even on 64-bit systems the int is still supposed to be 4 bytes. An yes, the _pointer_...
4
by: joyce | last post by:
hi How would I go abouts finding out how many bytes a string has. ( I want to do this so that I can set the datatype on the database approriately.) Thanks Joyce
32
by: vippstar | last post by:
Assuming all the values of int are in the range of unsigned char, what happends if getc returns EOF? Is it possible that EOF was the value of the byte read? Does that mean that code aiming for...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.