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

Discussion in 'C++' started by BogusException, Feb 3, 2007.

  1. 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
     
    BogusException, Feb 3, 2007
    #1
    1. Advertising

  2. BogusException

    Ian Collins Guest

    BogusException wrote:
    > 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.
    >

    Your asking about an implementation issue, try a VS focused group.

    --
    Ian Collins.
     
    Ian Collins, Feb 3, 2007
    #2
    1. Advertising

  3. BogusException

    Kai-Uwe Bux Guest

    BogusException wrote:

    > Why is it that VS 2005, VC++.NET needs 12 bytes to store an int, when
    > it can be done natively with 4?


    You may want to ask that question in a forum where it is on-topic. Here, we
    do standard C++ and VC++.NET specific questions are off-topic. Please refer
    to the FAQ and to the weekly welcome message for details.

    > Mind you, even on 64-bit systems the
    > int is still supposed to be 4 bytes.


    There is nothing in the standard that forbids 96bit ints on 64bit systems.

    > An yes, the _pointer_ will be 8 bytes on a 64 bit system versus 4 bytes on
    > a 32 bit one.


    Pointers on such systems may or may not have 64 bits. The standard has
    nothing to say about that.

    >
    > 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(){


    The standard says, main returns int. If the above compiles on your system,
    it does so by means of an extension. The behavior of the program is then
    undefined (as the standard does not impose any requirements on programs
    that only compile by means of an extension). A diagnostic message is
    required (i.e., your compiler is supposed to tell you that main returns
    int). If you don't see that message, your compiler is not compliant (or you
    run it with settings that make it non-compliant).

    > 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.

    [interesting piece of artwork snipped]
    > WTF???


    One can only guess what the compiler is thinking. Here are a few questions
    the answers to which you might want to include into a post to a forum where
    this is on-topic:

    1) What happens to other types like signed char, signed long?
    2) What happens to unsigned int?
    3) Do the results depend on optimization settings?
    4) Do the results depend on settings influencing run-time overflow checks?


    Best of luck

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Feb 3, 2007
    #3
  4. Ian,

    Point taken. I'll also post to
    microsoft.public.dotnet.languages.vc...

    Feel free to offer any suggestions, though!

    BogusException

    On Feb 3, 6:06 pm, Ian Collins <> wrote:
    > Your asking about an implementation issue, try a VS focused group.
    >
    > --
    > Ian Collins.
     
    BogusException, Feb 3, 2007
    #4
  5. BogusException

    Ian Collins Guest

    BogusException wrote:
    > Ian,
    >
    > Point taken. I'll also post to
    > microsoft.public.dotnet.languages.vc...
    >
    > Feel free to offer any suggestions, though!
    >

    Don't top-post on Usenet?

    --
    Ian Collins.
     
    Ian Collins, Feb 4, 2007
    #5
  6. BogusException

    John Carson Guest

    "BogusException" <> wrote in message
    news:...
    > Why is it that VS 2005, VC++.NET needs 12 bytes to store an int, when
    > it can be done natively with 4?


    Your claim is rather ambiguous. VC++ 2005 can produce both native and
    managed code. If you are compiling your code as managed, then it is offtopic
    here.

    In any case, your claim is wrong. sizeof(int) is 4 with VC++ 2005, whether
    managed or unmanaged.

    > 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.


    Starting addresses don't tell you storage requirements. The compiler can put
    things where it pleases. Nothing says that sequentially declared variables
    must be stored sequentially. Further, in Debug mode the compiler allocates
    extra space for its debugging activities.

    When I run the code in native Debug mode, z is stored *before* x and y. The
    addresses are (using just the last two digits)

    z 0x5C
    x 0x60
    y 0x64

    (I get these by simply using cout << &x etc.). When I run the code in native
    Release mode, I get:

    x 0x70
    y 0x74
    z 0x78

    When I compile the code as managed, I get a 4 byte gap in all cases.

    --
    John Carson
     
    John Carson, Feb 4, 2007
    #6
  7. BogusException

    Rolf Magnus Guest

    BogusException wrote:

    > 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.


    Actually, on 64 bit systems, an int is "supposed" to be 64 bits, but isn't
    required to. On most platforms, it isn't, because you'd run out of smaller
    types.

    > An yes, the _pointer_ will be 8 bytes on a 64 bit system versus 4 bytes on
    > a 32 bit one.


    If the implementation chooses this.

    > So what gives?


    There is nothing in the standard that forbids that. Even if int only has 32
    value bits, it's allowed to have as many padding bits as the implementation
    deems necessary.

    > 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(){


    From this point on, the program has undefined behavior. main() must return
    int.

    > 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.


    C++ doesn't require local variables to be stored on a stack. Further, it
    doesn't say anything about how far they are away from each other. If you
    really want to find out the size of int, just try:

    #include <iostream>
    int main()
    {
    std::cout << "An int is " << sizeof(int) << " bytes big\n";
    }
     
    Rolf Magnus, Feb 4, 2007
    #7
  8. BogusException

    Guest

    On Feb 3, 4:57 pm, "BogusException" <> wrote:
    > 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?



    The exact code generated by a compiler is implementation dependent,
    and OT here.

    That being said, you're probably doing a debug build, and have both
    runtime checks (-RTC1) and "edit and continue" debugging (-ZI) on,
    which cause him to allocate extra space. Change either of those
    options and he should stop.
     
    , Feb 6, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VB Programmer
    Replies:
    1
    Views:
    358
    Chris Moore
    Jun 12, 2004
  2. Schnoffos
    Replies:
    2
    Views:
    1,236
    Martien Verbruggen
    Jun 27, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,681
    Old Wolf
    Jan 20, 2004
  4. arun
    Replies:
    8
    Views:
    467
    Dave Thompson
    Jul 31, 2006
  5. luser- -droog

    Pack bitmap bytes into native-endian 32bit int

    luser- -droog, Jan 11, 2011, in forum: C Programming
    Replies:
    11
    Views:
    1,076
    luser- -droog
    Jan 17, 2011
Loading...

Share This Page