/Zc:inline
(移除未引用的 COMDAT)
移除作为 COMDAT 或仅具有内部链接的未引用函数或数据。 在 /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 开发环境中设置此编译器选项
打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性。
选择“配置属性”>“C/C++”>“语言”属性页。
修改“移除未引用的代码和数据”属性,然后选择“确定”。