My project compiles in .net 2003, but when compiling in .net2005, i got tons of errors like this.
error C2248: 'std::vector<_Ty>::_Myfirst' : cannot access protected member declared in class 'std::vector<_Ty>'
with
[
_Ty=unsigned char
]
c:\program files\microsoft visual studio 8\vc\incude\vector(1243) : see declaration of 'std::vector<_Ty>::_Myfirst'
with
[
_Ty=unsigned char
]
thanks for helping me on this.

C2248 error when migrating my project from VC7(2003) to VC8(2005)
zambiniman
I don't agree with Brian.
Even if he is right on a strict technical point of view, you shouldn't use anything that is not part of the documented interface of the class, unless it's the only way to do it and you are ready to pay later for maintenance costs. These protected fields are intended for internal use of the library, not for general use.
This specific part had a breaking change from VC 6 to VC 2003, and another breaking change from VC 2003 to VC 2005. You have to consider the chance there will be breaking changes with the next versions of VC.
In the next version (Orcas), MS plans to adapt the STL containers to allow for much better parallelizability (see for example the WebCast on the future of C++ at http://microsoft.sitestream.com/PDC05/), which I guess will introduce breaking changes.
A little further, the next C++ standard is expected around 2009. It could very well introduce notions like internal protected, already present in C++/CLI. Such an internal protected field would be private for anything outside the library, and protected only for the library itself.
So, why take a risk
An answer could be performance, but it is not the case with vector : after inlining by the compiler, the code with the iterator resolves to the same pointer arithmetic you could do with an ordinary C++ array. You could convince yourself of this point by compiling my previous example and looking at the machine code generated.
Phm
ptukey
#include <vector>
typedef std::vector<unsigned char> TByteArray
int _tmain(int argc, TCHAR* argv[])
{
TByteArray tt;
void* tv = (void*)tt._Myfirst;
}
these code compiles under 2003 but fails in 2005
Daniel Herling
Short answer :
void *tv = (void*)&tt[0];
... but you shouldn't.
You're not supposed to access the internals of a vector, so your code is erroneous even in 2003.
Use an iterator instead of a pointer :
for (TByteArray::iterator tv = tt.begin(); tv < tt.end(); tv++) {
unsigned char uc = *tv;
}
gbereny
Phm, I think you argued against using _MyFirst very well. In light of future breaking changes, sticking to a documented interface is the best bet for forward compatibility.
Note however, that he already has a way to access elements using operator[] (he doesn't need to loop through them using an iterator). It's the direct access to the memory that is at issue here, as far as I can tell anyway.
Barring compatibility to a future managed memory (pointer-less) implementation, I actually like your (unrecommended) option of using &t[0], as that is defined to be the starting address of the contiguously-allocated array, and it doesn't use any protected members. Any C++ implementation of std::vector that did not use contiguous memory, or had an extra level of indirection, would probably be rejected as performance-prohibitive. (Of course I might be wrong, but this is a real world where we code based on what we know today.)
Brian
Kunal Yadav
Dan Moorehead
Take a look at http://msdn2.microsoft.com/en-us/library/tsbce2bh.aspx where the breaking change is described.
Thanks, Ayman Shoukry VC++ TeamMike Jensen
Could you show a few examples of where you get these errors. The 2005 compiler is slightly more standards compliant than the 2003 compiler - so sometimes, code that compiles in 2003 won't do so in 2005.
Waldemar Erhardt
_MyFirst is protected, not private, so it is accessable from a derived class. I would restrict your code to reading only, and you should find out whether _MyFirst is really the start of a contiguous block of memory.
#include
<vector>class
TByteArray : std::vector<unsigned char>{
public
: unsigned char* GetFirst(){
return _Myfirst;}
};
int
_tmain(int argc, char* argv[]){
TByteArray tt;
void* tv = (void*)tt.GetFirst();}
I did something similar with std:stack. I wanted stack-like behavior of push/pop, but I also needed to index the stack, so I accessed the memory through a protected member.
Brian