/Zc:inline(移除未引用的 COMDAT)

移除作为 COMDAT 或仅具有内部链接的未引用函数或数据。 在 /Zc:inline 下,编译器指定具有内联数据或函数的转换单元还必须包含其定义。

语法

/Zc:inline[-]

注解

指定 /Zc:inline 时,编译器不会为未引用的 COMDAT 函数或数据发出符号信息。 或者,不会对仅具有内部链接的数据或函数发出符号信息。 此优化将简化在发布生成中或在指定 /OPT:REF 链接器选项时链接器所执行的一些工作。 编译器优化可显著减小 .obj 文件大小并提高链接器速度。 禁用优化 (/Od) 时,不会启用编译器选项。 或者,指定 /GL(整个程序优化)时,也不会启用编译器选项。

默认情况下,此选项在命令行版本中处于关闭状态 (/Zc:inline-)。 /permissive- 选项不启用 /Zc:inline。 在 MSBuild 项目中,该选项由“配置属性”>“C/C++”>“语言”>“移除未引用的代码和数据”属性进行设置,默认情况下设置为“是”。

如果指定 /Zc:inline,则编译器强制执行 C++11 需求,所有声明为 inline 的函数都必须具有在同一转换单元中(如果使用了这些函数)可用的定义。 未指定该选项时,即使没有可见定义,Microsoft 编译器仍允许调用声明为 inline 的函数的不一致代码。 有关详细信息,请参阅 3.2 节和 7.1.2 节中的 C++11 标准。 Visual Studio 2013 Update 2 中引入了此编译器选项。

若要使用 /Zc:inline 选项,请更新不符合标准的代码。

此示例显示在使用默认 /Zc:inline- 选项时,在不符合规定地使用没有定义的内联函数声明的情况下,仍然能够进行编译和链接的方式:

源文件 example.h

// example.h
// Compile by using: cl /W4 /EHsc /O2 zcinline.cpp example.cpp
#pragma once

class Example {
public:
   inline void inline_call(); // declared but not defined inline
   void normal_call();
   Example() {};
};

源文件 example.cpp

// example.cpp
// Compile by using: cl /W4 /EHsc /O2 zcinline.cpp example.cpp
#include <stdio.h>
#include "example.h"

void Example::inline_call() {
   printf("inline_call was called.\n");
}

void Example::normal_call() {
   printf("normal_call was called.\n");
   inline_call(); // with /Zc:inline-, inline_call forced into .obj file
}

源文件 zcinline.cpp

// zcinline.cpp
// Compile by using: cl /W4 /EHsc /O2 zcinline.cpp example.cpp
#include "example.h"

int main() {
   Example example;
   example.inline_call(); // normal call when definition unavailable
}

启用 /Zc:inline 时,相同的代码会导致 LNK2019 错误,因为编译器未在 example.obj 中发出 Example::inline_call 的非内联代码体。 缺失的代码会导致 main 中的非内联调用以引用未定义的外部符号。

若要解决此错误,可从 Example::inline_call 的声明中移除 inline 关键字、将 Example::inline_call 的定义移到头文件中,或将 Example 的实现移到 main.cpp 中。 下一个示例将定义移到头文件中,其中该定义对包含该头文件的所有调用方都可见。

源文件 example2.h

// example2.h
// Compile by using: cl /W4 /EHsc /O2 zcinline2.cpp example2.cpp
#pragma once
#include <stdio.h>

class Example2 {
public:
   inline void inline_call() {
      printf("inline_call was called.\n");
   }
   void normal_call();
   Example2() {};
};

源文件 example2.cpp

// example2.cpp
// Compile by using: cl /W4 /EHsc /O2 zcinline2.cpp example2.cpp
#include "example2.h"

void Example2::normal_call() {
   printf("normal_call was called.\n");
   inline_call();
}

源文件 zcinline2.h

// zcinline2.cpp
// Compile by using: cl /W4 /EHsc /O2 zcinline2.cpp example2.cpp
#include "example2.h"

int main() {
   Example2 example2;
   example2.inline_call(); // normal call when definition unavailable
}

有关 Visual C++ 中一致性问题的详细信息,请参阅非标准行为

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

  1. 打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性

  2. 选择“配置属性”>“C/C++”>“语言”属性页。

  3. 修改“移除未引用的代码和数据”属性,然后选择“确定”。

另请参阅

/Zc(一致性)