转载

VC编译器设置(/GR,/EH,/Zc,/Ob)

VC 编译器设置

工欲善其事,必先利其器;要想用 VC 开发出高效率程序,必须对 VC 编译器有充分的了解。如果我们已经习惯编译器给我的默认设置,那么现在起开始尝试改变吧 ! 本篇文章(或者后续文章)讲解 VC 编译器设置选项并没有先后顺序,只是作者在具体开发过程碰见了不同的编译设置,进行深入了解,做此文章记录。也希望读到这篇文章的您有所收获;本文章主要参考 MSDN ,编译器为 VC7.1 ,作者只是添加一些通俗例子,或者翻译部分英文内容,从而达到对编译器设置的通俗理解。

1 /GR (启用运行时类型信息)

说明:此选项 (/GR) 添加代码以便在运行时检查对象类型。当指定此选项时,编译器定义 _ CPPRTTI 预处理器宏。默认情况下,此选项被清除 (/GR–)

Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的 属性页 对话框。
  2. 单击 “C/C++” 文件夹。
  3. 单击 语言 属性页。
  4. 修改 启用运行时类型信息 属性。

例子:我们使用 typeid ,在运行时刻获的变量的类型

// expre_typeid_Operator.cpp

// compile with: /GR /EHsc

#include <iostream>

#include <typeinfo.h>

class Base {

public:

virtual void vvfunc() {}

};

class Derived : public Base {};

using namespace std;

int main()

{

Derived* pd = new Derived;

Base* pb = pd;

cout << typeid( pb ).name() << endl;    //prints "class Base *"

cout << typeid( *pb ).name() << endl;    //prints "class Derived"

cout << typeid( pd ).name() << endl;    //prints "class Derived *"

cout << typeid( *pd ).name() << endl;    //prints "class Derived"

delete pd;

}

2 /EH (异常处理模型)

/EH{s|a}[c][-]

此选项指定编译器使用的异常处理模型。

  • 使用 /EHs 指定同步异常处理模型(没有结构化异常处理异常的 C++ 异常处理)。如果使用 /EHs ,不要依靠编译器捕捉异步异常。
  • 使用 /EHa 指定异步异常处理模型(带结构化异常处理异常的 C++ 异常处理)。

/EHc 选项要求指定 /EHs/EHa/GX 。它通知编译器假定 extern C 函数从不引发异常。

该选项可以用符号 - 清除。例如, /EHsc- 解释为 /EHs /EHc- ,并且等效于 /EHs

Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的 属性页 对话框。
  2. 单击 “C/C++” 文件夹。
  3. 单击 代码生成 属性页。
  4. 修改 启用 C++ 异常 属性。
  1. 单击 “C/C++” 文件夹。
  2. 单击 代码生成 属性页。
  3. 启用 C++ 异常 设置为
  4. 单击 命令行 属性页。
  5. 附加选项 框中键入编译器选项。

/Zc (一致性)

/Zc 编译器选项使您可以用 /Ze 指定标准行为。以下是 /Zc 编译器选项列表:

/Zc:forScope

/Zc:wchar_t

1 ): /Zc:forScope (强制 for 循环范围中的一致性)

MS 标准行为是使 for 循环的初始值设定项在 for 循环之后超出范围。在 /Ze 下, for 循环的初始值设定项保持在范围内,直到局部范围结束。

可以用 conform 杂注修改 /Zc:forScope 的运行时行为。

如果在具有现有 .pch 文件的项目中使用 /Zc:forScope ,则忽略 /Zc:forScope (伴有警告),并继续用现有的 .pch 文件编译。如果需要生成新的 .pch 文件,请使用 /Yc

Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的 属性页 对话框。
  2. 单击 “C/C++” 文件夹。
  3. 单击 语言 属性页。
  4. 修改 强制 For 循环范围中的一致性 属性。

例子说明:

    下列代码将在 /Ze 下编译,但不在 /Za 下编译:

使用 /Zc:forScope 时,如果变量因为存在一个在以前的范围内所做的声明而处在范围内,则将得到警告。为了说明这点,请移除上面代码中的 // 字符以声明 int i

2 /Zc:wchar_t wchar_t 是本机类型)

如果未指定 /Zc:wchar_t ,则编译器要求您或者定义 wchar_t ,或者包括定义 wchar_t 的众多头文件中的一个文件(例如 wchar.h )。 wchar_t 通常定义为 unsigned short

在指定 /Zc:wchar_t 编译器选项时,类型 wchar_t 成为映射到 __wchar_t 的本机类型,其映射方式与 short 映射到 __int16 相同。

如果使用 /Zc:wchar_t ,编译器将 wchar_t 识别为本机类型。有关 wchar_t 的更多信息,请参见数据类型范围。

__wchar_t 始终可用。

通过同时为 wchar_t 的无符号短格式和 __wchar_t 变体提供重载,您可以创建能够轻松通过用(或未用) /Zc:wchar_t 编译的代码链接的库,并且无需提供该库的两个不同的版本(启用和未启用 /Zc:wchar_t 的版本)。

指定 /Zc:wchar_t 时,定义 _WCHAR_T_DEFINED _NATIVE_WCHAR_T_DEFINED 符号;有关更多信息,请参见预定义宏。

Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的 属性页 对话框。
  2. 单击 “C/C++” 文件夹。
  3. 单击 语言 属性页。
  4. 修改 wchar_t 视为内置类型 属性。

例子说明:

/Ob (内联函数展开)

/Ob{0|1|2}

内联函数展开 ”(/Ob n ) 选项控制函数的内联展开,其中 n 是下列之一:

/Ob0

禁用内联展开(默认情况下是打开的)。

/Ob1

只展开标记为 inline __inline 的函数,或在类声明内定义的 C++ 成员函数中的函数。

/Ob2

展开标记为 inline __inline 的函数和编译器选择的任何其他函数(由编译器自行进行展开,通常称作自动内联)。 此选项要求使用 /O1/O2/Ox/Og 启用优化。

编译器将内联展开选项和关键字视为建议。不保证函数将内联展开。无法强制编译器内联特定函数。

还可以使用 #pragma auto_inline 将某些函数排除在作为内联展开的候选函数而加以考虑的函数之外。另见 #pragma intrinsic

Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的 属性页 对话框。
  2. 单击 “C/C++” 文件夹。
  3. 单击 优化 属性页。
  4. 修改 内联函数展开 属性。

例子说明:

1

class A

{

A(){};//

隐含 inline 模式 void fun(){cout << “OB” << endl;}// 隐含 inline 模式 }

如上面的函数,在类或者结构体内定义的函数,将自动设置为 inline 模式

MS 还有一个关键字 __forceinline (强制 inline ),使用这个关键字后,如果函数没有被 __forceinline 将会产成一级警告(警告号是 4714

函数或者编译器设置属于下面的情况,使用 inline,__inline,__forceinline 将失效。

1 :内联模式( /Ob0 )关闭的( debug 模式下默认设置)

2 :函数和调用者使用不同异常类型的。

3 :可变参数函数

4 :函数使用 inline 关键字,但是没有使用编译设置 /Og( 全局优化 ), /Ox( 完全优化 ), /O1( 最小化大小 ), or /O2( 最小化速度 ).

5 :函数使用 inline 关键字,编译选项没有设置返回值检查异常类型,编译选项为 /GX 启用异常处理 , /EHs, or /EHa 它通知编译器假定 extern C 函数从不引发异常

6 :函数接受存在异常类型的拷贝构造对象,但是开启为 /GX 启用异常处理 , /EHs, or /EHa 它通知编译器假定 extern C 函数从不引发异常

7 :函数是一个循环体并且没有使用 #pragma inline_recursion(on) 指定的。(使用 pragma 选项,循环体函数将 inline ,循环体内执行循环次数是 8 次,可以通过 inline_depth 设置

8 :函数是虚函数,或者被虚函数调用。(直接调用虚函数被 inline

9 :程序获得一个函数地址,并且通过指针访问这个地址,函数被 inlined 的。

10 :函数调用约定为 naked __declspec .

主要参考资料: WSDN

声明:云栖社区站内文章,未经作者本人允许或特别声明,严禁转载,但欢迎分享。

原文  https://yq.aliyun.com/articles/6342
正文到此结束
Loading...