Visual C++ compiling help

Help and discussing programming in C and C++.

Moderator:Moderators

Fanael
Posts:8
Joined:Sat Feb 20, 2010 12:55 am
Location:Poland
Re: Visual C++ compiling help

Post by Fanael » Mon Jun 28, 2010 5:21 pm

It doesn't? So why

Code: Select all

#include <cstdio>

template <typename T> void foo(const T& x)
{ std::printf("%d\n", sizeof x);
}

int main()
{
  int arr[8], *ptr;

  foo(arr);
  foo(ptr);
}
does print two different values (assuming sizeof ptr != 8 * sizeof(int))?

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: Visual C++ compiling help

Post by Andyhhp » Mon Jun 28, 2010 8:09 pm

Because sizeof is magic compiler voodoo. It is evaluated at compiletime and inserted as pure numbers.

Take a look at the dissasembly of that small fragment of code (well - the relevent parts - i left out the compiled stdio library)

Code: Select all

0000000000400578 <main>:
  400578:       55                      push   %rbp
  400579:       48 89 e5                mov    %rsp,%rbp
  40057c:       48 83 ec 30             sub    $0x30,%rsp
  400580:       48 8d 7d d0             lea    0xffffffffffffffd0(%rbp),%rdi
  400584:       e8 11 00 00 00          callq  40059a <_Z3fooIA8_iEvRKT_>
  400589:       48 8d 7d f8             lea    0xfffffffffffffff8(%rbp),%rdi
  40058d:       e8 2a 00 00 00          callq  4005bc <_Z3fooIPiEvRKT_>
  400592:       b8 00 00 00 00          mov    $0x0,%eax
  400597:       c9                      leaveq
  400598:       c3                      retq
  400599:       90                      nop

000000000040059a <_Z3fooIA8_iEvRKT_>:
  40059a:       55                      push   %rbp
  40059b:       48 89 e5                mov    %rsp,%rbp
  40059e:       48 83 ec 10             sub    $0x10,%rsp
  4005a2:       48 89 7d f8             mov    %rdi,0xfffffffffffffff8(%rbp)
  4005a6:       be 20 00 00 00          mov    $0x20,%esi
  4005ab:       bf d8 06 40 00          mov    $0x4006d8,%edi
  4005b0:       b8 00 00 00 00          mov    $0x0,%eax
  4005b5:       e8 ae fe ff ff          callq  400468 <printf@plt>
  4005ba:       c9                      leaveq
  4005bb:       c3                      retq

00000000004005bc <_Z3fooIPiEvRKT_>:
  4005bc:       55                      push   %rbp
  4005bd:       48 89 e5                mov    %rsp,%rbp
  4005c0:       48 83 ec 10             sub    $0x10,%rsp
  4005c4:       48 89 7d f8             mov    %rdi,0xfffffffffffffff8(%rbp)
  4005c8:       be 08 00 00 00          mov    $0x8,%esi
  4005cd:       bf d8 06 40 00          mov    $0x4006d8,%edi
  4005d2:       b8 00 00 00 00          mov    $0x0,%eax
  4005d7:       e8 8c fe ff ff          callq  400468 <printf@plt>
  4005dc:       c9                      leaveq
  4005dd:       c3                      retq
  4005de:       90                      nop
  4005df:       90                      nop
Notice the only difference between the two foo functions is the hardcoded integer movd into esi.

This does not alter the fact that at the opcode level, array identifers are pointers. (Actually, at the opcode level you only have binary numbers - an array is a higher level construct which is irrelevent)

~Andrew
Image

halofreak1990
Posts:92
Joined:Thu May 27, 2010 8:54 pm
Location:Netherlands

Re: Visual C++ compiling help

Post by halofreak1990 » Tue Jun 29, 2010 9:49 am

An array is just a pointer to a specific range of memory.

Consider this:

Code: Select all

for(int i = 0; i < 32; i++)
{
    arr[i] = somevalue;
    *ptr++ = somevalue;
}
Both statements have the same effect, though stepping through a pointer like this is extremely dangerous considering the fact you might go beyond the data contained within it, causing memory corruption. Only do this if you are absolutely sure how large the pointer is.

On the XBOX, where only one process runs at any given time, you can get away with such things, but in a multitasking environment this is a no no.

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: Visual C++ compiling help

Post by Andyhhp » Tue Jun 29, 2010 10:54 pm

Sigh
Both statements have the same effect, though stepping through a pointer like this is extremely dangerous considering the fact you might go beyond the data contained within it, causing memory corruption.
I suggest you try things like: (Warning - only works on 64bit compiles - 32bit should change 'ptr[6]+=16' to 'ptr[4]+=16' but ive not tested that)

Code: Select all

#include<stdio.h>

int foo();

int main()
{
  if(foo())
    {
      printf("Twas true\n");
    }
  else
    {
      printf("Twas false\n");
    }
}

int foo()
{
  int arr[2] = {0,0};
  arr[6]+=16;
  return 1;
}
#gcc ret.c -o ret
#./ret
#Twas false
Using array offset operators in C++ gives you NO FORM OF BOUND CHECKING. This is not Java or C#!
Only do this if you are absolutely sure how large the pointer is.
A 32bit pointer is always 32 bits. A 64bit pointer is always 64 bits. No exceptions.
On the XBOX, where only one process runs at any given time, you can get away with such things, but in a multitasking environment this is a no no.
This has no relevence to the point you were trying to make - whats it doing here? (also, the xbox is most definitly a multitasking environment)

~Andrew
Image

halofreak1990
Posts:92
Joined:Thu May 27, 2010 8:54 pm
Location:Netherlands

Re: Visual C++ compiling help

Post by halofreak1990 » Mon Jul 05, 2010 8:12 am

the xbox is most definitly a multitasking environment
Actually, no. The XBOX (not XBOX360) kernel does not support more than one XBE (XBOX Executable) running at any given time, nor does it support DLLs.
It wouldn't be feasible with only 64MB, which has to be shared between the program and the framebuffer.
Also, all XBOX software runs in ring 0, for performance reasons, but that's beyond the point.

My point was that in a multitasking environment, you should never, ever use array offset operators, for the obvious reasons. On the XBOX, you might get away with this, but I don't advise it, regardless.
There is no case in which a variable sized array can be implicitly declared. It simply doesnt work.
How about this, then?
It's in my implementation of mscorlib.dll
Apparently, a template class can have an array of unspecified size.
Or at least, it doesn't throw any errors with warnings set at W3

Code: Select all

template <class T>
class List
			{
			private:
				T internalArray[];

			public:
				int Count();
				int Capacity();
				void Capacity(int value);

				List();
				List(int size);
				List(T collection[]);

				void Add(T &item);
				void Clear();
				bool Contains(T &item);
				bool Remove(T &item);
				void RemoveAt(int index);
				void Reverse();
				T *ToArray();
				void TrimExcess();
			};

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: Visual C++ compiling help

Post by Andyhhp » Mon Jul 05, 2010 10:01 am

Actually, no. The XBOX (not XBOX360) kernel does not support more than one XBE (XBOX Executable) running at any given time, nor does it support DLLs.
Fair enough. However, IIRC the XDK standard library exposes windows fibers interface which allows for Cooperative Multitasking (similar to the DOS days).
My point was that in a multitasking environment, you should never, ever use array offset operators, for the obvious reasons. On the XBOX, you might get away with this, but I don't advise it, regardless.
Arguments about XBOX multithreading support aside, I still cannot see any relevence for this comment. Nor can I see any obvious reasons. Array offset operators act no differently in a multitasking envronment than they do in a singletasking environment. Using them in an unsafe mannor is unsafe irrispective of the type of environment. Please can you explain what you mean?
There is no case in which a variable sized array can be implicitly declared. It simply doesnt work.
Perhaps I should have been clearer - we were arguing about C. As far as I am aware (and not certain), C++ has laxer rules about implicit conversion between arrays and pointers, so I believe that that code fragment is just declaring a pointer of type T. Either way, if you try using it without allocating some memory to it, things are going to go wrong.

~Andrew
Image

halofreak1990
Posts:92
Joined:Thu May 27, 2010 8:54 pm
Location:Netherlands

Re: Visual C++ compiling help

Post by halofreak1990 » Mon Jul 05, 2010 6:10 pm

Perhaps I should have been clearer - we were arguing about C.
I think that's where we started to confuse each other.
I was under the impression ('cause the topic title says Visual C++) that we were talking about C++

[offtopic]
However, IIRC the XDK standard library exposes windows fibers interface which allows for Cooperative Multitasking (similar to the DOS days).
The MS XDK might, but I was referring to the OpenXDK (because it's free and open-source), which is written in C and barely supports C++ (only new and delete operators, nothing more.)
[/offtopic]

Andyhhp
Moderator
Posts:387
Joined:Tue Oct 23, 2007 10:05 am
Location:127.0.0.1
Contact:

Re: Visual C++ compiling help

Post by Andyhhp » Mon Jul 05, 2010 7:19 pm

Yeah - the subject matter did change somewhat from the initial title.

~Andrew
Image

Post Reply