In the mid-year of 2005, my company started to port our product from vc7.1 to vc8. Our strategy is to make source code compile both in VC7.1 and in VC8. I was happy to be involved into porting. We ported almost 30 solutions and 200 projects. VC8 compiler is stricter than VC7.1. The followings are some tips. (Linking problems are not included.) My colleague Mr. Han made great contribution to this article. Many thanks to Han.
1. Variable scope
In vc7.1, if a variable is declared in a FOR loop, it can be used after this FOR loop. But Vc8 compiler will report a C2065 error.
for
(
int
i
=
0
; i
<
10
;
++
i)
{
//codes here
}
if
(i
<
10
)..
//
error in Vc8
for
(i
=
0
; i
<
5
;
++
i)
//
error in Vc8
Solution:
Declare the variable before the FOR statement
int
i
=
0
;
for
(i
=
0
; i
<
10
;
++
i)
for
(i
=
0
; i
<
5
;
++
i)
2. Variable declaration
In Vc7.1, these codes can compile, but VC8 compiler reports a C4430 error
const
&
int
a;
//
error in VC8
const
*
int
b;
//
error in VC8
int
myfun (
const
&
B);
//
error in VC8
Solution:
Put * or & after type.
const
int
&
a;
const
int
*
b;
int
myfun (
const
B
&
);
3. Default int
VC8 doesn’t support Default int
static
i
=
0
;
//
C4430 error in Vc8
const
i
=
0
;
//
C4430 error
Solution:
Add int.
static
int
i
=
0
;
const
int
i
=
0
;
4. Function's return value type
VC8 doesn’t treat int as default return value type
Func()
{return 0;}
;
//
error in VC8
Solution:
Add int.
5. Function address
To create a pointer to a member function, the address of operator (&) must be used with the fully qualified name of the method. Not having to use the & operator and the fully qualified name of the method lead to logic bugs in code due missing parenthesis in function calls.
class
A
{
public:
int Test(void);
}
;
void
fun(
int
(A::
*
test) (
void
));
int
main()
{
fun(A::Test);//C3867 error in VC
return 0;
}
Solution:
Add &.
fun(
&
A::Test);
6. Reference to a pointer to a const variable
VC8 doesn’t allow implicit conversion from B* to const B*&.
class
B
{}
;
void
fun (
const
B
*
&
);
//
if possible use const B* instead
int
main()
{
B *test = new B();
fun (test); //error in VC8
return 0;
}
Solution:
c-style cast. If possible, use const B* instead
void
fun (
const
B
*
);
7. Friend function
VC8 doesn’t allow declaring a private or protected function as a friend function.
class
A
{
private:
void c();
}
;
class
B
{
friend void A::c(); //C2248 error, c() is invisible to class B.
}
;
Solution 1:
Declare friend class.
class
A
{
private:
void c();
}
;
class
B
{
friend class A;
}
;
Solution 2:
Make the function public
class
A
{
public:
void c();
}
;
class
B
{
friend void A::c();
}
;
8. stdext namespace
hash_map and hash_set are moved into stdext namespace in VC8.
#include
<
hash_map
>
std::hash_map
//
error in VC8
Solution:
Use stdext namespace.
#include
<
hash_map
>
stdext::hash_map
9. Header files
Many headers such as fstream.h and iostream.h are removed in VC8.
#include
<
fstream.h
>
//
error in VC8
Solution:
Use STL headers.
#include
<
fstream
>
10. Iterator
In some Standard C++ Library classes, iterators are no longer implemented by pointers.
std::vector
<
DMDetailRow
>
m_data;
std::vector
<
DMDetailRow
>
::iterator iter
=
&
m_data[rowNum];
Solution:
std::vector
<
DMDetailRow
>
::iterator Iter
=
m_data.begin()
+
rowNum;
11. Enum
Don't qualify the member of an Enum with the Enum name
enum
E
{
a,b,c
};
E e1
=
E::a;
//
warning in VC8
Solution:
Remove Enum name.
E e1
=
a;