编译选项简析及相关编码规范
环境:VS2005
作者:童磊(magictong)
一、基础
Debug和Release本身并没有什么本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项工作而已。因此,我们可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
Debug 版本:
/MDd /MLd 或 /MTd |
调试版本的运行时库 |
/Od |
关闭优化 |
/D "_DEBUG" |
#define _DEBUG,打开编译调试开关 |
/ZI |
创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译 |
/GZ |
捕获内存错误(VS2005已经废去,用RTC代替) |
/Gm |
最小化重编译开关,减少编译时间 |
Release 版本:
/MD /ML 或 /MT |
发布版本的运行时刻函数库 |
/O1 /O2或 /Ox |
优化开关,使程序最小,最快或者全面优化 |
/D "NDEBUG" |
关闭编译调试开关 |
/GF |
常量字符串池开关,合并重复的字符串 |
1、ASSERT在Release版本中是不会被编译的,这种语句要转化成检测语句才有效果,这个地方曾经发生过crash,原因就是pos越界了。
ASSERT宏大概是这样定义的:
#ifdef _DEBUG
#define ASSERT(x) if( (x) == 0) report_assert_failure()
#else
#define ASSERT(x)
#endif
而assert本身在assert.h里面的定义是这样的:
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else
……
2、DEBUG下会进行变量特别填充(开启/RTC1),这个可以在debug下直接调试查看内存。在调试内存错误的时候特别有用(是不是真的有用,谁用谁知道)。
0xCC:填充未初始化的栈变量。(烫烫烫烫烫烫烫烫烫烫)有木有!!!
0xCD:填充从堆中申请的内存。(经常见到的“屯屯屯屯屯屯屯屯屯”)
0xDD:(VC6)已经释放的内存。(“葺葺葺葺葺葺葺葺葺葺”)
0xFEEE:已经释放的内存。(“铪铪铪铪铪铪铪铪铪铪铪”)
0xFD:填充应用程序申请内存的前后的内存(前面4个字节,后面4个字节)。
3、尽量建立UNICODE工程。国际化,尤其是从VC6转换过来的工程最好是第一时间转换成UNICODE工程。
二、高级
/EH /EH{s|a}[c][-] |
异常处理模型 |
/GR |
启用运行时类型信息 |
/Zc |
一致性 |
/RTC /RTCc /RTCu /RTCs |
运行时检测 |
/Ob /Ob{0|1|2} |
内联函数展开 |
/Oy |
传说中的FPO,栈帧指针省略 |
1、 下面的代码如果关闭了GR选项,会有运行时错误,编译时会报4541警告:
warning C4541: 'typeid' used on polymorphic type 'Base' with /GR-; unpredictable behavior may result
class Base
{
public:
virtual void func() {}
};
class DClass : public Base
{
};
……
DClass* pd = new DClass;
Base* pb = pd;
cout << typeid( pb ).name() << endl;
cout << typeid( *pb ).name() << endl;
cout << typeid( pd ).name() << endl;
cout << typeid( *pd ).name() << endl;
……
2、/Zc
/Zc:forScope 强制for 循环变量的作用域
for (int i = 0; i < 10; ++i)
{
cout << i << endl;
}
i = 100;
/Zc:wchar_t 设置wchar_t为内置类型
3、/Ob 内联函数展开,后面分别跟0 1 2三个数字表示三种意思。
/Ob0 不进行内联;
/Ob1 只内联使用关键字inline标识的函数或者类声明中定义的函数;
/Ob2 包含Ob1选择的函数并智能选择一些可以内联的函数进行内联;
注意:对于这个编译选项,编译器将其和关键字inline视为建议的。不保证函数将被内联。而且不能强制编译器去内联特定的函数。(譬如虚函数就不可能内联)
4、/Oy FPO栈帧指针优化,默认是关闭的
5、/EH /EH{s|a} 异常处理模型
/EHs 同步异常处理模型
/EHa 异步异常处理模型
详细说明可以见:
http://blog.csdn.net/magictong/archive/2011/03/17/6256685.aspx
关于异常处理一个有意思的问题,看下面的一段代码(这是一个真实的例子):
vector<int> vecData;
try
{
vecData[100] = 12;
}
catch(...)
{
printf("Catched a exception/n");
}
在正常情况,这个异常是不会被catch的,即使设置了异步异常处理,也不会被catch。看起来似乎很奇怪。
跟踪一下代码流程,也许就不奇怪了……
VS2005里面微软对CRT的一些与安全相关的代码做了些改动,新的CRT版本在遇到参数异常时,把异常抛给了默认的调试器(默认是Dr.Watson),而不再通知应用程序设置的异常捕获函数。我们可以看一下代码的流程。
0040129D cmp dword ptr [ebp-1Ch],0
004012A1 jne main+2AFh (4012AFh)
004012A3 mov dword ptr [ebp-104h],0
004012AD jmp main+2BEh (4012BEh)
004012AF mov edx,dword ptr [ebp-18h]
004012B2 sub edx,dword ptr [ebp-1Ch]
004012B5 sar edx,2
004012B8 mov dword ptr [ebp-104h],edx
004012BE cmp dword ptr [ebp-104h],64h
004012C5 ja main+2CCh (4012CCh)
004012C7 call _invalid_parameter_noinfo (407384h)
004012CC mov eax,64h
004012D1 shl eax,2
004012D4 mov ecx,dword ptr [ebp-1Ch]
004012D7 mov dword ptr [eax+ecx],0Ch
_CRTIMP void __cdecl _invalid_parameter_noinfo(void)
{
_invalid_parameter(NULL, NULL, NULL, 0, 0);
}
_CRTIMP void __cdecl _invalid_parameter(
const wchar_t *pszExpression,
const wchar_t *pszFunction,
const wchar_t *pszFile,
unsigned int nLine,
uintptr_t pReserved
)
{
_invalid_parameter_handler pHandler = __pInvalidArgHandler;
pszExpression;
pszFunction;
pszFile;
pHandler = (_invalid_parameter_handler) _decode_pointer(pHandler);
if (pHandler != NULL)
{
pHandler(pszExpression, pszFunction, pszFile, nLine, pReserved);
return;
}
// No user handler is defined. Notify the debugger if attached.
_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_INVALIDPARAMETER);
_invoke_watson(pszExpression, pszFunction, pszFile, nLine, pReserved);
}
_CRTIMP void __cdecl _invoke_watson(
const wchar_t *pszExpression,
const wchar_t *pszFunction,
const wchar_t *pszFile,
unsigned int nLine,
uintptr_t pReserved
)
{
......
/* Make sure any filter already in place is deleted. */
SetUnhandledExceptionFilter(NULL);
ret = UnhandledExceptionFilter(&ExceptionPointers);
// if no handler found and no debugger previously attached
// the execution must stop into the debugger hook.
if (ret == EXCEPTION_CONTINUE_SEARCH && !wasDebuggerPresent) {
_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_INVALIDPARAMETER);
}
TerminateProcess(GetCurrentProcess(), STATUS_INVALID_PARAMETER);
}
/* Make sure any filter already in place is deleted. */
SetUnhandledExceptionFilter(NULL);
通过这一句干掉了我们设置的异常处理程序,然后就直接结束程序了……太暴力了,但是我们也是可以干预这个过程的,在函数_invalid_parameter里面有句:
pHandler = (_invalid_parameter_handler) _decode_pointer(pHandler);
if (pHandler != NULL)
{
pHandler(pszExpression, pszFunction, pszFile, nLine, pReserved);
return;
}
这里有个Handler貌似可以设置,确实是可以设置的:
void invalid_parameter_handler(
const wchar_t * expression,
const wchar_t * function,
const wchar_t * file,
unsigned int line,
uintptr_t pReserved)
{
}
_set_invalid_parameter_handler(invalid_parameter_handler);
调用之后就直接返回,你可以在invalid_parameter_handler函数里面做一些事情,然后退出程序,或者啥都不做,因为_invalid_parameter里面如果是设置了invalid_parameter_handler的情况,也调用了之后,就直接return了,因此异常还会存在,会被SEH捕获。
附录:
http://msdn.microsoft.com/zh-cn/library/y0zzbyt4(v=vs.80).aspx
链接器选项
分享到:
相关推荐
Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战...
### 编码器工作原理及分类详解 #### 一、引言 编码器作为一种重要的位置检测元件,在自动化控制领域有着广泛的应用。根据不同的工作原理,编码器可以分为两大类:增量式编码器和绝对式编码器。这两种类型的编码器...
2023上半年脂肪醇市场简析及下半年展望报告.pptx
针灸--非物质文化遗产简析及欣赏..ppt
S小学语文一年级上册教材简析及教法建议PPT教案.pptx
【嘉世咨询】2024休闲食品行业简析报告.pdf【嘉世咨询】2024休闲食品行业简析报告.pdf【嘉世咨询】2024休闲食品行业简析报告.pdf【嘉世咨询】2024休闲食品行业简析报告.pdf【嘉世咨询】2024休闲食品行业简析报告.pdf...
【嘉世咨询】2024智能音箱市场简析报告.pdf【嘉世咨询】2024智能音箱市场简析报告.pdf【嘉世咨询】2024智能音箱市场简析报告.pdf【嘉世咨询】2024智能音箱市场简析报告.pdf【嘉世咨询】2024智能音箱市场简析报告.pdf...
node.js中包的分类及简析
STL简析STL简析STL简析基础学习STL简析基础学习STL简析基础学习STL简析基础学习STL简析基础学习STL简析基础学习
Web3.0概念的实现需要相关技术、产业、用户认知、法律法规的推动及适配。 Web3.0概念下的场景生态简析是指下一代互联网的发展方向,旨在解决用户与用户之间的信息互动、提升信息的传递效率、实现信息交互过程中的...
《中国厨房空调市场简析及预测》 中国家电市场历经三个发展阶段,从早期的野蛮生长期,以城镇普及为主,到高质量增长期,城乡同步普及,再到当前的消费内部迭代期,农村市场仍有增量,城镇普及接近饱和,新型家电...
《251机架零件加工工艺简析及编程》这篇文档是关于数控铣削加工的一份课程课件,旨在帮助学习者掌握机架零件的加工工艺和编程技术。以下是其中涉及的重要知识点和技能点的详细解析: 1. 宏程序编程基础: - 宏程序...
【江北区房地产市场运行简析及思考】 江北区在“十二五”期间的房地产市场发展状况反映出一系列值得关注的问题和挑战。本文将围绕房地产市场运行的主要方面进行深入解析,并提出相应的对策建议。 首先,从土地供给...
《谏太宗十思疏》原文、练习、简析及译文(翻译)-word文档.doc
这篇文档《(降重版)简析及探讨工程造价管理过程和成本控制》深入剖析了这一主题,旨在为相关从业者提供有效的理论指导和实践参考。 在工程造价管理过程中,首先需要进行的是工程量清单的编制。这是估算工程总成本...
嘉世咨询:2024中医药行业简析报告(1).pdf
【华夏柏欣深圳怡景中心城项目简析及改造设想】是华夏柏欣(北京)经营管理顾问有限公司在2008年4月14日为保德信(Pramerica)公司提出的关于深圳怡景中心城商业地产项目的分析报告。报告重点在于识别项目存在的问题...
校企合作现况及策略简析.docx