1. 编译器改动
1. wcscpy等CRT的字符串函数不再允许使用,几乎都改成后面带_s的函数。并且每传入一个非const的字符串指针,都会要求后面跟一个表示字符串指针长度的参数
[标注]
虽然可以用宏定义来强制使用旧的字符串函数,但MS还是建议改用新的函数,因为在以后的版本中MS会完全不支持旧代码。
[示例]
老代码: wchar_t strTmp[100] = {0}; wcscpy(strTmp, L”This is a Sample!”); 新代码: wchar_t strTmp[100] = {0}; wcscpy_s(strTmp, 100, L”This is a Sample!”);
|
wcscpy_s的第二参数表示传入字符串的长度,这个长度是申请的实际长度(包括最后的一个L’/ 0’ )。比如: void Sameple1(const wchar_t* p) { int iLen = wcslen(p); wchar_t* p2 = new wchar_t[iLen + 1]; wcscpy_s(p2, iLen, p); // Wrong, the second param must be “iLen + 1” _wcsupr_s(p2, iLen); …… delete[] p2; }
|
2. 部分CRT函数的返回值是一个有效的指针或者句柄,新版本的函数则是返回一个errno_t,实际上一个int类型的数值,返回0为成功,否则可以根据具体的返回值判断是什么错误
[示例]
wcscpy_s wfopen_s |
3. for循环中声明的循环体变量,只有在循环体中有效,出了循环体就不起作用。
[示例]
for (int i = 0; i < 10; i++) { …… if (…) { break; } } if (i != 10) // 错误,变量i没有被声明 { …… }
|
4. STL改动。
[标注]
成员变量不能直接访问std::vector<_Ty>::_Myfirst,使用&std::vector<_Ty>::at(0)
|
使用end()做操作 std::vector<T>::iterator it = arrSample.end(); it->DoSomething(); 在VS8以前的版本中这样做是没错的,但是VS8会出错。
|
循环中删除元素 std::vector<T>::iterator it = arrSample.begin(); for (; it != arrSample.end(); it++) { if (…) { arrSample.erase(it); } } |
5. 函数必须要有返回值。
6. wchar_t作为内置类型
[标注]
unsigned short 不等于 wchar_t
7. 函数指针
[标注]
要使用函数指针,则必须加上&。如果使用类的成员函数指针,则必须要加上&和类名。另外派生类不能将父类的保护成员函数作用函数指针使用。
8.源文件必须是Unicode编码的
[标注]
VS8不能识别老版本某些文件的字符,会报大量的Warning4819。如果遇到这样的Warning,对于新工程,最好一开始就将所有的文件保存成Unicode;对于旧工程,则在工程设置中忽略4819。
8. 将导出函数参数为类型const wchar_t*的改为const unsigned short*,否则连接出错。
2. VSS的使用注意事项
1. 编辑未Checkout的文件,回车便会CheckOut文件,没有提示。
[标注]
修改没有CheckOut的代码时,不会提示是否要CheckOut文件,直接将文件CheckOut,容易导致误操作。即使设置提示了也无效。
2. 在获得最新代码时,如果本地有可写的、没有CheckOut的文件,VSS只会通知要么CheckOut,要么Override,不能Leave。因此现在我们将公用的dll、v12x模块放入VSS的做法需要改进了。
3. 在获得最新代码时,VSS会很智能的检查VSS上被删除的文件,如果VSS上文件被删除,则自动或者提示性的删除本地的文件。因此小心自己新加的文件被删除。
3. 其他
最后是一个好消息,虽然VA.net在VS8中无法使用,但是Visual.Assist.X可以使用。