Professional Documents
Culture Documents
Visual C++ provides two ways of building a C/C++ program. The easiest (and most common) way is to build
within the Visual Studio IDE. The other way is to build from a command prompt using command-line tools. In
either case, you can create and edit your source files using Visual Studio or a third-party editor of your choice.
In This Section
MSBuild reference for C++ projects
MSVC Compiler Reference
Describes the MSVC compiler, which creates an object file containing machine code, linker directives, sections,
external references, and function/data names.
MSVC linker reference
Describes the linker, which combines code from the object files created by the compiler and from statically linked
libraries, resolves the name references, and creates an executable file.
Unicode Support in the Compiler and Linker
Additional MSVC Build Tools
Additional command-line tools for C++.
C/C++ Build Errors
Introduces the build errors section in the table of contents.
Related Sections
C/C++ Preprocessor Reference
Discusses the preprocessor, which prepares source files for the compiler by translating macros, operators, and
directives.
Understanding Custom Build Steps and Build Events
Discusses customizing the build process.
Building a C/C++ Program
Provides links to topics describing building your program from the command line or from the integrated
development environment of Visual Studio.
MSVC Compiler Command-Line Syntax
Describes setting compiler options in the development environment or on the command line.
MSVC Compiler Options
Provides links to topics discussing using compiler options.
MSVC linker reference
Describes setting linker options inside or outside the integrated development environment.
MSVC Linker Options
Provides links to topics discussing using linker options.
BSCMAKE Reference
Describes the Microsoft Browse Information Maintenance Utility (BSCMAKE.EXE ), which builds a browse
information file (.bsc) from .sbr files created during compilation.
LIB Reference
Describes the Microsoft Library Manager (LIB.exe), which creates and manages a library of Common Object File
Format (COFF ) object files.
EDITBIN Reference
Describes the Microsoft COFF Binary File Editor (EDITBIN.EXE ), which modifies Common Object File Format
(COFF ) binary files.
DUMPBIN Reference
Describes the Microsoft COFF Binary File Dumper (DUMPBIN.EXE ), which displays information about Common
Object File Format (COFF ) binary files.
NMAKE Reference
Describes the Microsoft Program Maintenance Utility (NMAKE.EXE ), which is a tool that builds projects based on
commands contained in a description file.
MSBuild reference for C++ projects
3/12/2019 • 2 minutes to read • Edit Online
MSBuild is the native build system for all projects in Visual Studio, including C++ projects. When you build a
project in the Visual Studio integrated development environment (IDE ), it invokes the msbuild.exe tool, which in
turn consumes the .vcxproj project file, and various .targets and .props files. In general, we strongly recommend
using the Visual Studio IDE to set project properties and invoke MSBuild. Manually editing project files can lead to
serious problems if not done correctly.
If for some reason you wish to use MSBuild directly from the command line, see Use MSBuild from the command
line. For more information about MSBuild in general, see MSBuild in the Visual Studio documentation.
In this section
MSBuild internals for C++ projects
Information about how properties and targets are stored and consumed.
Common macros for build commands and properties
Describes macros (compile-time constants) that can be used to define properties such as paths and product
versions.
File types created for C++ projects
Describes the various kinds of files that Visual Studio creates for different project types.
Visual Studio C++ project templates
Describes the MSBuild-based project types that are available for C++.
C++ new item templates
Describes source files and other items you can add to a Visual Studio project.
Precompiled header files How to use precompiled header files and how to create your own custom precompiled
code to speed up build times.
Visual Studio project property reference
Reference documentation for project properties that are set in the Visual Studio IDE.
See Also
C/C++ Building Reference
MSBuild internals for C++ projects
3/12/2019 • 5 minutes to read • Edit Online
When you set project properties in the IDE and then save the project, Visual Studio writes the project settings to
your project file. The project file contains settings that are unique to your project, but it does not contain all the
settings that are required to build your project. The project file contains Import elements that include a network of
additional support files. The support files contain the remaining properties, targets, and settings that are required
to build the project.
Most targets and properties in the support files exist solely to implement the build system. The following section
discusses some useful targets and properties that you can specify on the MSBuild command line. To discover more
targets and properties, explore the files in the support file directories.
DIRECTORY DESCRIPTION
drive:\Program Files (x86)\Microsoft Visual Contains the primary target files (.targets) and property files
Studio\year\edition\Common7\IDE\VC\VCTargets\ (.props) that are used by the targets. By default, the
$(VCTargetsPath) macro references this directory.
drive:\Program Files (x86)\MSBuild\Microsoft.Cpp
(x86)\v4.0\version\
drive:\Program Files (x86)\Microsoft Visual Contains platform-specific target and property files that
Studio\year\edition\Common7\IDE\VC\VCTargets\Platforms\p override targets and properties in its parent directory. This
latform\ directory also contains a DLL that defines the tasks that are
used by the targets in this directory.
drive:\Program Files
(x86)\MSBuild\Microsoft.Cpp\v4.0\version\Platforms\platform The platform placeholder represents the ARM, Win32, or x64
\ subdirectory.
drive:\Program Files (x86)\Microsoft Visual Contains the directories that enable the build to generate
Studio\year\edition\Common7\IDE\VC\VCTargets\Platforms\p C++ applications by using the specified toolset.
latform\PlatformToolsets\toolset\
The year and edition placeholders are used by Visual Studio
drive:\Program Files 2017 and later editions. The version placeholder is V110 for
(x86)\MSBuild\Microsoft.Cpp\v4.0\version\Platforms\platform Visual Studio 2012, V120 for Visual Studio 2013, or V140 for
\PlatformToolsets\toolset\ Visual Studio 2015. The platform placeholder represents the
ARM, Win32, or x64 subdirectory. The toolset placeholder
drive:\Program Files represents the toolset subdirectory, for example, v140 for
(x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\platform\Platfor building Windows apps by using the Visual Studio 2015
mToolsets\toolset\ toolset, v120_xp to build for Windows XP using the Visual
Studio 2013 toolset, or v110_wp80 to build Windows Phone
8.0 apps by using the Visual Studio 2012 toolset.
The path that contains the directories that enable the build to
generate either Visual Studio 2008 or Visual Studio 2010
applications doesn't include the version, and the platform
placeholder represents the Itanium, Win32, or x64
subdirectory. The toolset placeholder represents the v90 or
v100 toolset subdirectory.
DIRECTORY DESCRIPTION
Support Files
The support file directories contain files with these extensions:
EX TENSION DESCRIPTION
.targets Contains Target XML elements that specify the tasks that
are executed by the target. May also contain PropertyGroup ,
ItemGroup , ItemDefinitionGroup , and user-defined Item
elements that are used to assign files and command-line
options to task parameters.
.xml Contains XML elements that declare and initialize IDE user
interface elements such as property sheets and property
pages, and text box and list box controls.
The .xml files directly support the IDE, not MSBuild. However,
the values of IDE properties are assigned to build properties
and items.
PreferredToolArchitecture property
The PreferredToolArchitecture property determines whether the 32-bit or 64-bit compiler and tools are used in
the build. This property does not affect the output platform architecture or configuration. By default, MSBuild uses
the x86 version of the compiler and tools if this property is not set.
For example, set the PreferredToolArchitecture property to x64 to use the 64-bit compiler and tools to build your
application:
msbuild myProject.vcxproj /p:PreferredToolArchitecture=x64
UseEnv property
By default, the platform-specific settings for the current project override the PATH, INCLUDE, LIB, LIBPATH,
CONFIGURATION, and PLATFORM environment variables. Set the UseEnv property to true to guarantee that
the environment variables are not overridden.
msbuild myProject.vcxproj /p:UseEnv=true
Targets
There are hundreds of targets in the Visual Studio support files. However, most are system-oriented targets that
the user can ignore. Most system targets are prefixed by an underscore (_), or have a name that starts with
"PrepareFor", "Compute", "Before", "After", "Pre", or "Post".
The following table lists several useful user-oriented targets.
TARGET DESCRIPTION
Xsd Executes the XML Schema Definition tool, xsd.exe. See note
below.
NOTE
In Visual Studio 2017, C++ project support for xsd files is deprecated. You can still use
Microsoft.VisualC.CppCodeProvider by adding CppCodeProvider.dll manually to the GAC.
See Also
MSBuild Task Reference
BscMake Task
CL Task
CPPClean Task
LIB Task
Link Task
MIDL Task
MT Task
RC Task
SetEnv Task
VCMessage Task
XDCMake Task
Common macros for build commands and properties
3/12/2019 • 6 minutes to read • Edit Online
Depending on your installation options, Visual Studio can make hundreds of macros available to you. These
correspond to the MSBuild properties that are set by default, or in .props or .targets files, or in your project
settings. You can use these macros anywhere in a project's Property Pages dialog box where strings are accepted.
These macros are not case sensitive.
MACRO DESCRIPTION
$(FrameworkDir) The directory into which the .NET Framework was installed.
$(FrameworkSDKDir) The directory into which you installed the .NET Framework.
The .NET Framework could have been installed as part of
Visual Studio or separately.
$(FxCopDir) The path to the fxcop.cmd file. The fxcop.cmd file is not
installed with all Visual C++ editions.
$(ProjectExt) The file extension of the project. It includes the '.' before the
file extension.
$(ProjectFileName) The file name of the project (defined as base name + file
extension).
$(SolutionExt) The file extension of the solution. It includes the '.' before the
file extension. Defined only when building a solution in the
IDE.
$(SolutionFileName) The file name of the solution (defined as base name + file
extension). Defined only when building a solution in the IDE.
$(SolutionName) The base name of the solution. Defined only when building a
solution in the IDE.
$(TargetDir) The directory of the primary output file for the build (defined
as drive + path); includes the trailing backslash '\'.
$(TargetExt) The file extension of the primary output file for the build. It
includes the '.' before the file extension.
$(TargetFileName) The file name of the primary output file for the build (defined
as base name + file extension).
MACRO DESCRIPTION
$(TargetName) The base name of the primary output file for the build.
$(TargetPath) The absolute path name of the primary output file for the
build (defined as drive + path + base name + file extension).
$(VCInstallDir) The directory that contains the C++ content of your Visual
Studio installation. This property contains the version of the
targeted Visual C++ toolset, which might be different that the
host Visual Studio. For example, when building with
$(PlatformToolset) = v140 , $(VCInstallDir) contains the
path to the Visual C++ 2015 installation.
$(VSInstallDir) The directory into which you installed Visual Studio. This
property contains the version of the targeted Visual Studio
toolset, which might be different that the host Visual Studio.
For example, when building with
$(PlatformToolset) = v110 , $(VSInstallDir) contains the
path to the Visual Studio 2012 installation.
$(WebDeployPath) The relative path from the web deployment root to where the
project outputs belong. Returns the same value as
RelativePath.
Obsolete macros
The build system for C++ was significantly changed between Visual Studio 2008 and Visual Studio 2010. Many
macros used in earlier project types have been changed to new ones. These macros are no longer used or have
been replaced by one or more equivalent properties or item metadata macro (%(name)) values. Macros that are
marked "migrated" can be updated by the project migration tool. If the project that contains the macro is migrated
from Visual Studio 2008 or earlier to Visual Studio 2010, Visual Studio converts the macro to the equivalent
current macro. Later versions of Visual Studio can't convert projects from Visual Studio 2008 and earlier to the
new project type. You must convert these projects in two steps; first convert them to Visual Studio 2010, and then
convert the result to your newer version of Visual Studio. For more information, see Overview of potential
upgrade issues.
MACRO DESCRIPTION
$(InputExt) (Migrated.) The file extension of the input file. It includes the '.'
before the file extension. If the project is the input, then this
macro is equivalent to $(ProjectExt). For source files, this is
%(Extension).
$(InputFileName) (Migrated.) The file name of the input file (defined as base
name + file extension). If the project is the input, then this
macro is equivalent to $(ProjectFileName). For source files,
this is %(Identity).
MACRO DESCRIPTION
$(InputName) (Migrated.) The base name of the input file. If the project is
the input, then this macro is equivalent to $(ProjectName).
For source files, this is %(Filename).
$(InputPath) (Migrated.) The absolute path name of the input file (defined
as drive + path + base name + file extension). If the project is
the input, then this macro is equivalent to $(ProjectPath).
For source files, this is %(FullPath).
$(ParentName) Name of the item containing this project item. This will be the
parent folder name, or project name.
$(SafeInputName) The name of the file as a valid class name, minus file
extension. This property does not have an exact equivalent.
$(SafeParentName) The name of the immediate parent in valid name format. For
example, a form is the parent of a .resx file. This property does
not have an exact equivalent.
$(SafeRootNamespace) The namespace name in which the project wizards will add
code. This namespace name will only contain characters that
would be permitted in a valid C++ identifier. This property
does not have an exact equivalent.
See also
Visual Studio Projects - C++
Visual C++ porting and upgrading guide
Overview of potential upgrade issues
File Types Created for Visual Studio C++ Projects
3/12/2019 • 3 minutes to read • Edit Online
This topic describes all the types of files that are associated with Visual Studio projects for classic desktop
applications. The actual files included in your project depend on the project type and the options you select when
using a wizard.
CLR Projects
ATL Program or Control Source and Header Files
MFC Program or Control Source and Header Files
Precompiled Header Files
Resource Files
Help Files (WinHelp)
Hint Files
When you create a Visual Studio project, you might be creating a new solution, or you might be adding a project
to a solution. Non-trivial applications are commonly developed with multiple projects in a solution.
Projects usually produce either an EXE or a DLL. Projects can be dependent on each other; during the build
process, the Visual Studio environment checks dependencies both within and between projects. Each project has
core source code, and depending on the kind of project, it may have many other files containing various aspects of
the project. The contents of these files are indicated by the file extension. The Visual Studio development
environment uses the file extensions to determine how to handle the file contents during a build.
The following table shows common files in a Visual Studio project, and identifies them with their file extension.
.bmp, .dib, .gif, .jpg, .jpe, .png Resource General image files.
.htm, .html, .xsp, .asp, .htc, .hta, .xml Resource Common Web files.
more information.
For information on other files associated with Visual Studio, see File Types and File Extensions in Visual Studio
.NET.
Project files are organized into folders in Solution Explorer. Visual Studio creates a folder for source files, header
files, and resource files, but you can reorganize these folders or create new ones. You can use folders to organize
explicitly logical clusters of files within the hierarchy of a project. For example, you could create folders to contain
all your user interface source files, or specifications, documentation, or test suites. All file folder names should be
unique.
When you add an item to a project, you add the item to all configurations for that project, regardless of whether
or not the item is buildable. For example, if you have a project named MyProject, adding an item adds it to both
the Debug and Release project configurations.
See Also
Creating and Managing Visual Studio C++ Projects
Visual Studio C++ Project Types
Project and Solution Files
3/12/2019 • 2 minutes to read • Edit Online
The following files are created when you create a project in Visual Studio. They are used to manage project files in
the solution.
SOLUTION EXPLORER
FILENAME DIRECTORY LOCATION LOCATION DESCRIPTION
Projname.vcxitems Projname Not displayed in Solution The Shared Items project file.
Explorer This project isn't built.
Instead, the project can be
referenced by another C++
project, and its files will
become part of the
referencing project's build
process. This can be used to
share common code with
cross-platform C++ projects.
Projname.vcxproj.user Projname Not displayed in Solution The migration user file. After
Explorer a project is migrated from
Visual Studio 2008, this file
contains information that
was converted from any
.vsprops file.
See also
File Types Created for Visual C++ Projects
C++ project templates
3/12/2019 • 3 minutes to read • Edit Online
Visual Studio project templates generate source code files, compiler options, menus, toolbars, icons, references,
and #include statements that are appropriate for the kind of project you want to create. Visual Studio includes
several kinds of Visual C++ project templates and provides wizards for many of them so that you can customize
your projects as you create them. Immediately after you create a project, you can build it and run the application;
it's good practice to build intermittently as you develop your application.
NOTE
You can create a C-language project by using C++ project templates. In the generated project, locate files that have a .cpp
file name extension and change it to .c. Then, on the Project Properties page for the project (not for the solution), expand
Configuration Properties, C/C++ and select Advanced. Change the Compile As setting to Compile as C Code (/TC).
Project templates
The project templates included in Visual Studio depend on the product version and the workloads you've installed.
If you've installed the Desktop development with C++ workload, Visual Studio has these Visual C++ project
templates.
Windows Desktop
PROJECT TEMPLATE DESCRIPTION
Windows Desktop Application A project for creating a Windows desktop (Win32) application.
Windows Desktop Wizard A wizard for creating Windows desktop applications and
libraries with additional options.
General
PROJECT TEMPLATE DESCRIPTION
Shared Items Project A project used for sharing code files or resource files between
multiple projects. This project type does not produce an
executable file.
ATL
PROJECT TEMPLATE DESCRIPTION
Test
PROJECT TEMPLATE DESCRIPTION
Native Unit Test Project A project that contains native C++ unit tests.
MFC
If you add the MFC and ATL support component to your Visual Studio installation, these project templates are
added to Visual Studio.
MFC Application A project for creating an application that uses the Microsoft
Foundation Class (MFC) Library.
MFC ActiveX Control A project for creating an ActiveX control that uses the MFC
library.
MFC DLL A project for creating a dynamic-link library that uses the
MFC library.
DirectX 11 App A project for a Universal Windows Platform app that uses
DirectX 11.
DirectX 12 App A project for a Universal Windows Platform app that uses
DirectX 12.
DirectX 11 and XAML App A project for a Universal Windows Platform app that uses
DirectX 11 and XAML.
Unit Test App A project to create a unit test app for Universal Windows
Platform (UWP) apps.
Static Library A project for a native static link library (LIB) that can be used
by a Universal Windows Platform app or runtime component.
Windows Runtime Component A project for a Windows Runtime component that can be
used by a Universal Windows Platform app, regardless of the
programming language in which the app is written.
Windows Application Packaging Project A project that creates a UWP package that enables a desktop
application to be side-loaded or distributed via the Microsoft
Store.
TODO Comments
Many of the files generated by a project template contain TODO comments to help you identify where you can
provide your own source code. For more information about how to add code, see Adding Functionality with Code
Wizards and Working with Resource Files.
Using Visual C++ Add New Item Templates
3/12/2019 • 2 minutes to read • Edit Online
You can easily add items that are common to Visual C++ projects by using the Add New Item command. When
you use the Add New Item command, the Add New Item dialog box appears with a list of item templates, which
add the appropriate files to your project.
The following table is an alphabetical list of Visual C++ Add New Item templates.
TEMPLATE DESCRIPTION
Code Analysis Rule Set (.ruleset) Creates a settings file for configuring Code Analysis.
Discovery File, Static (.disco) Creates a static discovery file, which is an XML document that
contains links to other resources that describe the XML Web
service, enables programmatic discovery of an XML Web
service.
Frameset (.htm) Adds an HTML file that hosts multiple HTML pages.
Installer Class Adds a class that inherits from the Installer using CLR features.
Server Response File (.srf) Creates a server response file that is used with ATL Server.
SQL Script File (.sql) Creates an SQL script file. Note: This template is not a
Professional Edition feature.
Style Sheet (.css) Adds a cascading style sheet used for rich HTML style
definitions.
XML Schema File (.xsd) Creates a file that is used to define a schema for XML
documents.
See also
Adding Functionality with Code Wizards
Resource Files (C++)
3/12/2019 • 2 minutes to read • Edit Online
Resources are interface elements that provide information to the user. Bitmaps, icons, toolbars, and cursors are all
resources. Some resources can be manipulated to perform an action such as selecting from a menu or entering
data in dialog box.
See Working with Resources for more information.
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION
Projname.ico Projname\res Resource Files The icon file for the project
or control. This icon appears
when the application is
minimized. It is also used in
the application's About box.
By default, MFC provides the
MFC icon, and ATL provides
the ATL icon.
See also
File Types Created for Visual C++ Projects
Files Created for CLR Projects
3/12/2019 • 2 minutes to read • Edit Online
When you use Visual C++ templates to create your projects, several files are created, depending on which
template you use. The following table lists all the files that are created by project templates for .NET Framework
projects.
AssemblyInfo.cpp The file that contains information (that is, attributes, files,
resources, types, versioning information, signing information,
and so on) for modifying the project's assembly metadata. For
more information see Assembly Concepts.
projname.cpp The main source file and entry point into the application that
Visual Studio created for you. Identifies the project .dll file and
the project namespace. Provide your own code in this file.
projname.h The main include file for the project, which contains all
declarations, global symbols, and #include directives for
other header files.
ReadMe.txt A file describing each file in your project using the actual
filenames created by the template.
ATL Program or Control Source and Header Files
3/12/2019 • 2 minutes to read • Edit Online
The following files are created when you create an ATL project in Visual Studio, depending on the options you
select for the project you create.
All of these files are located in the Projname directory, and in either the Header Files (.h files) folder or Source Files
(.cpp files) folder in Solution Explorer.
Projname.h The main include file containing the C++ interface definitions
and GUID declarations of the items defined in ATLSample.idl. It
is regenerated by MIDL during compilation.
See also
File Types Created for Visual C++ Projects
MFC Program or Control Source and Header Files
CLR Projects
MFC Program or Control Source and Header Files
3/12/2019 • 3 minutes to read • Edit Online
The following files are created when you create an MFC project in Visual Studio, depending on the options you
select for the project you create. For example, your project contains Projnamedlg.cpp and Projnamedlg.h files only
if you create a dialog-based project or class.
All of these files are located in the Projname directory, and in either the Header Files (.h files) folder or Source
Files (.cpp files) folder in Solution Explorer.
Projname.h The main include file for the program or DLL. It contains all
global symbols and #include directives for other header
files. It derives the CPrjnameApp class from CWinApp and
declares an InitInstance member function. For a control,
the CPrjnameApp class is derived from COleControlModule .
Projname.cpp The main program source file. It creates one object of the class
CPrjnameApp , which is derived from CWinApp , and overrides
the InitInstance member function.
Projnameview.cpp, Projnameview.h Derive and implement the view class, named CProjnameView ,
which is used to display and print the document data. The
CProjnameView class is derived from one of the following
MFC classes:
- CEditView
- CFormView
- CRecordView
- COleDBRecordView
- CTreeView
- CListView
- CRichEditView
- CScrollView
- CView
- CHTMLView
- CHTMLEditView
Mainfrm.cpp, Mainfrm.h Derive the CMainFrame class from either CFrameWnd (for
SDI applications) or CMDIFrameWnd (for MDI applications).
The CMainFrame class handles the creation of toolbar
buttons and the status bar, if the corresponding options are
selected in the application wizard's Application Options page
(step 4 of 6). For information on using CMainFrame, see The
Frame-Window Classes Created by the Application Wizard.
FILE NAME DESCRIPTION
See also
File Types Created for Visual C++ Projects
ATL Program or Control Source and Header Files
CLR Projects
Help Files (HTML Help)
3/12/2019 • 2 minutes to read • Edit Online
The following files are created when you add the HTML Help type of Help support to your application by selecting
the Context-sensitive help check box and then selecting HTML Help format in the Advanced Features page of
the MFC Application Wizard.
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION
Afxprint.htm Projname\hlp HTML Help Topics Contains the help topics for
the printing commands.
See also
File Types Created for Visual C++ Projects
Help Files (WinHelp)
3/12/2019 • 2 minutes to read • Edit Online
The following files are created when you add the WinHelp type of Help support to your application by selecting
the Context-sensitive help check box and then selecting WinHelp format in the Advanced Features page of the
MFC Application Wizard.
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION
You can add WinHelp support to an MFC ActiveX Control project by selecting Generate help files in the
Application Settings tab of the MFC ActiveX Control Wizard. The following files are added to your project when
you add Help support to an MFC ActiveX control:
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION
See also
File Types Created for Visual C++ Projects
Hint Files
3/12/2019 • 8 minutes to read • Edit Online
A hint file contains macros that would otherwise cause regions of code to be skipped by the C++ Browsing
Database Parser. When you open a Visual C++ project, the parser analyzes the code in each source file in the
project and builds a database with information about every identifier. The IDE uses that information to support
code browsing features such as the Class View browser and the Navigation Bar.
The C++ Browsing Database Parser is a fuzzy parser that can parse large amounts of code in a short amount of
time. One reason it's fast is because it skips the content of blocks. For instance, it only records the location and
parameters of a function, and ignores its contents. Certain macros can cause issues for the heuristics used to
determine the start and end of a block. These issues cause regions of code to be recorded improperly.
These skipped regions can manifest in multiple ways:
Missing types and functions in Class View, Go To and Navigation Bar
Incorrect scopes in the Navigation Bar
Suggestions to Create Declaration/Definition for functions that are already defined
A hint file contains user-customizable hints, which have the same syntax as C/C++ macro definitions. Visual C++
includes a built-in hint file that is sufficient for most projects. However, you can create your own hint files to
improve the parser specifically for your project.
IMPORTANT
If you modify or add a hint file, you need to take additional steps in order for the changes to take effect:
In versions before Visual Studio 2017 version 15.6: Delete the .sdf file and/or VC.db file in the solution for all changes.
In Visual Studio 2017 versions 15.6 through 15.9: Close and reopen the solution after adding new hint files.
Scenario
#define NOEXCEPT noexcept
void Function() NOEXCEPT
{
}
Without a hint file, Function doesn't show up in Class View, Go To or the Navigation Bar. After adding a hint
file with this macro definition, the parser now understands and replaces the NOEXCEPT macro, which allows it to
correctly parse the function:
#define NOEXCEPT
Disruptive Macros
There are two categories of macros that disrupt the parser:
Macros that encapsulate keywords that adorn a function
#define NOEXCEPT noexcept
#define STDMETHODCALLTYPE __stdcall
For these types of macros, only the macro name is required in the hint file:
#define NOEXCEPT
#define STDMETHODCALLTYPE
#define BEGIN {
For these types of macros, both the macro name and its contents are required in the hint file:
#define BEGIN {
Editor Support
Starting in Visual Studio 2017 version 15.8 there are several features to identify disruptive macros:
Macros that are inside regions skipped by the parser are highlighted.
There's a Quick Action to create a hint file that includes the highlighted macro, or if there's an existing hint
file, to add the macro to the hint file.
After executing either of the Quick Actions, the parser reparses the files affected by the hint file.
By default, the problem macro is highlighted as a suggestion. The highlight can be changed to something more
noticeable, such as a red or green squiggle. Use the Macros in Skipped Browsing Regions option in the Code
Squiggles section under Tools > Options > Text Editor > C/C++ > View.
Architecture
Hint files relate to physical directories, not the logical directories shown in Solution Explorer. You don't have to
add a hint file to your project for the hint file to have an effect. The parsing system uses hint files only when it
parses source files.
Every hint file is named cpp.hint. Many directories can contain a hint file, but only one hint file can occur in a
particular directory.
Your project can be affected by zero or more hint files. If there are no hint files, the parsing system uses error
recovery techniques to ignore indecipherable source code. Otherwise, the parsing system uses the following
strategy to find and gather hints.
Search Order
The parsing system searches directories for hint files in the following order.
The directory that contains the installation package for Visual C++ ( vcpackages). This directory contains a
built-in hint file that describes symbols in frequently used system files, such as windows.h. Consequently,
your project automatically inherits most of the hints that it needs.
The path from the root directory of a source file to the directory that contains the source file itself. In a
typical Visual C++ project, the root directory contains the solution or project file.
The exception to this rule is if a stop file is in the path to the source file. A stop file is any file that is named
cpp.stop. A stop file provides additional control over the search order. Instead of starting from the root
directory, the parsing system searches from the directory that contains the stop file to the directory that
contains the source file. In a typical project, you don't need a stop file.
Hint Gathering
A hint file contains zero or more hints. A hint is defined or deleted just like a C/C++ macro. That is, the #define
preprocessor directive creates or redefines a hint, and the #undef directive deletes a hint.
The parsing system opens each hint file in the search order described earlier. It accumulates each file's hints into a
set of effective hints, and then uses the effective hints to interpret the identifiers in your code.
The parsing system uses these rules to accumulate hints:
If the new hint specifies a name that isn't already defined, the new hint adds the name to the effective hints.
If the new hint specifies a name that is already defined, the new hint redefines the existing hint.
If the new hint is an #undef directive that specifies an existing effective hint, the new hint deletes the
existing hint.
The first rule means that effective hints are inherited from previously opened hint files. The last two rules mean
that hints later in the search order can override earlier hints. For example, you can override any previous hints if
you create a hint file in the directory that contains a source file.
For a depiction of how hints are gathered, see the Example section.
Syntax
You create and delete hints by using the same syntax as the preprocessor directives to create and delete macros. In
fact, the parsing system uses the C/C++ preprocessor to evaluate the hints. For more information about the
preprocessor directives, see #define Directive (C/C++) and #undef Directive (C/C++).
The only unusual syntax elements are the @< , @= , and @> replacement strings. These hint-file specific
replacement strings are only used in map macros. A map is a set of macros that relate data, functions, or events to
other data, functions, or event handlers. For example, MFC uses maps to create message maps, and ATL uses
maps to create object maps. The hint-file specific replacement strings mark the starting, intermediate, and ending
elements of a map. Only the name of a map macro is significant. Therefore, each replacement string intentionally
hides the implementation of the macro.
Hints use this syntax:
SYNTAX MEANING
#define hint-name replacement-string A preprocessor directive that defines a new hint or redefines
an existing hint. After the directive, the preprocessor replaces
#define hint-name ( parameter, ... ) replacement-string each occurrence of hint-name in source code with
replacement-string.
#undef hint-name The preprocessor directive that deletes an existing hint. The
name of the hint is provided by the hint-name identifier.
Example
This example shows how hints are accumulated from hint files. Stop files aren't used in this example.
The illustration shows some of the physical directories in a Visual C++ project. There are hint files in the
vcpackages , Debug , A1 , and A2 directories.
Debug
// Debug
#undef _In_
#define OBRACE {
#define CBRACE }
#define RAISE_EXCEPTION(x) throw (x)
#define START_NAMESPACE namespace MyProject {
#define END_NAMESPACE }
A1
// A1
#define START_NAMESPACE namespace A1Namespace {
A2
// A2
#undef OBRACE
#undef CBRACE
Effective Hints
This table lists the effective hints for the source files in this project:
Source File: A1_A2_B.cpp
Effective hints:
See also
File Types Created for Visual C++ Projects
#define Directive (C/C++)
#undef Directive (C/C++)
SAL Annotations
Property Page XML rule files
3/12/2019 • 9 minutes to read • Edit Online
The project property pages in the IDE are configured by XML files in the VCTargets folder. The exact path depends
on which edition(s) of Visual Studio are installed, and the product language. For Visual Studio 2017 Enterprise
Edition, in English, the path is
%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\1033 . The XML files describe the
names of the rules, the categories, and the individual properties, their data type, default values, and how they are to
be displayed. When you set a property in the IDE, the new value is stored in the project file.
The only scenarios in which you need to understand the internal workings of these files and the Visual Studio IDE
are (a) you want to create a custom property page, or (b) you want to customize your project properties by some
means other than through the Visual Studio IDE.
First, let's open the property pages for a project (right click on the project node in Solution Explorer and choose
Properties):
Each node under Configuration Properties is called a Rule. A Rule sometimes represents a single tool like the
compiler, but in general the term refers to something that has properties, that executes and that may produce some
output. Each rule is populated from an xml file in the VCTargets folder. For example, the C/C++ rule that is shown
above is populated by `cl.xml'.
As shown above, each Rule has a set of properties which are organized into categories. Each sub-node under a
Rule represents a category. For example, the Optimization node under C/C++ contains all the optimization-related
properties of the compiler tool. The properties and their values themselves are rendered in a grid format on the
right pane.
You can open cl.xml in notepad or any XML editor (see snapshot below ). You will see a root node called Rule that
has the same list of properties defined under it as is displayed in the UI, along with additional metadata.
<?xml version="1.0" encoding="utf-8"?>
<!--Copyright, Microsoft Corporation, All rights reserved.-->
<Rule Name="CL" PageTemplate="tool" DisplayName="C/C++" SwitchPrefix="/" Order="10"
xmlns="http://schemas.microsoft.com/build/2009/properties"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Rule.Categories>
<Category Name="General" DisplayName="General" />
<Category Name="Optimization" DisplayName="Optimization" />
<Category Name="Preprocessor" DisplayName="Preprocessor" />
<Category Name="Code Generation" DisplayName="Code Generation" />
<Category Name="Language" DisplayName="Language" />
<Category Name="Precompiled Headers" DisplayName="Precompiled Headers" />
<Category Name="Output Files" DisplayName="Output Files" />
<Category Name="Browse Information" DisplayName="Browse Information" />
<Category Name="Advanced" DisplayName="Advanced" />
<Category Name="All Options" DisplayName="All Options" Subtype="Search" />
<Category Name="Command Line" DisplayName="Command Line" Subtype="CommandLine" />
</Rule.Categories>
...
There is one XML file corresponding to every node under Configuration Properties in the property pages UI. You
can add or remove rules in the UI by including or removing locations to corresponding XML files in the project.
For example, this is how Microsoft.CppBuild.targets (one level up from the 1033 folder) includes cl.xml:
If you strip cl.xml of all data, you will end up with the following skeleton:
The following section describes each major elements and some of the metadata that can be attached to them.
1. Rule: Rule is generally the root node in the xml file; it can have many attributes:
a. Name: The Name attribute is an id for the Rule. It needs to be unique among all the property page xml
files for a project.
b. PageTemplate: The value of this attribute is used by the UI to choose from a collection of UI templates.
The "tool" template renders the properties in a standard grid format. Other in-built values for this attribute
are "debugger" and "generic". See the Debugging node and General node, respectively, to see the UI format
resulting from specifying these values. The UI for "debugger" page template uses a drop-down box to
switch between the properties of different debuggers whereas the "generic" template displays different
property categories all in one page as opposed to having multiple category sub-nodes under the Rule node.
This attribute is just a suggestion to the UI; the xml file is designed to be UI independent. A different UI
might use this attribute for different purposes.
c. SwitchPrefix: This is the prefix used in the command line for the switches. A value of "/" would result in
switches that look like /ZI, /nologo, /W3, etc.
d. Order: This is a suggestion to a prospective UI client on the relative location of this Rule compared to all
other Rules in the system.
e. xmlns: This is a standard XAML element. You can see three namespaces listed. These correspond to the
namespaces for the XAML deserialization classes, XAML schema and system namespace, respectively.
f. DisplayName: This is the name that is shown on the property page UI for the Rule node. This value is
localized. We created DisplayName as a child element of Rule rather than as an attribute (like Name or
SwitchPrefix) because of internal localization tool requirements. From XAML’s perspective, both are
equivalent. So, you can just make it an attribute to reduce clutter or leave it as it is.
g. DataSource: This is a very important property that tells the project system the location from which the
property value should read from and written to, and its grouping (explained below ). For cl.xml, these values
are:
Persistence="ProjectFile tells the project system that all properties for the Rule should be written to
the project file or the property sheet file (depending on which node was used to spawn the property
pages). The other possible value is "UserFile" which will write the value to the .user file.
ItemType="ClCompile" says that the properties will be stored as ItemDefinition metadata or item
metadata (the latter only if the property pages were spawned from a file node in solution explorer) of
this item type. If this field is not set, then the property is written as a common property in a
PropertyGroup.
Label="" indicates that when the properties are written as ItemDefinition metadata, the label of the
parent ItemDefinitionGroup will be empty (every MSBuild element can have a Label). Visual Studio
2017 uses labeled groups to navigate the .vcxproj project file. Note that the groups that contain most
Rule properties have an empty string as a label.
HasConfigurationCondition="true" tells the project system to affix a configuration condition to the
value so that it takes effect only for the current project configuration (the condition could be affixed to
the parent group or the value itself). For example, open the property pages off the project node and
set the value of the property Treat Warnings As Error under Configuration Properties > C/C++
General to "Yes". The following value is written to the project file. Notice the configuration condition
attached to the parent ItemDefinitionGroup.
<ItemDefinitionGroup Condition="‘$(Configuration)|$(Platform)’==’Debug|Win32’">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
If this value were set in the property page for a specific file, such as stdafx.cpp, then the property
value would be written under the stdafx.cpp item in the project file as shown below. Notice how the
configuration condition is directly attached to the metadata itself.
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<TreatWarningAsError
Condition="‘$(Configuration)|$(Platform)’==’Debug|Win32’">true</TreatWarningAsError>
</ClCompile>
</ItemGroup>
Another attribute of DataSource not listed above is PersistedName. You can use this attribute to
represent a property in the project file using a different name. By default this attribute is set to the
property’s Name.
An individual property can override its parent Rule’s DataSource. In that case, the location for that
property’s value will be different from other properties in the Rule.
h. There are other attributes of a Rule such as Description, SupportsFileBatching, etc that are not shown
here. The full set of attributes applicable to a Rule or on any other element can be obtained by browsing the
documentation for these types. Alternately, you can examine the public properties on the types in the
Microsoft.Build.Framework.XamlTypes namespace in the Microsoft.Build.Framework .dll assembly.
i. DisplayName, PageTemplate, and Order are UI-related properties that are present in this otherwise
UI-independent data model. These properties are almost certain to be used by any UI that is used to display
the property pages. DisplayName and Description are two properties that are present on almost all
elements in the xml file. And these are the only two properties that are localized (localization of these strings
will be explained in a later post).
2. Category: A Rule can have multiple Categories. The order in which the categories are listed in the xml file is
a suggestion to the UI to display the categories in the same order. For example, the order of the categories
under the C/C++ node as seen in the UI –General, Optimization, Preprocessor, … – is the same as that in
cl.xml. A sample category looks like this:
<Category Name="Optimization">
<Category.DisplayName>
<sys:String>Optimization</sys:String>
</Category.DisplayName>
</Category>
The above snippet shows the Name and DisplayName attributes that have been described before. Once
again, there are other attributes a Category can have that are not used above. You can know about them by
reading the documentation or by examining the assemblies using ildasm.exe.
3. Properties: This is the meat of the xml file and contains the list of all properties in this Rule. Each property
can be one of five possible types shown in the XAML skeleton above. Of course, you could have only a few
of those types in your file. A property has a number of attributes that allow it to be described richly. I’ll
explain only the StringProperty here. The rest are very similar.
<StringProperty Subtype="file" Name="ObjectFileName" Category="Output Files" Switch="Fo">
<StringProperty.DisplayName>
<sys:String>Object File Name</sys:String>
</StringProperty.DisplayName>
<StringProperty.Description>
<sys:String>Specifies a name to override the default object file name; can be file or directory
name.(/Fo[name])</sys:String>
</StringProperty.Description>
</StringProperty>
Most of the attributes in the snippet have been described before. The new ones are Subtype, Category and
Switch.
a. Subtype is an attribute available only for StringProperty and StringListProperty; it gives contextual
information. For example, the value of "file" indicates that the property represents a file path. Such
contextual information is used to enhance the editing experience by providing a Windows Explorer as the
property’s editor that allows the user to choose the file visually.
b. Category: This declares the category under which this property falls. Try to find this property under the
Output Files category in the UI.
c. Switch: When a Rule represents a tool – such as the compiler tool in this case – most properties of the
Rule are passed as switches to the tool executable during build time. The value of this attribute indicates the
switch literal to be used. The property above specifies that its switch should be Fo. Combined with the
SwitchPrefix attribute on the parent Rule, this property is passed to the executable as /Fo"Debug" (visible
in the command line for C/C++ in the property page UI).
Other property attributes include:
d. Visible: If for some reason, you don’t want your property to show up in the property pages (but probably
still available during build time), set this attribute to false.
e. ReadOnly: If you want to provide a read-only view of this property’s value in the property pages, set this
attribute to true.
f. IncludeInCommandLine: Some properties may not need to be passed to a tool during build time.
Setting this attribute to false will prevent it from being passed.
.vcxproj and .props file structure
3/12/2019 • 10 minutes to read • Edit Online
MSBuild is the default project system in Visual Studio; when you choose File > New Project in Visual C++ you
are creating an MSBuild project whose settings are stored in an XML project file that has the extension .vcxproj .
The project file may also import .props files and .targets files where settings can be stored. In most cases, you never
need to manually edit the project file, and in fact you should not edit it manually unless you have a good
understanding of MSBuild. Whenever possible you should use the Visual Studio property pages to modify project
settings (see Set C++ compiler and build properties in Visual Studio. However, in some cases you may need to
modify a project file or property sheet manually. For those scenarios, this article contains basic information about
the structure of the file.
Important:
If you choose to manually edit a .vcxproj file, be aware of these facts:
1. The structure of the file must follow a prescribed form, which is described in this article.
2. The Visual C++ project system currently does not support wildcards in project items. For example, this is
not supported:
<ClCompile Include="*.cpp"/>
3. The Visual C++ project system currently does not support macros in project item paths. For example, this is
not supported:
<ClCompile Include="$(IntDir)\generated.cpp"/>
"Not supported" means that macros are not guaranteed to work for all operations in the IDE. Macros which
don’t change their value in different configurations should work, but might not be preserved if an item is
moved to a different filter or project. Macros which change their value for different configurations will cause
problems because the IDE doesn't expect project item paths to be different for different project
configurations.
4. In order to have project properties correctly added, removed, or modified when edited in the Project
Properties dialog, the file must contain separate groups for each project configuration, and the conditions
must be in this form:
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"
5. Each property must be specified in the group with correct label, as specified in the property rule file. For
more information, see Property page xml rule files.
<MyProperty>abc</MyProperty>
<MyProperty>xyz</MyProperty>
The following snippet shows a minimal .vcxproj file. Any .vcxproj file generated by Visual Studio will contain these
top-level MSBuild elements and they will appear in this order (although they may contain multiple copies of each
such top-level element). Note that Label attributes are arbitrary tags that are only used by Visual Studio as
signposts for editing; they have no other function.
The following sections describe the purpose of each of these elements and why they are ordered this way:
Project element
Project is the root node. It specifies the MSBuild version to use and also the default target to be executed when
this file is passed to MSBuild.exe.
ProjectConfigurations ItemGroup element
ProjectConfigurations contains the project configuration description. Examples are Debug|Win32, Release|Win32,
Debug|ARM and so on. Many project settings are specific to a given configuration. For example, you will probably
want to set optimization properties for a release build but not a debug build.
The ProjectConfigurations item group is not used at build time. The Visual Studio IDE requires it in order to load
the project. This item group can be moved to a .props file and imported into the .vcxproj file. However, in that case,
if you need to add or remove configurations, you must manually edit the .props file; you can't use the IDE.
ProjectConfiguration elements
The following snippet shows a project configuration. In this example 'Debug|x64' is the configuration name. The
project configuration name must be in the format $(Configuration)|$(Platform). A Project Configuration node can
have two properties: Configuration and Platform. Those properties will be automatically set with the values
specified here when the configuration is active.
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
The IDE expects to find a project configuration for any combination of Configuration and Platform values used in
all ProjectConfiguration items. This often means that a project might have meaningless project configurations to
fulfill this requirement. For instance, if a project has these configurations:
Debug|Win32
Retail|Win32
Special 32-bit Optimization|Win32
then it must also have these configurations, even though "Special 32-bit Optimization" is meaningless for x64:
Debug|x64
Retail|x64
Special 32-bit Optimization|x64
You can disable the build and deploy commands for any configuration in the Solution Configuration Manager.
Globals PropertyGroup element
Globals contains project level settings such as ProjectGuid, RootNamespace, and ApplicationType/
ApplicationTypeRevision. The last two often define the target OS. A project can only target a single OS due to the
fact that references and project items cannot have conditions currently. These properties are typically not
overridden elsewhere in the project file. This group is not configuration-dependent and therefore typically only one
Globals group exists in the project file.
Microsoft.Cpp.default.props Import element
The Microsoft.Cpp.default.props property sheet comes with Visual Studio and cannot be modified. It contains
the default settings for the project. The defaults might vary depending on the ApplicationType.
Configuration PropertyGroup elements
The Microsoft.Cpp.props property sheet (directly or via imports) defines the default values for many tool-specific
properties such as the compiler's Optimization and Warning Level properties, the MIDL tool's TypeLibraryName
property, and so on. It also imports various system property sheets based on which configuration properties are
defined in the property group immediately above.
ExtensionSettings ImportGroup element
The ExtensionSettings group contains imports for the property sheets that are part of Build Customizations. A
Build Customization is defined by up to three files: a .targets file, a .props file and an .xml file. This import group
contains the imports for the .props file.
PropertySheets ImportGroup elements
The PropertySheets group contains the imports for user property sheets. These are the property sheets that you
add through the Property Manager view in Visual Studio. The order in which these imports are listed is important
and is reflected in the Property Manager. The project file normally contains multiple instances of this kind of
import group, one for each project configuration.
UserMacros PropertyGroup element
UserMacroscontains properties you create as variables that are used to customize your build process. For example,
you can define a user macro to define your custom output path as $(CustomOutputPath) and use it to define other
variables. This property group houses such properties. Note that in Visual Studio, this group is not populated in the
project file because Visual C++ does not support user macros for configurations. User macros are supported in
property sheets.
Per-configuration PropertyGroup elements
<PropertyGroup />
There are multiple instances of this property group, one per configuration for all project configurations. Each
property group must have one configuration condition attached. If any configurations are missing, the Project
Properties dialog won't work correctly. Unlike the property groups above, this one does not have a label. This
group contains project configuration-level settings. These settings apply to all files that are part of the specified
item group. Build customization item definition metadata is initialized here.
This PropertyGroup must come after <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> and there must
be no other PropertyGroup without a Label before it (otherwise Project Properties editing won’t work correctly).
Per-configuration ItemDefinitionGroup elements
<ItemDefinitionGroup />
Contains item definitions. These must follow the same conditions rules as the label-less per-configuration
PropertyGroup elements.
ItemGroup elements
<ItemGroup />
Contains the items (source files, etc.) in the project. Conditions are not supported for Project items (that is, item
types which are treated as project items by rules definitions).
The metadata should have configuration conditions for each configuration, even if they are all the same. For
example:
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<TreatWarningAsError Condition="‘$(Configuration)|$(Platform)’==’Debug|Win32’">true</TreatWarningAsError>
<TreatWarningAsError Condition="‘$(Configuration)|$(Platform)’==’Debug|x64’">true</TreatWarningAsError>
</ClCompile>
</ItemGroup>
The Visual C++ project system currently does not support wildcards in project items.
<ItemGroup>
<ClCompile Include="*.cpp"> <!--Error-->
</ItemGroup>
The Visual C++ project system currently does not support macros in project items.
<ItemGroup>
<ClCompile Include="$(IntDir)\generated.cpp"> <!--not guaranteed to work in all scenarios-->
</ItemGroup>
Defines (directly or via imports) Visual C++ targets such as build, clean, etc.
ExtensionTargets ImportGroup element
This group contains imports for the Build Customization target files.
Impact of incorrect ordering
The Visual Studio IDE depends on the project file having the ordering described above. For example, when you
define a property value in the property pages, the IDE will generally place the property definition in the property
group with the empty label. This ensures that default values brought in the system property sheets are overridden
by user defined values. Similarly, the target files are imported at the end since they consume the properties defined
above and since they generally do not define properties themselves. Likewise, user property sheets are imported
after the system property sheets (included via Microsoft.Cpp.props). This ensures that the user can override any
defaults brought in by the system property sheets.
If a .vcxproj file does not follow this layout, the build results may not be what you expect. For example, if you
mistakenly import a system property sheet after the property sheets defined by the user, the user settings will be
overridden by the system property sheets.
Even the IDE design time experience depends to some extent on correct ordering of elements. For example, if your
.vcxproj file does not have the PropertySheets import group, the IDE might not be able to determine where to
place a new property sheet that the user has created in Property Manager. This could result in a user sheet being
overriden by a system sheet. Although the heuristic used by IDE can tolerate minor inconsistencies in the .vcxproj
file layout, it is strongly recommended not to deviate from the structure shown earlier in this article.
To make your own property sheet, copy one of the .props files in the VCTargets folder and modify it for your
purposes. For Visual Studio 2017 Enterprise edition, the default VCTargets path is
%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets .
See also
Set C++ compiler and build properties in Visual Studio
Property Page XML Files
Project Files
3/12/2019 • 2 minutes to read • Edit Online
A Visual C++ project file is an XML -based file that has the .vcxproj file name extension and contains information
that is required to build a Visual C++ project. Note that the project file imports various project files that have the
extension .props or .targets. These files contain additional build information, and might themselves refer to other
.props or .targets files. The macros in the file path (for example $(VCTargetsPath) ) are dependent on your Visual
Studio installation. For more information about these macros and .props and .targets files, see VC++ Directories
Property Page, Set C++ compiler and build properties in Visual Studio and Common macros for build commands
and properties.
Example
The following sample .vcxproj file was produced by specifying a Win32 Console Application in the New Project
dialog box. To process a project file use either the msbuild.exe tool at the command line, or the Build command in
the IDE. (This sample cannot be processed because the required source and header files are not provided.) For
more information about the XML elements in a project file, see Project File Schema Reference.
See also
Visual Studio Projects - C++
Set C++ compiler and build properties in Visual Studio
C++ project property page reference
3/12/2019 • 2 minutes to read • Edit Online
By using property pages, you can specify settings for Visual Studio projects. To open the Property Pages dialog
box for a Visual Studio project, on the Project menu, choose Properties. For more information about project
properties, see Set C++ compiler and build properties in Visual Studio.
For property pages in non-Windows projects, see Linux C++ Property Page Reference.
In This Section
Advanced, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Command Line Property Pages
Custom Build Step Property Page: General
Adding references
General Property Page (File)
General Property Page (Project)
General, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
HLSL Property Pages
HLSL Property Pages: Advanced
HLSL Property Pages: General
HLSL Property Pages: Output Files
Input and Output, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Isolated COM, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Linker Property Pages
Managed Resources Property Page
Manifest Tool Property Pages
MIDL Property Pages
MIDL Property Pages: Advanced
MIDL Property Pages: General
MIDL Property Pages: Output
NMake Property Page
Resources Property Pages
VC++ Directories Property Page
Web References Property Page
XML Data Generator Tool Property Page
XML Document Generator Tool Property Pages
See also
How to: Create and Remove Project Dependencies
How to: Create and Edit Configurations
General Property Page (Project)
3/12/2019 • 6 minutes to read • Edit Online
When you right-click on a project node in Solution Explorer, and select Properties, the General property page
under the Configuration Properties node in the left pane displays two sections of properties:
General
Project Defaults
For non-Windows projects, see Linux C++ Property Page Reference.
General
The properties in the General section affect the location of files that are created in the build process and which
files to delete when the Clean option (Build menu) is selected.
Target Platform
Specifies the platform that the project will run on. For example, Windows, Android, or iOS. The value
Windows 10 means the project targets the Universal Windows Platform. If you are targeting earlier
versions of Windows, the version is not listed and the value in this field appears as just Windows. This is a
read-only field that is set when you create a project.
Windows SDK Version
For the Windows target platform, this specifies the version of the Windows SDK that your project requires.
When you install a C++ Workload by using the Visual Studio installer, the required parts of the Windows
SDK are also installed. If you have other Windows SDK versions on your computer, each version of the
SDK tools that you have installed appears in the dropdown.
To target Windows 7 or Windows Vista, use the value 8.1, since Windows SDK 8.1 is backward compatible
to those platforms. In addition, you should define the appropriate value for _WIN32_WINNT in
targetver.h. For Windows 7, that's 0x0601. See Modifying WINVER and _WIN32_WINNT.
You can install the Windows XP platform toolset included in Visual Studio to use the current version of the
libraries to build Windows XP and Windows 2003 Server projects. For information on how to obtain and
use this platform toolset, see Configuring Programs for Windows XP. For additional information on
changing the platform toolset, see How to: Modify the Target Framework and Platform Toolset.
Target Platform Min. Version
Specifies the lowest version of the platform that the project can run on. This property appears only if the
project type supports it, such as in Windows Universal projects. If your app can take advantage of features
in a newer Windows SDK version, but can still run on earlier versions without those features, perhaps with
some loss of functionality, then the value of these two properties might be different. If so, your code should
check the version of the platform it is running against at runtime and not try to use features that aren't
available in older platform version.
Note that Visual C++ does not enforce this option. It is included for consistency with other languages, such
as C# and JavaScript, and as a guide for anyone who uses your project. Visual C++ won't generate an error
if you use a feature that is not available in the minimum version.
Output Directory
Specifies the directory where tools such as the linker will place all final output files that are created during
the build process. Typically, this includes the output of tools such as the linker, librarian, or BSCMake. By
default, this property is the directory specified by the macros $(SolutionDir)$(Configuration).
To programmatically access this property, see OutputDirectory.
Intermediate Directory
Specifies the directory where tools such as the compiler will place all intermediate files created during the
build process. Typically, this includes the output of tools such as the C/C++ compiler, MIDL, and the
resource compiler. By default, this property is the directory specified by the macro $(Configuration).
To programmatically access this property, see IntermediateDirectory.
Target Name
Specifies the file name this project generates. By default, this property is the filename specified by the
macro $(ProjectName).
Target Extension
Specifies the file name extension this project generates; for example, .exe or .dll.
Extensions to Delete on Clean
The Clean option (Build menu) deletes files from the intermediate directory where a project's
configuration is built. Files with extensions specified with this property will be deleted when Clean is run or
when you perform a rebuild. In addition to files of these extensions in the intermediate directory, the build
system will also delete any known output of the build regardless of where it is located (including
intermediate outputs such as .obj files). Note that you can specify wildcard characters.
To programmatically access this property, see DeleteExtensionsOnClean.
Build Log File
Allows you to specify a non-default location for the log file that is created whenever you build a project. The
default location is specified by the macros $(IntDir)$(MSBuildProjectName).log.
You can use project macros to change the directory location. See Common macros for build commands
and properties.
Platform Toolset
Allows the project to target a different version of the Visual C++ libraries and compiler. Visual C++
projects can target either the default toolset installed by Visual Studio, or one of the toolsets installed by
several previous versions of Visual Studio, including toolsets that create executables that can run on
Windowx XP. For information on changing the platform toolset, see How to: Modify the Target Framework
and Platform Toolset.
Enable Managed Incremental Build
For managed projects, this enables detection of external visibility when you generate assemblies. If a
change to a managed project is not visible to other projects, then dependent projects are not rebuilt. This
can dramatically improve build times in solutions that include managed projects.
Project Defaults
The properties in the Project Default section represent default properties that you can modify. The definition for
these properties can be found in the .props files in Installation Directory\VC\VCProjectDefaults.
Configuration Type
There are several configuration types from which to choose:
Application (.exe)
Displays linker toolset (C/C++ Compiler, MIDL, Resource Compiler, Linker, BSCMake, XML Web
Service Proxy Generator, custom build, prebuild, prelink, postbuild events).
Dynamic Library (.dll)
Displays linker toolset, specifies /DLL linker option, and adds the _WINDLL define to CL.
Makefile
Displays makefile toolset (NMake).
Static Library (.lib)
Displays librarian toolset (same as linker toolset except substitute librarian for linker and omit XML
Web Service Proxy Generator).
Utility
Displays utility toolset (MIDL, custom build, prebuild, postbuild events).
To programmatically access this property, see ConfigurationType.
Use of MFC
Specifies whether the MFC project will statically or dynamically link to the MFC DLL. Non-MFC projects
can select Use Standard Windows Libraries to link to various Win32 libraries that are included when you
use MFC.
To programmatically access this property, see useOfMfc.
Use of ATL
Specifies whether the ATL project will statically or dynamically link to the ATL .DLL. If you specify anything
other than Not Using ATL, a define will be added to the compiler's Command Line property page.
To programmatically access this property, see useOfATL.
Character Set
Defines whether _UNICODE or _MBCS should be set. Also affects the linker entry point where appropriate.
To programmatically access this property, see CharacterSet.
Common Language Runtime support
Causes the /clr compiler option to be used.
To programmatically access this property, see ManagedExtensions.
.NET Target Framework Version
In managed projects, specifies the .NET framework version to target.
Whole Program Optimization
Specifies the /GL compiler option and /LTCG linker option. By default, this is disabled for Debug
configurations, and enabled for Retail configurations.
Windows Store App Support
Specifies whether this project supports Windows Runtime (Universal Windows Platform) apps. For more
information, see /ZW (Windows Runtime Compilation), and the Windows Developer Center.
See also
C++ project property page reference
General Property Page (File)
3/12/2019 • 2 minutes to read • Edit Online
When a file is selected in Solution Explorer, the General property page under the Configuration Properties
node contains the following properties:
Exclude From Build
Specifies whether the file should be in the build for the current configuration.
To programmatically access this property, see ExcludedFromBuild.
Tool
The tool that will be used to build this file. See Specifying Custom Build Tools for more information.
To programmatically access this property, see Tool.
For information on how to access the General property page under the Configuration Properties node, see Set
C++ compiler and build properties in Visual Studio.
For non-Windows projects, see Linux C++ Property Page Reference.
See also
C++ project property page reference
VC++ Directories Property Page (Windows)
3/12/2019 • 3 minutes to read • Edit Online
Use this property page to tell Visual Studio which directories to use when building the currently-selected project.
To set directories for multiple projects in a solution, use a custom property sheet as described in Share or resuse
Visual Studio C++ project settings.
For the Linux version of this page, see VC++ Directories (Linux C++).
To access the VC++ Directories property page:
1. If the Solution Explorer window is not visible, then on the main menu choose View > Solution Explorer.
2. Right-click on a project node (not the top-level solution) and choose Properties.
3. In the left pane of the Property Pages dialog box, select Configuration Properties > VC++ Directories.
VC++ Directories properties apply to a project, not the top-level solution node. If you do not see VC++
Directories under Configuration Properties, select a C++ project node in the Solution Explorer window:
Note that the VC++ Directories property page for cross-platform projects looks different. For information
specific to Linux C++ projects, see VC++ Directories (Linux C++).
If you are not familiar with project properties in Visual Studio, you might find it helpful to first read Set C++
compiler and build properties in Visual Studio.
The default settings for VC++ Directories properties depend on project type. For desktop projects they include
the C++ tools locations for a particular Platform Toolset and the Windows SDK location. You can change the
Platform Toolset and Windows SDK version on the Configuration Properties > General page.
To view the values for any of the directories:
1. Select one of the properties in the VC++ Directories page. For example, choose Library Directories.
2. Choose the down-arrow button at the end of the property value field.
3. In the drop-down menu, choose Edit.
Directory Types
You can also specify other directories, as follows.
Executable Directories
Directories in which to search for executable files. Corresponds to the PATH environment variable.
Include Directories
Directories in which to search for include files that are referenced in the source code. Corresponds to the
INCLUDE environment variable.
Reference Directories
Directories in which to search for assembly and module (metadata) files that are referenced in the source code by
the #using directive. Corresponds to the LIBPATH environment variable.
Library Directories
Directories in which to search for libraries (.lib) files; this includes run-time libraries. Corresponds to the LIB
environment variable. This setting does not apply to .obj files; to link to an .obj file, on the Configuration
Properties > Linker > General property page, select Additional Library Dependencies and then specify the
relative path of the file. For more information, see Linker property pages.
Library WinRT Directories
Directories to search for WinRT library files for use in Universal Windows Platform (UWP ) apps.
Source Directories
Directories in which to search for source files to use for IntelliSense.
Exclude Directories
Before each compilation, Visual Studio queries the timestamp on all files to determine whether any have been
modified since the previous compilation. If your project has large stable libraries, you can potentially speed up
build times by excluding those directories from the timestamp check.
Most property page folders contain a Command Line property page. This page displays which properties are set
in the folder. The Command Line property page also contains an Additional Options box where you can specify
properties that are valid for the tool but for which there is no property in the folder.
Any command that you enter in the edit box will be passed through to the tool for the folder. No verification or
checks will be done on the input, nor will there be any dependency checking.
For information on how to access the Command Line property pages, see Set C++ compiler and build
properties in Visual Studio.
See also
C++ project property page reference
.Lib Files as Linker Input
NMake Property Page
3/12/2019 • 2 minutes to read • Edit Online
The NMake property page lets you specify build settings for NMake projects. (NMAKE is the Microsoft
implementation of Make.)
For more information about NMake projects, see Creating a Makefile Project. For non-Windows MakeFile
projects, see MakeFile Project Properties (Linux C++), General Project Properties (Android C++ Makefile) or
NMake Properties (Android C++).
The NMake property page contains the following properties.
UIElement List
Build Command Line
Specifies the command to be run when Build is clicked on the Build menu.
Rebuild All Command Line
Specifies the command to be run when Rebuild All is clicked on the Build menu.
Clean Command Line
Specifies the command to be run when Clean is clicked on the Build menu.
Output
Specifies the name of the file that will contain the output for the command line. By default, this file name is
based on the project name.
Preprocessor Definitions
Specifies any preprocessor definitions that the source files use. The default value is determined by the
current platform and configuration.
Include Search Path
Specifies the directories where the compiler searches for include files.
Forced Includes
Specifies files that the preprocessor automatically processes even if they are not included in the project files.
Assembly Search Path
Specifies the directories where the .NET Framework searches when it trys to resolve .NET assemblies.
Forced Using Assemblies
Specifies assemblies that the .NET Framework automatically processes.
Additional Options
Specifies any additional compiler switches for IntelliSense to use when it parses C++ files.
For information about how to access the NMake property page, see Set C++ compiler and build properties in
Visual Studio.
For information about how to programmatically access members of this object, see VCNMakeTool.
See also
C++ project property page reference
Linker Property Pages
3/12/2019 • 2 minutes to read • Edit Online
This topic discusses the following properties on the General linker property page. For the Linux version of this
page, see Linker Properties (Linux C++).
See also
VC++ Project Settings, Projects and Solutions, Options Dialog Box
C++ project property page reference
Manifest Tool Property Pages
3/12/2019 • 2 minutes to read • Edit Online
Use the Manifest Tool property pages to set build options for mt.exe.
For more information on the manifest tool, see Mt.exe.
General, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Input and Output, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Isolated COM, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
Advanced, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box
See also
C++ project property page reference
General, Manifest Tool, Configuration Properties,
<Projectname> Property Pages Dialog Box
3/12/2019 • 2 minutes to read • Edit Online
UIElement List
Suppress Startup Banner
Yes (/nologo) specifies that standard Microsoft copyright data will be concealed when the manifest tool is
started. Use this option to suppress unwanted output in log files, when you run mt.exe as part of a build
process or from a build environment.
Verbose Output
Yes (/verbose) specifies that additional build information will be displayed during manifest generation.
Assembly Identity
Uses the /identity option to specify an identity string, which comprises the attributes for the
<assemblyIdentity> Element. An identity string begins with the value for the name attribute, and is
followed by attribute = value pairs. The attributes in an identity string are delimited by a comma.
The following is an example identity string:
Microsoft.Windows.Common-Controls, processorArchitecture=x86, version=6.0.0.0, type=win32,
publicKeyToken=6595b64144ccf1df
See also
ClickOnce Application Manifest
Manifest Tool Property Pages
Set C++ compiler and build properties in Visual Studio
Input and Output, Manifest Tool, Configuration
Properties, <Projectname> Property Pages Dialog
Box
3/12/2019 • 2 minutes to read • Edit Online
Use this dialog box to specify input and output options for Mt.exe.
To access this property page dialog box, open the property pages for your project or your property sheet. Expand
the Manifest Tool node under Configuration Properties, and then select Input and Output.
UIElement List
Additional Manifest Files
Uses the /manifest option to specify the full paths of additional manifest files that the manifest tool will process
or merge. Full paths are delimited by a semicolon.
Input Resource Manifests
Uses the /inputresource option to specify the full path of a resource of type RT_MANIFEST, to input into the
manifest tool. The path can be followed by the specified resource ID. For example:
dll_with_manifest.dll;#1
See also
ClickOnce Application Manifest
Manifest Tool Property Pages
Set C++ compiler and build properties in Visual Studio
Isolated COM, Manifest Tool, Configuration
Properties, <Projectname> Property Pages Dialog
Box
3/12/2019 • 2 minutes to read • Edit Online
Use this dialog box to specify Isolated COM options for Mt.exe.
To access this property page dialog box, open the property pages for your project or your property sheet. Expand
the Manifest Tool node under Common Properties, and then select Isolated COM.
Task List
How to: Build Isolated Applications to Consume COM Components
UIElement List
Type Library File
Uses the /tlb option to specify the name of the type library file (.tlb file) that the manifest tool will use to
generate the manifest file.
Registrar Script File
Uses the /rgs option to specify the name of the registrar script file (.rgs file) that the manifest tool will use to
generate the manifest file.
Component File Name
Uses the /dll option to specify the name of the resource that the manifest tool will generate. You must enter
a value for this property when values for either Type Library File or Registrar Script File are specified.
Replacements File
Uses the /replacements option to specify the full path to the file that contains values for replaceable strings
in the .rgs file.
See also
Isolated Applications
ClickOnce Application Manifest
Manifest Tool Property Pages
Set C++ compiler and build properties in Visual Studio
Advanced, Manifest Tool, Configuration Properties,
<Projectname> Property Pages Dialog Box
3/12/2019 • 2 minutes to read • Edit Online
UIElement List
Update File Hashes
Uses the /hashupdate option to specify that the manifest tool will compute the hash of files specified in
<file> elements, and then update the hash attributes with the computed value.
See also
<file> Element
ClickOnce Application Manifest
Manifest Tool Property Pages
Set C++ compiler and build properties in Visual Studio
Resources Property Pages
3/12/2019 • 2 minutes to read • Edit Online
For more information on using the resource compiler, see Using RC (The RC Command Line).
For information on how to access the Resources property pages, see Set C++ compiler and build properties in
Visual Studio.
To programmatically access these properties, see VCResourceCompilerTool.
See also
C++ project property page reference
Managed Resources Property Page
3/12/2019 • 2 minutes to read • Edit Online
See also
Using RC (The RC Command Line)
C++ project property page reference
/ASSEMBLYRESOURCE (Embed a Managed Resource)
MIDL Property Pages
3/12/2019 • 2 minutes to read • Edit Online
The MIDL node contains several property pages. To access them. right-click on the .idl file in Solution Explorer.
MIDL Property Pages: General
MIDL Property Pages: Output
MIDL Property Pages: Advanced
For information on how to programmatically access MIDL options for C++ projects, see VCMidlTool
See also
C++ project property page reference
MIDL Property Pages: General
3/12/2019 • 2 minutes to read • Edit Online
The General property page in the MIDL folder specifies the following MIDL compiler options:
Preprocessor Definitions (/D )
Additional Include Directories (/I)
Ignore Standard Include Path (/no_def_idir)
MkTypLib Compatible (/mktyplib203)
Warning Level (/W )
Warn As Error (/WX)
Suppress Startup Banner (/nologo)
MIDL Char Type (/char)
Target Environment (/env)
Generate Stubless Proxies (/Oicf)
For information on how to access the General property page in the MIDL folder, see Set C++ compiler and build
properties in Visual Studio.
For information on how to programmatically access MIDL options for C++ projects, see VCMidlTool object.
See also
MIDL Property Pages
MIDL Property Pages: Output
3/12/2019 • 2 minutes to read • Edit Online
The Output property page in the MIDL folder specifies the following MIDL compiler options:
Output Directory (/out)
Header File (/h)
DLL Data File (/dlldata)
IID File (/iid)
Proxy File (/proxy)
Generate Type Library (/notlb)
Type Library (/tlb)
For information on how to access the Output property page in the MIDL folder, see Set C++ compiler and build
properties in Visual Studio.
For information on how to programmatically access MIDL options for C++ projects, see VCMidlTool.
See also
MIDL Property Pages
MIDL Property Pages: Advanced
3/12/2019 • 2 minutes to read • Edit Online
The Advanced property page in the MIDL folder specifies the following MIDL compiler options:
Enable Error Checking (/error)
Check Allocations (/error)
Check Bounds (/error)
Check Enum Range (/error)
Check Reference Pointers (/error)
Check Stub Data (/error)
Validate Parameters (/robust) *
Struct Member Alignment (/Zp)
Redirect Output (/o)
C Preprocess Options (/cpp_opt)
Undefine Preprocessor Definitions (/U )
* /robust is only for use when building for a Windows 2000 or later machine. If you build an ATL project and want
to use /robust, change this line in the dlldatax.c file:
For information on how to access the Advanced property page in the MIDL folder, see Set C++ compiler and
build properties in Visual Studio.
For information on how to programmatically access MIDL options for C++ projects, see VCMidlTool.
See also
MIDL Property Pages
Web References Property Page
3/12/2019 • 2 minutes to read • Edit Online
The Web References property page specifies how the XML Web service proxy class will be generated. An XML
Web service proxy class will be generated if you add a web reference to your project.
The Web References property page contains the following properties:
Output file
The name of the file to contain the XML Web service proxy class.
Suppress Startup Banner
Do not display the banner for the Web Services Description Language Tool (Wsdl.exe).
Namespace
Specifies the name of the generated web proxy.
Additional References
Specifies the additional DLLs referenced by the proxy DLL.
For information on how to access the Web Reference property page, see Set C++ compiler and build properties
in Visual Studio.
See also
C++ project property page reference
XML Data Generator Tool Property Page
3/12/2019 • 2 minutes to read • Edit Online
The XML Data Generator Tool property page becomes available when you add a dataset to a project.
The XML Data Generator Tool property page contains the following properties:
Output File
Specifies the output file name to use.
Suppress Startup Banner
Suppresses the display of the startup banner and information messages.
Generated Proxy Language
Determines whether or not to emit managed code.
For information on how to access the XML Data Generator Tool property page, see Set C++ compiler and build
properties in Visual Studio.
For information on how to programmatically access members of this object, see VCXMLDataGeneratorTool
See also
C++ project property page reference
XML Document Generator Tool Property Pages
3/12/2019 • 2 minutes to read • Edit Online
The XML Document Generator Tool property page exposes the functionality of xdcmake.exe. xdcmake.exe merges
.xdc files into an .xml file when your source code contains documentation comments and /doc (Process
Documentation Comments) (C/C++) is specified,. See Recommended Tags for Documentation Comments for
information on adding documentation comments to source code.
NOTE
xdcmake.exe options in the development environment (property pages) differ from the options when xdcmake.exe is used at
the command line. For information on using xdcmake.exe at the command line, see XDCMake Reference.
UIElement List
Suppress Startup Banner
Suppress copyright message.
Additional Document Files
Additional directories in which you want the project system to look for .xdc files. xdcmake will always look
for .xdc files generated by the project. Multiple directories can be specified.
Output Document File
The name and directory location of the .xml output file. See Common macros for build commands and
properties for information on using macros to specify directory locations.
Document Library Dependencies
If your project has a dependency on a .lib project in the solution, you can process .xdc files from the .lib
project into the .xml files for the current project.
See also
C++ project property page reference
Custom Build Step Property Page: General
3/12/2019 • 2 minutes to read • Edit Online
For each combination of project configuration and target platform in your project, you can specify a custom step to
be performed when the project is built.
For the Linux version of this page, see Custom Build Step Properties (Linux C++).
UIElement List
Command Line
The command to be executed by the custom build step.
Description
A message that's displayed when the custom build step runs.
Outputs
The output file that the custom build step generates. This setting is required so that incremental builds work
correctly.
Additional Dependencies
A semicolon-delimited list of any additional input files to use for the custom build step.
Execute After and Execute Before
These options define when the custom build step is run in the build process, relative to the listed targets.
The most commonly listed targets are BuildGenerateSources, BuildCompile, and BuildLink, because they
represent the major steps in the build process. Other often-listed targets are Midl, CLCompile, and Link.
Treat Output As Content
This option is only meaningful for Universal Windows Platform or Windows Phone apps, which include all
content files in the .appx package.
To specify a custom build step
1. On the menu bar, choose Project, Properties. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. In the Property Pages dialog box, navigate to the Configuration Properties, Custom Build Step,
General page.
3. Modify the settings.
See also
C++ project property page reference
HLSL Property Pages
3/12/2019 • 2 minutes to read • Edit Online
You can use the HLSL compiler (fxc.exe) property pages to configure how individual HLSL shader files are built.
The properties are divided into three categories:
HLSL Property Pages: General
Provides properties to specify commonly-used options for the HLSL compiler.
HLSL Property Pages: Advanced
Provides properties to specify additional options for the HLSL compiler.
HLSL Property Pages: Output Files
Provides properties to specify how files are output by the HLSL compiler.
You can specify command-line arguments to the HLSL compiler by using the Additional Options property of the
Command Line property page; this includes arguments that can't be configured by using other properties of the
HLSL property pages. For information about the HLSL compiler, see Effect-Compiler Tool
See also
C++ project property page reference
Command Line Property Pages
Compiling Shaders
HLSL Property Pages: General
3/12/2019 • 2 minutes to read • Edit Online
To configure the following properties of the HLSL compiler (fxc.exe), use its General property page. For
information about how to access the General property page in the HLSL folder, see Set C++ compiler and build
properties in Visual Studio.
UIElement List
Additional Include Directories
Adds one or more directories to the include path. Use semi-colons to separate the directories.
This property corresponds to the /I [path] command-line argument.
Entrypoint Name
Specifies the entry point for the shader. By default, the value is main.
This property corresponds to the /E [name] command-line argument.
Disable Optimizations
Yes (/Od) to disable optimizations; otherwise, No. By default, the value is Yes (/Od) for Debug
configurations and No for Release configurations.
The /Od command-line argument to the HLSL compiler implicitly applies the /Gfp command-line argument, but
output may not be identical to output that is produced by passing both the /Od and /Gfp command-line
arguments explicitly.
Enable Debugging Information
Yes (/Zi) to enable debugging information; otherwise, No. By default, the value is Yes (/Zi) for Debug
configurations and No for Release configurations.
Shader Type
Specifies the kind of shader. Different kinds of shaders implement different parts of the graphics pipeline.
Certain kinds of shaders are available only in more recent shader models (which are specified by the
Shader Model property)—for example, compute shaders were introduced in shader model 5.
This property corresponds to the [type] portion of the /T [type]_[model] command-line argument to the
HLSL compiler. The Shader Models property specifies the [model] portion of the argument.
Shader Model
Specifies the shader model. Different shader models have different capabilities. In general, more recent
shader models offer expanded capabilities but require more modern graphics hardware to run the shader
code. Certain kinds of shaders (which are specified by the Shader Type property) are available only in
more recent shader models—for example, compute shaders were introduced in shader model 5.
This property corresponds to the [model] portion of the /T [type]_[model] command-line argument to
the HLSL compiler. The Shader Type property specifies the [type] portion of the argument.
Preprocessor Definitions
Adds one or more preprocessor symbol definitions to apply to the HLSL source code file. Use semi-colons
to separate the symbol definitions.
This property corresponds to the /D [definitions] command-line argument to the HLSL compiler.
See also
HLSL Property Pages
HLSL Property Pages: Advanced
HLSL Property Pages: Output Files
HLSL Property Pages: Advanced
3/12/2019 • 2 minutes to read • Edit Online
To configure the following properties of the HLSL compiler (fxc.exe), use its Advanced property page. For
information about how to access the Advanced property page in the HLSL folder, see Set C++ compiler and
build properties in Visual Studio.
UIElement List
Suppress Startup Banner
Yes (/nologo) to suppress the display of the startup banner and information message; otherwise, No. By
default, the value is Yes (/nologo).
Treat Warnings As Errors
Yes (/WX) to treat all compiler warnings as errors; otherwise, No.
See also
HLSL Property Pages
HLSL Property Pages: General
HLSL Property Pages: Output Files
HLSL Property Pages: Output Files
3/12/2019 • 2 minutes to read • Edit Online
To configure the following properties of the HLSL compiler (fxc.exe), use its Output Files property. For
information about how to access the Output Files property page in the HLSL folder, see Set C++ compiler and
build properties in Visual Studio.
UIElement List
Header Variable Name
Specifies the name of an array that is used to encoded HLSL object code. The array is contained in a header
file that is output by the HLSL compiler. The name of the header file is specified by the Header File Name
property.
This property corresponds to the /Vn[name] command-line argument.
Header File Name
Specifies the name of the header file that is output by the HLSL compiler. The header contains HLSL object
code that is encoded into an array. The name of the array is specified by the Header Variable Name
property.
This property corresponds to the /Fh[name] command-line argument.
Object File Name
Specifies the name of the object file that is output by the HLSL compiler. By default, the value is
$(OutDir)%(Filename).cso.
This property corresponds to the /Fo[name] command-line argument.
Assembler Output
Assembly-Only Listing (/Fc) to output just assembly language statements. Assembly Code and Hex
(/Fx) to output both assembly language statements and the corresponding op-code in hexadecimal. By
default, no listing is output.
Assembler Output File
Specifies the name of the assembly listing file that is output by the HLSL compiler.
This property corresponds to the /Fc[name] and /Fx [name] command-line arguments.
See also
HLSL Property Pages
HLSL Property Pages: General
HLSL Property Pages: Advanced
Compiling a C/C++ project
3/12/2019 • 2 minutes to read • Edit Online
C and C++ compiler options can be set either in the Visual Studio IDE or on the command line.
In Visual Studio
You can set compiler options for each project in its Visual Studio Property Pages dialog box. In the left pane, select
Configuration Properties, C/C++ and then choose the compiler option category. The topic for each compiler
option describes how it can be set and where it is found in the development environment. See MSVC Compiler
Options for a complete list.
See also
C/C++ Building Reference
Compiler Command-Line Syntax
3/12/2019 • 2 minutes to read • Edit Online
ENTRY MEANING
You can specify any number of options, filenames, and library names, as long as the number of
characters on the command line does not exceed 1024, the limit dictated by the operating
system.
For information about the return value of cl.exe, see Return Value of cl.exe .
NOTE
The command-line input limit of 1024 characters is not guaranteed to remain the same in future
releases of Windows.
See also
MSVC Compiler Options
CL Filename Syntax
3/12/2019 • 2 minutes to read • Edit Online
CL accepts files with names that follow FAT, HPFS, or NTFS naming conventions. Any filename can include a full
or partial path. A full path includes a drive name and one or more directory names. CL accepts filenames separated
either by backslashes (\) or forward slashes (/). Filenames that contain spaces must be surrounded by double
quote characters. A partial path omits the drive name, which CL assumes to be the current drive. If you don't
specify a path, CL assumes the file is in the current directory.
The filename extension determines how files are processed. C and C++ files, which have the extension .c, .cxx, or
.cpp, are compiled. Other files, including .obj files, libraries (.lib), and module-definition (.def) files, are passed to the
linker without being processed.
See also
MSVC Compiler Command-Line Syntax
Order of CL Options
3/12/2019 • 2 minutes to read • Edit Online
Options can appear anywhere on the CL command line, except for the /link option, which must occur last. The
compiler begins with options specified in the CL environment variable and then reads the command line from left
to right — processing command files in the order it encounters them. Each option applies to all files on the
command line. If CL encounters conflicting options, it uses the rightmost option.
See also
MSVC Compiler Command-Line Syntax
Return Value of cl.exe
3/12/2019 • 2 minutes to read • Edit Online
cl.exe returns zero for success (no errors) and non-zero otherwise.
The return value of cl.exe can be useful if you are compiling from a script, powershell, .cmd, or .bat file. We
recommend that you capture the output of the compiler in case there are errors or warnings, so that you can
resolve them.
There are too many possible error exit codes for cl.exe to list them all. You can look up an error code in the
winerror.h or ntstatus.h files included in the Windows Software Development Kit in the
%ProgramFiles(x86)%\Windows Kits\version\Include\shared\ directory. Error codes returned in decimal must be
converted to hexadecimal for search. For example, an error code of -1073741620 converted to hexadecimal is
0xC00000CC. This error is found in ntstatus.h, where the corresponding message is "The specified share name
cannot be found on the remote server." For a downloadable list of Windows error codes, see [MS -ERREF ]:
Windows Error Codes.
You can also use the error lookup utility in Visual Studio to find out what a compiler error message means. In a
Visual Studio command shell, enter errlook.exe to start the utility; or in the Visual Studio IDE, on the menu bar,
choose Tools, Error Lookup. Enter the error value to find the descriptive text associated with the error. For more
information see ERRLOOK Reference.
Remarks
The following is a sample .bat file that uses the return value of cl.exe.
echo off
cl /W4 t.cpp
@if ERRORLEVEL == 0 (
goto good
)
@if ERRORLEVEL != 0 (
goto bad
)
:good
echo "clean compile"
echo %ERRORLEVEL%
goto end
:bad
echo "error or warning"
echo %ERRORLEVEL%
goto end
:end
See also
MSVC Compiler Command-Line Syntax
CL Environment Variables
3/12/2019 • 2 minutes to read • Edit Online
SET CL=[ [option] ... [file] ...] [/link link-opt ...] SET _CL_=[ [option] ... [file] ...] [/link link-opt ...]
For details on the arguments to the CL and _CL_ environment variables, see MSVC Compiler Command-Line
Syntax.
You can use these environment variables to define the files and options you use most often and use the command
line to define specific files and options for specific purposes. The CL and _CL_ environment variables are limited to
1024 characters (the command-line input limit).
You cannot use the /D option to define a symbol that uses an equal sign (=). You can substitute the number sign
(#) for an equal sign. In this way, you can use the CL or _CL_ environment variables to define preprocessor
constants with explicit values—for example, /DDEBUG#1 to define DEBUG=1 .
For related information, see Set Environment Variables.
Examples
The following is an example of setting the CL environment variable:
When this environment variable is set, if you enter CL INPUT.C at the command line, this is the effective
command:
The following example causes a plain CL command to compile the source files FILE1.c and FILE2.c, and then link
the object files FILE1.obj, FILE2.obj, and FILE3.obj:
A command file is a text file that contains options and filenames you would otherwise type on the command line
or specify using the CL environment variable. CL accepts a compiler command file as an argument in the CL
environment variable or on the command line. Unlike either the command line or the CL environment variable, a
command file allows you to use multiple lines of options and filenames.
Options and filenames in a command file are processed according to the location of a command filename within
the CL environment variable or on the command line. However, if the /link option appears in the command file, all
options on the rest of the line are passed to the linker. Options in subsequent lines in the command file and
options on the command line after the command file invocation are still accepted as compiler options. For more
information on how the order of options affects their interpretation, see Order of CL Options.
A command file must not contain the CL command. Each option must begin and end on the same line; you cannot
use the backslash (\) to combine an option across two lines.
A command file is specified by an at sign (@) followed by a filename; the filename can specify an absolute or
relative path.
For example, if the following command is in a file named RESP:
Note that the command line and the command-file commands are effectively combined.
See also
MSVC Compiler Command-Line Syntax
MSVC Compiler Options
CL Invokes the Linker
3/12/2019 • 2 minutes to read • Edit Online
CL automatically invokes the linker after compiling unless the /c option is used. CL passes to the linker the names
of .obj files created during compiling and the names of any other files specified on the command line. The linker
uses the options listed in the LINK environment variable. You can use the /link option to specify linker options on
the CL command line. Options that follow the /link option override those in the LINK environment variable. The
options in the following table suppress linking.
OPTION DESCRIPTION
Example
Assume that you are compiling three C source files: MAIN.c, MOD1.c, and MOD2.c. Each file includes a call to a
function defined in a different file:
MAIN.c calls the function func1 in MOD1.c and the function func2 in MOD2.c.
MOD1.c calls the standard library functions printf_s and scanf_s .
MOD2.c calls graphics functions named myline and mycircle , which are defined in a library named
MYGRAPH.lib.
To build this program, compile with the following command line:
CL first compiles the C source files and creates the object files MAIN.obj, MOD1.obj, and MOD2.obj. The compiler
places the name of the standard library in each .obj file. For more details, see Use Run-Time Library.
CL passes the names of the .obj files, along with the name MYGRAPH.lib, to the linker. The linker resolves the
external references as follows:
1. In MAIN.obj, the reference to func1 is resolved using the definition in MOD1.obj; the reference to func2 is
resolved using the definition in MOD2.obj.
2. In MOD1.obj, the references to printf_s and scanf_s are resolved using the definitions in the library that
the linker finds named within MOD1.obj.
3. In MOD2.obj, the references to myline and mycircle are resolved using the definitions in MYGRAPH.lib.
See also
MSVC Compiler Options
Setting Compiler Options
Compiler Options
3/12/2019 • 2 minutes to read • Edit Online
cl.exe is a tool that controls the Microsoft Visual C++ (MSVC ) C and C++ compilers and linker.
cl.exe can be run only on operating systems that support Microsoft Visual Studio for Windows.
NOTE
You can start this tool only from a Visual Studio developer command prompt. You cannot start it from
a system command prompt or from File Explorer. For more information, see Use the MSVC toolset
from the command line.
The compilers produce Common Object File Format (COFF ) object (.obj) files. The linker
produces executable (.exe) files or dynamic-link libraries (DLLs).
Note that all compiler options are case sensitive. You may use either a forward slash ( / ) or a
dash ( - ) to specify a compiler option.
To compile without linking, use the /c option.
See also
C/C++ Building Reference
CL Invokes the Linker
Compiler options listed by category
3/12/2019 • 6 minutes to read • Edit Online
This article contains a categorical list of compiler options. For an alphabetical list, see Compiler Options Listed
Alphabetically.
Optimization
OPTION PURPOSE
Code generation
OPTION PURPOSE
Output files
OPTION PURPOSE
Preprocessor
OPTION PURPOSE
/FU Forces the use of a file name, as if it had been passed to the
#using directive.
Language
OPTION PURPOSE
/Zl Removes the default library name from the .obj file.
Linking
OPTION PURPOSE
Miscellaneous
OPTION PURPOSE
/FC Displays the full path of source code files passed to cl.exe in
diagnostic text.
/kernel The compiler and linker will create a binary that can be
executed in the Windows kernel.
/w1, /w2, /w3, /w4 Sets warning level for the specified warning.
See also
C/C++ Building Reference
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Compiler Options Listed Alphabetically
3/12/2019 • 5 minutes to read • Edit Online
The following is a comprehensive alphabetical list of compiler options. For a categorical list, see the Compiler
Options Listed by Category.
OPTION PURPOSE
/Fr
/FU Forces the use of a file name as if it had been passed to the
#using directive.
/GT Supports fiber safety for data allocated using static thread-
local storage.
/kernel The compiler and linker will create a binary that can be
executed in the Windows kernel.
/Qvec-report (Auto-Vectorizer Reporting Level) Enables reporting levels for automatic vectorization.
/W0, /W1, /W2, /W3, /W4 Sets which warning level to output.
/w1, /w2, /w3, /w4 Sets the warning level for the specified warning.
/Zl Removes default library name from .obj file (x86 only).
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
@ (Specify a Compiler Response File)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
@response_file
Arguments
response_file
A text file containing compiler commands.
Remarks
A response file can contain any commands that you would specify on the command line. This can be useful if your
command-line arguments exceed 127 characters.
It is not possible to specify the @ option from within a response file. That is, a response file cannot embed another
response file.
From the command line you can specify as many response file options (for example, @respfile.1 @respfile.2 ) as
you want.
To set this compiler option in the Visual Studio development environment
A response file cannot be specified from within the development environment and must be specified at the
command line.
To set this compiler option programmatically
This compiler option cannot be changed programmatically.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/AI (Specify Metadata Directories)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a directory that the compiler will search to resolve file references passed to the #using directive.
Syntax
/AIdirectory
Arguments
directory
The directory or path for the compiler to search.
Remarks
Only one directory can be passed to an /AI invocation. Specify one /AI option for each path you want the
compiler to search. For example, to add both C:\Project\Meta and C:\Common\Meta to the compiler search path
for #using directives, add /AI"C:\Project\Meta" /AI"C:\Common\Meta" to the compiler command line or add each
directory to the Additional #using Directories property in Visual Studio.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > General property page.
3. Modify the Additional #using Directories property.
To set this compiler option programmatically
See AdditionalUsingDirectories.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
#using Directive
/analyze (Code Analysis)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/analyze[-][:WX-][:log filename][:quiet][:stacksize number][:max_paths number][:only][:ruleset]
Arguments
/analyze Turns on analysis in the default mode. Analysis output goes to the Output window like other error
messages. Use /analyze- to explicitly turn off analysis.
/analyze:WX- Specifying /analyze:WX- means that code analysis warnings are not treated as errors when you
compile by using /WX. For more information, see /w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd,
/we, /wo, /Wv, /WX (Warning Level).
/analyze:log filename Detailed analyzer results are written as XML to the file that is specified by filename .
/analyze:quiet Turns off analyzer output to the Output window.
/analyze:stacksize number The number parameter that is used with this option specifies the size, in bytes, of the
stack frame for which warning C6262 is generated. If this parameter is not specified, the stack frame size is 16KB
by default.
/analyze:max_paths number The number parameter that is used with this option specifies the maximum number
of code paths to be analyzed. If this parameter is not specified, the number is 256 by default. Larger values
perform more thorough checking, but the analysis might take longer.
/analyze:only Typically, the compiler generates code and does more syntax checking after it runs the analyzer. The
/analyze:only option turns off this code generation pass; this makes analysis faster but compile errors and
warnings that might have been discovered by the code generation pass of the compiler are not emitted. If the
program is not free of code-generation errors, analysis results might be unreliable; therefore, we recommend that
you use this option only if the code already passes code-generation syntax checking without errors.
/analyze:ruleset <file_path>.ruleset Enables you to specify which rule sets to analyze, including custom rule sets
that you can create yourself. When this switch is set, the rules engine is more efficient because it excludes non-
members of the specified rule set before running. When the switch is not set, the engine checks all rules.
The rulesets that ship with Visual Studio are found in %VSINSTALLDIR%\Team Tools\Static Analysis
Tools\Rule Sets.
The following sample custom rule set tells the rules engine to check for C6001 and C26494. You can place this file
anywhere as long as it has a .ruleset extension and you provide the full path in the argument.
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="15.0">
<Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
<Rule Id="C6001" Action="Warning" />
<Rule Id="C26494" Action="Warning" />
</Rules>
</RuleSet>
/analyze:plugin Enables the specified PREfast plugin as part of code analysis runs. LocalEspC.dll is the plugin that
implements concurrency-related code analysis checks in the range of C261XX warnings. For example, C26100,
C26101, ..., C26167.
To run LocalEspC.dll, use this compiler option: /analyze:plugin LocalEspC.dll
To run CppCoreCheck.dll, first run this command from a developer command prompt:
set Esp.Extensions=CppCoreCheck.dll
Remarks
For more information, see Code Analysis for C/C++ Overview and Code Analysis for C/C++ Warnings.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Code Analysis node.
4. Select the General property page.
5. Modify one or more of the Code Analysis properties.
To set this compiler option programmatically
1. See EnablePREfast.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/arch (Minimum CPU Architecture)
3/12/2019 • 2 minutes to read • Edit Online
The architecture options specify the architecture for code generation. Select the base hardware architecture you
are working with to see /arch options for that target platform.
/arch (x86)
/arch (x64)
/arch (ARM )
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/arch (x86)
3/12/2019 • 2 minutes to read • Edit Online
Specifies the architecture for code generation on x86. Also see /arch (x64) and /arch (ARM ).
Syntax
/arch:[IA32|SSE|SSE2|AVX|AVX2]
Arguments
/arch:IA32
Specifies no enhanced instructions and also specifies x87 for floating-point calculations.
/arch:SSE
Enables the use of SSE instructions.
/arch:SSE2
Enables the use of SSE2 instructions. This is the default instruction on x86 platforms if no /arch option is
specified.
/arch:AVX
Enables the use of Intel Advanced Vector Extensions instructions.
/arch:AVX2
Enables the use of Intel Advanced Vector Extensions 2 instructions.
Remarks
The SSE and SSE2 instructions exist on various Intel and AMD processors. The AVX instructions exist on Intel
Sandy Bridge processors and AMD Bulldozer processors. AVX2 instructions are supported by Intel Haswell and
Broadwell processors and AMD Excavator-based processors.
The _M_IX86_FP , __AVX__ and __AVX2__ macros indicate which, if any, /arch compiler option was used. For more
information, see Predefined Macros. The /arch:AVX2 option and __AVX2__ macro were introduced in Visual
Studio 2013 Update 2, version 12.0.34567.1.
The optimizer chooses when and how to use the SSE and SSE2 instructions when /arch is specified. It uses SSE
and SSE2 instructions for some scalar floating-point computations when it determines that it is faster to use the
SSE/SSE2 instructions and registers instead of the x87 floating-point register stack. As a result, your code may
actually use a mixture of both x87 and SSE/SSE2 for floating-point computations. Also, with /arch:SSE2, SSE2
instructions can be used for some 64-bit integer operations.
In addition to using the SSE and SSE2 instructions, the compiler also uses other instructions that are present on
the processor revisions that support SSE and SSE2. An example is the CMOV instruction that first appeared on
the Pentium Pro revision of the Intel processors.
Because the x86 compiler generates code that uses SSE2 instructions by default, you must specify /arch:IA32 to
disable generation of SSE and SSE2 instructions for x86 processors.
/arch only affects code generation for native functions. When you use /clr to compile, /arch has no effect on code
generation for managed functions.
/arch and /QIfist cannot be used on the same compiland. In particular, if you do not use _controlfp to modify
the FP control word, then the run-time startup code sets the x87 FPU control word precision-control field to 53-
bits. Therefore, every float and double operation in an expression uses a 53-bit significand and a 15-bit exponent.
However, every SSE single-precision operation uses a 24-bit significand and an 8-bit exponent, and SSE2 double-
precision operations use a 53-bit significand and an 11-bit exponent. For more information, see _control87,
_controlfp, __control87_2. These differences are possible in one expression tree, but not in cases where a user
assignment is involved after each subexpression. Consider the following:
Compare:
To set this compiler option for AVX, AVX2, IA32, SSE, or SSE2 in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the Configuration Properties, C/C++ folder.
3. Select the Code Generation property page.
4. Modify the Enable Enhanced Instruction Set property.
To set this compiler option programmatically
See EnableEnhancedInstructionSet.
See also
/arch (Minimum CPU Architecture)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/arch (x64)
3/12/2019 • 2 minutes to read • Edit Online
Specifies the architecture for code generation on x64. Also see /arch (x86) and /arch (ARM ).
Syntax
/arch:[AVX|AVX2]
Arguments
/arch:AVX
Enables the use of Intel Advanced Vector Extensions instructions.
/arch:AVX2
Enables the use of Intel Advanced Vector Extensions 2 instructions.
Remarks
/arch only affects code generation for native functions. When you use /clr to compile, /arch has no effect on code
generation for managed functions.
The __AVX__ preprocessor symbol is defined when the /arch:AVX compiler option is specified. The __AVX2__
preprocessor symbol is defined when the /arch:AVX2 compiler option is specified. For more information, see
Predefined Macros. The /arch:AVX2 option was introduced in Visual Studio 2013 Update 2, version 12.0.34567.1.
To set the /arch:AVX or /arch:AVX2 compiler option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the Configuration Properties, C/C++ folder.
3. Select the Code Generation property page.
4. In the Enable Enhanced Instruction Set drop-down box, choose Advanced Vector Extensions
(/arch:AVX) or Advanced Vector Extensions 2 (/arch:AVX2).
To set this compiler option programmatically
See EnableEnhancedInstructionSet.
See also
/arch (Minimum CPU Architecture)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/arch (ARM)
3/12/2019 • 2 minutes to read • Edit Online
Specifies the architecture for code generation on ARM. See also /arch (x86) and /arch (x64).
Syntax
/arch:[ARMv7VE|VFPv4]
Arguments
/arch:ARMv7VE
Enables the use of ARMv7VE Virtualization Extensions instructions.
/arch:VFPv4
Enables the use of ARM VFPv4 instructions. If this option is not specified, VFPv3 is the default.
Remarks
The _M_ARM_FP macro (for ARM only) indicates which, if any, /arch compiler option was used. For more
information, see Predefined Macros.
When you use /clr to compile, /arch has no effect on code generation for managed functions. /arch only affects
code generation for native functions.
To set the /arch:ARMv7VE or /arch:VFPv4 compiler option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. In the Additional options box, add /arch:ARMv7VE or /arch:VFPv4 .
To set this compiler option programmatically
See EnableEnhancedInstructionSet.
See also
/arch (Minimum CPU Architecture)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/await (Enable coroutine support)
3/12/2019 • 2 minutes to read • Edit Online
Use the /await compiler option to enable compiler support for coroutines.
Syntax
/await
Remarks
The /await compiler option enables compiler support for C++ coroutines and the keywords co_await, co_yield,
and co_return. This option is off by default. For information about support for coroutines in Visual Studio, see the
Visual Studio Team Blog. For more information about the coroutines standard proposal, see N4628 Working
Draft, Technical Specification for C++ Extensions for Coroutines.
The /await option is available beginning in Visual Studio 2015.
To set this compiler option in the Visual Studio development environment
1. Open your project's Property Pages dialog box.
2. Under Configuration Properties, expand the C/C++ folder and choose the Command Line property
page.
3. Enter the /await compiler option in the Additional Options box. Choose OK or Apply to save your
changes.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/bigobj (Increase Number of Sections in .Obj file)
3/12/2019 • 2 minutes to read • Edit Online
/bigobj increases the number of sections that an object file can contain.
Syntax
/bigobj
Remarks
By default, an object file can hold up to 65,536 (2^16) addressable sections. This is the case no matter which
target platform is specified. /bigobj increases that address capacity to 4,294,967,296 (2^32).
Most modules will never generate an .obj file that contains more than 65,536 sections. However, machine
generated code, or code that makes heavy use of template libraries may require .obj files that can hold more
sections. /bigobj is enabled by default on Universal Windows Platform (UWP ) projects because the machine-
generated XAML code includes a large number of headers. If you disable this option on a UWP app project you
are likely to encounter compiler error C1128.
Linkers that shipped prior to Visual C++ 2005 cannot read .obj files that were produced with /bigobj.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/C (Preserve Comments During Preprocessing)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/C
Remarks
This compiler option requires the /E, /P, or /EP option.
The following code sample will display the source code comment.
// C_compiler_option.cpp
// compile with: /E /C /c
int i; // a variable
#line 1 "C_compiler_option.cpp"
int i; // a variable
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/E (Preprocess to stdout)
/P (Preprocess to a File)
/EP (Preprocess to stdout Without #line Directives)
/c (Compile Without Linking)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/c
Remarks
Compiling with /c creates .obj files only. You must call LINK explicitly with the proper files and options to perform
the linking phase of the build.
Any internal project created in the development environment uses the /c option by default.
To set this compiler option in the Visual Studio development environment
This option is not available from within the development environment.
To set this compiler option programmatically
To set this compiler option programmatically, see CompileOnly.
Example
The following command line creates the object files FIRST.obj and SECOND.obj. THIRD.obj is ignored.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/cgthreads (Code Generation Threads)
3/12/2019 • 2 minutes to read • Edit Online
Sets number of cl.exe threads to use for optimization and code generation.
Syntax
/cgthreads[1-8]
Arguments
number
The maximum number of threads for cl.exe to use, in the range 1 to 8.
Remarks
The /cgthreads option specifies the maximum number of threads cl.exe uses in parallel for the optimization and
code generation phases of compilation. Notice that there can be no space between /cgthreads and the number
argument. By default, cl.exe uses four threads, as if /cgthreads4 were specified. If more processor cores are
available, a larger number value can improve build times. This option is especially useful when it's combined with
/GL (Whole Program Optimization).
Multiple levels of parallelism can be specified for a build. The msbuild.exe switch /maxcpucount specifies the
number of MSBuild processes that can be run in parallel. The /MP (Build with Multiple Processes) compiler flag
specifies the number of cl.exe processes that simultaneously compile the source files. The /cgthreads option
specifies the number of threads used by each cl.exe process. Because the processor can only run as many threads
at the same time as there are processor cores, it's not useful to specify larger values for all of these options at the
same time, and it can be counterproductive. For more information about how to build projects in parallel, see
Building Multiple Projects in Parallel.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties, C/C++ folder.
3. Select the Command Line property page.
4. Modify the Additional Options property to include /cgthreads N , where N is a value from 1 to 8, and
then select OK.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/clr (Common Language Runtime Compilation)
3/12/2019 • 3 minutes to read • Edit Online
Enables applications and components to use features from the common language runtime (CLR ).
Syntax
/clr[:options]
Arguments
options
One or more of the following switches, comma-separated.
none
With no options, /clr creates metadata for the application. The metadata can be consumed by
other CLR applications, and enables the application to consume types and data in the metadata of
other CLR components. For more information, see Mixed (Native and Managed) Assemblies.
pure
/clr:pure is deprecated. The option is removed in Visual Studio 2017. We recommend that you
port code that must be pure MSIL to C#.
safe
/clr:safe is deprecated. The option is removed in Visual Studio 2017. We recommend that you
port code that must be safe MSIL to C#.
noAssembly
/clr:noAssembly is deprecated. Use /LN (Create MSIL Module) instead.
Specifies that an assembly manifest should not be inserted into the output file. By default, the
noAssembly option is not in effect.
A managed program that does not have assembly metadata in the manifest is known as a module.
The noAssembly option can be used only to produce a module. If you compile by using /c and
/clr:noAssembly, then specify the /NOASSEMBLY option in the linker phase to create a module.
Before Visual C++ 2005, /clr:noAssembly required /LD. /LD is now implied when you specify
/clr:noAssembly.
initialAppDomain
Enables a Visual C++ application to run on version 1 of the CLR. An application that is compiled
by using initialAppDomain should not be used by an application that uses ASP.NET because it
is not supported in version 1 of the CLR.
nostdlib
Instructs the compiler to ignore the default \clr directory. The compiler produces errors if you are
including multiple versions of a DLL such as System.dll. Using this option lets you specify the
specific framework to use during compilation.
Remarks
Managed code is code that can be inspected and managed by the CLR. Managed code can access
managed objects. For more information, see /clr Restrictions.
For information about how to develop applications that define and consume managed types, see
Component Extensions for Runtime Platforms.
An application compiled by using /clr may or may not contain managed data.
To enable debugging on a managed application, see /ASSEMBLYDEBUG (Add DebuggableAttribute).
Only CLR types will be instantiated on the garbage-collected heap. For more information, see Classes
and Structs. To compile a function to native code, use the unmanaged pragma. For more information, see
managed, unmanaged.
By default, /clr is not in effect. When /clr is in effect, /MD is also in effect. For more information, see
/MD, /MT, /LD (Use Run-Time Library). /MD ensures that the dynamically linked, multithreaded
versions of the runtime routines are selected from the standard header (.h) files. Multithreading is
required for managed programming because the CLR garbage collector runs finalizers in an auxiliary
thread.
If you compile by using /c, you can specify the CLR type of the resulting output file with
/CLRIMAGETYPE.
/clr implies /EHa, and no other /EH options are supported for /clr. For more information, see /EH
(Exception Handling Model).
For information about how to determine the CLR image type of a file, see /CLRHEADER.
All modules passed to a given invocation of the linker must be compiled by using the same run-time
library compiler option (/MD or /LD ).
Use the /ASSEMBLYRESOURCE linker option to embed a resource in an assembly. /DELAYSIGN,
/KEYCONTAINER, and /KEYFILE linker options also let you customize how an assembly is created.
When /clr is used, the _MANAGED symbol is defined to be 1. For more information, see Predefined
Macros.
The global variables in a native object file are initialized first (during DllMain if the executable is a DLL ),
and then the global variables in the managed section are initialized (before any managed code is run).
#pragma init_seg only affects the order of initialization in the managed and unmanaged categories.
// clr_unnamed_class.cpp
// compile by using: /clr /LD
class {} x;
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/clr Restrictions
3/12/2019 • 3 minutes to read • Edit Online
/GS is ignored when compiling with /clr, unless a function is under #pragma unmanaged or if the function
must be compiled to native, in which case the compiler will generate warning C4793, which is off by default.
See /ENTRY for function signature requirements of a managed application.
Applications compiled with /openmp and /clr can only be run in a single appdomain process. See
/openmp (Enable OpenMP 2.0 Support) for more information.
Functions that take a variable number of arguments (varargs) will be generated as native functions. Any
managed data types in the variable argument position will be marshaled to native types. Note that
System.String types are actually wide-character strings, but they are marshaled to single-byte character
strings. So if a printf specifier is %S (wchar_t*), it will marshal to a %s string instead.
When using the va_arg macro, you may get unexpected results when compiling with /clr:pure. For more
information, see va_arg, va_copy, va_end, va_start. The /clr:pure and /clr:safe compiler options are
deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017. Code that must be "pure" or
"safe" should be ported to C#.
You should not call, from managed code, any functions that walk the stack to get parameter information
(function arguments); the P/Invoke layer causes that information to be further down the stack. For example,
do not compile proxy/stub with /clr.
Functions will be compiled to managed code whenever possible, but not all C++ constructs can be
translated to managed code. This determination is made on a function-by-function basis. If any part of a
function cannot be converted to managed code, the entire function will be converted to native code instead.
The following cases prevent the compiler from generating managed code.
Compiler-generated thunks or helper functions. Native thunks are generated for any function call
through a function pointer, including virtual function calls.
Functions that call setjmp or longjmp .
Functions that use certain intrinsic routines to directly manipulate machine resources. For example,
the use of __enable and __disable , _ReturnAddress and _AddressOfReturnAddress , or multimedia
intrinsics will all result in native code.
Functions that follow the #pragma unmanaged directive. (Note that the inverse, #pragma managed , is
also supported.)
A function that contains references to aligned types, that is, types declared using
__declspec(align(...)) .
See also
/clr (Common Language Runtime Compilation)
/constexpr (Control constexpr evaluation)
3/12/2019 • 2 minutes to read • Edit Online
Use the /constexpr compiler options to control parameters for constexpr evaluation at compile time.
Syntax
/constexpr:depthN /constexpr:backtraceN /constexpr:stepsN
Arguments
depthN Limit the depth of recursive constexpr function invocation to N levels. The default is 512.
backtraceN Show up to N constexpr evaluations in diagnostics. The default is 10.
stepsN Terminate constexpr evaluation after N steps. The default is 100,000.
Remarks
The /constexpr compiler options control compile-time evaluation of constexpr expressions. Evaluation steps,
recursion levels, and backtrace depth are controlled to prevent the compiler from spending too much time on
constexpr evaluation. For more information on the constexpr language element, see constexpr (C++).
The /constexpr options are available beginning in Visual Studio 2015.
To set this compiler option in the Visual Studio development environment
1. Open your project's Property Pages dialog box.
2. Under Configuration Properties, expand the C/C++ folder and choose the Command Line property
page.
3. Enter any /constexpr compiler options in the Additional Options box. Choose OK or Apply to save your
changes.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/D (Preprocessor Definitions)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Dname[= | # [{string | number}] ]
Remarks
You can use this symbol together with #if or #ifdef to compile source code conditionally. The symbol definition
remains in effect until it is redefined in the code or is undefined in the code by the #undef directive.
/D has the same effect as the #define directive at the beginning of a source code file, except that /D strips
quotation marks on the command line and #define retains them.
By default, the value associated with a symbol is 1. For example, /D name is equivalent to /D name =1. In the
example at the end of this article, the definition of TEST is shown to print 1 .
Compiling by using /D name = causes the symbol to have no associated value. Although the symbol can still be
used to conditionally compile code, it otherwise evaluates to nothing. In the example, if you compile by using
/DTEST=, an error occurs. This behavior resembles the use of #define with or without a value.
This command defines the symbol DEBUG in TEST.c:
CL /DDEBUG TEST.C
This command removes all occurrences of the keyword __far in TEST.c:
CL /D__far= TEST.C
The CL environment variable cannot be set to a string that contains the equal sign. To use /D together with the CL
environment variable, you must specify the number sign instead of the equal sign:
SET CL=/DTEST#0
When you define a preprocessing symbol at the command prompt, consider both compiler parsing rules and shell
parsing rules. For example, to define a percent-sign preprocessing symbol (%) in your program, specify two
percent-sign characters (%%) at the command prompt: If you specify only one, a parsing error is emitted.
CL /DTEST=%% TEST.C
Example
// cpp_D_compiler_option.cpp
// compile with: /DTEST
#include <stdio.h>
int main( )
{
#ifdef TEST
printf_s("TEST defined %d\n", TEST);
#else
printf_s("TEST not defined\n");
#endif
}
TEST defined 1
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/U, /u (Undefine Symbols)
#undef Directive (C/C++)
#define Directive (C/C++)
/diagnostics (Compiler diagnostic options)
3/12/2019 • 2 minutes to read • Edit Online
Use the /diagnostics compiler option to specify the display of error and warning location information.
Syntax
/diagnostics:{caret|classic|column}
Remarks
This option is supported in Visual Studio 2017 and later.
The /diagnostics compiler option controls the display of error and warning information.
The /diagnostics:classic option is the default, which reports only the line number where the issue was found.
The /diagnostics:column option also includes the column where the issue was found. This can help you identify
the specific language construct or character that is causing the issue.
The /diagnostics:caret option includes the column where the issue was found and places a caret (^) under the
location in the line of code where the issue was detected.
Note that in some cases, the compiler does not detect an issue where it occurred. For example, a missing
semicolon may not be detected until other, unexpected symbols have been encountered. The column is reported
and the caret is placed where the compiler detected that something was wrong, which is not always where you
need to make your correction.
The /diagnostics option is available starting in Visual Studio 2017.
To set this compiler option in the Visual Studio development environment
1. Open your project's Property Pages dialog box.
2. Under Configuration Properties, expand the C/C++ folder and choose the General property page.
3. Use the dropdown control in the Diagnostics Format field to select a diagnostics display option. Choose
OK or Apply to save your changes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/doc (Process Documentation Comments) (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
Causes the compiler to process documentation comments in source code files and to create an .xdc file for each
source code file that has documentation comments.
Syntax
/doc[name]
Arguments
name
The name of the .xdc file that the compiler will create. Only valid when one .cpp file is passed in the compilation.
Remarks
The .xdc files are processed into an .xml file with xdcmake.exe. For more information, see XDCMake Reference.
You can add documentation comments to your source code files. For more information, see Recommended Tags
for Documentation Comments.
To use the generated .xml file with IntelliSense, make the file name of the .xml file the same as the assembly that
you want to support and put the .xml file is in the same directory as the assembly. When the assembly is
referenced in the Visual Studio project, the .xml file is also found. For more information, see Using IntelliSense
and Supplying XML Code Comments.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Output Files property page.
3. Modify the Generate XML Documentation Files property.
To set this linker option programmatically
See GenerateXMLDocumentationFiles.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/E (Preprocess to stdout)
3/12/2019 • 2 minutes to read • Edit Online
Preprocesses C and C++ source files and copies the preprocessed files to the standard output device.
Syntax
/E
Remarks
In this process, all preprocessor directives are carried out, macro expansions are performed, and comments are
removed. To preserve comments in the preprocessed output, use the /C (Preserve Comments During
Preprocessing) compiler option as well.
/E adds #line directives to the output at the beginning and end of each included file and around lines removed
by preprocessor directives for conditional compilation. These directives renumber the lines of the preprocessed
file. As a result, errors generated during later stages of processing refer to the line numbers of the original source
file rather than lines in the preprocessed file.
The /E option suppresses compilation. You must resubmit the preprocessed file for compilation. /E also
suppresses the output files from the /FA, /Fa, and /Fm options. For more information, see /FA, /Fa (Listing File)
and /Fm (Name Mapfile).
To suppress #line directives, use the /EP (Preprocess to stdout Without #line Directives) option instead.
To send the preprocessed output to a file instead of to stdout , use the /P (Preprocess to a File) option instead.
To suppress #line directives and send the preprocessed output to a file, use /P and /EP together.
You cannot use precompiled headers with the /E option.
Note that when preprocessing to a separate file, spaces are not emitted after tokens. This can result in an illegal
program or have unintended side effects. The following program compiles successfully:
#define m(x) x
m(int)main( )
{
return 0;
}
Example
The following command line preprocesses ADD.C , preserves comments, adds #line directives, and displays the
result on the standard output device:
CL /E /C ADD.C
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/EH (Exception Handling Model)
3/12/2019 • 5 minutes to read • Edit Online
Specifies the kind of exception handling used by the compiler, when to optimize away exception checks, and
whether to destroy C++ objects that go out of scope because of an exception. If /EH is not specified, the
compiler enables your code to catch both asynchronous structured exceptions and C++ exceptions, but does
not destroy C++ objects that go out of scope because of an asynchronous exception.
Syntax
/EH {s|a}[c][r][-]
Arguments
a
The exception-handling model that catches both asynchronous (structured) and synchronous (C++) exceptions
by use of C++ catch(...) syntax.
s
The exception-handling model that catches synchronous (C++) exceptions only and tells the compiler to
assume that functions declared as extern "C" may throw an exception.
c
If used with s (/EHsc), catches C++ exceptions only and tells the compiler to assume that functions declared as
extern "C" never throw a C++ exception. /EHca is equivalent to /EHa.
r
Tells the compiler to always generate runtime termination checks for all noexcept functions. By default,
runtime checks for noexcept may be optimized away if the compiler determines the function calls only non-
throwing functions.
Remarks
The /EHa compiler option is used to support asynchronous structured exception handling (SEH) with the
native C++ catch(...) clause. To implement SEH without specifying /EHa, you may use the __try, __except,
and __finally syntax. Although Windows and Visual C++ support SEH, we strongly recommend that you use
ISO -standard C++ exception handling (/EHs or /EHsc) because it makes code more portable and flexible.
Nevertheless, in existing code or for particular kinds of programs—for example, in code compiled to support
the common language runtime (/clr (Common Language Runtime Compilation))—you still might have to use
SEH. For more information, see Structured Exception Handling (C/C++).
Specifying /EHa and trying to handle all exceptions by using catch(...) can be dangerous. In most cases,
asynchronous exceptions are unrecoverable and should be considered fatal. Catching them and proceeding can
cause process corruption and lead to bugs that are hard to find and fix.
If you use /EHs or /EHsc, then your catch(...) clause does not catch asynchronous structured exceptions.
Access violations and managed System.Exception exceptions are not caught, and objects in scope when an
asynchronous exception is generated are not destroyed even if the asynchronous exception is handled.
If you use /EHa, the image may be larger and might perform less well because the compiler does not optimize
a try block as aggressively. It also leaves in exception filters that automatically call the destructors of all local
objects even if the compiler does not see any code that can throw a C++ exception. This enables safe stack
unwinding for asynchronous exceptions as well as for C++ exceptions. When you use /EHs, the compiler
assumes that exceptions can only occur at a throw statement or at a function call. This allows the compiler to
eliminate code for tracking the lifetime of many unwindable objects, and this can significantly reduce code size.
We recommend that you not link objects compiled by using /EHa together with objects compiled by using
/EHs or /EHsc in the same executable module. If you have to handle an asynchronous exception by using
/EHa anywhere in your module, use /EHa to compile all the code in the module. You can use structured
exception handling syntax in the same module as code that's compiled by using /EHs, but you can’t mix the
SEH syntax with try, throw, and catch in the same function.
Use /EHa if you want to catch an exception that's raised by something other than a throw. This example
generates and catches a structured exception:
// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;
int main() {
__try {
fail();
}
The /EHc option requires that /EHs or /EHa is specified. The /clr option implies /EHa (that is, /clr /EHa is
redundant). The compiler generates an error if /EHs or /EHsc is used after /clr. Optimizations do not affect
this behavior. When an exception is caught, the compiler invokes the class destructor or destructors for the
object or objects that are in the same scope as the exception. When an exception is not caught, those
destructors are not run.
For information about exception handling restrictions under /clr, see _set_se_translator.
The option can be cleared by using the symbol -. For example, /EHsc- is interpreted as /EHs /EHc- and is
equivalent to /EHs.
The /EHr compiler option forces runtime termination checks in all functions that have a noexcept attribute. By
default, runtime checks may be optimized away if the compiler back end determines that a function only calls
non-throwing functions. Non-throwing functions are any functions that have an attribute that specifies no
exceptions may be thrown. This includes functions marked noexcept, throw() , __declspec(nothrow) , and,
when /EHc is specified, extern "C" functions. Non-throwing functions also include any that the compiler has
determined are non-throwing by inspection. You can explicitly set the default by using /EHr-.
However, the non-throwing attribute is not a guarantee that no exceptions can be thrown by a function. Unlike
the behavior of a noexcept function, the MSVC compiler considers an exception thrown by a function declared
using throw() , __declspec(nothrow) , or extern "C" as undefined behavior. Functions that use these three
declaration attributes do not enforce runtime termination checks for exceptions. You can use the /EHr option to
help you identify this undefined behavior, by forcing the compiler to generate runtime checks for unhandled
exceptions that escape a noexcept function.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select Configuration Properties > C/C++ > Code Generation.
3. Modify the Enable C++ Exceptions property.
Or, set Enable C++ Exceptions to No, and then on the Command Line property page, in the
Additional Options box, add the compiler option.
To set this compiler option programmatically
See ExceptionHandling.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Errors and Exception Handling
Exception Specifications (throw )
Structured Exception Handling (C/C++)
/EP (Preprocess to stdout Without #line Directives)
3/12/2019 • 2 minutes to read • Edit Online
Preprocesses C and C++ source files and copies the preprocessed files to the standard output device.
Syntax
/EP
Remarks
In the process, all preprocessor directives are carried out, macro expansions are performed, and comments are
removed. To preserve comments in the preprocessed output, use the /C (Preserve Comments During
Preprocessing) option with /EP.
The /EP option suppresses compilation. You must resubmit the preprocessed file for compilation. /EP also
suppresses the output files from the /FA, /Fa, and /Fm options. For more information, see /FA, /Fa (Listing File)
and /Fm (Name Mapfile).
Errors generated during later stages of processing refer to the line numbers of the preprocessed file rather than
the original source file. If you want line numbers to refer to the original source file, use /E (Preprocess to stdout)
instead. The /E option adds #line directives to the output for this purpose.
To send the preprocessed output, with #line directives, to a file, use the /P (Preprocess to a File) option instead.
To send the preprocessed output to stdout, with #line directives, use /P and /EP together.
You cannot use precompiled headers with the /EP option.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Preprocessor property page.
4. Modify the Generate Preprocessed File property.
To set this compiler option programmatically
See GeneratePreprocessedFile.
Example
The following command line preprocesses file ADD.C , preserves comments, and displays the result on the
standard output device:
CL /EP /C ADD.C
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/errorReport (Report Internal Compiler Errors)
3/12/2019 • 2 minutes to read • Edit Online
Lets you provide internal compiler error (ICE ) information directly to Microsoft.
Syntax
/errorReport:[ none | prompt | queue | send ]
Arguments
none
Reports about internal compiler errors will not be collected or sent to Microsoft.
prompt
Prompts you to send a report when you receive an internal compiler error. prompt is the default when an
application is compiled in the development environment.
queue
Queues the error report. When you log in with administrator privileges, a window is displayed so that you can
report any failures since the last time you were logged in (you will not be prompted to send reports for failures
more than once every three days). queue is the default when an application is compiled at a command prompt.
send
Automatically sends reports of internal compiler errors to Microsoft if reporting is enabled by the Windows Error
Reporting system settings.
Remarks
An internal compiler error (ICE ) results when the compiler cannot process a source code file. When an ICE occurs,
the compiler does not produce an output file or any useful diagnostic that you can use to fix your code.
In earlier releases, when you got an ICE, you were encouraged to call Microsoft Product Support Services to
report the problem. With /errorReport, you can provide ICE information directly to Microsoft. Your error reports
can help improve future compiler releases.
A user's ability to send reports depends on computer and user policy permissions.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Click the C/C++ folder.
3. Click the Advanced property page.
4. Modify the Error Reporting property.
To set this compiler option programmatically
See ErrorReporting.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/execution-charset (Set Execution Character Set)
3/12/2019 • 2 minutes to read • Edit Online
Lets you specify the execution character set for your executable.
Syntax
/execution-charset:[IANA_name|.CPID]
Arguments
IANA_name
The IANA-defined character set name.
CPID
The code page identifier.
Remarks
You can use the /execution-charset option to specify an execution character set. The execution character set is
the encoding used for the text of your program that is input to the compilation phase after all preprocessing steps.
This character set is used for the internal representation of any string or character literals in the compiled code. Set
this option to specify the extended execution character set to use when your source files include characters that are
not representable in the basic execution character set. You can use either the IANA or ISO character set name, or a
dot (.) followed by a 3 to 5 digit decimal code page identifier to specify the character set to use. For a list of
supported code page identifiers and character set names, see Code Page Identifiers.
By default, Visual Studio detects a byte-order mark to determine if the source file is in an encoded Unicode format,
for example, UTF -16 or UTF -8. If no byte-order mark is found, it assumes the source file is encoded using the
current user code page, unless you have specified a character set name or code page by using the /source-
charset option or the /utf-8 option. Visual Studio allows you to save your C++ source code by using any of
several character encodings. For information about source and execution character sets, see Character Sets in the
language documentation.
If you want to set both the source character set and the execution character set to UTF -8, you can use the /utf-8
compiler option as a shortcut. It is equivalent to specifying /source-charset:utf-8 /execution-charset:utf-8 on
the command line. Any of these options also enables the /validate-charset option by default.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties, C/C++, Command Line folder.
3. In Additional Options, add the /execution-charset option, and specify your preferred encoding.
4. Choose OK to save your changes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/source-charset (Set Source Character Set)
/utf-8 (Set Source and Executable character sets to UTF -8)
/validate-charset (Validate for compatible characters)
/F (Set Stack Size)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/F number
Arguments
number
The stack size in bytes.
Remarks
Without this option the stack size defaults to 1 MB. The number argument can be in decimal or C -language
notation. The argument can range from 1 to the maximum stack size accepted by the linker. The linker rounds up
the specified value to the nearest 4 bytes. The space between /F and number is optional.
You may need to increase the stack size if your program gets stack-overflow messages.
You can also set the stack size by:
Using the /STACK linker option. For more information, see /STACK.
Using EDITBIN on the .exe file. For more information, see EDITBIN Reference.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Output-File (/F) Options
3/12/2019 • 2 minutes to read • Edit Online
The output-file options create or rename output files. They affect all C or C++ source files specified in the CL
environment variable, on the command line, or in any command file.
/FA, /Fa (Listing File)
Specifying the Pathname
/Fd (Name PDB File)
/Fe (Name EXE File)
/FI (Name Forced Include File)
/Fm (Name Mapfile)
/Fo (Name Object File)
/Fp (Name .pch File)
/FR, /Fr (Create .sbr File)
/FU (Name Forced #using File)
/Fx (Merge Injected Code)
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/FA, /Fa (Listing File)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/FA [c][s][u] /Fapathname
Remarks
The /FA compiler option generates an assembler listing file for each translation unit in the compilation, which
generally corresponds to a C or C++ source file. By default, only assembler is included in the listing file, which is
encoded as ANSI. The optional c, s, and u arguments to /FA control whether machine code or source code are
output together with the assembler listing, and whether the listing is encoded as UTF -8.
By default, each listing file gets the same base name as the source file, and has a .asm extension. When machine
code is included by using the c option, the listing file has a .cod extension. You can change the name and
extension of the listing file and the directory where it is created by using the /Fa option.
/FA arguments
none
Only assembler language is included in the listing.
c
Optional. Includes machine code in the listing.
s
Optional. Includes source code in the listing.
u
Optional. Encodes the listing file in UTF -8 format, and includes a byte order marker. By default, the file is
encoded as ANSI. Use u to create a listing file that displays correctly on any system, or if you are using Unicode
source code files as input to the compiler.
If both s and u are specified, and if a source code file uses a Unicode encoding other than UTF -8, then the code
lines in the .asm file may not display correctly.
/Fa argument
none
One source.asm file is created for each source code file in the compilation.
filename
A listing file named filename.asm is placed in the current directory. This is only valid when compiling a single
source code file.
filename.extension
A listing file named filename.extension is placed in the current directory. This is only valid when compiling a
single source code file.
directory\
One source_file.asm file is created and placed in the specified directory for each source code file in the
compilation. Note the required trailing backslash. Only paths on the current disk are allowed.
directory\filename
A listing file named filename.asm is placed in the specified directory. This is only valid when compiling a single
source code file.
directory\filename.extension
A listing file named filename.extension is placed in the specified directory. This is only valid when compiling a
single source code file.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Output Files property page.
3. Modify the Assembler Output property to set the /FAc and /FAs options for assembler, machine, and
source code. Modify the Use Unicode For Assembler Listing property to set the /FAu option for ANSI
or UTF -8 output. Modify the ASM List Location to set the /Fa option for listing file name and location.
Note that setting both Assembler Output and Use Unicode For Assembler Listing properties can cause
Command-Line Warning D9025. To combine these options in the IDE, use the Additional Options field in the
Command Line property page instead.
To set this compiler option programmatically
See AssemblerListingLocation or AssemblerOutput. To specify /FAu, see AdditionalOptions.
Example
The following command line produces a combined source and machine-code listing called HELLO.cod:
CL /FAcs HELLO.CPP
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
Specifying the Pathname
3/12/2019 • 2 minutes to read • Edit Online
Each output-file option accepts a pathname argument that can specify a location and a name for the output file.
The argument can include a drive name, directory, and file name. No space is allowed between the option and the
argument.
If pathname includes a file name without an extension, the compiler gives the output a default extension. If
pathname includes a directory but no file name, the compiler creates a file with a default name in the specified
directory. The default name is based on the base name of the source file and a default extension based on the
type of the output file. If you leave off pathname entirely, the compiler creates a file with a default name in a
default directory.
Alternatively, the pathname argument can be a device name (AUX, CON, PRN, or NUL ) rather than a file name.
Do not use a space between the option and the device name or a colon as part of the device name.
CON Console
PRN Printer
Example
The following command line sends a mapfile to the printer:
CL /FmPRN HELLO.CPP
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/FD (IDE Minimal Rebuild)
3/12/2019 • 2 minutes to read • Edit Online
/FD is not exposed to users except in the Command Line property page of a C++ project's Property Pages dialog
box, if and only if /Gm (Enable Minimal Rebuild) is not also selected. /FD has no effect other than from the
development environment. /FD is not exposed in the output of cl /?.
If you do not enable /Gm in the development environment, /FD will be used. /FD ensures that the .idb file has
sufficient dependency information. /FD is only used by the development environment, and it should not be used
from the command line or a build script.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Fd (Program Database File Name)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a file name for the program database (PDB ) file created by /Z7, /Zi, /ZI (Debug Information Format).
Syntax
/Fdpathname
Remarks
Without /Fd, the PDB file name defaults to VCx0.pdb, where x is the major version of Visual C++ in use.
If you specify a path name that does not include a file name (the path ends in backslash), the compiler creates a
.pdb file named VCx0.pdb in the specified directory.
If you specify a file name that does not include an extension, the compiler uses .pdb as the extension.
This option also names the state (.idb) file used for minimal rebuild and incremental compilation.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Output Files property page.
4. Modify the Program Database File Name property.
To set this compiler option programmatically
See ProgramDataBaseFileName.
Example
This command line creates a .pdb file named PROG.pdb and an .idb file named PROG.idb:
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/Fe (Name EXE File)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a name and a directory for the .exe file or DLL created by the compiler.
Syntax
/Fe[pathname] /Fe: pathname
Arguments
pathname
The relative or absolute path and base file name, or relative or absolute path to a directory, or base file name to
use for the generated executable.
Remarks
The /Fe option allows you to specify the output directory, output executable name, or both, for the generated
executable file. If pathname ends in a path separator (\), it is assumed to specify only the output directory.
Otherwise, the last component of pathname is used as the output file base name, and the rest of pathname
specifies the output directory. If pathname does not have any path separators, it's assumed to specify the output
file name in the current directory. The pathname must be enclosed in double quotes (") if it contains any
characters that can't be in a short path, such as spaces, extended characters, or path components more than eight
characters long.
When the /Fe option is not specified, or when a file base name is not specified in pathname, the compiler gives
the output file a default name using the base name of the first source or object file specified on the command line
and the extension .exe or .dll.
If you specify the /c (Compile Without Linking) option, /Fe has no effect.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Open the Configuration Properties > Linker > General property page.
3. Modify the Output File property. Choose OK to save your changes.
To set this compiler option programmatically
See OutputFile.
Example
The following command line compiles and links all C source files in the current directory. The resulting executable
file is named PROCESS.exe and is created in the directory "C:\Users\User Name\repos\My Project\bin".
Example
The following command line creates an executable file in C:\BIN with the same base name as the first source file
in the current directory:
CL /FeC:\BIN\ *.C
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/Fi (Preprocess Output File Name)
3/12/2019 • 2 minutes to read • Edit Online
Specifies the name of the output file to which the /P (Preprocess to a File) compiler option writes preprocessed
output.
Syntax
/Fipathname
Parameters
PARAMETER DESCRIPTION
pathname The name and path of the output file produced by the /P
compiler option.
Remarks
Use the /Fi compiler option in combination with the /P compiler option.
If you specify only a path for the pathname parameter, the base name of the source file is used as the base name of
the preprocessed output file. The pathname parameter does not require a particular file name extension. However,
an extension of ".i" is used if you do not specify a file name extension.
Example
The following command line preprocesses PROGRAM.cpp, preserves comments, adds #line directives, and writes
the result to the MYPROCESS.i file.
CL /P /FiMYPROCESS.I PROGRAM.CPP
See also
MSVC Compiler Options
/P (Preprocess to a File)
Specifying the Pathname
/FI (Name Forced Include File)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/FI[ ]pathname
Remarks
This option has the same effect as specifying the file with double quotation marks in an #include directive on the
first line of every source file specified on the command line, in the CL environment variable, or in a command file.
If you use multiple /FI options, files are included in the order they are processed by CL.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Advanced property page.
4. Modify the Force Includes property.
To set this compiler option programmatically
See ForcedIncludeFiles.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/Fm (Name Mapfile)
3/12/2019 • 2 minutes to read • Edit Online
Tells the linker to produce a mapfile containing a list of segments in the order in which they appear in the
corresponding .exe file or DLL.
Syntax
/Fmpathname
Remarks
By default, the mapfile is given the base name of the corresponding C or C++ source file with a .MAP extension.
Specifying /Fm has the same effect as if you had specified the /MAP (Generate Mapfile) linker option.
If you specify /c (Compile Without Linking) to suppress linking, /Fm has no effect.
Global symbols in a mapfile usually have one or more leading underscores because the compiler adds a leading
underscore to variable names. Many global symbols that appear in the mapfile are used internally by the
compiler and the standard libraries.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/Fo (Object File Name)
3/12/2019 • 2 minutes to read • Edit Online
Specifies an object (.obj) file name or directory to be used instead of the default.
Syntax
/Fopathname
Remarks
If you do not use this option, the object file uses the base name of the source file and the .obj extension. You can
use any name and extension you want, but the recommended convention is to use .obj.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Output Files property page.
4. Modify the Object File Name property. In the development environment, the object file must have an
extension of .obj.
To set this compiler option programmatically
See ObjectFile.
Example
The following command line creates an object file named THIS.obj in an existing directory, \OBJECT, on drive B.
CL /FoB:\OBJECT\ THIS.C
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/Fp (Name .Pch File)
3/12/2019 • 2 minutes to read • Edit Online
Provides a path name for a precompiled header instead of using the default path name.
Syntax
/Fppathname
Remarks
Use this option with /Yc (Create Precompiled Header File) or /Yu (Use Precompiled Header File) to provide a path
name for a precompiled header instead of using the default path name. You can also use /Fp with /Yc to specify
the use of a precompiled header file that differs from the /Ycfilename argument and from the base name of the
source file.
If you do not specify an extension as part of the path name, an extension of .pch is assumed. If you specify a
directory without a file name, the default file name is VCx0.pch, where x is the major version of Visual C++ in use.
You can also use the /Fp option with /Yu.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Precompiled Headers property page.
4. Modify the Precompiled Header File property.
To set this compiler option programmatically
See PrecompiledHeaderFile.
Example
If you want to create a precompiled header file for a debugging version of your program and you are compiling
both header files and source code, you can specify a command such as:
Example
The following command specifies the use of a precompiled header file named MYPCH.pch. The compiler assumes
that the source code in PROG.cpp has been precompiled through MYAPP.h and that the precompiled code resides
in MYPCH.pch. It uses the content of MYPCH.pch and compiles the rest of PROG.cpp to create an .obj file. The
output of this example is a file named PROG.exe.
Syntax
/FR[pathname[\filename]]
/Fr[pathname[\filename]]
Remarks
During the build process, the Microsoft Browse Information File Maintenance Utility (BSCMAKE ) uses these files
to create a .BSC file, which is used to display browse information.
/FR creates an .sbr file with complete symbolic information.
/Fr creates an .sbr file without information on local variables.
If you do not specify filename , the .sbr file gets the same base name as the source file.
/Fr is deprecated; use /FR instead. For more information, see Deprecated and Removed Compiler Options in
Compiler Options Listed by Category.
NOTE
Do not change the .sbr extension. BSCMAKE requires the intermediary files to have that extension.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/FU (Name Forced #using File)
3/12/2019 • 2 minutes to read • Edit Online
A compiler option that you can use as an alternative to passing a file name to #using Directive in source code.
Syntax
/FU file
Arguments
file
Specifies the metadata file to reference in this compilation.
Remarks
The /FU switch takes just one file name. To specify multiple files, use /FU with each one.
If you are using C++/CLI and are referencing metadata to use the Friend Assemblies feature, you can't use /FU.
You must reference the metadata in code by using #using —together with the [as friend] attribute. Friend
assemblies are not supported in Visual C++ component extensions C++/CX.
For information about how to create an assembly or module for the common language runtime (CLR ), see /clr
(Common Language Runtime Compilation). For information about how to build in C++/CX, see Building apps
and libraries.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Advanced property page.
3. Modify the Force #using property.
To set this compiler option programmatically
See ForcedUsingFiles.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Fx (Merge Injected Code)
3/12/2019 • 2 minutes to read • Edit Online
Produces a copy of each source file with injected code merged into the source.
Syntax
/Fx
Remarks
To distinguish a merged source file from an original source file, /Fx adds an .mrg extension between the file name
and file extension. For example, a file named MyCode.cpp containing attributed code and built with /Fx creates a
file named MyCode.mrg.cpp containing the following code:
In an .mrg file, code that was injected because of an attribute will be delimited as follows:
The no_injected_text attribute is embedded in an .mrg file, which allows for the compilation of the .mrg file without
text being reinjected.
You should be aware that the .mrg source file is intended to be a representation of the source code injected by the
compiler. The .mrg file may not compile or run exactly as the original source file.
Macros are not expanded in the .mrg file.
If your program includes a header file that uses injected code, /Fx generates an .mrg.h file for that header. /Fx
does not merge include files that do not use injected code.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Output Files property page.
4. Modify the Expand Attributed Source property.
To set this compiler option programmatically
See ExpandAttributedSource.
See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/favor (Optimize for Architecture Specifics)
3/12/2019 • 2 minutes to read • Edit Online
/favor: option produces the code that is optimized for a specific architecture or for the specifics of micro-
architectures in the AMD and the Intel architectures.
Syntax
/favor:{blend | ATOM | AMD64 | INTEL64}
Remarks
/favor:blend
(x86 and x64) produces the code that is optimized for the specifics of micro-architectures in the AMD and the Intel
architectures. While /favor:blend may not give the best performance possible on a specific processor, it is
designed to give the best performance across a broad range of x86 and x64 processors. By default, /favor:blend
is in effect.
/favor:ATOM
(x86 and x64) produces the code that is optimized for the specifics of the Intel Atom processor and Intel Centrino
Atom Processor Technology. Code that is generated by using /favor:ATOM may also produce Intel SSSE3, SSE3,
SSE2, and SSE instructions for Intel processors.
/favor:AMD64
(x64 only) optimizes the generated code for the AMD Opteron, and Athlon processors that support 64-bit
extensions. The optimized code can run on all x64 compatible platforms. Code that is generated by using
/favor:AMD64 might cause worse performance on Intel processors that support Intel64.
/favor:INTEL64
(x64 only) optimizes the generated code for Intel processors that support Intel64, which typically yields better
performance for that platform. The resulting code can run on any x64 platform. Code that is generated with
/favor:INTEL64 might cause worse performance on AMD Opteron, and Athlon processors that support 64-bit
extensions.
NOTE
Intel64 architecture was previously known as Extended Memory 64 Technology, and the corresponding compiler option was
/favor:EM64T.
For information about how to program for the x64 architecture, see x64 Software Conventions.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. Enter the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/FC (Full Path of Source Code File in Diagnostics)
3/12/2019 • 2 minutes to read • Edit Online
Causes the compiler to display the full path of source code files passed to the compiler in diagnostics.
Syntax
/FC
Remarks
Consider the following code sample:
// compiler_option_FC.cpp
int main( ) {
int i // C2143
}
Without /FC, the diagnostic text would look similar to this diagnostic text:
compiler_option_FC.cpp(5) : error C2143: syntax error : missing ';' before '}'
With /FC, the diagnostic text would look similar to this diagnostic text:
c:\test\compiler_option_fc.cpp(5) : error C2143: syntax error : missing ';' before '}'
/FC is also needed if you want to see the full path of a file name when using the __FILE__ macro. See Predefined
Macros for more information on __FILE__.
The /FC option is implied by /ZI. For more information about /ZI, see /Z7, /Zi, /ZI (Debug Information Format).
/FC outputs full paths in lower case.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Advanced property page.
3. Modify the Use Full Paths property.
To set this linker option programmatically
See UseFullPaths.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/fp (Specify floating-point behavior)
3/12/2019 • 11 minutes to read • Edit Online
Specifies how the compiler treats floating-point expressions, optimizations, and exceptions. The /fp options
specify whether the generated code allows floating-point environment changes to the rounding mode, exception
masks, and subnormal behavior, and whether floating-point status checks return current, accurate results. It
controls whether the compiler generates code that maintains source operation and expression ordering and
conforms to the standard for NaN propagation, or if it instead generates more efficient code that may reorder or
combine operations and use simplifying algebraic transformations that are not allowed by the standard.
Syntax
/fp:[precise | strict | fast | except[-]]
Arguments
precise
By default, the compiler uses /fp:precise behavior.
Under /fp:precise the compiler preserves the source expression ordering and rounding properties of floating-
point code when it generates and optimizes object code for the target machine. The compiler rounds to source
code precision at four specific points during expression evaluation: at assignments, at typecasts, when a floating-
point argument is passed to a function call, and when a floating-point value is returned from a function call.
Intermediate computations may be performed at machine precision. Typecasts can be used to explicitly round
intermediate computations.
The compiler does not perform algebraic transformations on floating-point expressions, such as reassociation or
distribution, unless the transformation is guaranteed to produce a bitwise identical result. Expressions that
involve special values (NaN, +infinity, -infinity, -0.0) are processed according to IEEE -754 specifications. For
example, x != x evaluates to true if x is NaN. Floating-point contractions, that is, machine instructions that
combine floating-point operations, may be generated under /fp:precise.
The compiler generates code intended to run in the default floating-point environment and assumes that the
floating-point environment is not accessed or modified at runtime. That is, it assumes that the code does not
unmask floating-point exceptions, read or write floating-point status registers, or change rounding modes.
If your floating-point code does not depend on the order of operations and expressions in your floating-point
statements (for example, if you don't care whether a * b + a * c is computed as (b + c) * a or 2 * a as
a + a ), consider the /fp:fast option, which can produce faster, more efficient code. If your code both depends on
the order of operations and expressions, and accesses or alters the floating-point environment (for example, to
change rounding modes or to trap floating-point exceptions), use /fp:strict.
strict
/fp:strict has behavior similar to /fp:precise, that is, the compiler preserves the source ordering and rounding
properties of floating-point code when it generates and optimizes object code for the target machine, and
observes the standard when handling special values. In addition, the program may safely access or modify the
floating-point environment at runtime.
Under /fp:strict, the compiler generates code that allows the program to safely unmask floating-point
exceptions, read or write floating-point status registers, or change rounding modes. It rounds to source code
precision at four specific points during expression evaluation: at assignments, at typecasts, when a floating-point
argument is passed to a function call, and when a floating-point value is returned from a function call.
Intermediate computations may be performed at machine precision. Typecasts can be used to explicitly round
intermediate computations. The compiler does not perform algebraic transformations on floating-point
expressions, such as reassociation or distribution, unless the transformation is guaranteed to produce a bitwise
identical result. Expressions that involve special values (NaN, +infinity, -infinity, -0.0) are processed according to
IEEE -754 specifications. For example, x != x evaluates to true if x is NaN. Floating-point contractions are not
generated under /fp:strict.
/fp:strict is computationally more expensive than /fp:precise because the compiler must insert additional
instructions to trap exceptions and allow programs to access or modify the floating-point environment at
runtime. If your code doesn’t use this capability, but requires source code ordering and rounding, or relies on
special values, use /fp:precise. Otherwise, consider using /fp:fast, which can produce faster and smaller code.
fast
The /fp:fast option allows the compiler to reorder, combine, or simplify floating-point operations to optimize
floating-point code for speed and space. The compiler may omit rounding at assignment statements, typecasts,
or function calls. It may reorder operations or perform algebraic transforms, for example, by use of associative
and distributive laws, even if such transformations result in observably different rounding behavior. Because of
this enhanced optimization, the result of some floating-point computations may differ from those produced by
other /fp options. Special values (NaN, +infinity, -infinity, -0.0) may not be propagated or behave strictly
according to the IEEE -754 standard. Floating-point contractions may be generated under /fp:fast. The compiler
is still bound by the underlying architecture under /fp:fast, and additional optimizations may be available
through use of the /arch option.
Under /fp:fast, the compiler generates code intended to run in the default floating-point environment and
assumes that the floating-point environment isn’t accessed or modified at runtime. That is, it assumes that the
code does not unmask floating-point exceptions, read or write floating-point status registers, or change
rounding modes.
/fp:fast is intended for programs that do not require strict source code ordering and rounding of floating-point
expressions, and do not rely on the standard rules for handling special values such as NaN. If your floating-point
code requires preservation of source code ordering and rounding, or relies on standard behavior of special
values, use /fp:precise. If your code accesses or modifies the floating-point environment to change rounding
modes, unmask floating-point exceptions, or check floating-point status, use /fp:strict.
except
The /fp:except option generates code to ensures that any unmasked floating-point exceptions are raised at the
exact point at which they occur, and that no additional floating-point exceptions are raised. By default, the
/fp:strict option enables /fp:except, and /fp:precise does not. The /fp:except option is not compatible with
/fp:fast. The option can be explicitly disabled by us of /fp:except-.
Note that /fp:except does not enable any floating-point exceptions by itself, but it is required for programs to
enable floating-point exceptions. See _controlfp for information on how to enable floating-point exceptions.
Remarks
Multiple /fp options can be specified in the same compiler command line. Only one of /fp:strict, /fp:fast, and
/fp:precise options can be in effect at a time. If more than one of these options is specified on the command
line, the later option takes precedence and the compiler generates a warning. The /fp:strict and /fp:except
options are not compatible with /clr.
The /Za (ANSI compatibility) option is not compatible with /fp.
Using Pragmas to Control Floating-Point Behavior
The compiler provides three pragma directives to override the floating-point behavior specified on the
command-line: float_control, fenv_access, and fp_contract. You can use these pragmas to control floating-point
behavior at function-level, not within a function. Note that these pragmas do not correspond directly to the /fp
options. This table shows how the /fp options and pragmas map to each other. For more information, see the
documentation for the individual options and pragmas.
FLOAT_CONTROL(PRECI FLOAT_CONTROL(EXCE
SE) PT) FENV_ACCESS FP_CONTRACT
/fp:strict on on on off
int main(void)
{
float a = std::<float>::max();
float b = -1.1;
float cLower = 0.0;
float cUpper = 0.0;
unsigned int control_word = 0;
int err = 0;
Since the compiler assumes the default floating point environment under /fp:fast and /fp:precise it is free to
ignore the calls to _controlfp_s . For example, when compiled by using both /O2 and /fp:precise for the x86
architecture, the bounds are not computed, and the sample program outputs:
cLower = -inf
cUpper = -inf
When compiled with both /O2 and /fp:strict for the x86 architecture, the sample program outputs:
cLower = -inf
cUpper = -3.40282e+38
// fp_special_values.cpp
#include <stdio.h>
#include <cmath>
int main()
{
float f1 = INFINITY;
float f2 = NAN;
float f3 = -INFINITY;
bool a, b;
float c, d, e;
a = (f1 == f1);
b = (f2 == f2);
c = (f1 - f1);
d = (f2 - f2);
printf("INFINITY == INFINITY : %d\n", a);
printf("NAN == NAN : %d\n", b);
printf("INFINITY - INFINITY : %f\n", c);
printf("NAN - NAN : %f\n", d);
e = gf0 / abs(f3);
printf("std::signbit(-0.0/-INFINITY): %d\n", std::signbit(c));
return 0;
}
When compiled with /O2 /fp:precise or /O2 /fp:strict for x86 architecture, the outputs are consistent with the
IEEE -754 specification:
INFINITY == INFINITY : 1
NAN == NAN : 0
INFINITY - INFINITY : -nan(ind)
NAN - NAN : -nan(ind)
std::signbit(-0.0/-INFINITY): 1
When compiled with /O2 /fp:fast for x86 architecture, the outputs are not consistent with IEEE -754:
INFINITY == INFINITY : 1
NAN == NAN : 1
INFINITY - INFINITY : 0.000000
NAN - NAN : 0.000000
std::signbit(-0.0/-INFINITY): 0
When compiled by using /O2 /fp:precise or /O2 /fp:strict, you can see that explicit type casts are inserted at
both the typecast and at the function return point in the generated code for the x64 architecture:
Under /O2 /fp:fast the generated code is simplified, because all type casts are optimized away:
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
MSVC floating point optimization
Microsoft Visual C++ floating-point optimization
3/12/2019 • 41 minutes to read • Edit Online
Get a handle on optimizing floating-point code using the Microsoft C++ compiler's method of managing floating-
point semantics. Create fast programs while ensuring that only safe optimizations are performed on floating-point
code.
This function adds n float values in the array vector A . Within the loop body, the algorithm computes a
"correction" value which is then applied to the next step of the summation. This method greatly reduces cumulative
rounding errors as compared to a simple summation, while retaining O (n) time complexity.
A naïve C++ compiler might assume that floating-point arithmetic follows the same algebraic rules as Real
number arithmetic. Such a compiler might then erroneously conclude that
That is, that the perceived value of C is always a constant zero. If this constant value is then propagated into
subsequent expressions, the loop body is reduced to a simple summation. To be precise,
Thus, to the naïve compiler, a logical transformation of the KahanSum function would be:
float KahanSum( const float A[], int n )
{
float sum=0; // C, Y & T are now unused
for (int i=0; i<n; i++)
sum = sum + A[i];
return sum;
}
Although the transformed algorithm is faster, it is not at all an accurate representation of the programmer's
intention. The carefully crafted error correction has been removed entirely, and we're left with a simple, direct
summation algorithm with all its associated error.
Of course a sophisticated C++ compiler would know that algebraic rules of Real arithmetic do not generally apply
to floating-point arithmetic. However, even a sophisticated C++ compiler might still incorrectly interpret the
programmer's intention.
Consider a common optimization that attempts to hold as many values in registers as possible (called
"enregistering" a value). In the KahanSum example, this optimization might attempt to enregister the variables C ,
Y and T since they're used only within the loop body. If the register precision is 52bits (double) instead of 23bits
(single), this optimization effectively type promotes C , Y and T to type double. If the sum variable is not
likewise enregistered, it will remain encoded in single precision. This transforms the semantics of KahanSum to the
following
Although Y , T and C are now computed at a higher precision, this new encoding may produce a less accurate
result depending on the values in A[] . Thus even seemingly harmless optimizations may have negative
consequences.
These kinds of optimization problems aren't restricted to "tricky" floating-point code. Even simple floating-point
algorithms can fail when optimized incorrectly. Consider a simple, direct-summation algorithm:
Because some floating-point units are capable of performing multiple operations simultaneously, a compiler might
choose to engage a scalar reduction optimization. This optimization effectively transforms the simple Sum function
from above into the following:
float Sum( const float A[], int n )
{
int n4 = n-n%4; // or n4=n4&(~3)
int i;
float sum=0, sum1=0, sum2=0, sum3=0;
for (i=0; i<n4; i+=4)
{
sum = sum + A[i];
sum1 = sum1 + A[i+1];
sum2 = sum2 + A[i+2];
sum3 = sum3 + A[i+3];
}
sum = sum + sum1 + sum2 + sum3;
for (; i<n; i++)
sum = sum + A[i];
return sum;
}
The function now maintains four separate summations, which can be processed simultaneously at each step.
Although the optimized function is now much faster, the optimized results can be quite different from the non-
optimized results. In making this change, the compiler assumed associative floating-point addition; that is, that
these two expressions are equivalent: (a + b) + c == a + (b + c) . However, associativity does not always hold
true for floating-point numbers. Instead of computing the summation as:
sum = A[0]+A[1]+A[2]+...+A[n-1];
sum = (A[0]+A[4]+A[8]+...)
+ (A[1]+A[5]+A[9]+...)
+ (A[2]+A[6]+A[10]+...)
+ (A[3]+A[7]+A[11]+...);
For some values of A[] , this different ordering of addition operations may produce unexpected results. To further
complicate matters, some programmers may choose to anticipate such optimizations and compensate for them
appropriately. In this case, a program can construct the array A in a different order so that the optimized sum
produces the expected results. Moreover, in many circumstances the accuracy of the optimized result may be
"close enough". This is especially true when the optimization provides compelling speed benefits. Video games, for
example, require as much speed as possible but don't often require highly accurate floating-point computations.
Compiler makers must therefore provide a mechanism for programmers to control the often disparate goals of
speed and accuracy.
Some compilers resolve the tradeoff between speed and accuracy by providing a separate switch for each type of
optimization. This allows developers to disable optimizations that are causing changes to floating-point accuracy
for their particular application. While this solution may offer a high degree of control over the compiler, it
introduces several additional problems:
It is often unclear which switches to enable or disable.
Disabling any single optimization may adversely affect the performance of non floating-point code.
Each additional switch incurs many new switch combinations; the number of combinations quickly becomes
unwieldy.
So while providing separate switches for each optimization may seem appealing, using such compilers can be
cumbersome and unreliable.
Many C++ compilers offer a consistency floating-point model, (through a /Op or /fltconsistency switch) which
enables a developer to create programs compliant with strict floating-point semantics. When engaged, this model
prevents the compiler from using most optimizations on floating-point computations while allowing those
optimizations for non-floating-point code. The consistency model, however, has a dark-side. In order to return
predictable results on different FPU architectures, nearly all implementations of /Op round intermediate
expressions to the user specified precision; for example, consider the following expression:
float a, b, c, d, e;
// . . .
a = b * c + d * e;
In order to produce consistent and repeatable results under /Op, this expression gets evaluated as if it were
implemented as follows:
float x = b *c;
float y = d * e;
a = x + y;
The final result now suffers from single-precision rounding errors at each step in evaluating the expression.
Although this interpretation doesn't strictly break any C++ semantics rules, it's almost never the best way to
evaluate floating-point expressions. It is generally more desirable to compute the intermediate results in as high as
precision as is practical. For instance, it would be better to compute the expression a = b * c + d * e in a higher
precision as in,
double x = b * c;
double y = d * e;
double z = x + y;
a = (float)z;
or better yet
long double x = b * c;
long double y = d * e
long double z = x + y;
a = (float)z;
When computing the intermediate results in a higher precision, the final result is significantly more accurate.
Ironically, by adopting a consistency model, the likelihood of error is increased precisely when the user is trying to
reduce error by disabling unsafe optimizations. Thus the consistency model can seriously reduce efficiency while
simultaneously providing no guarantee of increased accuracy. To serious numerical programmers, this doesn't
seem like a very good tradeoff and is the primary reason that the model is not generally well received.
Beginning in version 8.0 (Visual C++® 2005), the Microsoft C++ compiler provides a much better alternative. It
allows programmers to select one of three general floating-point modes: fp:precise, fp:fast and fp:strict.
Under fp:precise, only safe optimizations are performed on floating-point code and, unlike /Op, intermediate
computations are consistently performed at the highest practical precision.
fp:fast mode relaxes floating-point rules allowing for more aggressive optimization at the expense of accuracy.
fp:strict mode provides all the general correctness of fp:precise while enabling fp-exception semantics and
preventing illegal transformations in the presence of FPU environment changes (e.g. changes to the register
precision, rounding direction etc).
Floating-point exception semantics can be controlled independently by either a command-line switch or a compiler
pragma; by default, floating-point exception semantics are disabled under fp:precise and enabled under fp:strict.
The compiler also provides control over FPU environment sensitivity and certain floating-point specific
optimizations, such as contractions. This straight-forward model gives developers a great deal of control over the
compilation of floating-point code without the burden of too many compiler switches or the prospect of
undesirable side-effects.
cl /fp:precise source.cpp
This instructs the compiler to use fp:precise semantics when generating code for the source.cpp file. The fp:precise
model can also be invoked on a function-by-function basis using the float_control compiler pragma.
Under the fp:precise mode, the compiler never performs any optimizations that perturb the accuracy of floating-
point computations. The compiler will always round correctly at assignments, typecasts and function calls, and
intermediate rounding will be consistently performed at the same precision as the FPU registers. Safe
optimizations, such as contractions, are enabled by default. Exception semantics and FPU environment sensitivity
are disabled by default.
Order of floating-point evaluation The compiler may reorder the evaluation of floating-point
expressions provided that the final results are not altered.
FPU environment access Disabled by default. For more information, see section The
fenv_access pragma. The default precision and rounding mode
is assumed.
Floating-point exception semantics Disabled by default. For more information, see /fp:except.
float a, b, c, d;
double x;
...
x = a*b + c*d;
is computed as
float a, b, c, d;
double x;
...
register tmp1 = a*b;
register tmp2 = c*d;
register tmp3 = tmp1+tmp2;
x = (double) tmp3;
To explicitly round an intermediate result, introduce a typecast. For example, if the previous code is modified by
adding an explicit typecast, the intermediate expression (c*d) will be rounded to the type of the typecast.
float a, b, c, d;
double x;
// . . .
x = a*b + (float)(c*d);
is computed as
float a, b, c, d;
double x;
// . . .
register tmp1 = a*b;
float tmp2 = c*d;
register tmp3 = tmp1+tmp2;
x = (double) tmp3;
One implication of this rounding method is that some seemingly equivalent transformations don't actually have
identical semantics. For instance, the following transformation splits a single assignment expression into two
assignment expressions.
float a, b, c, d;
// . . .
a = b*(c+d);
is NOT equivalent to
float a, b, c, d;
// . . .
a = c+d;
a = b*a;
Likewise:
a = b*(c+d);
is NOT equivalent to
a = b*(a=c+d);
These encodings do not have equivalent semantics because the second encodings have each introduced an
additional assignment operation, and hence an additional rounding point.
When a function returns a floating-point value, the value will be rounded to the type of the function. When a
floating-point value is passed as a parameter to a function, the value will be rounded to the type of the parameter.
For example:
is computed as
Likewise:
float w, x, y, z;
double c;
...
c = symsqr(w*x+y, z);
is computed as
float x, y, z;
double c;
...
register tmp1 = w*x;
register tmp2 = tmp1+y;
float tmp3 = tmp2;
c = symsqr( tmp3, z);
FORM DESCRIPTION
As depicted in the introduction example with the function KahanSum , the compiler might be tempted to perform
various algebraic transformations in order to produce considerably faster programs. Although optimizations
dependent on such algebraic transformations are almost always incorrect, there are occasions for which they are
perfectly safe. For instance, it is sometimes desirable to replace division by a constant value with multiplication by
the multiplicative-inverse of the constant:
const double four = 4.0;
double a, b;
...
a = b/four;
This is a safe transformation because the optimizer can determine at compile time that x/4.0 == x*(1/4.0) for all
floating-point values of x, including infinities and NaN. By replacing a division operation with a multiplication, the
compiler can save several cycles—especially on FPUs that don't directly implement division, but require the
compiler to generate a combination of reciprocal-approximation and multiply-add instructions. The compiler may
perform such an optimization under fp:precise only when the replacement multiplication produces the exact same
result as the division. The compiler may also perform trivial transformations under fp:precise, provided the results
are identical. These include:
FORM DESCRIPTION
This computation can be performed a series of multiply-add instructions of the form p = p + x[i]*y[i].
The contraction optimization can be independently controlled using the fp_contract compiler pragma. By default,
the fp:precise model allows for contractions since they improve both accuracy and speed. Under fp:precise, the
compiler will never contract an expression with explicit rounding. Examples
float a, b, c, d, e, t;
...
d = a*b + c; // may be contracted
d += a*b; // may be contracted
d = a*b + e*d; // may be contracted into a mult followed by a mult-add
etc...
//original function
float dotProduct( float x[], float y[], int n )
{
float p=0;
for (int i=0; i<n; i++)
p += x[i]*y[i];
return p;
}
return p;
}
The primary benefit of this optimization is that it reduces the number of conditional loop-branching by as much as
75%. Also, by increasing the number of operations within the loop body, the compiler may now have more
opportunities to optimize further. For instance, some FPUs may be able to perform the multiply-add in p+=x[i]*y[i]
while simultaneously fetching the values for x[i+1] and y[i+1] for use in the next step. This type of optimization is
perfectly safe for floating-point computations because it preserves the order of operations.
It's often advantageous for the compiler to reorder entire operations in order to produce faster code. Consider the
following code:
double a, b, c, d;
double x, y, z;
...
x = a*a*a + b*b*b + c*c*c;
...
y = a*a + b*b + c*c;
...
z = a + b + c;
C++ semantic rules indicate that the program should produce results as if it first computed x, then y and finally z.
Suppose the compiler has only four available floating-point registers. If the compiler is forced to compute x, y and
z in order, it might choose to generate code with the following semantics:
double a, b, c, d;
double x, y, z;
register r0, r1, r2, r3;
...
// Compute x
r0 = a; // r1 = a*a*a
r1 = r0*r0;
r1 = r1*r0;
r0 = b; // r2 = b*b*b
r2 = r0*r0;
r2 = r2*r0;
r0 = c; // r3 = c*c*c
r3 = r0*r0;
r3 = r3*r0;
r0 = r1 + r2;
r0 = r0 + r3;
x = r0; // x = r1+r2+r3
// . . .
// Compute y
r0 = a; // r1 = a*a
r1 = r0*r0;
r0 = b; // r2 = b*b
r2 = r0*r0;
r0 = c; // r3 = c*c
r3 = r0*r0;
r0 = r1 + r2;
r0 = r0 + r3;
y = r0; // y = r1+r2+r3
// . . .
// Compute z
r1 = a;
r2 = b;
r3 = c;
r0 = r1 + r2;
r0 = r0 + r3;
z = r0; // z = r1+r2+r3
There are several clearly redundant operations is this encoding. If the compiler strictly follows C++ semantic rules,
this ordering is necessary because the program might access the FPU environment in-between each assignment.
However, the default settings for fp:precise allow the compiler to optimize as though the program doesn't access
the environment, allowing it to reorder these expressions. It's then free to remove the redundancies by computing
the three values in reverse order, as follows:
double a, b, c, d;
double x, y, z;
register r0, r1, r2, r3;
...
// Compute z
r1 = a;
r2 = b;
r3 = c;
r0 = r1+r2;
r0 = r0+r3;
z = r0;
...
// Compute y
r1 = r1*r1;
r2 = r2*r2;
r3 = r3*r3;
r0 = r1+r2;
r0 = r0+r3;
y = r0;
...
// Compute x
r0 = a;
r1 = r1*r0;
r0 = b;
r2 = r2*r0;
r0 = c;
r3 = r3*r0;
r0 = r1+r2;
r0 = r0+r3;
x = r0;
This encoding is clearly superior, having reduced the number of fp-instructions by almost 40%. The results for x, y
and z are the same as before, but computed with less overhead.
Under fp:precise, the compiler may also interlace common sub-expressions so as to produce faster code. For
example, code to compute the roots of a quadratic equation might be written as follows:
Although these expressions only differ by a single operation, the programmer may have written it this way to
guarantee that each root value will be computed in the highest practical precision. Under fp:precise, the compiler is
free to interlace the computation of root0 and root1 to remove common sub-expressions without losing precision.
For instance, the following has removed several redundant steps while producing the exact same answer.
Other optimizations may attempt to move the evaluation of certain independent expressions. Consider the
following algorithm which contains a conditional-branch within a loop-body.
vector<double> a(n);
double d, s;
// . . .
for (int i=0; i<n; i++)
{
if (abs(d)>1.0)
s = s+a[i]/d;
else
s = s+a[i]*d;
}
The compiler may detect that the value of the expression (abs(d)>1) is invariant within the loop body. This enables
the compiler to "hoist" the if statement outside the loop body, transforming the above code into the following:
vector<double> a(n);
double d, s;
// . . .
if (abs(d)>1.0)
for (int i=0; i<n; i++)
s = s+a[i]/d;
else
for (int i=0; i<n; i++)
s = s+a[i]*d;
After the transformation, there is no longer a conditional branch in either of the loop bodies, thus greatly
improving the overall performance of the loop. This type of optimization is perfectly safe because the evaluation of
the expression (abs(d)>1.0) is independent of other expressions.
In the presence of FPU environment access or floating-point exceptions, these types of optimization are
contraindicated because they change the semantic flow. Such optimizations are only available under the fp:precise
mode because FPU environment access and floating-point exception semantics are disabled by default. Functions
that access the FPU environment can explicitly disable such optimizations by using the fenv_access compiler
pragma. Likewise, functions using floating-point exceptions should use the float_control(except ... ) compiler
pragma (or use the /fp:except command line switch).
In summary, the fp:precise mode allows the compiler to reorder the evaluation of floating-point expressions on
condition that the final results are not altered and that results are not dependant on the FPU environment or on
floating-point exceptions.
FPU environment access under fp:precise
When the fp:precise mode is enabled, the compiler assumes that a program does not access or alter the FPU
environment. As stated earlier, this assumption enables the compiler to reorder or move floating-point operations
to improve efficiency under fp:precise.
Some programs may alter the floating-point rounding-direction by using the _controlfp function. For instance,
some programs compute upper and lower error bounds on arithmetic operations by performing the same
computation twice, first while rounding towards negative infinity, then while rounding towards positive infinity.
Since the FPU provides a convenient way to control rounding, a programmer may choose to change rounding
mode by altering the FPU environment. The following code computes an exact error bound of a floating-point
multiplication by altering the FPU environment.
double a, b, cLower, cUpper;
// . . .
_controlfp( _RC_DOWN, _MCW_RC ); // round to -∞
cLower = a*b;
_controlfp( _RC_UP, _MCW_RC ); // round to +∞
cUpper = a*b;
_controlfp( _RC_NEAR, _MCW_RC ); // restore rounding mode
Under fp:precise, the compiler always assumes the default FPU environment, so the optimizer is free to ignore the
calls to _controlfp and reduce the above assignments to cUpper = cLower = a*b; this would clearly yield incorrect
results. To prevent such optimizations, enable FPU environment access by using the fenv_access compiler
pragma.
Other programs may attempt to detect certain floating-point errors by checking the FPU's status word. For
example, the following code checks for the divide-by-zero and inexact conditions
double a, b, c, r;
float x;
// . . .
_clearfp();
r = (a*b + sqrt(b*b-4*a*c))/(2*a);
if (_statusfp() & _SW_ZERODIVIDE)
handle divide by zero as a special case
_clearfp();
x = r;
if (_statusfp() & _SW_INEXACT)
handle inexact error as a special case
etc...
Under fp:precise, optimizations that reorder expression evaluation may change the points at which certain errors
occur. Programs accessing the status word should enable FPU environment access by using the fenv_access
compiler pragma.
For more information, see section The fenv_access pragma.
Floating-point exception semantics under fp:precise
By default, floating-point exception semantics are disabled under fp:precise. Most C++ programmers prefer to
handle exceptional floating-point conditions without using system or C++ exceptions. Moreover, as stated earlier,
disabling floating-point exception semantics allows the compiler greater flexibility when optimizing floating-point
operations. Use either the /fp:except switch or the float_control pragma to enable floating-point exception
semantics when using the fp:precise model.
For more information, see section Enabling floating-point exception semantics.
cl /fp:fast source.cpp
This example instructs the compiler to use fp:fast semantics when generating code for the source.cpp file. The
fp:fast model can also be invoked on a function-by-function basis using the float_control compiler pragma.
For more information, see section The float_control pragma.
Under the fp:fast mode, the compiler may perform optimizations that alter the accuracy of floating-point
computations. The compiler may not round correctly at assignments, typecasts or function calls, and intermediate
rounding will not always be performed. Floating-point specific optimizations, such as contractions, are always
enabled. Floating-point exception semantics and FPU environment sensitivity are disabled and unavailable.
Order of floating-point evaluation The compiler may reorder the evaluation of floating-point
expressions, even when such changes may alter the final
results.
Variables enregistered:
float KahanSum( const float A[], int n )
{
float sum=0;
double C=0, Y, T; // now held in-register
for (int i=0; i<n; i++)
{
Y = A[i] - C;
T = sum + Y;
C = T - sum - Y;
sum = (float) T;
}
return sum;
}
In this example, fp:fast has subverted the intent of the original function. The final optimized result, held in the
variable sum , may be quite perturbed from the correct result.
Under fp:fast, the compiler will typically attempt to maintain at least the precision specified by the source code.
However, in some instances the compiler may choose to perform intermediate expressions at a lower precision
than specified in the source code. For example, the first code block below calls a double precision version of the
square-root function. Under fp:fast, in certain circumstances, such as when the result and operands of the function
are explicitly cast to single-precision, the compiler may choose to replace the call to the double precision sqrt
with a call to a single precision sqrtf function. Because casts ensure that the value going into sqrt and the value
coming out are rounded to single precision, this only changes the place of rounding. If the value coming into sqrt
was a double-precision value and the compiler performed this transformation, as many as half of the precision bits
could be wrong.
Original function
double sqrt(double);
// . . .
double a, b, c;
float f1, f2;
// . . .
float length = (float)sqrt((float)(a*a + b*b + c*c));
float sum = (float) ((double)f1 + (double)f2);
Optimized function
float sqrtf(float)...
// . . .
double a, b, c;
float f1, f2;
// . . .
double tmp0 = a*a + b*b + c*c;
float tmp1 = tmp0; // round of parameter value
float length = sqrtf(tmp1); // rounded sqrt result
float sum = f1 + f2;
Although less accurate, this optimization may be especially beneficial when targeting processors that provide
single precision, intrinsic versions of functions such as sqrt . Just precisely when the compiler will use such
optimizations is both platform and context dependant.
Furthermore, there is no guaranteed consistency for the precision of intermediate computations, which may be
performed at any precision level available to the compiler. Although the compiler will attempt to maintain at least
the level of precision as specified by the code, fp:fast allows the optimizer to downcast intermediate computations
in order to produce faster or smaller machine code. For instance, the compiler may further optimize the code from
above to round some of the intermediate multiplications to single precision.
float sqrtf(float)...
// . . .
double a, b, c;
float f1, f2;
// . . .
float tmp0 = a*a; // round intermediate a*a to single-precision
float tmp1 = b*b; // round intermediate b*b to single-precision
double tmp2 = c*c; // do NOT round intermediate c*c to single-precision
float tmp3 = tmp0 + tmp1 + tmp2;
float length = sqrtf(tmp3);
float sum = f1 + f2;
This kind of additional rounding may result from using a lower precision floating-point unit, such as SSE2, to
perform some of the intermediate computations. The accuracy of fp:fast rounding is therefore platform dependant;
code that compiles well for one processor may not necessarily work well for another processor. It's left to the user
to determine if the speed benefits outweigh any accuracy problems.
If fp:fast optimization is particularly problematic for a specific function, the floating-point mode can be locally
switched to fp:precise using the float_control compiler pragma.
Algebraic transformations under fp:fast
The fp:fast mode enables the compiler to perform certain, unsafe algebraic transformations to floating point
expressions. For example, the following unsafe optimizations may be employed under fp:fast.
c = x – z; c = x – 0; c = x;
c = x * z; c = x * 0; c = 0;
c = x - z; c = x - 0; c = x;
c = x + z; c = x + 0; c = x;
c = z-x; c = 0 - x; c = -x;
In step 1, the compiler observes that z = y – a – b is always equal to zero. Although this is technically an invalid
observation, it is permitted under fp:fast. The compiler then propagates the constant value zero to every
subsequent use of the variable z. In step 2, the compiler further optimizes by observing that x - 0 == x ,
x * 0 == 0 , etc. Again, even though these observations are not strictly valid, they are permitted under fp:fast. The
optimized code is now much faster, but may also be considerably less accurate or even incorrect.
Any of the following (unsafe) algebraic rules may be employed by the optimizer when the fp:fast mode is enabled:
Form Description
If fp:fast optimization is particularly problematic for a particular function, the floating-point mode can be locally
switched to fp:precise using the float_control compiler pragma.
Order of floating-point expression evaluation under fp:fast
Unlike fp:precise, fp:fast allows the compiler to reorder floating-point operations so as to produce faster code.
Thus, some optimizations under fp:fast may not preserve the intended order of expressions. For instance, consider
the following function that computes the dot product of two n-dimensional vectors.
Under fp:fast, the optimizer may perform a scalar reduction of the dotProduct function effectively transforming
the function as follows:
return p;
}
In the optimized version of the function four separate product-summations are taken simultaneously and then
added together. This optimization can speed up the computation of the dotProduct by as much as a factor of four
depending on the target processor, but the final result may be so inaccurate as to render it useless. If such
optimizations are particularly problematic for single function or translation unit, the floating-point mode can be
locally switched to fp:precise using the float_control compiler pragma.
cl /fp:strict source.cpp
This example instructs the compiler to use fp:strict semantics when generating code for the source.cpp file. The
fp:strict model can also be invoked on a function-by-function basis using the float_control compiler pragma.
For more information, see section The float_control pragma.
Under the fp:strict mode, the compiler never performs any optimizations that perturb the accuracy of floating-
point computations. The compiler will always round correctly at assignments, typecasts and function calls, and
intermediate rounding will be consistently performed at the same precision as the FPU registers. Floating-point
exception semantics and FPU environment sensitivity are enabled by default. Certain optimizations, such as
contractions, are disabled because the compiler cannot guarantee correctness in every case.
Order of floating-point evaluation The compiler will not reorder the evaluation of floating-point
expressions
The fenv_access pragma allows the compiler to make certain optimizations that might subvert FPU flag tests and
FPU mode changes. When the state of fenv_access is disabled, the compiler can assume the default FPU modes
are in effect and that FPU flags are not tested. By default, environment access is disabled for the fp:precise mode,
though it may be explicitly enabled using this pragma. Under fp:strict, fenv_access is always enabled and cannot
be disabled. Under fp:fast, fenv_access is always disabled, and cannot be enabled.
As described in the fp:precise section, some programmers may alter the floating-point rounding-direction using
the _controlfp function. For example, to compute the upper and lower error bounds on arithmetic operations,
some programs perform the same computation twice, first while rounding towards negative infinity, then while
rounding towards positive infinity. Since the FPU provides a convenient way to control rounding, a programmer
may choose to change rounding mode by altering the FPU environment. The following code computes an exact
error bound of a floating-point multiplication by altering the FPU environment.
When disabled, the fenv_access pragma allows the compiler to assume the default FPU environment; thus the
optimizer is free to ignore the calls to _controlfp and reduce the above assignments to cUpper = cLower = a*b .
When enabled, however, fenv_access prevents such optimizations.
Programs may also check the FPU status word to detect certain floating-point errors. For example, the following
code checks for the divide-by-zero and inexact conditions
double a, b, c, r;
float x;
// . . .
_clearfp();
r = (a*b + sqrt(b*b-4*a*c))/(2*a);
if (_statusfp() & _SW_ZERODIVIDE)
handle divide by zero as a special case
_clearfp();
x = (a*b + sqrt(b*b-4*a*c))/(2*a);
if (_statusfp() & _SW_INEXACT)
handle inexact error as a special case
etc...
When fenv_access is disabled, the compiler might rearrange the execution order of the floating-point expressions,
thus possibly subverting the FPU status checks. Enabling fenv_access prevents such optimizations.
As described in the fp:precise section, contraction is a fundamental architectural feature for many modern floating-
point units. Contractions provide the ability to perform a multiplication followed by an addition as a single
operation with no intermediate round-off error. These single instructions are faster than executing separate
multiply and add instructions, and are more accurate since there is no intermediate rounding of the product. A
contracted operation can computes the value of (a*b+c) as if both operations were computed to infinite precision,
and then rounded to the nearest floating-point number. This optimization can significantly speed up functions
containing several interleaved multiply and add operations. For example, consider the following algorithm which
computes the dot-product of two n-dimensional vectors.
This computation can be performed a series of multiply-add instructions of the form p = p + x[i]*y[i] .
The fp_contract pragma specifies whether floating-point expressions can be contracted. By default, the fp:precise
mode allows for contractions since they improve both accuracy and speed. Contractions are always enabled for the
fp:fast mode. However, because contractions can subvert the explicit detection of error conditions, the fp_contract
pragma is always disabled under the fp:strict mode. Examples of expressions that may be contracted when the
fp_contract pragma is enabled:
float a, b, c, d, e, t;
...
d = a*b + c; // may be contracted
d += a*b; // may be contracted
d = a*b + e*d; // may be contracted into a mult followed by a mult-add etc...
#pragma float_control(push)
#pragma float_control(pop)
#pragma float_control( precise, on | off [, push] )
#pragma float_control( except, on | off [, push] )
The pragmas float_control(push) and float_control(pop) respectively push and pop the current state of the
floating-point mode and the exception option onto a stack. Note that the state of the fenv_access and
fp_contract pragma are not affected by pragma float_control(push/pop) .
Calling the pragma float_control(precise, on) will enable and float_control(precise, off) will disable precise-
mode semantics. Likewise, the pragma float_control(except, on) will enable and float_control(except, off) will
disable exception semantics. Exception semantics can only be enabled when precise semantics are also enabled.
When the optional push argument is present, the states of the float_control options are pushed prior to
changing semantics.
Setting the floating-point semantic mode on a function-by-function basis
The command-line switches are in fact shorthand for setting the four different floating-point pragmas. To explicitly
choose a particular floating-point semantic mode on a function-by-function basis, select each of the four floating-
point option pragmas as described in the following table:
/fp:strict on on off on
NOTE
Exception semantics must be turned off before turning off "precise" semantics.
When the divide-by-zero exception is enabled, any division operation with a denominator equal to zero will cause a
FPU exception to be signaled.
To restore the FPU control word to the default mode, call _controlfp(_CW_DEFAULT, ~0) .
Enabling floating-point exception semantics with the /fp:except flag is not the same as enabling floating-point
exceptions. When floating-point exception semantics are enabled, the compiler must account for the possibility that
any floating-point operation might throw an exception. Because the FPU is a separate processor unit, instructions
executing on the FPU can be performed concurrently with instructions on other units.
When a floating-point exception is enabled, the FPU will halt execution of the offending instruction and then signal
an exceptional condition by setting the FPU status word. When the CPU reaches the next floating-point instruction,
it first checks for any pending FPU exceptions. If there is a pending exception, the processor traps it by calling an
exception handler provided by the Operating System. This means that when a floating-point operation encounters
an exceptional condition, the corresponding exception won't be detected until the next floating-point operation is
executed. For example, the following code traps a divide-by-zero exception:
double a, b, c;
// . . .
// ...unmasking of FPU exceptions omitted...
__try
{
b/c; // assume c==0.0
printf("This line shouldn't be reached when c==0.0\n");
c = 2.0*b;
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
printf("SEH Exception Detected\n");
}
// . . .
If a divide-by-zero condition occurs in the expression a=b/c, the FPU won't trap/raise the exception until the next
floating-point operation in the expression 2.0*b. This results in the following output:
The printf corresponding to the first line of the output should not have been reached; it was reached because the
floating-point exception caused by the expression b/c wasn't raised until execution reached 2.0*b. To raise the
exception just after executing b/c, the compiler must introduce a "wait" instruction:
// . . .
__try
{
b/c; // assume this expression will cause a "divide-by-zero" exception
__asm fwait;
printf("This line shouldn't be reached when c==0.0\n");
c = 2.0*b;
}
// . . .
This "wait" instruction forces the processor to synchronize with the state of the FPU and handle any pending
exceptions. The compiler will only generate these "wait" instructions when floating-point semantics are enabled.
When these semantics are disabled, as there are by default, programs may encounter synchronicity errors, similar
to the one above, when using floating-point exceptions.
When floating-point semantics are enabled, the compiler will not only introduce "wait" instructions, it will also
prevent the compiler from illegally optimizing floating-point code in the presence of possible exceptions. This
includes any transformations that alter the points at which exceptions are thrown. Because of these factors,
enabling floating-point semantics may considerably reduce the efficiency of the generated machine code thus
degrading an application's performance.
Floating-point exception semantics are enabled by default under the fp:strict mode. To enable these semantics in
the fp:precise mode, add the /fp:except switch to the compiler command-line. Floating-point exception semantics
can also be enabled and disabled on a function-by-function basis using the float_control pragma.
Floating-point exceptions as C++ exceptions
As with all hardware exceptions, floating-point exceptions do not intrinsically cause a C++ exception, but instead
trigger a structured exception. To map floating-point structured exceptions to C++ exceptions, users can introduce
a custom SEH exception translator. First, introduce a C++ exception corresponding to each floating-point
exception:
Then, introduce a translation function that will detect a floating-point SEH exception and throw the corresponding
C++ exception. To use this function, set the structured-exception handler translator for the current process thread
with the _set_se_translator function from the runtime library.
Once this mapping is initialized, floating-point exceptions will behave as though they are C++ exceptions. For
example:
try
{
// floating-point code that might throw divide-by-zero
// or other floating-point exception
}
catch(fe_divide_by_zero)
{
cout << "fe_divide_by_zero exception detected" << endl;
}
catch(float_exception)
{
cout << "float_exception exception detected" << endl;
}
References
What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg.
See also
Optimizing Your Code
/FS (Force Synchronous PDB Writes)
3/12/2019 • 2 minutes to read • Edit Online
Forces writes to the program database (PDB ) file—created by /Zi or /ZI—to be serialized through
MSPDBSRV.EXE.
Syntax
/FS
Remarks
By default, when /Zi or /ZI is specified, the compiler locks PDB files to write type information and symbolic
debugging information. This can significantly reduce the time it takes the compiler to generate type information
when the number of types is large. If another process temporarily locks the PDB file—for example, an anti-virus
program—writes by the compiler may fail and a fatal error may occur. This problem can also happen when
multiple copies of cl.exe access the same PDB file—for example, if your solution has independent projects that use
the same intermediate directories or output directories and parallel builds are enabled. The /FS compiler option
prevents the compiler from locking the PDB file and forces writes to go through MSPDBSRV.EXE, which serializes
access. This may make builds significantly longer, and it doesn't prevent all errors that may occur when multiple
instances of cl.exe access the PDB file at the same time. We recommend that you change your solution so that
independent projects write to separate intermediate and output locations, or that you make one of the projects
dependent on the other to force serialized project builds.
The /MP option enables /FS by default.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. Modify the Additional Options property to include /FS and then choose OK.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GA (Optimize for Windows Application)
3/12/2019 • 2 minutes to read • Edit Online
Results in more efficient code for an .exe file for accessing thread-local storage (TLS ) variables.
Syntax
/GA
Remarks
/GA speeds access to data declared with __declspec(thread) in a Windows-based program. When this option is set,
the __tls_index macro is assumed to be 0.
Using /GA for a DLL can result in bad code generation.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Gd, /Gr, /Gv, /Gz (Calling Convention)
3/12/2019 • 4 minutes to read • Edit Online
These options determine the order in which function arguments are pushed onto the stack, whether the caller
function or called function removes the arguments from the stack at the end of the call, and the name-decorating
convention that the compiler uses to identify individual functions.
Syntax
/Gd
/Gr
/Gv
/Gz
Remarks
/Gd, the default setting, specifies the __cdecl calling convention for all functions except C++ member functions
and functions that are marked __stdcall, __fastcall, or __vectorcall.
/Gr specifies the __fastcall calling convention for all functions except C++ member functions, functions named
main , and functions that are marked __cdecl , __stdcall , or __vectorcall . All __fastcall functions must have
prototypes. This calling convention is only available in compilers that target x86, and is ignored by compilers that
target other architectures.
/Gz specifies the __stdcall calling convention for all functions except C++ member functions, functions named
main , and functions that are marked __cdecl , __fastcall , or __vectorcall . All __stdcall functions must have
prototypes. This calling convention is only available in compilers that target x86, and is ignored by compilers that
target other architectures.
/Gv specifies the __vectorcall calling convention for all functions except C++ member functions, functions
named main, functions with a vararg variable argument list, or functions that are marked with a conflicting
__cdecl , __stdcall , or __fastcall attribute. This calling convention is only available on x86 and x64
architectures that support /arch:SSE2 and above, and is ignored by compilers that target the ARM architecture.
Functions that take a variable number of arguments must be marked __cdecl .
/Gd, /Gr, /Gv and /Gz are not compatible with /clr:safe or /clr:pure. The /clr:pure and /clr:safe compiler
options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
NOTE
By default for x86 processors, C++ member functions use __thiscall.
For all processors, a member function that is explicitly marked as __cdecl , __fastcall , __vectorcall , or
__stdcall uses the specified calling convention if it is not ignored on that architecture. A member function that
takes a variable number of arguments always uses the __cdecl calling convention.
These compiler options have no effect on the name decoration of C++ methods and functions. Unless declared
as extern "C" , C++ methods and functions use a different name-decorating scheme. For more information, see
Decorated Names.
For more information about calling conventions, see Calling Conventions.
__cdecl Specifics
On x86 processors, all function arguments are passed on the stack from right to left. On ARM and x64
architectures, some arguments are passed by register and the rest are passed on the stack from right to left. The
calling routine pops the arguments from the stack.
For C, the __cdecl naming convention uses the function name preceded by an underscore ( _ ); no case
translation is performed. Unless declared as extern "C" , C++ functions use a different name-decorating
scheme. For more information, see Decorated Names.
__fastcall Specifics
Some of a __fastcall function's arguments are passed in registers (for x86 processors, ECX, and EDX), and the
rest are pushed onto the stack from right to left. The called routine pops these arguments from the stack before it
returns. Typically, /Gr decreases execution time.
NOTE
Be careful when you use the __fastcall calling convention for any function that's written in inline assembly language.
Your use of registers could conflict with the compiler's use.
For C, the __fastcall naming convention uses the function name preceded by an at sign (@) followed by the
size of the function's arguments in bytes. No case translation is done. The compiler uses this template for the
naming convention:
@function_name@number
When you use the __fastcall naming convention, use the standard include files. Otherwise, you will get
unresolved external references.
__stdcall Specifics
A __stdcall function's arguments are pushed onto the stack from right to left, and the called function pops
these arguments from the stack before it returns.
For C, the __stdcall naming convention uses the function name preceded by an underscore (_) and followed by
an at sign (@) and the size of the function's arguments in bytes. No case translation is performed. The compiler
uses this template for the naming convention:
_functionname@number
__vectorcall Specifics
A __vectorcall function’s integer arguments are passed by value, using up to two (on x86) or four (on x64)
integer registers, and up to six XMM registers for floating-point and vector values, and the rest are passed on the
stack from right to left. The called function cleans off the stack before it returns. Vector and floating-point return
values are returned in XMM0.
For C, the __vectorcall naming convention uses the function name followed by two at signs (@@) and the size
of the function's arguments in bytes. No case translation is performed. The compiler uses this template for the
naming convention:
functionname@@number
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ > Advanced property page.
3. Modify the Calling Convention property.
To set this compiler option programmatically
See CallingConvention.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Ge (Enable Stack Probes)
3/12/2019 • 2 minutes to read • Edit Online
Activates stack probes for every function call that requires storage for local variables.
Syntax
/Ge
Remarks
This mechanism is useful if you rewrite the functionality of the stack probe. It is recommended that you use /Gh
(Enable _penter Hook Function) instead of rewriting the stack probe.
/Gs (Control Stack Checking Calls) has the same effect.
/Ge is deprecated; beginning in Visual Studio 2005, the compiler automatically generates stack checking. For a list
of deprecated compiler options, see Deprecated and Removed Compiler Options in Compiler Options Listed
by Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GF (Eliminate Duplicate Strings)
3/12/2019 • 2 minutes to read • Edit Online
Enables the compiler to create a single copy of identical strings in the program image and in memory during
execution. This is an optimization called string pooling that can create smaller programs.
Syntax
/GF
Remarks
If you use /GF, the operating system does not swap the string portion of memory and can read the strings back
from the image file.
/GF pools strings as read-only. If you try to modify strings under /GF, an application error occurs.
String pooling allows what were intended as multiple pointers to multiple buffers to be multiple pointers to a
single buffer. In the following code, s and t are initialized with the same string. String pooling causes them to
point to the same memory:
NOTE
The /ZI option, used for Edit and Continue, automatically sets the /GF option.
NOTE
The /GF compiler option creates an addressable section for each unique string. And by default, an object file can contain up
to 65,536 addressable sections. If your program contains more than 65,536 strings, use the /bigobj compiler option to
create more sections.
Syntax
/GH
Remarks
The _pexit function is not part of any library and it is up to you to provide a definition for _pexit .
Unless you plan to explicitly call _pexit , you do not need to provide a prototype. The function must appear as if it
had the following prototype, and it must push the content of all registers on entry and pop the unchanged content
on exit:
_pexit is similar to _penter ; see /Gh (Enable _penter Hook Function) for an example of how to write a _pexit
function.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Gh (Enable _penter Hook Function)
3/12/2019 • 2 minutes to read • Edit Online
Causes a call to the _penter function at the start of every method or function.
Syntax
/Gh
Remarks
The _penter function is not part of any library and it is up to you to provide a definition for _penter .
Unless you plan to explicitly call _penter , you do not need to provide a prototype. The function must appear as if
it had the following prototype, and it must push the content of all registers on entry and pop the unchanged
content on exit:
Example
The following code, when compiled with /Gh, shows how _penter is called twice; once when entering function
main and once when entering function x .
// Gh_compiler_option.cpp
// compile with: /Gh
// processor: x86
#include <stdio.h>
void x() {}
int main() {
x();
}
printf_s("\nIn a function!");
_asm {
pop esi
pop edi
pop ebp
pop edx
pop ecx
pop ebx
pop eax
ret
}
}
In a function!
In a function!
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GL (Whole Program Optimization)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/GL[-]
Remarks
Whole program optimization allows the compiler to perform optimizations with information on all modules
in the program. Without whole program optimization, optimizations are performed on a per module
(compiland) basis.
Whole program optimization is off by default and must be explicitly enabled. However, it is also possible to
explicitly disable it with /GL -.
With information on all modules, the compiler can:
Optimize the use of registers across function boundaries.
Do a better job of tracking modifications to global data, allowing a reduction in the number of loads
and stores.
Do a better job of tracking the possible set of items modified by a pointer dereference, reducing the
numbers of loads and stores.
Inline a function in a module even when the function is defined in another module.
.obj files produced with /GL will not be available to such linker utilities as EDITBIN and DUMPBIN.
If you compile your program with /GL and /c, you should use the /LTCG linker option to create the output
file.
/ZI cannot be used with /GL
The format of files produced with /GL in the current version may not be readable by subsequent versions of
Visual C++. You should not ship a .lib file comprised of .obj files that were produced with /GL unless you are
willing to ship copies of the .lib file for all versions of Visual C++ you expect your users to use, now and in
the future.
.obj files produced with /GL and precompiled header files should not be used to build a .lib file unless the .lib
file will be linked on the same machine that produced the /GL .obj file. Information from the .obj file's
precompiled header file will be needed at link time.
For more information on the optimizations available with and the limitations of whole program optimization,
see /LTCG. /GL also makes profile guided optimization available; see /LTCG. When compiling for profile
guided optimizations and if you want function ordering from your profile guided optimizations, you must
compile with /Gy or a compiler option that implies /Gy.
To set this linker option in the Visual Studio development environment
1. See /LTCG (Link-time Code Generation) for information on how to specify /GL in the development
environment.
To set this linker option programmatically
1. See WholeProgramOptimization.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Gm (Enable Minimal Rebuild)
3/12/2019 • 2 minutes to read • Edit Online
Deprecated. Enables minimal rebuild, which determines whether C++ source files that include changed C++
class definitions (stored in header (.h) files) need to be recompiled.
Syntax
/Gm
Remarks
/Gm is deprecated. It may not trigger a build for certain kinds of header file changes. You may safely remove this
option from your projects. To improve build times, we recommend you use precompiled headers and
incremental and parallel build options instead. For a list of deprecated compiler options, see the Deprecated
and Removed Compiler Options section in Compiler Options Listed by Category.
The compiler stores dependency information between source files and class definitions in the project's .idb file
during the first compile. (Dependency information tells which source file is dependent on which class definition,
and which .h file the definition is located in.) Subsequent compiles use the information stored in the .idb file to
determine whether a source file needs to be compiled, even if it includes a modified .h file.
NOTE
Minimal rebuild relies on class definitions not changing between include files. Class definitions must be global for a project
(there should be only one definition of a given class), because the dependency information in the .idb file is created for the
entire project. If you have more than one definition for a class in your project, disable minimal rebuild.
Because the incremental linker does not support the Windows metadata included in .obj files by using the /ZW
(Windows Runtime Compilation) option, the /Gm option is incompatible with /ZW.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Code Generation property page.
3. Modify the Enable Minimal Rebuild property.
To set this compiler option programmatically
See MinimalRebuild.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GR (Enable Run-Time Type Information)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/GR[-]
Remarks
When /GR is on, the compiler defines the _CPPRTTI preprocessor macro. By default, /GR is on. /GR- disables run-
time type information.
Use /GR if the compiler cannot statically resolve an object type in your code. You usually need the /GR option
when your code uses dynamic_cast Operator or typeid. However, /GR increases the size of the .rdata sections of
your image. If your code does not use dynamic_cast or typeid, /GR- may produce a smaller image.
For more information about run-time type checking, see Run-Time Type Information in the C++ Language
Reference.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Language property page.
4. Modify the Enable Run-Time Type Info property.
To set this compiler option programmatically
See RuntimeTypeInfo.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GS (Buffer Security Check)
3/12/2019 • 4 minutes to read • Edit Online
Detects some buffer overruns that overwrite a function's return address, exception handler address, or certain
types of parameters. Causing a buffer overrun is a technique used by hackers to exploit code that does not
enforce buffer size restrictions.
Syntax
/GS[-]
Remarks
/GS is on by default. If you expect your application to have no security exposure, use /GS -. For more information
about suppressing buffer overrun detection, see safebuffers.
Security Checks
On functions that the compiler recognizes as subject to buffer overrun problems, the compiler allocates space on
the stack before the return address. On function entry, the allocated space is loaded with a security cookie that is
computed once at module load. On function exit, and during frame unwinding on 64-bit operating systems, a
helper function is called to make sure that the value of the cookie is still the same. A different value indicates that
an overwrite of the stack may have occurred. If a different value is detected, the process is terminated.
GS Buffers
A buffer overrun security check is performed on a GS buffer. A GS buffer can be one of these:
An array that is larger than 4 bytes, has more than two elements, and has an element type that is not a
pointer type.
A data structure whose size is more than 8 bytes and contains no pointers.
A buffer allocated by using the _alloca function.
Any class or structure that contains a GS buffer.
For example, the following statements declare GS buffers.
char buffer[20];
int buffer[20];
struct { int a; int b; int c; int d; } myStruct;
struct { int a; char buf[20]; };
However, the following statements do not declare GS buffers. The first two declarations contain elements of
pointer type. The third and fourth statements declare arrays whose size is too small. The fifth statement declares a
structure whose size on an x86 platform is not more than 8 bytes.
char *pBuf[20];
void *pv[20];
char buf[4];
int buf[2];
struct { int a; int b; };
What Is Protected
The /GS compiler option protects the following items:
The return address of a function call.
The address of an exception handler for a function.
Vulnerable function parameters.
On all platforms, /GS attempts to detect buffer overruns into the return address. Buffer overruns are more easily
exploited on platforms such as x86 and x64, which use calling conventions that store the return address of a
function call on the stack.
On x86, if a function uses an exception handler, the compiler injects a security cookie to protect the address of the
exception handler. The cookie is checked during frame unwinding.
/GS protects vulnerable parameters that are passed into a function. A vulnerable parameter is a pointer, a C++
reference, a C -structure (C++ POD type) that contains a pointer, or a GS buffer.
A vulnerable parameter is allocated before the cookie and local variables. A buffer overrun can overwrite these
parameters. And code in the function that uses these parameters could cause an attack before the function returns
and the security check is performed. To minimize this danger, the compiler makes a copy of the vulnerable
parameters during the function prolog and puts them below the storage area for any buffers.
The compiler does not make copies of vulnerable parameters in the following situations:
Functions that do not contain a GS buffer.
Optimizations (/O options) are not enabled.
Functions that have a variable argument list (...).
Functions that are marked with naked.
Functions that contain inline assembly code in the first statement.
A parameter is used only in ways that are less likely to be exploitable in the event of a buffer overrun.
Example
This sample overruns a buffer. This causes the application to fail at runtime.
// Vulnerable function
void vulnerable(const char *str) {
char buffer[10];
strcpy(buffer, str); // overrun buffer !!!
int main() {
// declare buffer that is bigger than expected
char large_buffer[] = "This string is longer than 10 characters!!";
vulnerable(large_buffer);
}
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Gs (Control Stack Checking Calls)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Gs[size]
Arguments
size
(Optional) The number of bytes that local variables can occupy before a stack probe is initiated. No space is
allowed between /Gs and size.
Remarks
A stack probe is a sequence of code that the compiler inserts at the beginning of a function call. When initiated, a
stack probe reaches benignly into memory by the amount of space that is required to store the function's local
variables. This causes the operating system to transparently page in additional stack memory if required, before
the rest of the function runs.
By default, the compiler generates code that initiates a stack probe when a function requires more than one page
of stack space. This is equivalent to a compiler option of /Gs4096 for x86, x64, ARM, and ARM64 platforms. This
value allows an application and the Windows memory manager to increase the amount of memory committed to
the program stack dynamically at run time.
NOTE
The default value of /Gs4096 allows the program stack of applications for Windows to grow correctly at run time. We
recommend that you do not change the default value unless you know exactly why you have to change it.
Some programs—for example, virtual device drivers—do not require this default stack-growth mechanism. In
such cases, the stack probes are not necessary and you can stop the compiler from generating them by setting size
to a value that is larger than any function will require for local variable storage.
/Gs0 initiates stack probes for every function call that requires storage for local variables. This can have a negative
impact on performance.
For x64 targets, if the /Gs option is specified without a size argument, it is the same as /Gs0. If the size argument is
1 through 9, warning D9014 is emitted, and the effect is the same as specifying /Gs0.
For x86, ARM, and ARM64 targets, the /Gs option without a size argument is the same as /Gs4096. If the size
argument is 1 through 9, warning D9014 is emitted, and the effect is the same as specifying /Gs4096.
For all targets, a size argument between 10 and 2147485647 sets the threshold at the specified value. A size of
2147485648 or greater causes fatal error C1049.
You can turn stack probes on or off by using the check_stack directive. /Gs and the check_stack pragma have no
effect on standard C library routines; they affect only the functions you compile.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Enter the /Gs compiler option and an optional size in Additional Options. Choose OK or Apply to save
your changes.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/guard (Enable Control Flow Guard)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/guard:cf[-]
Remarks
The /guard:cf option causes the compiler to analyze control flow for indirect call targets at compile time, and then
to insert code to verify the targets at runtime. By default, /guard:cf is off and must be explicitly enabled. To
explicitly disable this option, use /guard:cf-.
Visual Studio 2017 and later: This option adds guards for switch statements that generate jump tables.
When the /guard:cf Control Flow Guard (CFG ) option is specified, the compiler and linker insert extra runtime
security checks to detect attempts to compromise your code. During compiling and linking, all indirect calls in your
code are analyzed to find every location that the code can reach when it runs correctly. This information is stored
in extra structures in the headers of your binaries. The compiler also injects a check before every indirect call in
your code that ensures the target is one of the verified locations. If the check fails at runtime on a CFG -aware
operating system, the operating system closes the program.
A common attack on software takes advantage of bugs in handling extreme or unexpected inputs. Carefully
crafted input to the application may overwrite a location that contains a pointer to executable code. This can be
used to redirect control flow to code controlled by the attacker. The CFG runtime checks do not fix the data
corruption bugs in your executable. They instead make it more difficult for an attacker to use them to execute
arbitrary code. CFG is a mitigation tool that prevents calls to locations other than function entry points in your
code. It's similar to how Data Execution Prevention (DEP ), /GS stack checks, and /DYNAMICBASE and
/HIGHENTROPYVA address space layout randomization (ASLR ) lower the chances that your code becomes an
exploit vector.
The /guard:cf option must be passed to both the compiler and linker to build code that uses the CFG exploit
mitigation technique. If your binary is built by using a single cl command, the compiler passes the option to the
linker. If you compile and link separately, the option must be set on both the compiler and linker commands. The
/DYNAMICBASE linker option is also required. To verify that your binary has CFG data, use the
dumpbin /headers /loadconfig command. CFG -enabled binaries have Guard in the list of EXE or DLL
characteristics, and Guard Flags include CF Instrumented and FID table present .
The /guard:cf option is incompatible with /ZI (Edit and Continue debug information) or /clr (Common Language
Runtime Compilation).
Code compiled by using /guard:cf can be linked to libraries and object files that are not compiled by using the
option. Only this code, when also linked by using the /guard:cf option and run on a CFG -aware operating system,
has CFG protection. Because code compiled without the option will not stop an attack, we recommend that you
use the option on all the code you compile. There is a small runtime cost for CFG checks, but the compiler analysis
attempts to optimize away the checks on indirect jumps that can be proven to be safe.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select Configuration Properties, C/C++, Code Generation.
3. Select the Control Flow Guard property.
4. In the dropdown control, choose Yes to enable Control Flow Guard, or No to disable it.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GT (Support Fiber-Safe Thread-Local Storage)
3/12/2019 • 2 minutes to read • Edit Online
Supports fiber safety for data allocated using static thread-local storage, that is, data allocated with
__declspec(thread) .
Syntax
/GT
Remarks
Data declared with __declspec(thread) is referenced through a thread-local storage (TLS ) array. The TLS array is
an array of addresses that the system maintains for each thread. Each address in this array gives the location of
thread-local storage data.
A fiber is a lightweight object that consists of a stack and a register context and can be scheduled on various
threads. A fiber can run on any thread. Because a fiber may get swapped out and restarted later on a different
thread, the address of the TLS array must not be cached or optimized as a common subexpression across a
function call (see the /Og (Global Optimizations) option for details). /GT prevents such optimizations.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Optimization property page.
4. Modify the Enable Fiber-safe Optimizations property.
To set this compiler option programmatically
See EnableFiberSafeOptimizations.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Gw (Optimize Global Data)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Gw[-]
Remarks
The /Gw option causes the compiler to package global data in individual COMDAT sections. By default, /Gw is off
and must be explicitly enabled. To explicitly disable it, use /Gw-. When both /Gw and /GL are enabled, the linker
uses whole-program optimization to compare COMDAT sections across multiple object files in order to exclude
unreferenced global data or to merge identical read-only global data. This can significantly reduce the size of the
resulting binary executable.
When you compile and link separately, you can use the /OPT:REF linker option to exclude from the executable the
unreferenced global data in object files compiled with the /Gw option.
You can also use the /OPT:ICF and /LTCG linker options together to merge in the executable any identical read-
only global data across multiple object files compiled with the /Gw option.
For more information, see Introducing /Gw Compiler Switch on the Visual C++ Team Blog.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. Modify the Additional Options property to include /Gw and then choose OK.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GX (Enable Exception Handling)
3/12/2019 • 2 minutes to read • Edit Online
Deprecated. Enables synchronous exception handling using the assumption that functions declared by using
extern "C" never throw an exception.
Syntax
/GX
Remarks
/GX is deprecated. Use the equivalent /EHsc option instead. For a list of deprecated compiler options, see the
Deprecated and Removed Compiler Options section in Compiler Options Listed by Category.
By default, /EHsc, the equivalent of /GX, is in effect when you compile by using the Visual Studio development
environment. When using the command line tools, no exception handling is specified. This is the equivalent of
/GX-.
For more information, see C++ Exception Handling.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. In the navigation pane, choose Configuration Properties, C/C++, Command Line.
3. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/EH (Exception Handling Model)
/Gy (Enable Function-Level Linking)
3/12/2019 • 2 minutes to read • Edit Online
Allows the compiler to package individual functions in the form of packaged functions (COMDATs).
Syntax
/Gy[-]
Remarks
The linker requires that functions be packaged separately as COMDATs to exclude or order individual functions
in a DLL or .exe file.
You can use the linker option /OPT (Optimizations) to exclude unreferenced packaged functions from the .exe
file.
You can use the linker option /ORDER (Put Functions in Order) to include packaged functions in a specified
order in the .exe file.
Inline functions are always packaged if they are instantiated as calls (which occurs, for example, if inlining is off
or you take a function address). In addition, C++ member functions defined in the class declaration are
automatically packaged; other functions are not, and selecting this option is required to compile them as
packaged functions.
NOTE
The /ZI option, used for Edit and Continue, automatically sets the /Gy option.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GZ (Enable Stack Frame Run-Time Error Checking)
3/12/2019 • 2 minutes to read • Edit Online
Performs the same operations as the /RTC (Run-Time Error Checks) option. Deprecated.
Syntax
/GZ
Remarks
/GZ is only for use in a nonoptimized (/Od (Disable (Debug))) build.
/GZ is deprecated since Visual Studio 2005; use /RTC (Run-Time Error Checks) instead. For a list of deprecated
compiler options, see Deprecated and Removed Compiler Options in Compiler Options Listed by Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/H (Restrict Length of External Names)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Hnumber
Arguments
number
Specifies the maximum length of external names allowed in a program.
Remarks
By default, the length of external (public) names is 2,047 characters. This is true for C and C++ programs. Using
/H can only decrease the maximum allowable length of identifiers, not increase it. A space between /H and
number is optional.
If a program contains external names longer than number, the extra characters are ignored. If you compile a
program without /H and if an identifier contains more than 2,047 characters, the compiler will generate Fatal
Error C1064.
The limit on length includes any compiler-created leading underscore (_) or at sign (@). These characters are part
of the identifier and take a significant location.
The compiler adds a leading underscore (_) to names modified by the __cdecl (default) and __stdcall
calling conventions, and a leading at sign (@) to names modified by the __fastcall calling convention.
The compiler appends argument size information to names modified by the __fastcall and __stdcall
calling conventions, and adds type information to C++ names.
You may find /H useful:
When you create mixed-language or portable programs.
When you use tools that impose limits on the length of external identifiers.
When you want to restrict the amount of space that symbols use in a debug build.
The following example shows how using /H can actually introduce errors if identifier lengths are limited too much:
// compiler_option_H.cpp
// compile with: /H5
// processor: x86
// LNK2005 expected
void func1(void);
void func2(void);
void func1(void) {}
void func2(void) {}
You must also be careful when using the /H option because of predefined compiler identifiers. If the maximum
identifier length is too small, certain predefined identifiers will be unresolved as well as certain library function
calls. For example, if the printf function is used and the option /H5 is specified at compile time, the symbol _prin
will be created in order to reference printf , and this will not be found in the library.
Use of /H is incompatible with /GL (Whole Program Optimization).
The /H option is deprecated since Visual Studio 2005; the maximum length limits have been increased and /H is
no longer needed. For a list of deprecated compiler options, see Deprecated and Removed Compiler Options
in Compiler Options Listed by Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Enter the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/HELP (Compiler Command-Line Help)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/HELP
/help
/?
Remarks
To set this compiler option in the Visual Studio development environment
This compiler option should only be accessed from the command line.
To set this compiler option programmatically
This compiler option cannot be changed programmatically.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/homeparams (Copy Register Parameters to Stack)
3/12/2019 • 2 minutes to read • Edit Online
Forces parameters passed in registers to also be written to their locations on the stack upon function entry.
Syntax
/homeparams
Remarks
This compiler option is only available in the native and cross-compilers that target x64.
The x64 calling convention requires stack space to be allocated for all parameters, even for parameters passed in
registers. For more information, see Parameter Passing. By default, the register parameters aren't copied into the
stack space allocated for them in release builds. This makes it difficult to debug an optimized release build of your
program.
For release builds, you can use the /homeparams option to force the compiler to copy register parameters to the
stack, to ensure that you can debug your application. /homeparams does imply a performance disadvantage,
because it requires an extra cycle to load the register parameters onto the stack.
In debug builds, the stack is always populated with parameters passed in registers.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Open the Configuration Properties > C/C++ > Command Line property page.
3. Enter the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/hotpatch (Create Hotpatchable Image)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/hotpatch
Remarks
When /hotpatch is used in a compilation, the compiler ensures that first instruction of each function is at least
two bytes, which is required for hot patching.
To complete the preparation for making an image hotpatchable, after you use /hotpatch to compile, you must use
/FUNCTIONPADMIN (Create Hotpatchable Image) to link. When you compile and link an image by using one
invocation of cl.exe, /hotpatch implies /functionpadmin.
Because instructions are always two bytes or larger on the ARM architecture, and because x64 compilation is
always treated as if /hotpatch has been specified, you don't have to specify /hotpatch when you compile for
these targets; however, you must still link by using /functionpadmin to create hotpatchable images for them. The
/hotpatch compiler option only affects x86 compilation.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. Add the compiler option to the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/I (Additional include directories)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/I [ ]directory
Arguments
directory
The directory to be added to the list of directories searched for include files.
Remarks
To add more than one directory, use this option more than once. Directories are searched only until the specified
include file is found.
You can use this option with the (/X (Ignore Standard Include Paths)) option.
The compiler searches directories in the following order:
1. If specified using a #include directive in double-quote form, it first searches local directories. The search
begins in the same directory as the file that contains the #include statement. If this fails to find the file, it
searches in the directories of the currently opened include files, in the reverse order in which they were
opened. The search begins in the directory of the parent include file and continues upward through the
directories of any grandparent include files.
2. If specified using a #include directive in angle bracket form, or if the local directory search has failed, it
searches directories specified by using the /I option, in the order that CL encounters them on the command
line.
3. Directories specified in the INCLUDE environment variable.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > General property page.
3. Modify the Additional Include Directories property.
To set this compiler option programmatically
See AdditionalIncludeDirectories.
Example
The following command looks for the include files requested by MAIN.c in the following order: First, if specified
by using double-quotes, local files are searched. Next, search continues in the \INCLUDE directory, then in the
\MY\INCLUDE directory, and finally in the directories assigned to the INCLUDE environment variable.
CL /I \INCLUDE /I\MY\INCLUDE MAIN.C
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/J (Default char Type Is unsigned)
3/12/2019 • 2 minutes to read • Edit Online
Changes the default char type from signed char to unsigned char , and the char type is zero-extended when it
is widened to an int type.
Syntax
/J
Remarks
If a char value is explicitly declared as signed , the /J option does not affect it, and the value is sign-extended
when it is widened to an int type.
The /J option defines _CHAR_UNSIGNED , which is used with #ifndef in the LIMITS.h file to define the range of the
default char type.
ANSI C and C++ do not require a specific implementation of the char type. This option is useful when you are
working with character data that will eventually be translated into a language other than English.
NOTE
If you use this compiler option with ATL/MFC, an error might be generated. Although you could disable this error by
defining _ATL_ALLOW_CHAR_UNSIGNED , this workaround is not supported and may not always work.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Set C++ compiler and build properties in Visual Studio
/JMC (Just My Code debugging)
3/12/2019 • 2 minutes to read • Edit Online
Specifies compiler support for native Just My Code debugging in the Visual Studio debugger. This option supports
the user settings that allow Visual Studio to step over system, framework, library, and other non-user calls, and to
collapse those calls in the call stack window. The /JMC compiler option is available starting in Visual Studio 2017
version 15.8.
Syntax
/JMC [-]
Remarks
The Visual Studio Just My Code settings specify whether the Visual Studio debugger steps over system,
framework, library, and other non-user calls. The /JMC compiler option enables support for Just My Code
debugging in your native C++ code. When /JMC is enabled, the compiler inserts calls to a helper function,
__CheckForDebuggerJustMyCode , in the function prolog. The helper function provides hooks that support Visual
Studio debugger Just My Code step operations. To enable Just My Code in the Visual Studio debugger, on the
menu bar, choose Tools > Options, and then set the option in Debugging > General > Enable Just My Code.
The /JMC option requires that your code links to the C Runtime Library (CRT), which provides the
__CheckForDebuggerJustMyCode helper function. If your project does not link to the CRT, you may see linker error
LNK2019: unresolved external symbol __CheckForDebuggerJustMyCode. To resolve this error, either link to
the CRT, or disable the /JMC option.
By default, the /JMC compiler option is off. However, starting in Visual Studio 2017 version 15.8 this option is
enabled in most Visual Studio project templates. To explicitly disable this option, use the /JMC - option on the
command line. In Visual Studio, open the project Property Pages dialog box, and change the Support Just My
Code Debugging property in the Configuration Properties > C/C++ > General property page to No.
For more information, see C++ Just My Code in Specify whether to debug only user code using Just My Code in
Visual Studio, and the Visual C++ Team Blog post Announcing C++ Just My Code Stepping in Visual Studio.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > General property page.
3. Modify the Support Just My Code Debugging property.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/kernel (Create Kernel Mode Binary)
3/12/2019 • 3 minutes to read • Edit Online
Syntax
/kernel[-]
Arguments
/kernel
The code in the current project is compiled and linked by using a set of C++ language rules that are specific to
code that will run in kernel mode.
/kernel-
The code in the current project is compiled and linked without using the C++ language rules that are specific to
code that will run in kernel mode.
Remarks
There is no #pragma equivalent to control this option.
Specifying the /kernel option tells the compiler and linker to arbitrate which language features are permissible in
kernel mode and to make sure that you have sufficient expressive power to avoid runtime instability that is unique
to kernel mode C++. This is accomplished by prohibiting the use of C++ language features that are disruptive in
kernel mode and by providing warnings for C++ language features that are potentially disruptive but cannot be
disabled.
The /kernel option applies to both the compiler and linker phases of a build and is set at the project level. Pass the
/kernel switch to indicate to the compiler that the resulting binary, after linking, should be loaded into the
Windows kernel. The compiler will narrow the spectrum of C++ language features to a subset that is compatible
with the kernel.
The following table lists changes in compiler behavior when /kernel is specified.
C++ Exception Handling Disabled. All instances of the throw and try keywords
emit a compiler error (except for the exception specification
throw() ). No /EH options are compatible with /kernel,
except for /EH-.
new and delete You must explicitly define the new() or delete() operator;
neither the compiler nor the runtime will supply a default
definition.
Custom calling conventions, the /GS build option, and all optimizations are permitted when you use the /kernel
option. Inlining is largely not affected by /kernel, with the same semantics honored by the compiler. If you want to
make sure that the __forceinline inlining qualifier is honored, you must make sure that warning C4714 is
enabled so that you know when a particular __forceinline function is not inlined.
When the compiler is passed the /kernel switch, it predefines a preprocessor macro that's named _KERNEL_MODE
and has the value 1. You can use this to conditionally compile code based on whether the execution environment is
in user mode or kernel mode. For example, the following code specifies that the class should be in a non-pageable
memory segment when it is compiled for kernel mode execution.
#ifdef _KERNEL_MODE
#define NONPAGESECTION __declspec(code_seg("$kerneltext$"))
#else
#define NONPAGESECTION
#endif
Some the following combinations of target architecture and the /arch option produce an error when they are used
with /kernel:
/arch:{SSE|SSE2|AVX} are not supported on x86. Only /arch:IA32 is supported with /kernel on x86.
/arch:AVX is not supported with /kernel on x64.
Building with /kernel also passes /kernel to the linker. Her's how this affects linker behavior:
Incremental linking is disabled. If you add /incremental to the command line, the linker emits this fatal
error:
LINK : fatal error LNK1295: '/INCREMENTAL' not compatible with '/KERNEL' specification; link
without '/INCREMENTAL'
The linker inspects each object file (or any included archive member from static libraries) to see whether it
could have been compiled by using the /kernel option but was not. If any instances meet this criterion, the
linker still successfully links but might issue a warning, as shown in the following table.
LNK4257 linking object not compiled with /KERNEL ; image may not run
The /kernel option and the /driver option operate independently and neither affects the other.
To set the /kernel compiler option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the C/C++ folder.
3. Select the Command Line property page.
4. In the Additional options box, add /kernel or /kernel- .
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/link (Pass Options to Linker)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/link linkeroptions
Arguments
linkeroptions
The linker option or options to be passed to the linker.
Remarks
The /link option and its linker options must appear after any file names and CL options. A space is required
between /link and linkeroptions . For more information, see MSVC linker reference.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click a linker property page.
4. Modify one or more properties.
To set this compiler option programmatically
This compiler option cannot be changed programmatically.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/LN (Create MSIL Module)
3/12/2019 • 2 minutes to read • Edit Online
Specifies that an assembly manifest should not be inserted into the output file.
Syntax
/LN
Remarks
By default, /LN is not in effect (an assembly manifest is inserted into the output file).
When /LN is used, one of the /clr (Common Language Runtime Compilation) options must also be used.
A managed program that does not have an assembly metadata in the manifest is called a module. If you compile
with /c (Compile Without Linking) and /LN, specify /NOASSEMBLY (Create a MSIL Module) in the linker phase
to create the output file.
You may want to create modules if you want to take a component-based approach to building assemblies. That
is, you can author types and compile them into modules. Then, you can generate an assembly from one or more
modules. For more information on creating assemblies from modules, see .netmodule Files as Linker Input or
Al.exe (Assembly Linker).
The default file extension for a module is .netmodule.
In Visual C++ releases before Visual C++ 2005, a module was created with /clr:noAssembly.
The MSVC linker accepts .netmodule files as input and the output file produced by the linker will be an assembly
or .netmodule with no run-time dependence on any of the .netmodules that were input to the linker. For more
information, see .netmodule Files as Linker Input.
To set this compiler option in the Visual Studio development environment
Specify /NOASSEMBLY (Create a MSIL Module) in the linker phase to create the output file.
To set this compiler option programmatically
This compiler option cannot be changed programmatically.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/MD, /MT, /LD (Use Run-Time Library)
3/12/2019 • 2 minutes to read • Edit Online
Indicates whether a multithreaded module is a DLL and specifies retail or debug versions of the run-time
library.
Syntax
/MD[d]
/MT[d]
/LD[d]
Remarks
OPTION DESCRIPTION
/MTd Defines _DEBUG and _MT . This option also causes the
compiler to place the library name LIBCMTD.lib into the .obj
file so that the linker will use LIBCMTD.lib to resolve
external symbols.
OPTION DESCRIPTION
Passes the /DLL option to the linker. The linker looks for,
but does not require, a DllMain function. If you do not
write a DllMain function, the linker inserts a DllMain
function that returns TRUE.
For more information about C run-time libraries and which libraries are used when you compile with /clr
(Common Language Runtime Compilation), see CRT Library Features.
All modules passed to a given invocation of the linker must have been compiled with the same run-time
library compiler option (/MD, /MT, /LD ).
For more information about how to use the debug versions of the run-time libraries, see C Run-Time Library
Reference.
For more about DLLs, see DLLs in Visual C++.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties
in Visual Studio.
2. Expand the C/C++ folder.
3. Select the Code Generation property page.
4. Modify the Runtime Library property.
To set this compiler option programmatically
See RuntimeLibrary.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/MP (Build with Multiple Processes)
3/12/2019 • 7 minutes to read • Edit Online
The /MP option can reduce the total time to compile the source files on the command line. The /MP option
causes the compiler to create one or more copies of itself, each in a separate process. Then these copies
simultaneously compile the source files. Consequently, the total time to build the source files can be significantly
reduced.
Syntax
/MP [processMax]
Arguments
processMax
(Optional) The maximum number of processes that the compiler can create.
The processMax argument must range from 1 through 65536. Otherwise, the compiler issues warning message
D9014, ignores the processMax argument, and assumes the maximum number of processes is 1.
If you omit the processMax argument, the compiler retrieves the number of effective processors on your
computer from the operating system, and creates a process for each processor.
Remarks
The /MP compiler option can significantly reduce build time when you compile many files. To improve build time,
the compiler creates up to processMax copies of itself, and then uses those copies to compile your source files at
the same time. The /MP option applies to compilations, but not to linking or link-time code generation. By default
the /MP option is off.
The improvement in build time depends on the number of processors on a computer, the number of files to
compile, and the availability of system resources, such as I/O capacity. Experiment with the /MP option to
determine the best setting to build a particular project. For advice to help you make that decision, see Guidelines.
NOTE
Most options are incompatible because if they were permitted, the concurrently executing compilers would write their
output at the same time to the console or to a particular file. As a result, the output would intermix and be garbled. In
some cases, the combination of options would make the performance worse.
The following table lists compiler options and language features that are incompatible with the /MP option:
OPTION OR LANGUAGE FEATURE DESCRIPTION
#import preprocessor directive Converts the types in a type library into C++ classes, and
then writes those classes to a header file.
Diagnostic Messages
If you specify an option or language feature that is incompatible with the /MP option, you will receive a
diagnostic message. The following table lists the messages and the behavior of the compiler:
C2813 The #import directive is not The compilation ends unless a compiler
compatible with the /MP option. warning level option specifies
otherwise.
D9014 An invalid value is specified for the The compiler ignores the invalid value
processMax argument. and assumes a value of 1.
D9030 The specified option is incompatible The compiler ignores the /MP option.
with /MP.
Guidelines
Measure Performance
Use total build time to measure performance. You can measure the build time with a physical clock, or you can
use software that calculates the difference between when the build starts and stops. If your computer has multiple
processors, a physical clock might yield more accurate results than a software time measurement.
Effective Processors
A computer can have one or more virtual processors, which are also known as effective processors, for each of its
physical processors. Each physical processor can have one or more cores, and if the operating system enables
hyperthreading for a core, each core appears to be two virtual processors.
For example, a computer has one effective processor if it has one physical processor that has one core, and
hyperthreading is disabled. In contrast, a computer has eight effective processors if it has two physical processors,
each of which has two cores, and all the cores have hyperthreading enabled. That is, (8 effective processors) = (2
physical processors) x (2 cores per physical processor) x (2 effective processors per core because of
hyperthreading).
If you omit the processMax argument in the /MP option, the compiler obtains the number of effective processors
from the operating system, and then creates one process per effective processor. However, the compiler cannot
guarantee which process executes on a particular processor; the operating system makes that decision.
Number of Processes
The compiler calculates the number of processes that it will use to compile the source files. That value is the lesser
of the number of source files that you specify on the command line, and the number of processes that you
explicitly or implicitly specify with the /MP option. You can explicitly set the maximum number of processes if you
provide the processMax argument of the /MP option. Or you can use the default, which is equal to the number of
effective processors in a computer, if you omit the processMax argument.
For example, suppose you specify the following command line:
cl /MP7 a.cpp b.cpp c.cpp d.cpp e.cpp
In this case the compiler uses five processes because that is the lesser of five source files and a maximum of
seven processes. Alternatively, suppose your computer has two effective processors and you specify the following
command line:
cl /MP a.cpp b.cpp c.cpp
In this case the operating system reports two processors; therefore, the compiler uses two processes in its
calculation. As a result, the compiler will execute the build with two processes because that is the lesser of two
processes and three source files.
Source Files and Build Order
The source files might not be compiled in the same order in which they appear on the command line. Although
the compiler creates a set of processes that contain copies of the compiler, the operating system schedules when
each process executes. Consequently, you cannot guarantee that the source files will be compiled in a particular
order.
A source file is compiled when a process is available to compile it. If there are more files than processes, the first
set of files is compiled by the available processes. The remaining files are processed when a process finishes
handling a previous file and is available to work on one of the remaining files.
Do not specify the same source file multiple times on a command line. This might occur, for example, if a tool
automatically creates a makefile that is based on dependency information in a project. If you do not specify the
/MP option, the compiler processes the list of files sequentially and recompiles each occurrence of the file.
However, if you specify the /MP option, different compilers might compile the same file at the same time.
Consequently, the different compilers will try to write to the same output file at the same time. One compiler will
acquire exclusive write access to the output file and succeed, and the other compilers will fail with a file access
error.
Using Type Libraries (#import)
The compiler does not support the use of the #import directive with the /MP switch. If possible, follow these
steps to work around this problem:
Move all the #import directives in your various source files to one or more files, and then compile those
files without the /MP option. The result is a set of generated header files.
In your remaining source files, insert #include directives that specify the generated headers, and then
compile your remaining source files by using the /MP option.
Visual Studio Project Settings
The MSBUILD.exe Tool
Visual Studio uses the MSBuild.exe tool to build solutions and projects. The /maxcpucount:number (or
/m:number) command-line option of the MSBuild.exe tool can build multiple projects at the same time. And the
/MP compiler option can build multiple compilation units at the same time. If it is appropriate for your
application, improve your solution's build time by using either or both /MP and /maxcpucount.
The build time of your solution partly depends on the number of processes that perform the build. The number
argument of the /maxcpucount MSBuild option specifies the maximum number of projects to build at the same
time. Similarly, the processMax argument of the /MP compiler option specifies the maximum number of
compilation units to build at the same time. If the /maxcpucount option specifies P projects and the /MP option
specifies C processes, a maximum of P x C processes execute at the same time.
The guideline for deciding whether to use MSBuild or /MP technology is as follows:
If there are many projects with few files in each project, use the MSBuild tool.
If there are few projects with many files in each project, use the /MP option.
If the number of projects and files per project is balanced, use both MSBuild and /MP. Initially set the
/maxcpucount option to the number of projects to build and the /MP option to the number of
processors on your computer. Measure performance and then adjust your settings to yield the best results.
Repeat that cycle until you are satisfied with the total build time.
The /Gm Compiler Option
By default, a project build enables the /Gm compiler option (incremental builds) for debug builds, and disables it
for release builds. Therefore, the /MP compiler option is automatically disabled in debug builds because it
conflicts with the default /Gm compiler option.
See also
#import Directive
Command-Line Reference
/Zf (Faster PDB generation)
/nologo (Suppress Startup Banner) (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
Suppresses the display of the copyright banner when the compiler starts up and display of informational
messages during compiling.
Syntax
/nologo
Remarks
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the General property page.
4. Modify the Suppress Startup Banner property.
To set this compiler option programmatically
See SuppressStartupBanner.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/O Options (Optimize Code)
3/12/2019 • 2 minutes to read • Edit Online
The /O options control various optimizations that help you create code for maximum speed or minimum size.
/O1 sets a combination of optimizations that generate minimum size code.
/O2 sets a combination of optimizations that optimizes code for maximum speed.
/Ob controls inline function expansion.
/Od disables optimization, to speed compilation and simplify debugging.
/Og enables global optimizations.
/Oi generates intrinsic functions for appropriate function calls.
/Os tells the compiler to favor optimizations for size over optimizations for speed.
/Ot (a default setting) tells the compiler to favor optimizations for speed over optimizations for size.
/Ox is a combination option that selects several of the optimizations with an emphasis on speed. It is a
strict subset of the /O2 optimizations.
/Oy suppresses the creation of frame pointers on the call stack for quicker function calls.
Remarks
You can combine multiple /O options into a single option statement. For example, /Odi is the same as /Od /Oi.
Certain options are mutually exclusive and cause a compiler error if used together. See the individual /O options
for more information.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/O1, /O2 (Minimize Size, Maximize Speed)
3/12/2019 • 2 minutes to read • Edit Online
Selects a predefined set of options that affect the size and speed of generated code.
Syntax
/O1 /O2
Remarks
The /O1 and /O2 compiler options are a quick way to set several specific optimization options at once. The
/O1 option sets the individual optimization options that create the smallest code in the majority of cases. The
/O2 option sets the options that create the fastest code in the majority of cases. The /O2 option is the default
for release builds. This table shows the specific options that are set by /O1 and /O2:
OPTION EQUIVALENT TO
/O2 (Maximize Speed) /Og /Oi /Ot /Oy /Ob2 /GF /Gy
NOTE
x86 Specific These options imply the use of the Frame-Pointer Omission (/Oy) option.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/EH (Exception Handling Model)
/Ob (Inline Function Expansion)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Ob{0|1|2}
Arguments
0
Disables inline expansions. By default, expansion occurs at the compiler's discretion on all functions, often
referred to as auto -inlining.
1
Allows expansion only of functions marked inline, __inline , or __forceinline , or in a C++ member function
defined in a class declaration.
2
The default value. Allows expansion of functions marked as inline , __inline , or __forceinline , and any other
function that the compiler chooses.
/Ob2 is in effect when /O1, /O2 (Minimize Size, Maximize Speed) or /Ox (Enable Most Speed Optimizations) is
used.
This option requires that you enable optimizations using /O1, /O2, /Ox, or /Og.
Remarks
The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that any
function will be expanded inline. You can disable inline expansions, but you cannot force the compiler to inline a
particular function, even when using the __forceinline keyword.
You can use the #pragma auto_inline directive to exclude functions from consideration as candidates for inline
expansion. Also see the #pragma intrinsic directive.
NOTE
Information that is gathered from profiling test runs overrides optimizations that would otherwise be in effect if you specify
/Ob, /Os, or /Ot. For more information, see Profile-Guided Optimizations.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Od (Disable (Debug))
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Od
Remarks
This option is the default. Because /Od suppresses code movement, it simplifies the debugging process. For
more information about compiler options for debugging, see /Z7, /Zi, /ZI (Debug Information Format).
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Optimization property page.
4. Modify the Optimization property.
To set this compiler option programmatically
See Optimization.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Z7, /Zi, /ZI (Debug Information Format)
/Og (Global Optimizations)
3/12/2019 • 2 minutes to read • Edit Online
Deprecated. Provides local and global optimizations, automatic-register allocation, and loop optimization. We
recommend you use either /O1 (Minimize Size) or /O2 (Maximize Speed) instead.
Syntax
/Og
Remarks
/Og is deprecated. These optimizations are now generally enabled by default. For more information on
optimizations, see /O1, /O2 (Minimize Size, Maximize Speed) or /Ox (Enable Most Speed Optimizations).
The following optimizations are available under /Og:
Local and global common subexpression elimination
In this optimization, the value of a common subexpression is calculated once. In the following example, if
the values of b and c do not change between the three expressions, the compiler can assign the
calculation of b + c to a temporary variable, and substitute the variable for b + c :
a = b + c;
d = b + c;
e = b + c;
For local common subexpression optimization, the compiler examines short sections of code for common
subexpressions. For global common subexpression optimization, the compiler searches entire functions
for common subexpressions.
Automatic register allocation
This optimization allows the compiler to store frequently used variables and subexpressions in registers;
the register keyword is ignored.
Loop optimization
This optimization removes invariant subexpressions from the body of a loop. An optimal loop contains
only expressions whose values change through each execution of the loop. In the following example, the
expression x + y does not change in the loop body:
i = -100;
while( i < 0 ) {
i += x + y;
}
After optimization, x + y is calculated once rather than every time the loop is executed:
i = -100;
t = x + y;
while( i < 0 ) {
i += t;
}
Loop optimization is much more effective when the compiler can assume no aliasing, which you set with
__restrict, noalias, or restrict.
NOTE
You can enable or disable global optimization on a function-by-function basis using the optimize pragma
together with the g option.
For related information, see /Oi (Generate Intrinsic Functions) and /Ox (Enable Most Speed Optimizations).
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Enter the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Command-Line Syntax
/Oi (Generate Intrinsic Functions)
3/12/2019 • 2 minutes to read • Edit Online
Replaces some function calls with intrinsic or otherwise special forms of the function that help your application
run faster.
Syntax
/Oi[-]
Remarks
Programs that use intrinsic functions are faster because they do not have the overhead of function calls, but may
be larger because of the additional code created.
See intrinsic for more information on which functions have intrinsic forms.
/Oi is only a request to the compiler to replace some function calls with intrinsics; the compiler may call the
function (and not replace the function call with an intrinsic) if it will result in better performance.
x86 Specific
The intrinsic floating-point functions do not perform any special checks on input values and so work in restricted
ranges of input, and have different exception handling and boundary conditions than the library routines with the
same name. Using the true intrinsic forms implies loss of IEEE exception handling, and loss of _matherr and
errno functionality; the latter implies loss of ANSI conformance. However, the intrinsic forms can considerably
speed up floating-point-intensive programs, and for many programs, the conformance issues are of little practical
value.
You can use the Za compiler option to override generation of true intrinsic floating-point options. In this case, the
functions are generated as library routines that pass arguments directly to the floating-point chip instead of
pushing them onto the program stack.
END x86 Specific
You also use intrinsic to create intrinsic functions, or function (C/C++) to explicitly force a function call.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Optimization property page.
4. Modify the Enable Intrinsic Functions property.
To set this compiler option programmatically
See EnableIntrinsicFunctions.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Compiler Intrinsics
/Os, /Ot (Favor Small Code, Favor Fast Code)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Os
/Ot
Remarks
/Os (Favor Small Code) minimizes the size of EXEs and DLLs by instructing the compiler to favor size over
speed. The compiler can reduce many C and C++ constructs to functionally similar sequences of machine code.
Occasionally these differences offer tradeoffs of size versus speed. The /Os and /Ot options allow you to specify
a preference for one over the other:
/Ot (Favor Fast Code) maximizes the speed of EXEs and DLLs by instructing the compiler to favor speed over
size. (This is the default.) The compiler can reduce many C and C++ constructs to functionally similar sequences
of machine code. Occasionally, these differences offer tradeoffs of size versus speed. The /Ot option is implied by
the Maximize Speed (/O2) option. The /O2 option combines several options to produce very fast code.
If you use /Os or /Ot, then you must also specify /Og to optimize the code.
NOTE
Information that is gathered from profiling test runs will override optimizations that would otherwise be in effect if you
specify /Ob, /Os, or /Ot. For more information, Profile-Guided Optimizations.
x86 Specific
The following example code demonstrates the difference between the Favor Small Code (/Os) options and the
Favor Fast Code (/Ot) option:
NOTE
The following describes the expected behavior when using /Os or /Ot. However, compiler behavior from release to release
may result in different optimizations for the code below.
/* differ.c
This program implements a multiplication operator
Compile with /Os to implement multiply explicitly as multiply.
Compile with /Ot to implement as a series of shift and LEA instructions.
*/
int differ(int x)
{
return x * 71;
}
As shown in the fragment of machine code below, when DIFFER.c is compiled for size (/Os), the compiler
implements the multiply expression in the return statement explicitly as a multiply to produce a short but slower
sequence of code:
Alternately, when DIFFER.c is compiled for speed (/Ot), the compiler implements the multiply expression in the
return statement as a series of shift and LEA instructions to produce a fast but longer sequence of code:
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Ox (Enable Most Speed Optimizations)
3/12/2019 • 2 minutes to read • Edit Online
The /Ox compiler option enables a combination of optimizations that favor speed. In some versions of the Visual
Studio IDE and the compiler help message, this is called full optimization, but the /Ox compiler option enables
only a subset of the speed optimization options enabled by /O2.
Syntax
/Ox
Remarks
The /Ox compiler option enables the /O compiler options that favor speed. The /Ox compiler option does not
include the additional /GF (Eliminate Duplicate Strings) and /Gy (Enable Function-Level Linking) options enabled
by /O1 or /O2 (Minimize Size, Maximize Speed). The additional options applied by /O1 and /O2 can cause
pointers to strings or to functions to share a target address, which can affect debugging and strict language
conformance. The /Ox option is an easy way to enable most optimizations without including /GF and /Gy. For
more information, see the descriptions of the /GF and /Gy options.
The /Ox compiler option is the same as using the following options in combination:
/Ob (Inline Function Expansion), where the option parameter is 2 (/Ob2)
/Og (Global Optimizations)
/Oi (Generate Intrinsic Functions)
/Ot (Favor Fast Code)
/Oy (Frame-Pointer Omission)
/Ox is mutually exclusive from:
/O1 (Minimize Size)
/O2 (Maximize Speed)
/Od (Disable (Debug))
You can cancel the bias toward speed of the /Ox compiler option if you specify /Oxs, which combines the /Ox
compiler option with /Os (Favor Small Code). The combined options favor smaller code size. The /Oxs option is
exactly the same as specifying /Ox /Os when the options appear in that order.
To apply all available file-level optimizations for release builds, we recommend you specify /O2 (Maximize
Speed) instead of /Ox, and /O1 (Minimize Size) instead of /Oxs. For even more optimization in release builds,
also consider the /GL (Whole Program Optimization) compiler option and /LTCG (Link-time Code Generation)
linker option.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Under Configuration Properties, open C/C++ and then choose the Optimization property page.
3. Modify the Optimization property.
To set this compiler option programmatically
See Optimization.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Oy (Frame-Pointer Omission)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Oy[-]
Remarks
This option speeds function calls, because no frame pointers need to be set up and removed. It also frees one
more register for general usage.
/Oy enables frame-pointer omission and /Oy- disables omission. In x64 compilers, /Oy and /Oy- are not
available.
If your code requires frame-based addressing, you can specify the /Oy- option after the /Ox option or use
optimize with the "y" and off arguments to gain maximum optimization with frame-based addressing. The
compiler detects most situations where frame-based addressing is required (for instance, with the _alloca and
setjmp functions and with structured exception handling).
The /Ox (Enable Most Speed Optimizations) and /O1, /O2 (Minimize Size, Maximize Speed) options imply /Oy.
Specifying /Oy- after the /Ox, /O1, or /O2 option disables /Oy, whether it is explicit or implied.
The /Oy compiler option makes using the debugger more difficult because the compiler suppresses frame
pointer information. If you specify a debug compiler option (/Z7, /Zi, /ZI), we recommend that you specify the
/Oy- option after any other optimization compiler options.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Optimization property page.
3. Modify the Omit Frame Pointers property. This property adds or removes only the /Oy option. If you
want to add the /Oy- option, select the Command Line property page and modify Additional options.
To set this compiler option programmatically
See OmitFramePointers.
See also
/O Options (Optimize Code)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/openmp (Enable OpenMP 2.0 Support)
3/12/2019 • 3 minutes to read • Edit Online
Syntax
/openmp
Remarks
#pragma omp is used to specify Directives and Clauses. If /openmp is not specified in a compilation, the compiler
ignores OpenMP clauses and directives. OpenMP Function calls are processed by the compiler even if /openmp
is not specified.
Applications compiled with /openmp and /clr can only be run in a single application domain process; multiple
application domains are not supported. That is, when the module constructor (.cctor) is run, it will detect the
process is compiled with /openmp and if the application is being loaded into a non-default runtime. For more
information, see appdomain, /clr (Common Language Runtime Compilation), and Initialization of Mixed
Assemblies.
If you attempt to load an application compiled with /openmp and /clr into a non-default application domain, a
TypeInitializationException exception will be thrown outside the debugger and a
OpenMPWithMultipleAppdomainsException exception will be thrown in the debugger.
These exceptions can also be raised in the following situations:
If your application compiled with /clr, but not with /openmp, is loaded into a non-default application
domain but where the process includes an application that was compiled with /openmp.
If you pass your /clr application to a utility, such as regasm.exe (Regasm.exe (Assembly Registration Tool)),
which loads its target assemblies into a non-default application domain.
The common language runtime's code access security doesn’t work in OpenMP regions. If you apply a CLR code
access security attribute outside a parallel region, it won't be in effect in the parallel region.
Microsoft advises that you do not write /openmp applications that allows partially trusted callers, using
AllowPartiallyTrustedCallersAttribute, or any CLR code access security attributes.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the C/C++ node.
4. Select the Language property page.
5. Modify the OpenMP Support property.
To set this compiler option programmatically
See OpenMP.
Example
The following sample shows some of the effects of threadpool startup versus using the threadpool after it started
up. Assuming an x64, single core, dual processor the threadpool takes about 16ms to startup. After that though
there is very little cost for the threadpool.
When you compile with /openmp, the second call to test2 never runs any longer than if you compile with
/openmp-, as there is no threadpool startup. At a million iterations the /openmp version is faster than the
/openmp- version for the second call to test2, and at 25 iterations both /openmp- and /openmp versions
register less than the clock granularity.
So if you have only one loop in your application and it runs in less than 15ms (adjusted for the approximate
overhead on your machine), /openmp may not be appropriate, but if it's anything more than that, you may want
to consider using /openmp.
// cpp_compiler_options_openmp.cpp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
pi = step * sum;
return pi;
}
if (argc > 1)
n = atoi(argv[1]);
dwStart = GetTickCount();
d = test2(n);
printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
dwStart = GetTickCount();
d = test2(n);
printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
}
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/P (Preprocess to a File)
3/12/2019 • 2 minutes to read • Edit Online
Preprocesses C and C++ source files and writes the preprocessed output to a file.
Syntax
/P
Remarks
The file has the same base name as the source file and an .i extension. In the process, all preprocessor directives
are carried out, macro expansions are performed, and comments are removed. To preserve comments in the
preprocessed output, use the /C (Preserve Comments During Preprocessing) option along with /P.
/P adds #line directives to the output, at the beginning and end of each included file and around lines removed
by preprocessor directives for conditional compilation. These directives renumber the lines of the preprocessed
file. As a result, errors generated during later stages of processing refer to the line numbers of the original
source file rather than lines in the preprocessed file. To suppress the generation of #line directives, use /EP
(Preprocess to stdout Without #line Directives) as well as /P.
The /P option suppresses compilation. It does not produce an .obj file, even if you use /Fo (Object File Name).
You must resubmit the preprocessed file for compilation. /P also suppresses the output files from the /FA, /Fa,
and /Fm options. For more information, see /FA, /Fa (Listing File) and /Fm (Name Mapfile).
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Preprocessor property page.
4. Modify the Generate Preprocessed File property.
To set this compiler option programmatically
See GeneratePreprocessedFile.
Example
The following command line preprocesses ADD.C , preserves comments, adds #line directives, and writes the
result to a file, ADD.I :
CL /P /C ADD.C
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Fi (Preprocess Output File Name)
/permissive- (Standards conformance)
3/12/2019 • 12 minutes to read • Edit Online
Specify standards conformance mode to the compiler. Use this option to help you identify and fix conformance
issues in your code, to make it both more correct and more portable.
Syntax
/permissive-
Remarks
This option is supported in Visual Studio 2017 and later.
You can use the /permissive- compiler option to specify standards-conforming compiler behavior. This option
disables permissive behaviors, and sets the /Zc compiler options for strict conformance. In the IDE, this option
also makes the IntelliSense engine underline non-conforming code.
By default, the /permissive- option is set in new projects created by Visual Studio 2017 version 15.5 and later
versions. It is not set by default in earlier versions. When the option is set, the compiler generates diagnostic
errors or warnings when non-standard language constructs are detected in your code, including some common
bugs in pre-C++11 code.
The /permissive- option is compatible with almost all of the header files from the latest Windows Kits, such as
the Software Development Kit (SDK) or Windows Driver Kit (WDK), starting in the Windows Fall Creators SDK
(10.0.16299.0). Older versions of the SDK may fail to compile under /permissive- for various source code
conformance reasons. The compiler and SDKs ship on different release timelines, therefore there are some
remaining issues. For specific header file issues, see Windows header issues below.
The /permissive- option sets the /Zc:strictStrings and /Zc:rvalueCast options to conforming behavior. They
default to non-conforming behavior. You can pass specific /Zc options after /permissive- on the command line
to override this behavior.
In versions of the compiler beginning in Visual Studio 2017 version 15.3, the /permissive- option sets the
/Zc:ternary option. The compiler also implements more of the requirements for two-phase name look-up.
When the /permissive- option is set, the compiler parses function and class template definitions, identifying
dependent and non-dependent names used in the templates. In this release, only name dependency analysis is
performed.
Environment-specific extensions and language areas that the standard leaves up to the implementation are not
affected by /permissive-. For example, the Microsoft-specific __declspec , calling convention and structured
exception handling keywords, and compiler-specific pragma directives or attributes are not flagged by the
compiler in /permissive- mode.
The /permissive- option uses the conformance support in the current compiler version to determine which
language constructs are non-conforming. The option does not determine if your code conforms to a specific
version of the C++ standard. To enable all implemented compiler support for the latest draft standard, use the
/std:latest option. To restrict the compiler support to the currently implemented C++17 standard, use the
/std:c++17 option. To restrict the compiler support to more closely match the C++14 standard, use the
/std:c++14 option, which is the default.
Not all C++11, C++14, or C++17 standards-conforming code is supported by the MSVC compiler in Visual
Studio 2017. Depending on the version of Visual Studio, the /permissive- option may not detect issues
regarding some aspects of two-phase name lookup, binding a non-const reference to a temporary, treating
copy init as direct init, allowing multiple user-defined conversions in initialization, or alternative tokens for
logical operators, and other non-supported conformance areas. For more information about conformance
issues in Visual C++, see Nonstandard Behavior. To get the most out of /permissive-, update Visual Studio to
the latest version.
How to fix your code
Here are some examples of code that is detected as non-conforming when you use /permissive-, along with
suggested ways to fix the issues.
Use default as an identifier in native code
void g() {
f(); // error C3861: 'f': identifier not found
// Another fix is to change it to 'this->f();'
}
};
void h() {
D<int> d;
d.g();
}
struct A {
void A::f() { } // error C4596: illegal qualified name in member
// declaration.
// Remove redundant 'A::' to fix.
};
// Example 1
struct S {
friend void f(S *);
};
// Uncomment this declaration to make the hidden friend visible:
// void f(S *); // This declaration makes the hidden friend visible
// Example 2
struct S {
friend void f(S *);
};
void g() {
// Using nullptr instead of S prevents argument dependent lookup in S
f(nullptr); // error C3861: 'f': identifier not found
S *p = nullptr;
f(S); // Hidden friend now found via argument-dependent lookup.
}
void func() {
int array[] = {1, 2, 30, 40};
for each (int i in array) // error C4496: nonstandard extension
// 'for each' used: replace with
// ranged-for statement:
// for (int i: array)
{
// ...
}
}
// Example 2
[emitidl];
[module(name="Foo")];
-- IDL FILE--
import "docobj.idl";
[ version(1.0), uuid(29079a2c-5f3f-3325-99a1-3ec9c40988bb) ]
library Foo {
importlib("stdole2.tlb");
importlib("olepro32.dll");
-- ATL IMPLEMENTATION--
#include <idl.header.h>
#include <atlbase.h>
// Example 1: class that provides conversion to and initialization from some type T
struct A
{
A(int);
operator int() const;
};
A a(42);
// Accepted when /Zc:ternary or /permissive- is not used:
auto x = cond ? 7 : a; // A: permissive behavior prefers A(7) over (int)a
// Accepted always:
auto y = cond ? 7 : int(a);
auto z = cond ? A(7) : a;
There is an important exception to this common pattern when T represents one of the null-terminated string
types (for example, const char * , const char16_t * , and so on) and the actual argument to ?: is a string
literal of corresponding type. C++17 has changed semantics from C++14. As a result, the code in example 2 is
accepted under /std:c++14 and rejected under /std:c++17 when /Zc:ternary or /permissive- is used.
MyString s;
// Using /std:c++14, /permissive- or /Zc:ternary behavior
// is to prefer MyString("A") over (const char*)s
// but under /std:c++17 this line causes error C2445:
auto x = cond ? "A" : s;
// You can use a static_cast to resolve the ambiguity:
auto y = cond ? "A" : static_cast<const char*>(s);
Another case where you may see errors is in conditional operators with one argument of type void . This case
may be common in ASSERT-like macros.
// Example 3: void arguments
void myassert(const char* text, const char* file, int line);
// Accepted when /Zc:ternary or /permissive- is not used:
#define ASSERT_A(ex) (void)((ex) ? 1 : myassert(#ex, __FILE__, __LINE__))
// Accepted always:
#define ASSERT_B(ex) (void)((ex) ? void() : myassert(#ex, __FILE__, __LINE__))
You may also see errors in template metaprogramming, where conditional operator result types may change
under /Zc:ternary and /permissive-. One way to resolve this issue is to use std::remove_reference on the
resulting type.
// dependent base
struct B {
void g() {}
};
template<typename T>
struct D : T {
void f() {
// The call to g was incorrectly allowed in VS2017:
g(); // Now under /permissive-: C3861
// Possible fixes:
// this->g();
// T::g();
}
};
int main()
{
D<B> d;
d.f();
}
If you want legacy behavior for two-phase lookup, but otherwise want /permissive- behavior, add the
/Zc:twoPhase- option.
Windows header issues
The /permissive- option is too strict for versions of the Windows Kits before Windows Fall Creators Update
SDK (10.0.16299.0), or the Windows Driver Kit (WDK) version 1709. We recommend you update to the latest
versions of the Windows Kits in order to use /permissive- in your Windows or device driver code.
Certain header files in the Windows April 2018 Update SDK (10.0.17134.0), the Windows Fall Creators Update
SDK (10.0.16299.0), or the Windows Driver Kit (WDK) 1709, still have issues that make them incompatible with
use of /permissive-. To work around these issues, we recommend you restrict the use of these headers to only
those source code files that require them, and remove the /permissive- option when you compile those
specific source code files.
These WinRT WRL headers released in the Windows April 2018 Update SDK (10.0.17134.0) are not clean with
/permissive-. To work around these issues, either do not use /permissive-, or use /permissive- with
/Zc:twoPhase- when working with these headers:
Issues in winrt/wrl/async.h
Issue in winrt/wrl/implements.h
These User Mode headers released in the Windows April 2018 Update SDK (10.0.17134.0) are not clean with
/permissive-. To work around these issues, do not use /permissive- when working with these headers:
Issues in um/Tune.h
Issue in um/spddkhlp.h
Issues in um/refptrco.h
These issues are specific to User Mode headers in the Windows Fall Creators Update SDK (10.0.16299.0):
Issue in um/Query.h
When using the /permissive- compiler switch, the tagRESTRICTION structure does not compile due to
the case(RTOr) member 'or'.
struct tagRESTRICTION
{
ULONG rt;
ULONG weight;
/* [switch_is][switch_type] */ union _URes
{
/* [case()] */ NODERESTRICTION ar;
/* [case()] */ NODERESTRICTION or; // error C2059: syntax error: '||'
/* [case()] */ NODERESTRICTION pxr;
/* [case()] */ VECTORRESTRICTION vr;
/* [case()] */ NOTRESTRICTION nr;
/* [case()] */ CONTENTRESTRICTION cr;
/* [case()] */ NATLANGUAGERESTRICTION nlr;
/* [case()] */ PROPERTYRESTRICTION pr;
/* [default] */ /* Empty union arm */
} res;
};
To address this issue, compile files that include Query.h without the /permissive- option.
Issue in um/cellularapi_oem.h
When using the /permissive- compiler switch, the forward declaration of enum UICCDATASTOREACCESSMODE
causes a warning:
The forward declaration of unscoped enum is a Microsoft extension. To address this issue, compile files
that include cellularapi_oem.h without the /permissive- option, or use the /wd option to silence warning
C4471.
Issue in um/omscript.h
In C++03, a conversion from a string literal to BSTR (which is a typedef to 'wchar_t *') is deprecated but
allowed. In C++11, the conversion is no longer allowed.
To address this issue, compile files that include omscript.h without the /permissive- option, or use
/Zc:strictStrings- instead.
To set this compiler option in the Visual Studio development environment
In Visual Studio 2017 version 15.5 and later versions, use this procedure:
1. Open your project's Property Pages dialog box.
2. Select the Configuration Properties > C/C++ > Language property page.
3. Change the Conformance mode property value to Yes (/permissive-). Choose OK or Apply to save
your changes.
In versions before Visual Studio 2017 version 15.5, use this procedure:
1. Open your project's Property Pages dialog box.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Enter the /permissive- compiler option in the Additional Options box. Choose OK or Apply to save
your changes.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Q Options (Low-Level Operations)
3/12/2019 • 2 minutes to read • Edit Online
You can use the /Q compiler options to perform the following low -level compiler operations:
/Qfast_transcendentals (Force Fast Transcendentals): Generates fast transcendentals.
/QIfist (Suppress _ftol): Suppresses _ftol when a conversion from a floating-point type to an integer type
is required (x86 only).
/Qimprecise_fwaits (Remove fwaits Inside Try Blocks): Removes fwait commands inside try blocks.
/Qpar (Auto-Parallelizer): Enables automatic parallelization of loops that are marked with the #pragma
loop() directive.
/Qpar-report (Auto-Parallelizer Reporting Level) : Enables reporting levels for automatic parallelization.
/Qsafe_fp_loads: Suppresses optimizations for floating-point register loads and for moves between
memory and MMX registers.
/Qspectre: Generates instructions to mitigate certain Spectre security vulnerabilities.
/Qvec-report (Auto-Vectorizer Reporting Level) : Enables reporting levels for automatic vectorization.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Qfast_transcendentals (Force Fast Transcendentals)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Qfast_transcendentals
Remarks
This compiler option forces transcendental functions to be converted to inline code to improve execution speed.
This option has an effect only when paired with /fp:except or /fp:precise. Generating inline code for
transcendental functions is already the default behavior under /fp:fast.
This option is incompatible with /fp:strict. See /fp (Specify Floating-Point Behavior) for more information about
floating point compiler options.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/QIfist (Suppress _ftol)
3/12/2019 • 2 minutes to read • Edit Online
Deprecated. Suppresses the call of the helper function _ftol when a conversion from a floating-point type to an
integral type is required.
Syntax
/QIfist
Remarks
NOTE
/QIfist is only available in the compiler targeting x86; this compiler option is not available in the compilers targeting x64
orARM.
In addition to converting from a floating-point type to integral type, the _ftol function ensures the rounding
mode of the floating-point unit (FPU ) is toward zero (truncate), by setting bits 10 and 11 of the control word. This
guarantees that converting from a floating-point type to an integral type occurs as described by the ANSI C
standard (the fractional portion of the number is discarded). When using /QIfist, this guarantee no longer
applies. The rounding mode will be one of four as documented in Intel reference manuals:
Round toward nearest (even number if equidistant)
Round toward negative infinity
Round toward positive infinity
Round toward zero
You can use the _control87, _controlfp, __control87_2 C Run-Time function to modify the rounding behavior of
the FPU. The default rounding mode of the FPU is "Round toward nearest." Using /QIfist can improve the
performance of your application, but not without risk. You should thoroughly test the portions of your code that
are sensitive to rounding modes before relying upon code built with /QIfist in production environments.
/arch (x86) and /QIfist can not be used on the same compiland.
NOTE
/QIfist is not in effect by default because the rounding bits also affect floating point to floating point rounding (which
occurs after every calculation), so when you set the flags for C-style (toward zero) rounding, your floating point calculations
might be different. /QIfist should not be used if your code depends upon the expected behavior of truncating the fractional
portion of the floating-point number. If you are unsure, do not use /QIfist.
The /QIfist option is deprecated starting in Visual Studio 2005. The compiler has made significant improvements
in float to int conversion speed. For a list of deprecated compiler options, see Deprecated and Removed
Compiler Options in Compiler Options Listed by Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Qimprecise_fwaits (Remove fwaits Inside Try Blocks)
3/12/2019 • 2 minutes to read • Edit Online
Removes the fwait commands internal to try blocks when you use the /fp:except compiler option.
Syntax
/Qimprecise_fwaits
Remarks
This option has no effect if /fp:except is not also specified. If you specify the /fp:except option, the compiler will
insert a fwait command around each line of code in a try block. In this way, the compiler can identify the
specific line of code that produces an exception. /Qimprecise_fwaits removes internal fwait instructions,
leaving only the waits around the try block. This improves performance, but the compiler will only be able to say
which try block causes an exception, not which line.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Qpar (Auto-Parallelizer)
3/12/2019 • 2 minutes to read • Edit Online
Enables the Auto-Parallelizer feature of the compiler to automatically parallelize loops in your code.
Syntax
/Qpar
Remarks
When the compiler automatically parallelizes loops in code, it spreads computation across multiple processor
cores. A loop is parallelized only if the compiler determines that it is legal to do so and that parallelization would
improve performance.
The #pragma loop() directives are available to help the optimizer parallelize specific loops. For more information,
see loop.
For information about how to enable output messages for the auto-parallelizer, see /Qpar-report (Auto-
Parallelizer Reporting Level).
To set the /Qpar compiler option in Visual Studio
1. In Solution Explorer, open the shortcut menu for the project and then choose Properties.
2. In the Property Pages dialog box, under C/C++, select Command Line.
3. In the Additional Options box, enter /Qpar .
To set the /Qpar compiler option programmatically
Use the code example in AdditionalOptions.
See also
/Q Options (Low -Level Operations)
/Qpar-report (Auto-Parallelizer Reporting Level)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
#pragma loop()
Parallel Programming in Native Code
/Qpar-report (Auto-Parallelizer Reporting Level)
3/12/2019 • 2 minutes to read • Edit Online
Enables the reporting feature of the compiler's Auto-Parallelizer and specifies the level of informational messages
for output during compilation.
Syntax
/Qpar-report:{1}{2}
Remarks
/Qpar-report:1
Outputs an informational message for loops that are parallelized.
/Qpar-report:2
Outputs an informational message for loops that are parallelized and also for loops that are not parallelized,
together with a reason code.
Messages are reported to stdout. If no informational messages are reported, then either the code contains no
loops, or the reporting level was not set to report loops that are not parallelized. For more information about
reason codes and messages, see Vectorizer and Parallelizer Messages.
To set the /Qpar-report compiler option in Visual Studio
1. In Solution Explorer, open the shortcut menu for the project and then choose Properties.
2. In the Property Pages dialog box, under C/C++, select Command Line.
3. In the Additional Options box, enter /Qpar-report:1 or /Qpar-report:2 .
To set the /Qpar-report compiler option programmatically
Use the code example in AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Parallel Programming in Native Code
/Qsafe_fp_loads
3/12/2019 • 2 minutes to read • Edit Online
Requires integer move instructions for floating-point values and disables certain floating-point load optimizations.
Syntax
/Qsafe_fp_loads
Remarks
/Qsafe_fp_loads is only available in the compilers that target x86; it is not available in the compilers that target
x64 or ARM.
/Qsafe_fp_loads forces the compiler to use integer move instructions instead of floating-point move instructions
to move data between memory and MMX registers. This option also disables register load optimization for
floating-point values that can be loaded in multiple control paths when the value may cause an exception on load
—for example, a NaN value.
This option is overridden by /fp:except. /Qsafe_fp_loads specifies a subset of the compiler behavior that's
specified by /fp:except.
/Qsafe_fp_loads is incompatible with /clr and /fp:fast. For more information about floating point compiler
options, see /fp (Specify Floating-Point Behavior).
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Enter the compiler option in the Additional Options box. Choose OK to apply the change.
To set this compiler option programmatically
See AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Qspectre
3/12/2019 • 4 minutes to read • Edit Online
Specifies compiler generation of instructions to mitigate certain Spectre variant 1 security vulnerabilities.
Syntax
/Qspectre
Remarks
The /Qspectre option is available in Visual Studio 2017 version 15.5.5 and later, and in Visual Studio 2015
Update 3 through KB 4338871. It causes the compiler to insert instructions to mitigate certain Spectre security
vulnerabilities. These vulnerabilities, called speculative execution side-channel attacks, affect many operating
systems and modern processors, including processors from Intel, AMD, and ARM.
The /Qspectre option is off by default.
In its initial release, the /Qspectre option only worked on optimized code. In Visual Studio 2017 version 15.7 and
later, the /Qspectre option is supported at all optimization levels.
Microsoft Visual C++ libraries are also available in versions with Spectre mitigation. The Spectre-mitigated
libraries for Visual Studio 2017 can be downloaded in the Visual Studio Installer. They are found in the
Individual Components tab under Compilers, build tools, and runtimes, and have "Libs for Spectre" in the
name. Both DLL and static runtime libraries with mitigation enabled are available for a subset of the Visual C++
runtimes: VC++ start-up code, vcruntime140, msvcp140, concrt140, and vcamp140. The DLLs are supported for
application-local deployment only; the contents of the Visual C++ 2017 Runtime Libraries Redistributable have
not been modified. You can also install Spectre-mitigated libraries for MFC and ATL, found in the Individual
Components tab under SDKs, libraries, and frameworks.
Applicability
If your code operates on data that crosses a trust boundary then we recommend that you use the /Qspectre
option to rebuild and redeploy your code to mitigate this issue as soon as possible. Examples of code that operates
on data that crosses a trust boundary include code that loads untrusted input that can affect execution, for
example, code that makes remote procedure calls, parses untrusted input or files, or uses other local inter-process
communication (IPC ) interfaces. Standard sandboxing techniques may not be sufficient. You should investigate
your sandboxes carefully before you decide that your code does not cross a trust boundary.
Availability
The /Qspectre option is available in Visual Studio 2017 version 15.5.5 and in all updates to Microsoft MSVC
compilers (MSVC ) made on or after January 23, 2018. Use the Visual Studio Installer to update the compiler, and
to install the Spectre-mitigated libraries as individual components. The /Qspectre option is also available in
Visual Studio 2015 Update 3 through a patch. For more information, see KB 4338871.
All versions of Visual Studio 2017 version 15.5 and all Previews of Visual Studio 2017 version 15.6 include an
undocumented option, /d2guardspecload, that is equivalent to the initial behavior of /Qspectre. You can use
/d2guardspecload to apply the same mitigations to your code in these versions of the compiler. Please update
your build to use /Qspectre in compilers that support the option; the /Qspectre option may also support new
mitigations in later versions of the compiler.
Effect
The /Qspectre option outputs code to mitigate Specter variant 1, Bounds Check Bypass, CVE -2017-5753. It
works by insertion of instructions that act as a speculative code execution barrier. The specific instructions used to
mitigate processor speculation depend upon the processor and its micro-architecture, and may change in future
versions of the compiler.
When the /Qspectre option is enabled, the compiler attempts to identify instances where speculative execution
may bypass bounds checks and inserts the barrier instructions. It is important to note that there are limits to the
analysis that a compiler can perform to identify instances of variant 1. As such, there is no guarantee that all
possible instances of variant 1 are instrumented under /Qspectre.
Performance impact
The performance impact of /Qspectre has been seen to be negligible in several very large code bases, but there
are no guarantees that performance of your code under /Qspectre remains unaffected. You should benchmark
your code to determine the effect of the option on performance. If you know that the mitigation is not required in
a performance-critical block or loop, the mitigation can be selectively disabled by use of a
__declspec(spectre(nomitigation)) directive. This directive is not available in compilers that only support the
/d2guardspecload option.
Required libraries
The /Qspectre compiler option generates code that implicitly links versions of the runtime libraries that have
been built to provide Spectre mitigations. These libraries are optional components that must be installed by using
the Visual Studio Installer:
VC++ 2017 version version_numbers Libs for Spectre [(x86 and x64) | (ARM ) | (ARM64)]
Visual C++ ATL for [(x86/x64) | ARM | ARM64] with Spectre Mitigations
Visual C++ MFC for [x86/x64 | ARM | ARM64] with Spectre Mitigations
If you build your code by using /Qspectre and these libraries are not installed, the build system reports warning
MSB8038: Spectre mitigation is enabled but Spectre mitigated libraries are not found. If your MFC or
ATL code fails to build and the linker reports an error such as fatal error LNK1104: cannot open file
'oldnames.lib', these missing libraries may be the cause.
Additional information
For more details please see the official Microsoft Security Advisory ADV180002, Guidance to mitigate speculative
execution side-channel vulnerabilities. Guidance is also available from Intel, Speculative Execution Side Channel
Mitigations, and ARM, Cache Speculation Side-channels. For a Windows-specific overview of Spectre and
Meltdown mitigations, see Understanding the performance impact of Spectre and Meltdown mitigations on
Windows Systems on the Microsoft Secure blog. For an overview of Spectre vulnerability addressed by the MSVC
mitigations, see Spectre mitigations in MSVC on the Visual C++ Team Blog.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Enter the /Qspectre compiler option in the Additional Options box. Choose OK to apply the change.
To set this compiler option programmatically
See AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Qvec-report (Auto-Vectorizer Reporting Level)
3/12/2019 • 2 minutes to read • Edit Online
Enables the reporting feature of the compiler Auto-Vectorizer and specifies the level of informational messages
for output during compilation.
Syntax
/Qvec-report:{1}{2}
Remarks
/Qvec-report:1
Outputs an informational message for loops that are vectorized.
/Qvec-report:2
Outputs an informational message for loops that are vectorized and for loops that are not vectorized, together
with a reason code.
For information about reason codes and messages, see Vectorizer and Parallelizer Messages.
To set the /Qvec-report compiler option in Visual Studio
1. In Solution Explorer, open the shortcut menu for the project and then choose Properties.
2. In the Property Pages dialog box, under C/C++, select Command Line.
3. In the Additional Options box, enter /Qvec-report:1 or /Qvec-report:2 .
To set the /Qvec-report compiler option programmatically
Use the code example in AdditionalOptions.
See also
/Q Options (Low -Level Operations)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Parallel Programming in Native Code
/RTC (Run-Time Error Checks)
3/12/2019 • 3 minutes to read • Edit Online
Used to enable and disable the run-time error checks feature, in conjunction with the runtime_checks pragma.
Syntax
/RTC1
/RTCc
/RTCs
/RTCu
Arguments
1
Equivalent of /RTC su .
c
Reports when a value is assigned to a smaller data type and results in a data loss. For example, if a value of type
short 0x101 is assigned to a variable of type char .
This option reports situations in which you intend to truncate, for example, if you want the first eight bits of an
int returned as a char . Because /RTC c causes a run-time error if any information is lost as a result of the
assignment, you can mask off the information you need to avoid a run-time error as a result of /RTC c . For
example:
#include <crtdbg.h>
int main() {
get8bits(12341235,3);
}
s
Enables stack frame run-time error checking, as follows:
Initialization of local variables to a nonzero value. This helps identify bugs that do not appear when
running in debug mode. There is a greater chance that stack variables will still be zero in a debug build
compared to a release build because of compiler optimizations of stack variables in a release build. Once a
program has used an area of its stack, it is never reset to 0 by the compiler. Therefore, subsequent,
uninitialized stack variables that happen to use the same stack area can return values left over from the
prior use of this stack memory.
Detection of overruns and underruns of local variables such as arrays. /RTC s will not detect overruns
when accessing memory that results from compiler padding within a structure. Padding could occur by
using align, /Zp (Struct Member Alignment), or pack, or if you order structure elements in such a way as
to require the compiler to add padding.
Stack pointer verification, which detects stack pointer corruption. Stack pointer corruption can be caused
by a calling convention mismatch. For example, using a function pointer, you call a function in a DLL that
is exported as __stdcall but you declare the pointer to the function as __cdecl.
u
Reports when a variable is used without having been initialized. For example, an instruction that generates
C4701 may also generate a run-time error under /RTC u . Any instruction that generates Compiler Warning
(level 1 and level 4) C4700 will generate a run-time error under /RTC u .
However, consider the following code fragment:
int a, *b, c;
if ( 1 )
b = &a;
c = a; // No run-time error with /RTCu
If a variable could have been initialized, it will not be reported at run time by /RTC u . For example, after a
variable is aliased through a pointer, the compiler will not track the variable and report uninitialized uses. In
effect, you can initialize a variable by taking its address. The & operator works like an assignment operator in this
situation.
Remarks
Run-time error checks are a way for you to find problems in your running code; for more information, see How
to: Use Native Run-Time Checks.
If you compile your program at the command line using any of the /RTC compiler options, any pragma optimize
instructions in your code will silently fail. This is because run-time error checks are not valid in a release
(optimized) build.
You should use /RTC for development builds; /RTC should not be used for a retail build. /RTC cannot be used
with compiler optimizations (/O Options (Optimize Code)). A program image built with /RTC will be slightly
larger and slightly slower than an image built with /Od (up to 5 percent slower than an /Od build).
The __MSVC_RUNTIME_CHECKS preprocessor directive will be defined when you use any /RTC option or /GZ.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Code Generation property page.
4. Modify one or both of the following properties: Basic Runtime Checks or Smaller Type Check.
To set this compiler option programmatically
See BasicRuntimeChecks and SmallerTypeCheck properties.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
How to: Use Native Run-Time Checks
/sdl (Enable Additional Security Checks)
3/12/2019 • 2 minutes to read • Edit Online
Adds recommended Security Development Lifecycle (SDL ) checks. These checks include extra security-relevant
warnings as errors, and additional secure code-generation features.
Syntax
/sdl[-]
Remarks
/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS -. By default, /sdl is off.
/sdl- disables the additional security checks.
Compile-time Checks
/sdl enables these warnings as errors:
Performs limited pointer sanitization. In expressions that do not involve dereferences and in types that have
no user-defined destructor, pointer references are set to a non-valid address after a call to delete . This
helps to prevent the reuse of stale pointer references.
Performs class member pointer initialization. Automatically initializes class members of pointer type to
nullptr on object instantiation (before the constructor runs). This helps prevent the use of uninitialized
pointers that the constructor does not explicitly initialize. The compiler-generated member pointer
initialization is called as long as:
The object is not allocated using a custom (user defined) operator new
The object is not allocated as part of an array (for example new A[x] )
The class is not managed or imported
The class has a user-defined default constructor.
To be initialized by the compiler-generated class initialization function, a member must be a pointer, and not
a property or constant.
Remarks
For more information, see Warnings, /sdl, and improving uninitialized variable detection.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ folder.
3. On the General page, select the option from the SDL checks drop-down list.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/showIncludes (List Include Files)
3/12/2019 • 2 minutes to read • Edit Online
Causes the compiler to output a list of the include files. Nested include files are also displayed (files that are
included from the files that you include).
Syntax
/showIncludes
Remarks
When an include file is encountered during compilation, a message is output, for example:
Nested include files are indicated by an indentation, one space for each level of nesting, for example:
In this case, 2.h was included from within 1.h , hence the indentation.
The /showIncludes option emits to stderr , not stdout .
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Advanced property page.
4. Modify the Show Includes property.
To set this compiler option programmatically
See ShowIncludes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/source-charset (Set Source Character Set)
3/12/2019 • 2 minutes to read • Edit Online
Lets you specify the source character set for your executable.
Syntax
/source-charset:[IANA_name|.CPID]
Arguments
IANA_name
The IANA-defined character set name.
CPID
The code page identifier as a decimal number.
Remarks
You can use the /source-charset option to specify an extended source character set to use when your source files
include characters that are not represented in the basic source character set. The source character set is the
encoding used to interpret the source text of your program into the internal representation used as input to the
preprocessing phases before compilation. The internal representation is then converted to the execution character
set to store string and character values in the executable. You can use either the IANA or ISO character set name,
or a dot (.) followed by a 3 to 5 digit decimal code page identifier to specify the character set to use. For a list of
supported code page identifiers and character set names, see Code Page Identifiers.
By default, Visual Studio detects a byte-order mark to determine if the source file is in an encoded Unicode
format, for example, UTF -16 or UTF -8. If no byte-order mark is found, it assumes the source file is encoded using
the current user code page, unless you specify a character set name or code page by using the /source-charset
option. Visual Studio allows you to save your C++ source code by using any of several character encodings. For
more information about source and execution character sets, see Character Sets in the language documentation.
The source character set you supply must map the 7-bit ASCII characters to the same code points in your
character set, or many compilation errors are likely to follow. Your source character set must also be mappable to
the extended Unicode character set encodable by UTF -8. Characters that are not encodable in UTF -8 are
represented by an implementation-specific substitute. The Microsoft compiler uses a question mark for these
characters.
If you want to set both the source character set and the execution character set to UTF -8, you can use the /utf-8
compiler option as a shortcut. It is equivalent to specifying /source-charset:utf-8 /execution-charset:utf-8 on
the command line. Any of these options also enables the /validate-charset option by default.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties, C/C++, Command Line folder.
3. In Additional Options, add the /source-charset option, and specify your preferred encoding.
4. Choose OK to save your changes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/execution-charset (Set Execution Character Set)
/utf-8 (Set Source and Executable character sets to UTF -8)
/validate-charset (Validate for compatible characters)
/std (Specify Language Standard Version)
3/12/2019 • 3 minutes to read • Edit Online
Enable supported C++ language features from the specified version of the C++ language standard.
Syntax
/std:[c++14|c++17|c++latest]
Remarks
The /std option is available in Visual Studio 2017 and later. It is used to control the version-specific ISO C++
programming language standard features enabled during compilation of your code. This option allows you to
disable support for certain new language and library features that may break your existing code that conforms
to a particular version of the language standard. By default, /std:c++14 is specified, which disables language
and standard library features found in later versions of the C++ language standard. Use /std:c++17 to enable
C++17 standard-specific features and behavior. To explicitly enable the currently implemented compiler and
standard library features proposed for the next draft standard, use /std:c++latest.
The default /std:c++14 option enables the set of C++14 features implemented by the MSVC compiler. This
option disables compiler and standard library support for features that are changed or new in more recent
versions of the language standard, with the exception of some C++17 features already implemented in previous
releases of the MSVC compiler. To avoid breaking changes for users who have already taken dependencies on
the features available as of Visual Studio 2015 Update 2, these features remain enabled when the /std:c++14
option is specified:
Rules for auto with braced-init-lists
typename in template template-parameters
Removing trigraphs
Attributes for namespaces and enumerators
u8 character literals
For additional information on which C++14 and C++17 features are enabled when /std:c++14 is specified, see
the notes in Visual C++ Language Conformance.
The /std:c++17 option enables the full set of C++17 features implemented by the MSVC compiler. This option
disables compiler and standard library support for features that are changed or new in versions of the Working
Draft and defect updates of the C++ Standard after C++17.
The /std:c++latest option enables the post-C++17 language and library features currently implemented in the
compiler and libraries. These may include features from the C++20 Working Draft and defect updates of the
C++ Standard that are not included in C++17, as well as experimental proposals for the draft standard. For a list
of supported language and library features, see What's New for Visual C++. The /std:c++latest option does
not enable features guarded by the /experimental switch, but may be required to enable them.
IMPORTANT
The compiler and library features enabled by /std:c++latest are provided as-is and without support. They are subject to
breaking changes or removal without notice. They are intended as a preview of language features that may appear in the
next version of the standard, but the standard is a work in progress. Use /std:c++17 to use the features in the latest ISO
C++ standard.
The /std option in effect during a C++ compilation can be detected by use of the _MSVC_LANG preprocessor
macro. For more information, see Preprocessor Macros.
The /std:c++14 and /std:c++latest options are available beginning in Visual C++ 2015 Update 3. The
/std:c++17 option is available beginning in Visual C++ 2017 version 15.3. As noted above, some C++17
standard behavior is enabled by the /std:c++14 option, but all other C++17 features are enabled by
/std:c++17.
NOTE
Depending on the MSVC compiler version or update level, certain C++14 or C++17 features may not be fully
implemented or fully conformant when you specify the /std:c++14 or /std:c++17 options. For example, the Visual C++
2017 RTM compiler does not fully support C++14-conformant constexpr , expression SFINAE, or 2-phase name lookup.
For an overview of C++ language conformance in Visual C++ by release version, see Visual C++ Language Conformance.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Tc, /Tp, /TC, /TP (Specify Source File Type)
3/12/2019 • 2 minutes to read • Edit Online
The /Tc option specifies that its filename argument is a C source file, even if it does not have a .c extension. The
/Tp option specifies that its filename argument is a C++ source file, even if it doesn't have a .cpp or .cxx
extension. A space between the option and the filename is optional. Each option specifies one file; to specify
additional files, repeat the option.
/TC and /TP are global variants of /Tc and /Tp. They specify to the compiler to treat all files named on the
command line as C source files (/TC ) or C++ source files (/TP ), without regard to location on the command
line in relation to the option. These global options can be overridden on a single file by means of /Tc or /Tp.
Syntax
/Tc filename /Tp filename /TC /TP
Arguments
filename
A C or C++ source file.
Remarks
By default, CL assumes that files with the .c extension are C source files and files with the .cpp or the .cxx
extension are C++ source files.
When either the TC or Tc option is specified, any specification of the /Zc:wchar_t (wchar_t Is Native Type)
option is ignored.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Advanced property page.
3. Modify the Compile As property. Choose OK or Apply to apply your changes.
To set this compiler option programmatically
See CompileAs.
Examples
This CL command line specifies that MAIN.c, TEST.prg, and COLLATE.prg are all C source files. CL will not
recognize PRINT.prg.
This CL command line specifies that TEST1.c, TEST2.cxx, TEST3.huh, and TEST4.o are compiled as C++ files,
and TEST5.z is compiled as a C file.
The /U compiler option undefines the specified preprocessor symbol. The /u compiler option undefines the
Microsoft-specific symbols that the compiler defines.
Syntax
/U[ ]symbol
/u
Arguments
symbol
The preprocessor symbol to undefine.
Remarks
Neither the /U or /u option can undefine a symbol created by using the #define directive.
The /U option can undefine a symbol that was previously defined by using the /D option.
By default, the compiler defines the following Microsoft-specific symbols.
SYMBOL FUNCTION
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/J (Default char Type Is unsigned)
/GR (Enable Run-Time Type Information)
/EH (Exception Handling Model)
/MD, /MT, /LD (Use Run-Time Library)
/utf-8 (Set Source and Executable character sets to
UTF-8)
3/12/2019 • 2 minutes to read • Edit Online
Specifies both the source character set and the execution character set as UTF -8.
Syntax
/utf-8
Remarks
You can use the /utf-8 option to specify both the source and execution character sets as encoded by using UTF -8.
It is equivalent to specifying /source-charset:utf-8 /execution-charset:utf-8 on the command line. Any of these
options also enables the /validate-charset option by default. For a list of supported code page identifiers and
character set names, see Code Page Identifiers.
By default, Visual Studio detects a byte-order mark to determine if the source file is in an encoded Unicode
format, for example, UTF -16 or UTF -8. If no byte-order mark is found, it assumes the source file is encoded using
the current user code page, unless you have specified a code page by using /utf-8 or the /source-charset option.
Visual Studio allows you to save your C++ source code by using any of several character encodings. For
information about source and execution character sets, see Character Sets in the language documentation.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties, C/C++, Command Line folder.
3. In Additional Options, add the /utf-8 option to specify your preferred encoding.
4. Choose OK to save your changes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/execution-charset (Set Execution Character Set)
/source-charset (Set Source Character Set)
/validate-charset (Validate for compatible characters)
/V (Version Number)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Vstring
Arguments
string
A string specifying the version number or copyright notice to be embedded in an .obj file.
Remarks
The stringcan label an .obj file with a version number or a copyright notice. Any space or tab characters must be
enclosed in double quotation marks (") if they are a part of the string. A backslash (\) must precede any double
quotation marks if they are a part of the string. A space between /V and string is optional.
You can also use comment (C/C++) with the compiler comment-type argument to place the name and version
number of the compiler in the .obj file.
The /V option is deprecated beginning in Visual Studio 2005; /V was primarily used to support building virtual
device drivers (VxDs), and building VxDs is no longer supported by the Visual C++ toolset. For a list of
deprecated compiler options, see Deprecated and Removed Compiler Options in Compiler Options Listed by
Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/validate-charset (Validate for compatible characters)
3/12/2019 • 2 minutes to read • Edit Online
Validates that the source file text contains only characters representable as UTF -8.
Syntax
/validate-charset[-]
Remarks
You can use the /validate-charset option to validate that the source code contains only characters that can be
represented in both the source character set and the execution character set. This check is enabled automatically
when you specify /source-charset, /execution-charset, or /utf-8 compiler options. You can explicitly disable
this check by specifying the /validate-charset- option.
By default, Visual Studio detects a byte-order mark to determine if the source file is in an encoded Unicode
format, for example, UTF -16 or UTF -8. If no byte-order mark is found, it assumes the source file is encoded using
the current user code page, unless you have specified a code page by using /utf-8 or the /source-charset option.
Visual Studio allows you to save your C++ source code by using any of several character encodings. For
information about source and execution character sets, see Character Sets in the language documentation. For a
list of supported code page identifiers and character set names, see Code Page Identifiers.
Visual Studio uses UTF -8 as the internal character encoding during conversion between the source character set
and the execution character set. If a character in the source file cannot be represented in the execution character
set, the UTF -8 conversion substitutes a question mark '?' character. The /validate-charset option causes the
compilation to report a warning if this occurs.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties, C/C++, Command Line folder.
3. In Additional Options, add the /validate-charset option, and specify your preferred encoding.
4. Choose OK to save your changes.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/execution-charset (Set Execution Character Set)
/source-charset (Set Source Character Set)
/utf-8 (Set Source and Executable character sets to UTF -8)
/vd (Disable Construction Displacements)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/vdn
Arguments
0
Suppresses the vtordisp constructor/destructor displacement member. Choose this option only if you are certain
that all class constructors and destructors call virtual functions virtually.
1
Enables the creation of hidden vtordisp constructor/destructor displacement members. This choice is the default.
2
Allows you to use dynamic_cast Operator on an object being constructed. For example, a dynamic_cast from a
virtual base class to a derived class.
/vd2 adds a vtordisp field when you have a virtual base with virtual functions. /vd1 should be sufficient. The most
common case where /vd2 is necessary is when the only virtual function in your virtual base is a destructor.
Remarks
These options apply only to C++ code that uses virtual bases.
Visual C++ implements C++ construction displacement support in situations where virtual inheritance is used.
Construction displacements solve the problem created when a virtual function, declared in a virtual base and
overridden in a derived class, is called from a constructor during construction of a further derived class.
The problem is that the virtual function may be passed an incorrect this pointer as a result of discrepancies
between the displacements to the virtual bases of a class and the displacements to its derived classes. The solution
provides a single construction displacement adjustment, called a vtordisp field, for each virtual base of a class.
By default, vtordisp fields are introduced whenever the code defines user-defined constructors and destructors
and also overrides virtual functions of virtual bases.
These options affect entire source files. Use vtordisp to suppress and then re-enable vtordisp fields on a class-by-
class basis.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/vmb, /vmg (Representation Method)
3/12/2019 • 2 minutes to read • Edit Online
Select the method that the compiler uses to represent pointers to class members.
Use /vmb if you always define a class before you declare a pointer to a member of the class.
Use /vmg to declare a pointer to a member of a class before defining the class. This need can arise if you define
members in two different classes that reference each other. For such mutually referencing classes, one class must
be referenced before it is defined.
Syntax
/vmb
/vmg
Remarks
You can also use pointers_to_members or Inheritance Keywords in your code to specify a pointer representation.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/vmm, /vms, /vmv (General Purpose Representation)
3/12/2019 • 2 minutes to read • Edit Online
Used when /vmb, /vmg (Representation Method) is selected as the representation method. These options
indicate the inheritance model of the not-yet-encountered class definition.
Syntax
/vmm
/vms
/vmv
Remarks
The options are described in the following table.
OPTION DESCRIPTION
See also
/vmb, /vmg (Representation Method)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/volatile (volatile Keyword Interpretation)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/volatile:{iso|ms}
Arguments
/volatile:iso
Selects strict volatile semantics as defined by the ISO -standard C++ language. Acquire/release semantics are
not guaranteed on volatile accesses. If the compiler targets ARM, this is the default interpretation of volatile .
/volatile:ms
Selects Microsoft extended volatile semantics, which add memory ordering guarantees beyond the ISO -
standard C++ language. Acquire/release semantics are guaranteed on volatile accesses. However, this option also
forces the compiler to generate hardware memory barriers, which might add significant overhead on ARM and
other weak memory-ordering architectures. If the compiler targets any platform except ARM, this is default
interpretation of volatile .
Remarks
We strongly recommend that you use /volatile:iso along with explicit synchronization primitives and compiler
intrinsics when you are dealing with memory that is shared across threads. For more information, see volatile.
If you port existing code or change this option in the middle of a project, it may be helpful to enable warning
C4746 to identify code locations that are affected by the difference in semantics.
There is no #pragma equivalent to control this option.
To set the /volatile compiler option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. In the Additional options box, add /volatile:iso or /volatile:ms and then choose OK or Apply to save
your changes.
See also
volatile
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4,
/Wall, /wd, /we, /wo, /Wv, /WX (Warning Level)
3/12/2019 • 5 minutes to read • Edit Online
Syntax
/w /W0 /W1 /W2 /W3 /W4 /Wall /Wv[:version] /WX /w1warning /w2warning /w3warning
/w4warning /wdwarning /wewarning /wowarning
Remarks
The warning options specify which compiler warnings to display and the warning behavior for the entire
compilation.
The warning options and related arguments are described in the following table:
OPTION DESCRIPTION
/w1nnnn Sets the warning level for the warning number specified
by nnnn. This lets you change the compiler behavior for
/w2nnnn that warning when a specific warning level is set. You can
use these options in combination with other warning
/w3nnnn options to enforce your own coding standards for
warnings, rather than the default ones provided by Visual
/w4nnnn Studio.
If you use any of the warning options when you create a precompiled header by using the /Yc option, any
use of the precompiled header by using the /Yu option causes those same warning options to be in effect
again. You can override the warning options set in the precompiled header by using another warning
option on the command line.
You can use a #pragma warning directive to control the level of warning that is reported at compile time in
specific source files.
Warning pragma directives in source code are unaffected by the /w option.
The build errors documentation describes the warnings and warning levels, and indicates why certain
statements may not compile as you intend.
To set the compiler options in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build
properties in Visual Studio.
2. To set the /W0, /W1, /W2, /W3, /W4, /Wallm /Wv, /WX or /WX- options, select the
Configuration Properties > C/C++ > General property page.
To set the /W0, /W1, /W2, /W3, /W4, or /Wall options, modify the Warning Level
property.
To set the /WX or /WX- options, modify the Treat Warnings as Errors property.
To set the version for the /Wv option, enter the compiler version number in the Warning
Version property.
3. To set the /wd or /we options, select the Configuration Properties > C/C++ > Advanced
property page.
To set the /wd option, select the Disable Specific Warnings property drop down control
and then choose Edit. In the edit box in the Disable Specific Warnings dialog, enter the
warning number. To enter more than one warning, separate the values by using a semicolon
(;). For example, to disable both C4001 and C4010, enter 4001;4010. Choose OK to save
your changes and return to the Property Pages dialog.
To set the /we option, Select the Treat Specific Warnings As Errors property drop down
control and then choose Edit. In the edit box in the Treat Specific Warnings As Errors
dialog, enter the warning number. To enter more than one warning, separate the values by
using a semicolon (;). For example, to treat both C4001 and C4010 as errors, enter
4001;4010. Choose OK to save your changes and return to the Property Pages dialog.
4. To set the /wo option, select the Configuration Properties > C/C++ > Command Line property
page. Enter the compiler option in the Additional Options box.
5. Choose OK to save your changes.
To set the compiler option programmatically
See WarningLevel, WarnAsError, DisableSpecificWarnings, and AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/WL (Enable One-Line Diagnostics)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/WL
Remarks
Error and warning messages from the C++ compiler can be followed by additional information that appears, by
default, on a new line. When you compile from the command line, the additional line of information can be
appended to the error or warning message. This might be desirable if you capture your build output to a log file
and then process that log to find all errors and warnings. A semicolon will separate the error or warning message
from the additional line.
Not all error and warning messages have an additional line of information. The following code will generate an
error that has an additional line of information; it will let you test the effect when you use /WL.
// compiler_option_WL.cpp
// compile with: /WL
#include <queue>
int main() {
std::queue<int> q;
q.fromthecontinuum(); // C2039
}
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Wp64 (Detect 64-Bit Portability Issues)
3/12/2019 • 2 minutes to read • Edit Online
This compiler option is obsolete. In versions of Visual Studio before Visual Studio 2013, this detects 64-bit
portability problems on types that are also marked with the __w64 keyword.
Syntax
/Wp64
Remarks
By default, in versions of Visual Studio before Visual Studio 2013, the /Wp64 compiler option is off in the MSVC
compiler that builds 32-bit x86 code, and on in the MSVC compiler that builds 64-bit, x64 code.
IMPORTANT
The /Wp64 compiler option and __w64 keyword are deprecated in Visual Studio 2010 and Visual Studio 2012, and not
supported starting in Visual Studio 2013. If you convert a project that uses this switch, the switch will not be migrated
during conversion. To use this option in Visual Studio 2010 or Visual Studio 2012, you must type the compiler switch under
Additional Options in the Command Line section of the project properties. If you use the /Wp64 compiler option on the
command line, the compiler issues Command-Line Warning D9002. Instead of using this option and keyword to detect 64-
bit portability issues, use a MSVC compiler that targets a 64-bit platform and specify the /W4 option. For more information,
see Configure C++ projects for 64-bit, x64 targets.
Variables of the following types are tested on a 32-bit operating system as if they were being used on a 64-bit
operating system:
int
long
pointer
If you regularly compile your application by using a compiler that builds 64-bit, x64 code, you can just disable
/Wp64 in your 32-bit compilations because the 64-bit compiler will detect all issues. For more information about
how to target a Windows 64-bit operating system, see Configure C++ projects for 64-bit, x64 targets.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box.
For more information, see Set C++ compiler and build properties in Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Modify the Additional Options box to include /Wp64.
To set this compiler option programmatically
See Detect64BitPortabilityProblems.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Configure C++ projects for 64-bit, x64 targets
/X (Ignore Standard Include Paths)
3/12/2019 • 2 minutes to read • Edit Online
Prevents the compiler from searching for include files in directories specified in the PATH and INCLUDE
environment variables.
Syntax
/X
Remarks
You can use this option with the /I (Additional Include Directories) (/I directory ) option.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Preprocessor property page.
4. Modify the Ignore Standard Include Path property.
To set this compiler option programmatically
See IgnoreStandardIncludePath.
Example
In the following command, /X tells the compiler to ignore locations specified by the PATH and INCLUDE
environment variables, and /I specifies the directory in which to look for include files:
CL /X /I \ALT\INCLUDE MAIN.C
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Y (Precompiled Headers)
3/12/2019 • 2 minutes to read • Edit Online
The following compiler options affect the generation and use of precompiled headers:
/Y - (Ignore Precompiled Header Options)
/Yc (Create Precompiled Header File)
/Yd (Place Debug Information in Object File)
/Yl (Inject PCH Reference for Debug Library)
/Yu (Use Precompiled Header File)
For details on working with precompiled headers, see Precompiled Header Files.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Y- (Ignore Precompiled Header Options)
3/12/2019 • 2 minutes to read • Edit Online
Causes all other /Y compiler options to be ignored (and cannot itself be overridden).
Syntax
/Y-
Remarks
For more information on precompiled headers, see:
/Y (Precompiled Headers)
Precompiled Header Files
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Yc (Create Precompiled Header File)
3/12/2019 • 2 minutes to read • Edit Online
Instructs the compiler to create a precompiled header (.pch) file that represents the state of compilation at a
certain point.
Syntax
/Yc
/Ycfilename
Arguments
filename
Specifies a header (.h) file. When this argument is used, the compiler compiles all code up to and including the
.h file.
Remarks
When /Yc is specified without an argument, the compiler compiles all code up to the end of the base source file,
or to the point in the base file where a hdrstop directive occurs. The resulting .pch file has the same base name
as your base source file unless you specify a different file name using the hdrstop pragma or the /Fp option.
The precompiled code is saved in a file with a name created from the base name of the file specified with the
/Yc option and a .pch extension. You can also use the /Fp (Name .Pch File) option to specify a name for the
precompiled header file.
If you use /Ycfilename, the compiler compiles all code up to and including the specified file for subsequent use
with the /Yu (Use Precompiled Header File) option.
If the options /Ycfilename and /Yufilename occur on the same command line and both reference, or imply, the
same file name, /Ycfilename takes precedence. This feature simplifies the writing of makefiles.
For more information on precompiled headers, see:
/Y (Precompiled Headers)
Precompiled Header Files
To set this compiler option in the Visual Studio development environment
1. Select a .cpp file. The .cpp file must #include the .h file that contains precompiled header information. The
project's /Yc setting can be overridden at the file level.
2. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
3. Open the Configuration Properties, C/C++, Precompiled Headers property page.
4. Modify the Precompiled Header property.
5. To set the filename, modify the Precompiled Header File property.
To set this compiler option programmatically
See PrecompiledHeaderThrough and UsePrecompiledHeader.
Example
Consider the following code:
// prog.cpp
// compile with: cl /c /Ycmyapp.h prog.cpp
#include <afxwin.h> // Include header for class library
#include "resource.h" // Include resource definitions
#include "myapp.h" // Include information specific to this app
// ...
When this code is compiled with the command CL /YcMYAPP.H PROG.CPP , the compiler saves all the
preprocessing for AFXWIN.h, RESOURCE.h, and MYAPP.h in a precompiled header file called MYAPP.pch.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Precompiled Header Files
/Yd (Place Debug Information in Object File)
3/12/2019 • 2 minutes to read • Edit Online
Paces complete debugging information in all object files created from a precompiled header (.pch) file when used
with the /Yc and /Z7 options. Deprecated.
Syntax
/Yd
Remarks
/Yd is deprecated; Visual C++ now supports multiple objects writing to a single .pdb file, use /Zi instead. For a list
of deprecated compiler options, see Deprecated and Removed Compiler Options in Compiler Options Listed
by Category.
Unless you need to distribute a library containing debugging information, use the /Zi option rather than /Z7 and
/Yd.
Storing complete debugging information in every .obj file is necessary only to distribute libraries that contain
debugging information. It slows compilation and requires considerable disk space. When /Yc and /Z7 are used
without /Yd, the compiler stores common debugging information in the first .obj file created from the .pch file.
The compiler does not insert this information into .obj files subsequently created from the .pch file; it inserts
cross-references to the information. No matter how many .obj files use the .pch file, only one .obj file contains the
common debugging information.
Although this default behavior results in faster build times and reduces disk-space demands, it is undesirable if a
small change requires rebuilding the .obj file containing the common debugging information. In this case, the
compiler must rebuild all .obj files containing cross-references to the original .obj file. Also, if a common .pch file is
used by different projects, reliance on cross-references to a single .obj file is difficult.
For more information on precompiled headers, see:
/Y (Precompiled Headers)
Precompiled Header Files
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
Examples
Suppose you have two base files, F.cpp and G.cpp, each containing these #include statements:
#include "windows.h"
#include "etc.h"
The following command creates the precompiled header file ETC.pch and the object file F.obj:
The object file F.obj includes type and symbol information for WINDOWS.h and ETC.h (and any other header files
they include). Now you can use the precompiled header ETC.pch to compile the source file G.cpp:
The object file G.obj does not include the debugging information for the precompiled header but simply
references that information in the F.obj file. Note that you must link with the F.obj file.
If your precompiled header was not compiled with /Z7, you can still use it in later compilations using /Z7.
However, the debugging information is placed in the current object file, and local symbols for functions and types
defined in the precompiled header are not available to the debugger.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Yl (Inject PCH Reference for Debug Library)
3/12/2019 • 2 minutes to read • Edit Online
The /Yl option generates a unique symbol in a precompiled header file, and a reference to this symbol is injected
in all object files that use the precompiled header.
Syntax
/Yl /Ylname /Yl-
Arguments
name
An optional name used as part of the unique symbol.
-
A dash (-) explicitly disables the /Yl compiler option.
Remarks
The /Yl compiler option creates a unique symbol definition in a precompiled header file created by using the /Yc
option. References to this symbol are automatically injected in all files that include the precompiled header by
using the /Yu compiler option. The /Yl option is enabled by default when /Yc is used to create a precompiled
header file.
The /Ylname option is used to create an identifiable symbol in the precompiled header file. The compiler uses the
name argument as part of the decorated symbol name it creates, similar to __@@_PchSym_@00@...@name , where the
ellipsis (...) represents a unique compiler-generated character string. If the name argument is omitted, the
compiler generates a symbol name automatically. Normally, you do not need to know the name of the symbol.
However, when your project uses more than one precompiled header file, the /Ylname option may be useful to
determine which object files use which precompiled header. You can use name as a search string to find the
symbol reference in a dump file.
/Yl- disables the default behavior and does not put an identifying symbol in the precompiled header file.
Compiled files that include this precompiled header do not get a common symbol reference.
When /Yc is not specified, any /Yl option has no effect, but if specified it must match any /Yl option passed when
/Yc is specified.
If you use /Yl-, /Yc and /Z7 options to build a precompiled header file, the debugging information is stored in the
object file for the source file used to create the precompiled header, rather than a separate .pdb file. If this object
file is then made part of a library, LNK1211 errors or LNK4206 warnings can occur in builds that use this library
and the precompiled header file, if the source file used to create the precompiled header file does not define any
symbols itself. The linker may exclude the object file from the link, along with the associated debugging
information, when nothing in the object file is referenced in the library client. To solve this problem, specify /Yl (or
remove the /Yl- option) when you use /Yc to create the precompiled header file. This ensures that the object file
from the library that contains the debugging information gets linked in your build.
For more information on precompiled headers, see:
/Y (Precompiled Headers)
Precompiled Header Files
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Add the /Ylname compiler option in the Additional Options box. Choose OK to save your changes.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Yu (Use Precompiled Header File)
3/12/2019 • 3 minutes to read • Edit Online
Instructs the compiler to use an existing precompiled header (.pch) file in the current compilation.
Syntax
/Yu[filename]
Arguments
filename
The name of a header file, which is included in the source file using an #include preprocessor directive.
Remarks
The name of the include file must be the same for both the /Yc option that creates the precompiled header and
any subsequent /Yu option indicating use of the precompiled header.
For /Yc, filenamespecifies the point at which precompilation stops; the compiler precompiles all code though
filename and names the resulting precompiled header using the base name of the include file and an extension
of .pch.
The .pch file must have been created using /Yc.
The compiler treats all code occurring before the .h file as precompiled. It skips to just beyond the #include
directive associated with the .h file, uses the code contained in the .pch file, and then compiles all code after
filename .
Examples
If the following code:
is compiled with the command line CL /YuMYAPP.H PROG.CPP , the compiler does not process the three include
statements but uses precompiled code from MYAPP.pch, thereby saving the time involved in preprocessing all
three of the files (and any files they might include).
You can use the /Fp (Name .Pch File) option with the /Yu option to specify the name of the .pch file if the name
is different from either the file name argument to /Yc or the base name of the source file, as in the following:
This command specifies a precompiled header file named MYPCH.pch. The compiler uses its contents to restore
the precompiled state of all header files up to and including MYAPP.h. The compiler then compiles the code that
occurs after the MYAPP.h include statement.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Z7, /Zi, /ZI (Debug Information Format)
3/12/2019 • 4 minutes to read • Edit Online
Specifies the type of debugging information created for your program and whether this information is
kept in object files or in a program database (PDB ) file.
Syntax
/Z {7|i|I }
Remarks
When code is compiled and built in debug mode, the compiler produces symbol names for functions and
variables, type information, and line number locations for use by the debugger. This symbolic debugging
information can be included either in the object files (.obj files) produced by the compiler, or in a separate
PDB file (a .pdb file) for the executable. The debug information format options are described in the
following sections.
None
By default, if no debug information format option is specified, the compiler produces no debugging
information, so compilation is faster.
/Z7
The /Z7 option produces object files that also contain full symbolic debugging information for use with
the debugger. These object files and the built executable can be substantially larger than files that have no
debugging information. The symbolic debugging information includes the names and types of variables,
as well as functions and line numbers. No PDB file is produced.
For distributors of debug versions of third-party libraries, there is an advantage to not having a PDB file.
However, the object files for any precompiled headers are necessary during the library link phase, and for
debugging. If there is only type information (and no code) in the .pch object file, you must also use the /Yl
(Inject PCH Reference for Debug Library) option, which is enabled by default, when you build the library.
The /Gm (Enable Minimal Rebuild) option is not available when /Z7 is specified.
/Zi
The /Zi option produces a separate PDB file that contains all the symbolic debugging information for use
with the debugger. The debugging information is not included in the object files or executable, which
makes them much smaller.
Use of /Zi does not affect optimizations. However, /Zi does imply /debug; see /DEBUG (Generate
Debug Info) for more information.
When you specify both /Zi and /clr, the DebuggableAttribute attribute is not placed in the assembly
metadata. If you want it, you must specify it in the source code. This attribute can affect the runtime
performance of the application. For more information about how the Debuggable attribute affects
performance and how you can modify the performance impact, see Making an Image Easier to Debug.
The compiler names the PDB file project.pdb. If you compile a file outside of a project, the compiler
creates a PDB file named VCx.pdb, where x is a concatenation of the major and minor version number of
the compiler version in use. The compiler embeds the name of the PDB and an identifying timestamped
signature in each object file created using this option, which points the debugger to the location of
symbolic and line-number information. The name and signature in the PDB file must match the
executable for symbols to be loaded in the debugger. The WinDBG debugger can load mismatched
symbols by using the .symopt+0x40 command. Visual Studio does not have a similar option to load
mismatched symbols.
If you create a library from objects that were compiled using /Zi, the associated .pdb file must be
available when the library is linked to a program. Thus, if you distribute the library, you must also
distribute the PDB file. To create a library that contains debugging information without using PDB files,
you must select the /Z7 option. If you use the precompiled headers options, debugging information for
both the precompiled header and the rest of the source code is placed in the PDB file.
/ZI
The /ZI option is similar to /Zi, but it produces a PDB file in a format that supports the Edit and Continue
feature. To use Edit and Continue debugging features, you must use this option. The Edit and Continue
feature is useful for developer productivity, but can cause issues in code size, performance, and compiler
conformance. Because most optimizations are incompatible with Edit and Continue, using /ZI disables
any #pragma optimize statements in your code. The /ZI option is also incompatible with use of the
__LINE__ predefined macro; code compiled with /ZI cannot use __LINE__ as a non-type template
argument, although __LINE__ can be used in macro expansions.
The /ZI option forces both the /Gy (Enable Function-Level Linking) and /FC (Full Path of Source Code
File in Diagnostics) options to be used in your compilation.
/ZI is not compatible with /clr (Common Language Runtime Compilation).
NOTE
The /ZI option is only available in the compilers targeting x86 and x64 processors; this compiler option is not
available in the compilers targeting ARM processors.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Za, /Ze (Disable Language Extensions)
3/12/2019 • 2 minutes to read • Edit Online
The /Za compiler option disables and emits errors for Microsoft extensions to C that aren't compatible
with ANSI C89/ISO C90. The deprecated /Ze compiler option enables Microsoft extensions. Microsoft
extensions are enabled by default.
Syntax
/Za
/Ze
Remarks
NOTE
The use of /Za when code is compiled as C++ is not recommended. The /Ze option is deprecated because its
behavior is on by default. For a list of deprecated compiler options, see Deprecated and removed compiler options.
See also
Compiler Options
/Zc (Conformance)
/permissive- (Standards conformance)
/std (Specify Language Standard Version)
Microsoft extensions to C and C++
3/12/2019 • 4 minutes to read • Edit Online
Visual C++ extends the ANSI C and ANSI C++ standards as follows.
Keywords
Several keywords are added. In the list in Keywords, the keywords that have two leading underscores are Visual
C++ extensions.
class CMyClass {
static const int max = 5;
int m_array[max];
}
// . . .
const int CMyClass::max; // out of class definition
Under /Ze, the out-of-class definition is optional for static, const integral, and const enum data members. Only
integrals and enums that are static and const can have initializers in a class; the initializing expression must be a
const expression.
To avoid errors when an out-of-class definition is provided in a header file and the header file is included in
multiple source files, use selectany. For example:
Casts
Both the C++ compiler and C compiler support these kinds of non-ANSI casts:
Non-ANSI casts to produce l-values. For example:
char *p;
(( int * ) p )++;
NOTE
This extension is available in the C language only. You can use the following ANSI C standard form in C++ code to
modify a pointer as if it is a pointer to a different type.
The preceding example could be rewritten as follows to conform to the ANSI C standard.
To perform the same cast and also maintain ANSI compatibility, you can cast the function pointer to a
uintptr_t before you cast it to a data pointer:
Single-line comments
The C compiler supports single-line comments, which are introduced by using two forward slash (//) characters:
Scope
The C compiler supports the following scope-related features.
Redefinitions of extern items as static:
void func1()
{
extern int func2( double );
}
int main( void )
{
func2( 4 ); // /Ze passes 4 as type double
} // /Za passes 4 as type int
Bit fields that have base types other than unsigned int or signed int.
Declarators that don't have a type:
x;
int main( void )
{
x = 1;
}
struct zero
{
char *c;
int zarray[];
};
struct
{
int i;
char *s;
};
union
{
int i;
float fl;
};
Unnamed members:
struct s
{
unsigned int flag : 1;
unsigned int : 31;
}
typedef int T;
void func2 ( const T*& rpcT ) // A reference to a pointer to a constant of type 'T'
{
rpcT = pcT;
}
void func ()
{
func2 ( pT ); // Should be an error, but isn't detected
*pT = 7; // Invalidly overwrites the constant 'acT'
}
Address of string literal has type const char [], not const char (*) []
The following example will output char const (*)[4] under /Za, but char const [4] under /Ze.
#include <stdio.h>
#include <typeinfo>
int main()
{
printf_s("%s\n", typeid(&"abc").name());
}
See also
/Za, /Ze (Disable Language Extensions)
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc (Conformance)
3/12/2019 • 2 minutes to read • Edit Online
You can use the /Zc compiler options to specify standard or Microsoft-specific compiler behavior.
Syntax
/Zc:option{,option}
Remarks
When Visual Studio has implemented an extension to C or C++ that is not compatible with the standard, you
can use a /Zc conformance option to specify standard-conforming or Microsoft-specific behavior. For some
options, the Microsoft-specific behavior is the default, to prevent large-scale breaking changes to existing code.
In other cases, the default is the standard behavior, where improvements in security, performance, or
compatibility outweigh the costs of breaking changes. The default setting of each conformance option may
change in newer versions of Visual Studio. For more information about each conformance option, see the topic
for the specific option. The /permissive- compiler option implicitly sets the conformance options that are not
set by default to their conformant setting.
These are the /Zc compiler options:
OPTION BEHAVIOR
auto[-] Enforce the new Standard C++ meaning for auto (on by
default).
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc:alignedNew (C++17 over-aligned allocation)
3/12/2019 • 3 minutes to read • Edit Online
Enable support for C++17 over-aligned new, dynamic memory allocation aligned on boundaries greater than the
default for the maximum-sized standard aligned type, max_align_t.
Syntax
/Zc:alignedNew[-]
Remarks
Visual Studio version 15.5 enables compiler and library support for C++17 standard over-aligned dynamic
memory allocation. When the /Zc:alignedNew option is specified, a dynamic allocation such as new Example;
respects the alignment of Example even when it’s greater than max_align_t , the largest alignment required for any
fundamental type. When the alignment of the allocated type is no more than that guaranteed by the original
operator new, available as the value of the predefined macro __STDCPP_DEFAULT_NEW_ALIGNMENT__, the
statement new Example; results in a call to ::operator new(size_t) as it did in C++14. When the alignment is
greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__, the implementation instead obtains the memory by
using ::operator new(size_t, align_val_t) . Similarly, deletion of over-aligned types invokes
::operator delete(void*, align_val_t) or the sized delete signature
::operator delete(void*, size_t, align_val_t) .
The /Zc:alignedNew option is only available when /std:c++17 or /std:c++latest is enabled. Under /std:c++17 or
/std:c++latest, /Zc:alignedNew is enabled by default to conform to the ISO C++17 standard. If the only reason
you implement operator new and delete is to support over-aligned allocations, you may no longer need this code
in C++17 mode. To turn this option off and revert to the C++14 behavior of new and delete when /std::c++17
or /std:c++latest is specified, specify /Zc:alignedNew-. If you implement operator new and delete but you are
not ready to implement the over-aligned operator new and delete overloads that have the align_val_t
parameter, use the /Zc:alignedNew- option to prevent the compiler and Standard Library from generating calls
to the over-aligned overloads. The /permissive- option does not change the default setting of /Zc:alignedNew.
Example
This sample shows how operator new and operator delete behave when the /Zc:alignedNew option is set.
// alignedNew.cpp
// Compile by using: cl /EHsc /std:c++17 /W4 alignedNew.cpp
#include <iostream>
#include <malloc.h>
#include <new>
int main() {
delete new int;
delete new OverAligned;
}
This output is typical for 32-bit builds. The pointer values vary based on where your application runs in memory.
For information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:alignedNew or /Zc:alignedNew- and then
choose OK.
See also
/Zc (Conformance)
/Zc:auto (Deduce Variable Type)
3/12/2019 • 2 minutes to read • Edit Online
The /Zc:auto[-] compiler option tells the compiler how to use the auto keyword to declare variables. If you
specify the default option, /Zc:auto, the compiler deduces the type of the declared variable from its initialization
expression. If you specify /Zc:auto-, the compiler allocates the variable to the automatic storage class.
Syntax
/Zc:auto[-]
Remarks
The C++ standard defines an original and a revised meaning for the auto keyword. Before Visual C++ 2010, the
keyword declares a variable in the automatic storage class; that is, a variable that has a local lifetime. Starting with
Visual C++ 2010, the keyword deduces the type of a variable from the declaration's initialization expression. Use
the /Zc:auto[-] compiler option to tell the compiler to use the original or revised meaning of the auto keyword.
The /Zc:auto option is on by default. The /permissive- option does not change the default setting of /Zc:auto.
The compiler issues an appropriate diagnostic message if your use of the auto keyword contradicts the current
/Zc:auto compiler option. For more information, see auto Keyword. For more information about conformance
issues with Visual C++, see Nonstandard Behavior.
To set this compiler option in Visual Studio
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Add /Zc:auto or /Zc:auto- to the Additional options: pane.
See also
/Zc (Conformance)
auto Keyword
/Zc:__cplusplus (Enable updated __cplusplus macro)
3/12/2019 • 2 minutes to read • Edit Online
The /Zc:__cplusplus compiler option enables the __cplusplus preprocessor macro to report an updated value for
recent C++ language standards support. By default, Visual Studio always returns the value "199711L" for the
__cplusplus preprocessor macro.
Syntax
/Zc:__cplusplus[-]
Remarks
The __cplusplus preprocessor macro is commonly used to report support for a particular version of the C++
standard. Because lots of existing code appears to depend on the value of this macro matching "199711L", the
compiler does not change the value of the macro unless you explicitly opt-in by using the /Zc:__cplusplus
compiler option. The /Zc:__cplusplus option is available starting in Visual Studio 2017 version 15.7, and is off by
default. In earlier versions of Visual Studio, and by default, or if /Zc:__cplusplus- is specified, Visual Studio returns
the value "199711L" for the __cplusplus preprocessor macro. The /permissive- option does not enable
/Zc:__cplusplus.
When the /Zc:__cplusplus option is enabled, the value reported by the __cplusplus macro depends on the /std
version switch setting. This table shows the possible values for the macro:
The compiler does not support standards switches for C++98, C++03, or C++11.
For finer-grained detection of changes to the compiler toolset, use the _MSC_VER predefined macro. The value of
this built-in macro is incremented for every toolset update in Visual Studio 2017 and later versions. The
_MSVC_LANG predefined macro reports the standard version whether the /Zc:__cplusplus option is enabled or
disabled. When /Zc:__cplusplus is enabled, __cplusplus == _MSVC_LANG .
To set this compiler option in Visual Studio
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Add /Zc:__cplusplus or /Zc:__cplusplus- to the Additional options: pane.
See also
/Zc (Conformance)
/std (Specify language standard version)
Predefined macros
/Zc:externConstexpr (Enable extern constexpr
variables)
3/12/2019 • 2 minutes to read • Edit Online
The /Zc:externConstexpr compiler option tells the compiler to conform to the C++ standard and allow external
linkage for constexpr variables. By default, Visual Studio always gives a constexpr variable internal linkage, even
if you specify the extern keyword.
Syntax
/Zc:externConstexpr[-]
Remarks
The /Zc:externConstexpr compiler option causes the compiler to apply external linkage to variables declared by
using extern constexpr . In earlier versions of Visual Studio, and by default or if /Zc:externConstexpr- is
specified, Visual Studio applies internal linkage to constexpr variables even if the extern keyword is used. The
/Zc:externConstexpr option is available starting in Visual Studio 2017 Update 15.6. and is off by default. The
/permissive- option does not enable /Zc:externConstexpr.
If a header file contains a variable declared extern constexpr , it must be marked __declspec(selectany) in order to
merge the duplicate declarations into a single instance in the linked binary. Otherwise you may see linker errors,
for example, LNK2005, for violations of the one-definition rule.
To set this compiler option in Visual Studio
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Add /Zc:externConstexpr or /Zc:externConstexpr- to the Additional options: pane.
See also
/Zc (Conformance)
auto Keyword
/Zc:forScope (Force Conformance in for Loop Scope)
3/12/2019 • 2 minutes to read • Edit Online
Used to implement standard C++ behavior for for loops with Microsoft extensions (/Ze).
Syntax
/Zc:forScope[-]
Remarks
Standard behavior is to let a for loop's initializer go out of scope after the for loop. Under /Zc:forScope- and /Ze,
the for loop's initializer remains in scope until the local scope ends.
The /Zc:forScope option is on by default. /Zc:forScope is not affected when the /permissive- option is specified.
The /Zc:forScope- option is deprecated and will be removed in a future release. Use of /Zc:forScope- generates
deprecation warning D9035.
The following code compiles under /Ze but not under /Za:
// zc_forScope.cpp
// compile by using: cl /Zc:forScope- /Za zc_forScope.cpp
// C2065, D9035 expected
int main() {
// Compile by using cl /Zc:forScope- zc_forScope.cpp
// to compile this non-standard code as-is.
// Uncomment the following line to resolve C2065 for /Za.
// int i;
for (int i = 0; i < 1; i++)
;
i = 20; // i has already gone out of scope under /Za
}
If you use /Zc:forScope-, warning C4288 (off by default) is generated if a variable is in scope because of a
declaration that was made in a previous scope. To demonstrate this, remove the // characters in the example
code to declare int i .
You can modify the run-time behavior of /Zc:forScope by using the conform pragma.
If you use /Zc:forScope- in a project that has an existing .pch file, a warning is generated, /Zc:forScope- is
ignored, and compilation continues by using the existing .pch files. If you want a new .pch file generated, use /Yc
(Create Precompiled Header File).
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Language property page.
3. Modify the Force Conformance in For Loop Scope property.
To set this compiler option programmatically
See ForceConformanceInForLoopScope.
See also
/Zc (Conformance)
/Za, /Ze (Disable Language Extensions)
/Zc:implicitNoexcept (Implicit Exception Specifiers)
3/12/2019 • 3 minutes to read • Edit Online
When the /Zc:implicitNoexcept option is specified, the compiler adds an implicit noexcept exception specifier to
compiler-defined special member functions and to user-defined destructors and deallocators. By default,
/Zc:implicitNoexcept is enabled to conform to the ISO C++11 standard. Turning this option off disables implicit
noexcept on user -defined destructors and dealloacators and compiler -defined special member functions.
Syntax
/Zc:implicitNoexcept[-]
Remarks
/Zc:implicitNoexcept tells the compiler to follow section 15.4 of the ISO C++11 standard. It implicitly adds a
noexcept exception specifier to each implicitly-declared or explicitly defaulted special member function—the
default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment
operator—and each user-defined destructor or deallocator function. A user-defined deallocator has an implicit
noexcept(true) exception specifier. For user -defined destructors, the implicit exception specifier is noexcept(true)
unless a contained member class or base class has a destructor that is not noexcept(true) . For compiler-generated
special member functions, if any function directly invoked by this function is effectively noexcept(false) , the
implicit exception specifier is noexcept(false) . Otherwise, the implicit exception specifier is noexcept(true) .
The compiler does not generate an implicit exception specifier for functions declared by using explicit noexcept or
throw specifiers or a __declspec(nothrow) attribute.
By default, /Zc:implicitNoexcept is enabled. The /permissive- option does not affect /Zc:implicitNoexcept.
If the option is disabled by specifying /Zc:implicitNoexcept-, no implicit exception specifiers are generated by
the compiler. This behavior is the same as Visual Studio 2013, where destructors and deallocators that did not have
exception specifiers could have throw statements. By default, and when /Zc:implicitNoexcept is specified, if a
throw statement is encountered at run time in a function with an implicit noexcept(true) specifier, it causes an
immediate invocation of std::terminate , and normal unwinding behavior for exception handlers is not
guaranteed. To help identify this situation, the compiler generates Compiler Warning (level 1) C4297. If the throw
is intentional, we recommend you change your function declaration to have an explicit noexcept(false) specifier
instead of using /Zc:implicitNoexcept-.
This sample shows how a user-defined destructor that has no explicit exception specifier behaves when the
/Zc:implicitNoexcept option is set or disabled. To show the behavior when set, compile by using
cl /EHsc /W4 implicitNoexcept.cpp . To show the behavior when disabled, compile by using
cl /EHsc /W4 /Zc:implicitNoexcept- implicitNoexcept.cpp .
// implicitNoexcept.cpp
// Compile by using: cl /EHsc /W4 implicitNoexcept.cpp
// Compile by using: cl /EHsc /W4 /Zc:implicitNoexcept- implicitNoexcept.cpp
#include <iostream>
#include <cstdlib> // for std::exit, EXIT_FAILURE, EXIT_SUCCESS
#include <exception> // for std::set_terminate
void my_terminate()
{
{
std::cout << "Unexpected throw caused std::terminate" << std::endl;
std::cout << "Exit returning EXIT_FAILURE" << std::endl;
std::exit(EXIT_FAILURE);
}
struct A {
// Explicit noexcept overrides implicit exception specification
~A() noexcept(false) {
throw 1;
}
};
struct B : public A {
// Compiler-generated ~B() definition inherits noexcept(false)
~B() = default;
};
struct C {
// By default, the compiler generates an implicit noexcept(true)
// specifier for this user-defined destructor. To enable it to
// throw an exception, use an explicit noexcept(false) specifier,
// or compile by using /Zc:implicitNoexcept-
~C() {
throw 1; // C4297, calls std::terminate() at run time
}
};
struct D : public C {
// This destructor gets the implicit specifier of its base.
~D() = default;
};
int main()
{
std::set_terminate(my_terminate);
try
{
{
B b;
}
}
catch (...)
{
// exception should reach here in all cases
std::cout << "~B Exception caught" << std::endl;
}
try
{
{
D d;
}
}
catch (...)
{
// exception should not reach here if /Zc:implicitNoexcept
std::cout << "~D Exception caught" << std::endl;
}
std::cout << "Exit returning EXIT_SUCCESS" << std::endl;
return EXIT_SUCCESS;
}
When compiled by using the default setting /Zc:implicitNoexcept, the sample generates this output:
~B Exception caught
Unexpected throw caused std::terminate
Exit returning EXIT_FAILURE
When compiled by using the setting /Zc:implicitNoexcept-, the sample generates this output:
~B Exception caught
~D Exception caught
Exit returning EXIT_SUCCESS
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:implicitNoexcept or /Zc:implicitNoexcept-
and then choose OK.
See also
/Zc (Conformance)
noexcept
Exception Specifications (throw )
terminate
/Zc:inline (Remove unreferenced COMDAT)
3/12/2019 • 2 minutes to read • Edit Online
Removes unreferenced functions or data that are COMDATs or only have internal linkage. When /Zc:inline is
specified, the compiler requires that translation units that use inline data or inline functions must also include the
definitions for the data or functions.
Syntax
/Zc:inline[-]
Remarks
When /Zc:inline is specified, the compiler does not emit symbol information for unreferenced COMDAT functions
or data, or for functions or data that have internal linkage only. This optimization simplifies some of the work
performed by the linker in release builds or when the linker option /OPT:REF is specified. When the compiler
performs this optimization, it can significantly reduce .obj file size and improve linker speeds. This compiler option
is not enabled when optimizations are disabled (/Od) or when /GL (Whole Program Optimization) is specified.
By default, this option is off (/Zc:inline-). The /permissive- option does not enable /Zc:inline.
If /Zc:inline is specified, the compiler enforces the C++11 requirement that all functions declared inline must
have a definition available in the same translation unit if they are used. When the option is not specified, the
Microsoft compiler allows non-conformant code that invokes functions declared inline even if no definition is
visible. For more information, see the C++11 standard, in section 3.2 and section 7.1.2. This compiler option was
introduced in Visual Studio 2013 Update 2.
To use the /Zc:inline option, update non-compliant code.
This example shows how the non-compliant use of an inline function declaration without a definition still compiles
and links when the default /Zc:inline- option is used:
// 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
// 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
// Compile by using: cl /W4 /EHsc /O2 zcinline.cpp example.cpp
#include "example.h"
void main() {
Example example;
example.inline_call(); // normal call when definition unavailable
}
When /Zc:inline is enabled, the same code causes a LNK2019 error, because the compiler does not emit a non-
inlined code body for Example::inline_call in example.obj. This causes the non-inlined call in main to reference
an undefined external symbol.
To resolve this error, you can remove the inline keyword from the declaration of Example::inline_call , move the
definition of Example::inline_call into the header file, or move the implementation of Example into main.cpp. The
next example moves the definition into the header file, where it is visible to any caller that includes the header.
// 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
// 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.cpp
// Compile by using: cl /W4 /EHsc /O2 zcinline2.cpp example2.cpp
#include "example2.h"
void main() {
Example2 example2;
example2.inline_call(); // normal call when definition unavailable
}
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Language property page.
3. Modify the Remove unreferenced code and data property, and then choose OK.
See also
/Zc (Conformance)
/Zc:noexceptTypes (C++17 noexcept rules)
3/12/2019 • 2 minutes to read • Edit Online
The C++17 standard makes throw() as an alias for noexcept , removes throw(<type list>) and throw(...) , and
allows certain types to include noexcept . This can cause a number of source compatibility issues in code that
conforms to C++14 or earlier. The /Zc:noexceptTypes option can specify conformance to the C++17 standard or
allow the C++14 and earlier behavior when code is compiled in C++17 mode.
Syntax
/Zc:noexceptTypes[-]
Remarks
When the /Zc:noexceptTypes option is specified, the compiler conforms to the C++17 standard and treats
throw () as an alias for noexcept, removes throw(<type list>) and throw(...) , and allows certain types to include
noexcept . The /Zc:noexceptTypes option is only available when /std:c++17 or /std:latest is enabled.
/Zc:noexceptTypes is enabled by default to conform to the ISO C++17 standard. The /permissive- option does
not affect /Zc:noexceptTypes. Turn this option off by specifying /Zc:noexceptTypes- to revert to the C++14
behavior of noexcept when /std::C++17 or /std::latest is specified.
Beginning in Visual Studio 2017 version 15.5, the C++ compiler diagnoses more mismatched exception
specifications in declarations in C++17 mode or when the /permissive- option is specified.
This sample shows how declarations with an exception specifier behave when the /Zc:noexceptTypes option is
set or disabled. To show the behavior when set, compile by using cl /EHsc /W4 noexceptTypes.cpp . To show the
behavior when disabled, compile by using cl /EHsc /W4 /Zc:noexceptTypes- noexceptTypes.cpp .
// noexceptTypes.cpp
// Compile by using: cl /EHsc /W4 noexceptTypes.cpp
// Compile by using: cl /EHsc /W4 /Zc:noexceptTypes- noexceptTypes.cpp
struct A
{
virtual void f() throw();
};
struct B : A
{
virtual void f() { } // error C2694
};
When compiled by using the default setting /Zc:noexceptTypes, the sample generates the listed warnings. To
update your code, use the following instead:
void f() noexcept;
void f() noexcept { }
void g() noexcept(false);
struct A
{
virtual void f() noexcept;
};
struct B : A
{
virtual void f() noexcept { }
};
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:noexceptTypes or /Zc:noexceptTypes- and
then choose OK.
See also
/Zc (Conformance)
noexcept
Exception Specifications (throw )
/Zc:referenceBinding (Enforce reference binding rules)
3/12/2019 • 2 minutes to read • Edit Online
When the /Zc:referenceBinding option is specified, the compiler does not allow a non-const lvalue reference to
bind to a temporary.
Syntax
/Zc:referenceBinding[-]
Remarks
If /Zc:referenceBinding is specified, the compiler follows section 8.5.3 of the C++11 standard and does not allow
expressions that bind a user-defined type temporary to a non-const lvalue reference. By default, or if
/Zc:referenceBinding- is specified, the compiler allows such expressions as a Microsoft extension, but a level 4
warning is issued. For code security, portability and conformance, we recommend that you use
/Zc:referenceBinding.
The /Zc:referenceBinding option is off by default. The /permissive- compiler option implicitly sets this option,
but it can be overridden by using /Zc:referenceBinding-.
Example
This sample shows the Microsoft extension that allows a temporary of a user-defined type to be bound to a non-
const lvalue reference.
// zcreferencebinding.cpp
struct S {
};
void f(S&) {
}
S g() {
return S{};
}
void main() {
S& s = g(); // warning C4239 at /W4
const S& cs = g(); // okay, bound to const ref
f(g()); // Extension: error C2664 only if /Zc:referenceBinding
}
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:referenceBinding and then choose OK.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc (Conformance)
/Zc:rvalueCast (Enforce type conversion rules)
3/12/2019 • 2 minutes to read • Edit Online
When the /Zc:rvalueCast option is specified, the compiler correctly identifies an rvalue reference type as the
result of a cast operation in accordance with the C++11 standard. When the option is not specified, the compiler
behavior is the same as in Visual Studio 2012.
Syntax
/Zc:rvalueCast[-]
Remarks
If /Zc:rvalueCast is specified, the compiler follows section 5.4 of the C++11 standard and treats only cast
expressions that result in non-reference types and cast expressions that result in rvalue references to non-function
types as rvalue types. By default, or if /Zc:rvalueCast- is specified, the compiler is non-conformant and treats all
cast expressions that result in rvalue references as rvalues. For conformance and to eliminate errors in the use of
casts, we recommend that you use /Zc:rvalueCast.
By default, /Zc:rvalueCast is off (/Zc:rvalueCast-). The /permissive- compiler option implicitly sets this option,
but it can be overridden by using /Zc:rvalueCast-.
Use /Zc:rvalueCast if you pass a cast expression as an argument to a function that takes an rvalue reference type.
The default behavior causes compiler error C2664 when the compiler incorrectly determines the type of the cast
expression. This example shows a compiler error in correct code when /Zc:rvalueCast is not specified:
// Test of /Zc:rvalueCast
// compile by using:
// cl /c /Zc:rvalueCast- make_thing.cpp
// cl /c /Zc:rvalueCast make_thing.cpp
#include <utility>
T& thing1;
T& thing2;
};
struct Test1 {
long a;
long b;
Thing<long> test() {
// Use identity casts to create rvalues as arguments
return make_thing(static_cast<long>(a), static_cast<long>(b));
}
};
The default compiler behavior may not report error C2102 when appropriate. In this example, the compiler does
not report an error if the address of an rvalue created by an identity cast is taken when /Zc:rvalueCast is not
specified:
int main() {
int a = 1;
int *p = &a; // Okay, take address of lvalue
// Identity cast creates rvalue from lvalue;
p = &(int)a; // problem: should cause C2102: '&' requires l-value
}
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:rvalueCast and then choose OK.
See also
/Zc (Conformance)
/Zc:sizedDealloc (Enable Global Sized Deallocation
Functions)
3/12/2019 • 2 minutes to read • Edit Online
The /Zc:sizedDealloc compiler option tells the compiler to preferentially call global operator delete or
operator delete[] functions that have a second parameter of type size_t when the size of the object is available.
These functions may use the size_t parameter to optimize deallocator performance.
Syntax
/Zc:sizedDealloc[-]
Remarks
In the C++11 standard, you may define static member functions operator delete and operator delete[] that take
a second, size_t parameter. Typically these are used in combination with operator new functions to implement
more efficient allocators and deallocators for the object. However, C++11 did not define an equivalent set of
deallocation functions at global scope. In C++11, global deallocation functions that have a second parameter of
type size_t are considered placement delete functions. They must be explicitly called by passing a size argument.
The C++14 standard changes the behavior of the compiler. When you define global operator delete and
operator delete[] that take a second parameter of type size_t , the compiler prefers to call these functions when
member scope versions are not invoked and the size of the object is available. The compiler passes the size
argument implicitly. The single argument versions are called when the compiler can't determine the size of the
object being deallocated. Otherwise, the usual rules for choosing the version of the deallocation function to invoke
still apply. Calls to the global functions may be explicitly specified by prepending the scope resolution operator (
:: ) to the deallocation function call.
By default, Visual C++ starting in Visual Studio 2015 implements this C++14 standard behavior. You may
explicitly specify this by setting the /Zc:sizedDealloc compiler option. This represents a potentially breaking
change. Use the /Zc:sizedDealloc- option to preserve the old behavior, for example, when your code defines
placement delete operators that use a second parameter of type size_t . The default Visual Studio library
implementations of the global deallocation functions that have the second parameter of type size_t invoke the
single parameter versions. If your code supplies only single-parameter global operator delete and operator
delete[], the default library implementations of the global sized deallocation functions invoke your global functions.
The /Zc:sizedDealloc compiler option is on by default. The /permissive- option does not affect
/Zc:sizedDealloc.
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc (Conformance)
/Zc:strictStrings (Disable string literal type conversion)
3/12/2019 • 2 minutes to read • Edit Online
When specified, the compiler requires strict const -qualification conformance for pointers initialized by using
string literals.
Syntax
/Zc:strictStrings[-]
Remarks
If /Zc:strictStrings is specified, the compiler enforces the standard C++ const qualifications for string literals, as
type 'array of const char ' or 'array of const wchar_t ', depending on the declaration. String literals are immutable,
and an attempt to modify the contents of one results in an access violation error at run time. You must declare a
string pointer as const to initialize it by using a string literal, or use an explicit const_cast to initialize a non-
const pointer. By default, or if /Zc:strictStrings- is specified, the compiler does not enforce the standard C++
const qualifications for string pointers initialized by using string literals.
The /Zc:strictStrings option is off by default. The /permissive- compiler option implicitly sets this option, but it
can be overridden by using /Zc:strictStrings-.
Use the /Zc:strictStrings option to prevent compilation of incorrect code. This example shows how a simple
declaration error leads to a crash at run time:
// strictStrings_off.cpp
// compile by using: cl /W4 strictStrings_off.cpp
int main() {
wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation
}
When /Zc:strictStrings is enabled, the same code reports an error in the declaration of str .
// strictStrings_on.cpp
// compile by using: cl /Zc:strictStrings /W4 strictStrings_on.cpp
int main() {
wchar_t* str = L"hello"; // error: Conversion from string literal
// loses const qualifier
str[2] = L'a';
}
If you use auto to declare a string pointer, the compiler creates the correct const pointer type declaration for you.
An attempt to modify the contents of a const pointer is reported by the compiler as an error.
NOTE
The C++ Standard Library in Visual Studio 2013 does not support the /Zc:strictStrings compiler option in debug builds. If
you see several C2665 errors in your build output, this may be the cause.
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:strictStrings and then choose OK.
See also
/Zc (Conformance)
/Zc:ternary (Enforce conditional operator rules)
3/12/2019 • 5 minutes to read • Edit Online
Enable enforcement of C++ Standard rules for the types and const or volatile (cv) qualification of the second and
third operands in a conditional operator expression.
Syntax
/Zc:ternary[-]
Remarks
Visual Studio version 15.3 enables compiler support for C++ standard conditional (or ternary) operator ( ?:)
behavior. The C++ Standard requires either the operands to be of the same type and cv-qualification, or for only
one operand to be unambiguously convertible to the same type and cv-qualification as the other, or for one or
both operands to be a throw expression. In versions before Visual Studio version 15.5, the compiler allowed
conversions that are considered ambiguous by the standard. When the /Zc:ternary option is specified, the
compiler conforms to the standard and rejects code that does not satisfy the rules for matched types and cv-
qualification of the second and third operands.
The /Zc:ternary option is off by default. Use /Zc:ternary to enable conforming behavior, or /Zc:ternary- to
explicitly specify the previous non-conforming compiler behavior. The /permissive- option implicitly enables this
option, but it can be overridden by using /Zc:ternary-.
Examples
This sample shows how a class that provides both non-explicit initialization from a type and conversion to a type
can lead to ambiguous conversions. This code is accepted by the compiler by default, but rejected when
/Zc:ternary or /permissive- is specified.
// zcternary1.cpp
// Compile by using: cl /EHsc /W4 /nologo /Zc:ternary zcternary1.cpp
struct A
{
long l;
A(int i) : l{i} {} // explicit prevents conversion of int
operator int() const { return static_cast<int>(l); }
};
int main()
{
A a(42);
// Accepted when /Zc:ternary (or /permissive-) is not used
auto x = true ? 7 : a; // old behavior prefers A(7) over (int)a
auto y = true ? A(7) : a; // always accepted
auto z = true ? 7 : (int)a; // always accepted
return x + y + z;
}
The fix required is to make an explicit cast to the preferred common type, or prevent one direction of conversion
from participation in the compiler search for a type match by making the conversion explicit.
An important exception to this common pattern is when the type of the operands is one of the null-terminated
string types, such as const char* , const char16_t* , and so on. You can also reproduce this with array types and
the pointer types they decay to. The behavior when the actual second or third operand to ?: is a string literal of
corresponding type depends on the language standard used. C++17 has changed semantics for this case from
C++14. As a result, the code in the following example is accepted under /std:c++14 (the compiler default) but is
rejected when /std:c++17 is specified.
// zcternary2.cpp
// Compile by using: cl /EHsc /W4 /nologo /Zc:ternary /std:c++17 zcternary2.cpp
struct MyString
{
const char * p;
MyString(const char* s = "") noexcept : p{s} {} // from char*
operator const char*() const noexcept { return p; } // to char*
};
int main()
{
MyString s;
auto x = true ? "A" : s; // MyString: permissive prefers MyString("A") over (const char*)s
}
// zcternary3.cpp
// Compile by using: cl /EHsc /W4 /nologo /Zc:ternary /c zcternary3.cpp
int main()
{
ASSERT(false); // C3447
}
The typical solution is to simply replace the non-void argument with void().
This sample shows code that generates an error under both /Zc:ternary and /Zc:ternary-:
// zcternary4.cpp
// Compile by using:
// cl /EHsc /W4 /nologo /Zc:ternary zcternary4.cpp
// cl /EHsc /W4 /nologo /Zc:ternary zcternary4.cpp
int main() {
auto p1 = [](int a, int b) { return a > b; };
auto p2 = [](int a, int b) { return a > b; };
auto p3 = true ? p1 : p2; // C2593 under /Zc:ternary, was C2446
}
With /Zc:ternary the reason for failure becomes clearer; on architectures where any of several implementation-
defined calling conventions could be used to generate each lambda, the compiler expresses no preference among
them that could disambiguate the possible lambda signatures. The new output looks like this:
A common source of problems related to adoption of /Zc:ternary comes from the use of the conditional operator
in template meta-programming, as some of the result types change under this switch. The following example
demonstrates two cases where /Zc:ternary changes a conditional expression’s result type in a non-meta-
programming context:
// zcternary5.cpp
// Compile by using: cl /EHsc /W4 /nologo /Zc:ternary zcternary5.cpp
The typical resolution in such cases is to apply a std::remove_reference trait on the result type where needed in
order to preserve the old behavior.
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:ternary or /Zc:ternary- and then choose OK.
See also
/Zc (Conformance)
/Zc:threadSafeInit (Thread-safe Local Static
Initialization)
3/12/2019 • 2 minutes to read • Edit Online
The /Zc:threadSafeInit compiler option tells the compiler to initialize static local (function scope) variables in a
thread-safe way, eliminating the need for manual synchronization. Only initialization is thread-safe. Use and
modification of static local variables by multiple threads must still be manually synchronized. This option is
available starting in Visual Studio 2015. By default, Visual Studio enables this option.
Syntax
/Zc:threadSafeInit[-]
Remarks
In the C++11 standard, block scope variables with static or thread storage duration must be zero-initialized before
any other initialization takes place. Initialization occurs when control first passes through the declaration of the
variable. If an exception is thrown during initialization, the variable is considered uninitialized, and initialization is
re-attempted the next time control passes through the declaration. If control enters the declaration concurrently
with initialization, the concurrent execution blocks while initialization is completed. The behavior is undefined if
control re-enters the declaration recursively during initialization. By default, Visual Studio starting in Visual Studio
2015 implements this standard behavior. This behavior may be explicitly specified by setting the
/Zc:threadSafeInit compiler option.
The /Zc:threadSafeInit compiler option is on by default. The /permissive- option does not affect
/Zc:threadSafeInit.
Thread-safe initialization of static local variables relies on code implemented in the Universal C run-time library
(UCRT). To avoid taking a dependency on the UCRT, or to preserve the non-thread-safe initialization behavior of
versions of Visual Studio prior to Visual Studio 2015, use the /Zc:threadSafeInit- option. If you know that
thread-safety is not required, use this option to generate slightly smaller, faster code around static local
declarations.
Thread-safe static local variables use thread-local storage (TLS ) internally to provide efficient execution when the
static has already been initialized. The implementation of this feature relies on Windows operating system support
functions in Windows Vista and later operating systems. Windows XP, Windows Server 2003, and older operating
systems do not have this support, so they do not get the efficiency advantage. These operating systems also have a
lower limit on the number of TLS sections that can be loaded. Exceeding the TLS section limit can cause a crash. If
this is a problem in your code, especially in code that must run on older operating systems, use
/Zc:threadSafeInit- to disable the thread-safe initialization code.
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. From the Configurations drop down menu, choose All Configurations.
3. Select the Configuration Properties > C/C++ > Command Line property page.
4. Modify the Additional Options property to include /Zc:threadSafeInit or /Zc:threadSafeInit- and then
choose OK.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc (Conformance)
/Zc:throwingNew (Assume operator new throws)
3/12/2019 • 2 minutes to read • Edit Online
When the /Zc:throwingNew option is specified, the compiler optimizes calls to operator new to skip checks for a
null pointer return. This option tells the compiler to assume that all linked implementations of operator new and
custom allocators conform to the C++ standard and throw on allocation failure. By default in Visual Studio, the
compiler pessimistically generates null checks (/Zc:throwingNew-) for these calls, because users can link with a
non-throwing implementation of operator new or write custom allocator routines that return null pointers.
Syntax
/Zc:throwingNew[-]
Remarks
Since ISO C++98, the standard has specified that the default operator new throws std::bad_alloc when memory
allocation fails. Versions of Visual C++ up to Visual Studio 6.0 returned a null pointer on an allocation failure.
Beginning in Visual Studio 2002, operator new conforms to the standard and throws on failure. To support code
that uses the older allocation style, Visual Studio provides a linkable implementation of operator new in
nothrownew.obj that returns a null pointer on failure. By default, the compiler also generates defensive null checks
to prevent these older-style allocators from causing an immediate crash on failure. The /Zc:throwingNew option
tells the compiler to leave out these null checks, on the assumption that all linked memory allocators conform to
the standard. This does not apply to explicit non-throwing operator new overloads, which are declared by using an
additional parameter of type std::nothrow_t and have an explicit noexcept specification.
Conceptually, to create an object on the free store, the compiler generates code to allocate its memory and then to
invoke its constructor to initialize the memory. Because the MSVC compiler normally cannot tell if this code will be
linked to a non-conforming, non-throwing allocator, by default it also generates a null check before calling the
constructor. This prevents a null pointer dereference in the constructor call if a non-throwing allocation fails. In
most cases, these checks are unnecessary, because the default operator new allocators throw instead of returning
null pointers. The checks also have unfortunate side effects. They bloat the code size, they flood the branch
predictor, and they inhibit other useful compiler optimizations such as devirtualization or const propagation out of
the initialized object. The checks exist only to support code that links to nothrownew.obj or has custom non-
conforming operator new implementations. If you do not use non-conforming operator new , we recommend you
use /Zc:throwingNew to optimize your code.
The /Zc:throwingNew option is off by default, and is not affected by the /permissive- option.
If you compile by using link-time code generation (LTCG ), you do not need to specify /Zc:throwingNew. When
your code is compiled by using LTCG, the compiler can detect if the default, conforming operator new
implementation is used. If so, the compiler leaves out the null checks automatically. The linker looks for the
/ThrowingNew flag to tell if the implementation of operator new is conforming. You can specify this flag to the
linker by including this directive in the source for your custom operator new implementation:
For more information about conformance issues in Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development
environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. From the Configuration drop down menu, choose All Configurations.
3. Select the Configuration Properties > C/C++ > Command Line property page.
4. Modify the Additional Options property to include /Zc:throwingNew or /Zc:throwingNew- and then
choose OK.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zc (Conformance)
noexcept (C++)
Exception Specifications (throw ) (C++)
terminate (exception)
/Zc:trigraphs (Trigraphs Substitution)
3/12/2019 • 2 minutes to read • Edit Online
When /Zc:trigraphs is specified, the compiler replaces a trigraph character sequence by using a corresponding
punctuation character.
Syntax
/Zc:trigraphs[-]
Remarks
A trigraph consists of two consecutive question marks ("??") followed by a unique third character. The C language
standard supports trigraphs for source files that use a character set that does not contain convenient graphic
representations for some punctuation characters. For example, when trigraphs are enabled, the compiler replaces
the "??=" trigraph by using the '#' character. Through C++14, trigraphs are supported as in C. The C++17
standard removes trigraphs from the C++ language. In C++ code, the /Zc:trigraphs compiler option enables
substitution of trigraph sequences by the corresponding punctuation character. /Zc:trigraphs- disables trigraph
substitution.
The /Zc:trigraphs option is off by default, and the option is not affected when the /permissive- option is specified.
For a list of C/C++ trigraphs, and an example that shows how to use trigraphs, see Trigraphs.
See also
/Zc (Conformance)
Trigraphs
/Zc:twoPhase- (disable two-phase name lookup)
3/12/2019 • 6 minutes to read • Edit Online
When the /Zc:twoPhase- option is specified, the compiler parses and instantiates class templates and function
templates in the same non-conforming way as versions of Visual Studio before Visual Studio 2017 version 15.3.
Syntax
/Zc:twoPhase-
Remarks
In Visual Studio 2017 version 15.3 and later, by default, the compiler uses two-phase name lookup for template
name resolution. If /Zc:twoPhase- is specified, the compiler reverts to its previous non-conforming class template
and function template name resolution and substitution behavior.
The /Zc:twoPhase- option to enable non-conforming behavior is not set by default. The /permissive- option
implicitly sets the conforming two-phase lookup compiler behavior, but it can be overridden by using
/Zc:twoPhase-.
The Windows SDK header files in version 10.0.15063.0 (Creators Update or Redstone 2) and earlier versions do
not work correctly in conformance mode. You must use /Zc:twoPhase- to compile code for those SDK versions
when you use Visual Studio 2017 version 15.3 and later versions. Versions of the Windows SDK starting with
version 10.0.15254.0 (Redstone 3 or Fall Creators Update) work correctly in conformance mode and do not require
the /Zc:twoPhase- option.
Use /Zc:twoPhase- if your code requires the old behavior to compile correctly. Strongly consider updating your
code to conform to the standard.
Compiler behavior under /Zc:twoPhase -
In versions of the compiler before Visual Studio 2017 version 15.3, and when /Zc:twoPhase- is specified, the
compiler uses this behavior:
It parses only the template declaration, the class head, and the base class list. The template body is captured
as a token stream. No function bodies, initializers, default arguments, or noexcept arguments are parsed.
The class template is pseudo-instantiated on a tentative type to validate that the declarations in the class
template are correct. Consider this class template:
The template declaration, template <typename T >, the class head class Derived , and the base-class list
public Base<T> are parsed, but the template body is captured as a token stream.
When parsing a function template, the compiler parses only the function signature. The function body is
never parsed. Instead, it is captured as a token stream.
As a result, if the template body has syntax errors and the template is never instantiated, the errors are never
diagnosed.
Another effect of this behavior is in overload resolution. Because of the way the token stream is expanded at the
site of instantiation, symbols that were not visible at the template declaration may be visible at the point of
instantiation and participate in overload resolution. This can lead to templates that change behavior based on code
that was not visible when the template was defined, contrary to the standard.
For example, consider this code:
#include <cstdio>
int main()
{
g(3.14);
}
When compiled under /Zc:twoPhase-, this program prints "The call resolves to int". In conformance mode under
/permissive-, this program prints "The call resolves to void*", because the second overload of func is not visible
when the compiler encounters the template.
Dependent names, names that depend on a template parameter, have lookup behavior that is also different under
/Zc:twoPhase-. In conformance mode, dependent names are not bound at the point of the template’s definition.
Instead, these names are looked up when the template is instantiated. For function calls with a dependent function
name, the name is bound to the set of functions that are visible at the point of the call in the template’s definition,
as above. Additional overloads from argument-dependent lookup are added at both the point of the template
definition and the point of where the template is instantiated. The two phases of two-phase lookup are the lookup
for non-dependent names at the time of template definition, and lookup for dependent names at the time of
template instantiation. Under /Zc:twoPhase-, the compiler does not do argument-dependent lookup separately
from ordinary, unqualified lookup (that is, it doesn't do two-phase lookup), so the results of overload resolution
may be different.
Here's another example:
// zctwophase1.cpp
// Compile by using
// cl /EHsc /W4 /permissive- zctwophase1.cpp
// cl /EHsc /W4 /permissive- /Zc:twoPhase- zctwophase1.cpp
#include <cstdio>
namespace NS {
struct S {};
void func(S) { std::puts("NS::func(NS::S)"); }
}
int main() {
tfunc(1729);
NS::S s;
tfunc(s);
}
func(long)
NS::func(NS::S)
func(int)
NS::func(NS::S)
In conformance mode under /permissive-, the call tfunc(1729) resolves to the void func(long) overload, not
void func(int) overload as under /Zc:twoPhase -, because the unqualified func(int) is declared after the
definition of the template and not found through argument-dependent lookup. But void func(S) does participate
in argument-dependent lookup, so it is added to the overload set for the call tfunc(s) even though it is declared
after the template function.
Update your code for two -phase conformance
Older versions of the compiler do not require the keywords template and typename everywhere the C++
Standard requires them. These keywords are needed in some positions to disambiguate how compilers should
parse a dependent name during the first phase of lookup. For example:
T::Foo<a || b>(c);
A conforming compiler parses Foo as a variable in the scope of T , meaning this code is a logical-or expression
with T::foo < a as the left operand and b > (c) as the right operand. If you mean to use Foo as a function
template, you must indicate that this is a template by adding the template keyword:
T::template Foo<a || b>(c);
In versions prior to Visual Studio 2017 version 15.3, and when /Zc:twoPhase- is specified, the compiler allows
this code without the template keyword and interprets it as a call to a function template with an argument of
a || b , because it parses templates in a very limited fashion. The code above isn't parsed at all in the first phase.
During the second phase there’s enough context to tell that T::Foo is a template rather than a variable so the
compiler does not enforce use of the keyword.
This behavior can also be seen by eliminating the keyword typename before names in function template bodies,
initializers, default arguments, and noexcept arguments. For example:
template<typename T>
typename T::TYPE func(typename T::TYPE*)
{
/* typename */ T::TYPE i;
}
If you do not use the keyword typename in the function body, this code compiles under /Zc:twoPhase-, but not
under /permissive-. The typename keyword is required to indicate that the TYPE is dependent. Because the body
is not parsed under /Zc:twoPhase-, the compiler does’t require the keyword. In /permissive- conformance mode,
code without the typename keyword generates errors. To migrate your code to Visual Studio 2017 version 15.3
and beyond, insert the typename keyword where it is missing.
Similarly, consider this code sample:
template<typename T>
typename T::template X<T>::TYPE func(typename T::TYPE)
{
typename T::/* template */ X<T>::TYPE i;
}
Under /Zc:twoPhase- and in older compilers, the compiler only requires the template keyword on line 2. By
default, and in conformance mode, the compiler now also requires the template keyword on line 4 to indicate that
T::X<T> is a template. Look for code that is missing this keyword, and supply it to make your code conform to the
standard.
For more information about conformance issues, see C++ conformance improvements in Visual Studio and
Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zc:twoPhase- and then choose OK.
See also
/Zc (Conformance)
/Zc:wchar_t (wchar_t Is Native Type)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Zc:wchar_t[-]
Remarks
If /Zc:wchar_t is on, wchar_t is a keyword for a built-in integral type in code compiled as C++. If /Zc:wchar_t-
(with a minus sign) is specified, or in code compiled as C, wchar_t is not a built-in type. Instead, wchar_t is
defined as a typedef for unsigned short in the canonical header stddef.h. (The Microsoft implementation defines
it in another header that is included by stddef.h and other standard headers.)
We do not recommend /Zc:wchar_t- because the C++ standard requires that wchar_t be a built-in type. Using
the typedef version can cause portability problems. If you upgrade from earlier versions of Visual C++ and
encounter compiler error C2664 because the code is trying to implicitly convert a wchar_t to unsigned short , we
recommend that you change the code to fix the error, instead of setting /Zc:wchar_t-.
The /Zc:wchar_t option is on by default in C++ compilations, and is ignored in C compilations. The /permissive-
option does not affect /Zc:wchar_t.
Microsoft implements wchar_t as a two-byte unsigned value. It maps to the Microsoft-specific native type
__wchar_t . For more information about wchar_t , see Data Type Ranges and Fundamental Types.
If you write new code that has to interoperate with older code that still uses the typedef version of wchar_t , you
can provide overloads for both the unsigned short and __wchar_t variations of wchar_t , so that your code can
be linked with code compiled with /Zc:wchar_t or code compiled without it. Otherwise, you would have to
provide two different builds of the library, one with and one without /Zc:wchar_t enabled. Even in this case, we
recommend that you build the older code by using the same compiler that you use to compile the new code.
Never mix binaries compiled with different compilers.
When /Zc:wchar_t is specified, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED symbols are
defined. For more information, see Predefined Macros.
If your code uses the compiler COM global functions, because /Zc:wchar_t is now on by default, we recommend
that you change explicit references to comsupp.lib (either from the comment pragma or on the command line) to
either comsuppw.lib or comsuppwd.lib. (If you must compile with /Zc:wchar_t-, use comsupp.lib.) If you include
the comdef.h header file, the correct library is specified for you. For information about compiler COM support, see
Compiler COM Support.
The wchar_t built-in type is not supported when you compile C code. For more information about conformance
issues with Visual C++, see Nonstandard Behavior.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Language page.
3. Modify the Treat wchar_t as Built-in Type property.
To set this compiler option programmatically
See TreatWChar_tAsBuiltInType.
See also
/Zc (Conformance)
/Zf (Faster PDB generation)
3/12/2019 • 2 minutes to read • Edit Online
Enable faster PDB generation in parallel builds by minimizing RPC calls to mspdbsrv.exe.
Syntax
/Zf
Remarks
The /Zf option enables compiler support for faster generation of PDB files when using the /MP (Build with
Multiple Processes) option, or when the build system (for example, MSBuild or CMake) may run multiple cl.exe
compiler processes at the same time. This option causes the compiler front end to delay generation of type
indexes for each type record in the PDB file until the end of compilation, then requests them all in a single RPC
call to mspdbsrv.exe, instead of making an RPC request for each record. This can substantially improve build
throughput by reducing the RPC load on the mspdbsrv.exe process in an environment where multiple cl.exe
compiler processes run simultaneously.
Because the /Zf option only applies to PDB generation, it requires the /Zi or /ZI option.
The /Zf option is available beginning in Visual Studio 2017 version 15.1, where it is off by default. Starting in
Visual Studio 2017 version 15.7 Preview 3, this option is on by default when the /Zi or /ZI option is enabled.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > C/C++ > Command Line property page.
3. Modify the Additional Options property to include /Zf and then choose OK.
See also
Compiler Options Listed Alphabetically
/MP (Build with Multiple Processes)
/Zg (Generate Function Prototypes)
3/12/2019 • 2 minutes to read • Edit Online
Removed. Creates a function prototype for each function defined in the source file, but does not compile the
source file.
Syntax
/Zg
Remarks
This compiler option is no longer available. It was removed in Visual C++ 2015. This page remains for users of
older versions of Visual C++.
The function prototype includes the function return type and an argument type list. The argument type list is
created from the types of the formal parameters of the function. Any function prototypes already present in the
source file are ignored.
The list of prototypes is written to standard output. You may find this list helpful to verify that actual arguments
and formal parameters of a function are compatible. You can save the list by redirecting standard output to a file.
Then you can use #include to make the list of function prototypes a part of your source file. Doing so causes the
compiler to perform argument type checking.
If you use the /Zg option and your program contains formal parameters that have struct, enum, or union type (or
pointers to such types), the declaration of each struct, enum, or union type must have a tag (name). In the
following sample, the tag name is MyStruct .
// Zg_compiler_option.c
// compile with: /Zg
typedef struct MyStruct { int i; } T2;
void f2(T2 * t) {}
The /Zg option was deprecated in Visual Studio 2005 and has been removed in Visual Studio 2015. The MSVC
compiler has removed support for older, C -style code. For a list of deprecated compiler options, see Deprecated
and Removed Compiler Options in Compiler Options Listed by Category.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zl (Omit Default Library Name)
3/12/2019 • 2 minutes to read • Edit Online
Omits the default C runtime library name from the .obj file. By default, the compiler puts the name of the library
into the .obj file to direct the linker to the correct library.
Syntax
/Zl
Remarks
For more information on the default library, see Use Run-Time Library.
You can use /Zl to compile .obj files you plan to put into a library. Although omitting the library name saves only a
small amount of space for a single .obj file, the total space saved is significant in a library that contains many
object modules.
This option is an advanced option. Setting this option removes certain C Runtime library support that may be
required by your application, resulting in link-time errors if your application depends on this support. If you use
this option you must provide the required components in some other way.
Use /NODEFAULTLIB (Ignore Libraries). to direct the linker to ignore library references in all .obj files.
For more information, see CRT Library Features.
When compiling with /Zl, _VC_NODEFAULTLIB is defined. For example:
// vc_nodefaultlib.cpp
// compile with: /Zl
void Test() {
#ifdef _VC_NODEFAULTLIB
int i;
#endif
int i; // C2086
}
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zm (Specify Precompiled Header Memory
Allocation Limit)
3/12/2019 • 2 minutes to read • Edit Online
Determines the amount of memory that the compiler allocates to construct precompiled headers.
Syntax
/Zmfactor
Arguments
factor
A scaling factor that determines the amount of memory that the compiler uses to construct precompiled headers.
The factor argument is a percentage of the default size of a compiler-defined work buffer. The default value of
factor is 100 (percent), but you can specify larger or smaller amounts.
Remarks
In versions before Visual Studio 2015, the C++ compiler used several discrete heaps, and each had a finite limit.
Currently, the compiler dynamically grows the heaps as necessary up to a total heap size limit, and allows the
precompiled header to comprise multiple address ranges. Consequently, the /Zm compiler option is rarely
necessary.
If the compiler runs out of heap space and emits the C1060 error message when you use the /Zm compiler
option, you might have reserved too much memory. Consider removing the /Zm option.
If the compiler emits the C1076 error message, an accompanying C3859 message specifies the factor argument
to use when you recompile by using the /Zm compiler option. This message is only significant when a
precompiled header uses #pragma hdrstop . In other cases, it is a spurious error caused by Windows virtual
memory pressure issues, and the recommendation to use the /Zm option should be ignored. Instead, consider
reducing the number of parallel processes when using the /maxcpucount option to MSBUILD.EXE in
conjunction with the /MP option to CL.EXE. For more information, see Precompiled Header (PCH) issues and
recommendations.
The following table shows how the factor argument affects the memory allocation limit if you assume the size of
the default precompiled header buffer is 75 MB.
10 7.5 MB
100 75 MB
200 150 MB
1000 750 MB
VALUE OF FACTOR MEMORY ALLOCATION LIMIT
2000 1500 MB
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zo (Enhance Optimized Debugging)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/Zo[-]
Remarks
The /Zo compiler switch generates enhanced debugging information for optimized code. Optimization may use
registers for local variables, reorder code, vectorize loops, and inline function calls. These optimizations can obscure
the relationship between the source code and the compiled object code. The /Zo switch tells the compiler to
generate additional debugging information for local variables and inlined functions. Use it to see variables in the
Autos, Locals, and Watch windows when you step through optimized code in the Visual Studio debugger. It also
enables stack traces to show inlined functions in the WinDBG debugger. Debug builds that have disabled
optimizations (/Od) do not need the additional debugging information generated when /Zo is specified. Use the
/Zo switch to debug Release configurations with optimization turned on. For more information on optimization
switches, see /O Options (Optimize Code). The /Zo option is enabled by default in Visual Studio when you specify
debugging information with /Zi or /Z7. Specify /Zo- to explicitly disable this compiler option.
The /Zo switch is available starting in Visual Studio 2013 Update 3, and it replaces the previously undocumented
/d2Zi+ switch.
To set the /Zo compiler option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Select the Configuration Properties, C/C++ folder.
3. Select the Command Line property page.
4. Modify the Additional Options property to include /Zo and then choose OK.
To set this compiler option programmatically
See AdditionalOptions.
See also
/O Options (Optimize Code)
/Z7, /Zi, /ZI (Debug Information Format)
Edit and Continue
/Zp (Struct Member Alignment)
3/12/2019 • 2 minutes to read • Edit Online
Controls how the members of a structure are packed into memory and specifies the same packing for all
structures in a module.
Syntax
/Zp[1|2|4|8|16]
Remarks
When you specify the /Zpn option, each structure member after the first is stored on either the size of the
member type or n-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.
The available packing values are described in the following table:
You should not use this option unless you have specific alignment requirements.
WARNING
C++ headers in the Windows SDK assume /Zp8 packing. Memory corruption may occur if the /Zp setting is changed when
using Windows SDK headers.
You can also use pack to control structure packing. For more information about alignment, see:
align
__alignof Operator
__unaligned
/ALIGN (Section Alignment)
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the C/C++ > Code Generation property page.
3. Modify the Struct Member Alignment property.
To set this compiler option programmatically
See StructMemberAlignment.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zs (Syntax Check Only)
3/12/2019 • 2 minutes to read • Edit Online
Tells the compiler to check only the syntax of the source files on the command line.
Syntax
/Zs
Remarks
When using this option, no output files are created, and error messages are written to standard output.
The /Zs option provides a quick way to find and correct syntax errors before you compile and link a source file.
To set this compiler option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the C/C++ folder.
3. Click the Command Line property page.
4. Type the compiler option in the Additional Options box.
To set this compiler option programmatically
See AdditionalOptions.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/ZW (Windows Runtime Compilation)
3/12/2019 • 2 minutes to read • Edit Online
Compiles source code to support Visual C++ component extensions C++/CX for the creation of Universal
Windows Platform (UWP ) apps.
When you use /ZW to compile, always specify /EHsc as well.
Syntax
/ZW /EHsc
/ZW:nostdlib /EHsc
Arguments
nostdlib
Indicates that Platform.winmd, Windows.Foundation.winmd, and other default Windows metadata (.winmd) files
are not automatically included in the compilation. Instead, you must use the /FU (Name Forced #using File)
compiler option to explicitly specify Windows metadata files.
Remarks
When you specify the /ZW option, the compiler supports these features:
The required metadata files, namespaces, data types, and functions that your app requires to execute in the
Windows Runtime.
Automatic reference-counting of Windows Runtime objects, and automatic discarding of an object when its
reference count goes to zero.
Because the incremental linker does not support the Windows metadata included in .obj files by using the /ZW
option, the /Gm (Enable Minimal Rebuild) option is incompatible with /ZW.
For more information, see Visual C++ Language Reference.
Requirements
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Unicode Support in the Compiler and Linker
3/12/2019 • 2 minutes to read • Edit Online
Most Visual C++ build tools support Unicode inputs and outputs.
Filenames
Filenames specified on the command line or in compiler directives (such as #include ) may contain Unicode
characters.
Output
During compilation, the compiler outputs diagnostics to the console in UTF -16. The characters that can be
displayed at your console depend on the console window properties. Compiler output redirected to a file is in the
current ANSI console codepage.
See also
Use the MSVC toolset from the command line
Linking
3/12/2019 • 4 minutes to read • Edit Online
In a C++ project, the linking step is performed after the compiler has compiled the source code into
object files (*.obj). The linker (link.exe) combines the object files into a single executable file.
Linker options can be set inside or outside of Visual Studio. Within Visual Studio, you access linker
options by right-clicking on a project node in Solution Explorer and choosing Properties to display
the property pages. Choose Linker in the left pane to expand the node and see all the options.
LINK arguments
The arguments include options and filenames and can be specified in any order. Options are
processed first, then files. Use one or more spaces or tabs to separate arguments.
NOTE
You can start this tool only from the Visual Studio command prompt. You cannot start it from a system
command prompt or from File Explorer.
Command line
On the command line, an option consists of an option specifier, either a dash (-) or a forward slash (/),
followed by the name of the option. Option names cannot be abbreviated. Some options take an
argument, specified after a colon (:). No spaces or tabs are allowed within an option specification,
except within a quoted string in the /COMMENT option. Specify numeric arguments in decimal or C -
language notation. Option names and their keyword or filename arguments are not case sensitive,
but identifiers as arguments are case sensitive.
To pass a file to the linker, specify the filename on the command line after the LINK command. You
can specify an absolute or relative path with the filename, and you can use wildcards in the filename.
If you omit the dot (.) and filename extension, LINK assumes .obj for the purpose of finding the file.
LINK does not use filename extensions or the lack of them to make assumptions about the contents
of files; it determines the type of file by examining it, and processes it accordingly.
link.exe returns zero for success (no errors). Otherwise, the linker returns the error number that
stopped the link. For example, if the linker generates LNK1104, the linker returns 1104. Accordingly,
the lowest error number returned on an error by the linker is 1000. A return value of 128 represents
a configuration problem with either the operating system or a .config file; the loader didn’t load either
link.exe or c2.dll.
LINK @commandfile
The commandfile is the name of a text file. No space or tab is allowed between the at sign (@) and
the filename. There is no default extension; you must specify the full filename, including any
extension. Wildcards cannot be used. You can specify an absolute or relative path with the filename.
LINK does not use an environment variable to search for the file.
In the command file, arguments can be separated by spaces or tabs (as on the command line) and by
newline characters.
You can specify all or part of the command line in a command file. You can use more than one
command file in a LINK command. LINK accepts the command-file input as if it were specified in that
location on the command line. Command files cannot be nested. LINK echoes the contents of
command files, unless the /NOLOGO option is specified.
Example
The following command to build a DLL passes the names of object files and libraries in separate
command files and uses a third command file for specification of the /EXPORTS option:
LINK.exe links Common Object File Format (COFF ) object files and libraries to create an executable
(.exe) file or a dynamic-link library (DLL ).
The following table lists options for LINK.exe. For more information about LINK, see:
Compiler-Controlled LINK Options
LINK Input Files
LINK Output
Reserved Words
On the command line, linker options are not case-sensitive; for example, /base and /BASE mean
the same thing. For details on how to specify each option on the command line or in Visual Studio,
see the documentation for that option.
You can use the comment pragma to specify some linker options.
OPTION PURPOSE
/IDLOUT Specifies the name of the .idl file and other MIDL
output files.
/SUBSYSTEM Tells the operating system how to run the .exe file.
/TLBOUT Specifies the name of the .tlb file and other MIDL
output files.
See also
C/C++ Building Reference
MSVC linker reference
Compiler-Controlled LINK Options
3/12/2019 • 2 minutes to read • Edit Online
The CL compiler automatically calls LINK unless you specify the /c option. CL provides some control over the
linker through command-line options and arguments. The following table summarizes the features in CL that
affect linking.
Any file name extension other than .c, .cxx, .cpp, or .def Passes a file name as input to LINK
/MDd or /MTd Places a default library name in the .obj file. Defines the
symbol _DEBUG
See also
MSVC linker reference
MSVC Linker Options
LINK Input Files
3/12/2019 • 2 minutes to read • Edit Online
You provide the linker with files that contain objects, import and standard libraries, resources, module definitions,
and command input. LINK does not use file extensions to make assumptions about the contents of a file. Instead,
LINK examines each input file to determine what kind of file it is.
Object files on the command line are processed in the order they appear on the command line. Libraries are
searched in command line order as well, with the following caveat: Symbols that are unresolved when bringing in
an object file from a library are searched for in that library first, and then the following libraries from the
command line and /DEFAULTLIB (Specify Default Library) directives, and then to any libraries at the beginning of
the command line.
NOTE
LINK no longer accepts a semicolon (or any other character) as the start of a comment in response files and order files.
Semicolons are recognized only as the start of comments in module-definition files (.def).
See also
MSVC linker reference
MSVC Linker Options
.Obj Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
The linker tool (LINK.EXE ) accepts .obj files that are in Common Object File Format (COFF ).
Remarks
Microsoft provides a complete description of the common object file format. For more information, see PE Format.
Unicode support
Starting with Visual Studio 2005, the Microsoft MSVC compiler supports Unicode characters in identifiers as
defined by the ISO/IEC C and C++ standards. Previous versions of the compiler supported only ASCII characters
in identifiers. To support Unicode in the names of functions, classes, and statics, the compiler and linker use the
Unicode UTF -8 encoding for COFF symbols in .obj files. The UTF -8 encoding is upwardly compatible with the
ASCII encoding used by earlier versions of Visual Studio.
For more information about the compiler and linker, see Unicode Support in the Compiler and Linker. For more
information about the Unicode standard, see the Unicode organization.
See also
LINK Input Files
MSVC Linker Options
Support for Unicode
Unicode Support in the Compiler and Linker
Unicode standard
PE Format
.netmodule Files as Linker Input
3/12/2019 • 3 minutes to read • Edit Online
link.exe now accepts MSIL .obj and .netmodules as input. The output file produced by the linker is an assembly or
a .netmodule with no run-time dependency on any of the .obj or .netmodules that were input to the linker.
.netmodules are created by the MSVC compiler with /LN (Create MSIL Module) or by the linker with
/NOASSEMBLY (Create a MSIL Module). .objs are always created in a Visual C++ compilation. For other Visual
Studio compilers, use the /target:module compiler option.
You must pass to the linker the .obj file from the Visual C++ compilation that created the .netmodule. Passing in a
.netmodule is no longer supported because the /clr:pure and /clr:safe compiler options are deprecated in Visual
Studio 2015 and unsupported in Visual Studio 2017.
For information on how to invoke the linker from the command line, see Linker Command-Line Syntax, Use the
MSVC toolset from the command line, and Set the Path and Environment Variables for Command-Line Builds.
Passing a .netmodule or .dll file to the linker that was compiled by the MSVC compiler with /clr can result in a
linker error. For more information, see Choosing the Format of .netmodule Input Files.
The linker accepts native .obj files as well as MSIL .obj files compiled with /clr. When passing mixed .objs in the
same build, the verifiability of the resulting output file will, by default, be equal to the lowest level of verifiability
of the input modules.
If you currently have an application that is composed of two or more assemblies and you want the application to
be contained in one assembly, you must recompile the assemblies and then link the .objs or .netmodules to
produce a single assembly.
You must specify an entry point using /ENTRY (Entry-Point Symbol) when creating an executable image.
When linking with an MSIL .obj or .netmodule file, use /LTCG (Link-time Code Generation), otherwise when the
linker encounters the MSIL .obj or .netmodule, it will restart the link with /LTCG.
MSIL .obj or .netmodule files can also be passed to cl.exe.
Input MSIL .obj or .netmodule files cannot have embedded resources. A resource is embedded in an output file
(module or assembly) with /ASSEMBLYRESOURCE (Embed a Managed Resource) linker option or with the
/resource compiler option in other Visual Studio compilers.
When performing MSIL linking, and if you do not also specify /LTCG (Link-time Code Generation), you will see
an informational message reporting that the link is restarting. This message can be ignored, but to improve linker
performance with MSIL linking, explicitly specify /LTCG.
Example
In C++ code the catch block of a corresponding try will be invoked for a non System exception. However, by
default, the CLR wraps non-System exceptions with RuntimeWrappedException. When an assembly is created
from Visual C++ and non-Visual C++ modules and you want a catch block in C++ code to be invoked from its
corresponding try clause when the try block throws a non-System exception, you must add the
[assembly:System::Runtime::CompilerServices::RuntimeCompatibility(WrapNonExceptionThrows=false)] attribute to
the source code for the non C++ modules.
// MSIL_linking.cpp
// compile with: /c /clr
value struct V {};
/*
int main() {
MCPP::Test();
}
*/
Example
By changing the Boolean value of the WrapNonExceptionThrows attribute, you modify the ability of the Visual C++
code to catch a non-System exception.
// MSIL_linking_2.cs
// compile with: /target:module /addmodule:MSIL_linking.obj
// post-build command: link /LTCG MSIL_linking.obj MSIL_linking_2.netmodule /entry:MLinkTest.Main
/out:MSIL_linking_2.exe /subsystem:console
using System.Runtime.CompilerServices;
class MLinkTest {
public static void Main() {
try {
MCPP.Test();
}
catch (RuntimeWrappedException) {
System.Console.WriteLine("caught a wrapped exception in C#");
}
}
}
See also
LINK Input Files
MSVC Linker Options
Choosing the Format of .netmodule Input Files
3/12/2019 • 2 minutes to read • Edit Online
An MSIL .obj file (compiled with /clr) can also be used as a .netmodule file. .obj files contain metadata and native
symbols. .netmodules only contain metadata.
You can pass an MSIL .obj file to any other Visual Studio compiler via the /addmodule compiler option (but be
aware that the .obj file becomes part of the resulting assembly and must be shipped with the assembly). For
example, Visual C# and Visual Basic have the /addmodule compiler option.
NOTE
In most cases, you will need to pass to the linker the .obj file from the compilation that created the .net module. Passing a .dll
or .netmodule MSIL module file to the linker may result in LNK1107.
.obj files, along with their associated .h files, which you reference via #include in source, allow C++ applications to
consume the native types in the module, whereas in a .netmodule file, only the managed types can be consumed
by a C++ application. If you attempt to pass a .obj file to #using, information about native types will not be
available; #include the .obj file's .h file instead.
Other Visual Studio compilers can only consume managed types from a module.
Use the following to determine whether you need to use a .netmodule or a .obj file as module input to the MSVC
linker:
If you are building with a Visual Studio compiler other than Visual C++, produce a .netmodule and use the
.netmodule as input to the linker.
If you are using the MSVC compiler to produce modules and if the module(s) will be used to build
something other than a library, use the .obj files produced by the compiler as module input to the linker; do
not use the .netmodule file as input.
If your modules will be used to build a native (not a managed) library, use .obj files as module input to the
linker and generate a .lib library file.
If your modules will be used to build a managed library, and if all module input to the linker will be
verifiable (produced with /clr:safe), use .obj files as module input to the linker and generate a .dll (assembly)
or .netmodule (module) library file.
If your modules will be used to build a managed library, and if one or more modules input to the linker will
be produced with just /clr, use .obj files as module input to the linker and generate a .dll (assembly). If you
want to expose managed types from the library and if you also want C++ applications to consume the
native types in the library, your library will consist of the .obj files for the libraries component modules (you
will also want to ship the .h files for each module, so they can be referenced with #include from source
code).
See also
.netmodule Files as Linker Input
.Lib Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
LINK accepts COFF standard libraries and COFF import libraries, both of which usually have the extension .lib.
Standard libraries contain objects and are created by the LIB tool. Import libraries contain information about
exports in other programs and are created either by LINK when it builds a program that contains exports or by
the LIB tool. For information on using LIB to create standard or import libraries, see LIB Reference. For details on
using LINK to create an import library, see the /DLL option.
A library is specified to LINK as either a file name argument or a default library. LINK resolves external references
by searching first in libraries specified on the command line, then in default libraries specified with the
/DEFAULTLIB option, and then in default libraries named in .obj files. If a path is specified with the library name,
LINK looks for the library in that directory. If no path is specified, LINK looks first in the directory that LINK is
running from, and then in any directories specified in the LIB environment variable.
Example
The following sample shows how to build and use a .lib file. First, build a .lib file:
// lib_link_input_1.cpp
// compile by using: cl /LD lib_link_input_1.cpp
__declspec(dllexport) int Test() {
return 213;
}
And then, compile this sample by using the .lib file you just created:
// lib_link_input_2.cpp
// compile by using: cl /EHsc lib_link_input_1.lib lib_link_input_2.cpp
__declspec(dllimport) int Test();
#include <iostream>
int main() {
std::cout << Test() << std::endl;
}
213
See also
LINK Input Files
MSVC Linker Options
.Exp Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
Export (.exp) files contain information about exported functions and data items. When LIB creates an import
library, it also creates an .exp file. You use the .exp file when you link a program that both exports to and imports
from another program, either directly or indirectly. If you link with an .exp file, LINK does not produce an import
library, because it assumes that LIB already created one. For details about .exp files and import libraries, see
Working with Import Libraries and Export Files.
See also
LINK Input Files
MSVC Linker Options
.Def Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
See Module-definition (.def) files for more information. Use the /DEF option to specify the .def file name.
See also
LINK Input Files
MSVC Linker Options
.Pdb Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
Object (.obj) files compiled using the /Zi option contain the name of a program database (PDB ). You do not specify
the object's PDB file name to the linker; LINK uses the embedded name to find the PDB if it is needed. This also
applies to debuggable objects contained in a library; the PDB for a debuggable library must be available to the
linker along with the library.
LINK also uses a PDB to hold debugging information for the .exe file or the .dll file. The program's PDB is both an
output file and an input file, because LINK updates the PDB when it rebuilds the program.
See also
LINK Input Files
MSVC Linker Options
.Res Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
You can specify a .res file when linking a program. The .res file is created by the resource compiler (RC ). LINK
automatically converts .res files to COFF. The CVTRES.exe tool must be in the same directory as LINK.exe or in a
directory specified in the PATH environment variable.
See also
LINK Input Files
MSVC Linker Options
.Exe Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
The MS -DOS Stub File Name (/STUB ) option specifies the name of an .exe file that runs with MS -DOS. LINK
examines the specified file to be sure that it is a valid MS -DOS program.
See also
LINK Input Files
MSVC Linker Options
.Txt Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
LINK expects various text files as additional input. The command-file specifier (@) and the Base Address (/BASE ),
/DEF, and /ORDER options all specify text files. These files can have any extension, not just .txt.
See also
LINK Input Files
MSVC Linker Options
.Ilk Files as Linker Input
3/12/2019 • 2 minutes to read • Edit Online
When linking incrementally, LINK updates the .ilk status file that it created during the first incremental link. This
file has the same base name as the .exe file or the .dll file, and it has the extension .ilk. During subsequent
incremental links, LINK updates the .ilk file. If the .ilk file is missing, LINK performs a full link and creates a new .ilk
file. If the .ilk file is unusable, LINK performs a nonincremental link. For details about incremental linking, see the
Link Incrementally (/INCREMENTAL ) option.
See also
LINK Input Files
MSVC Linker Options
LINK Output
3/12/2019 • 2 minutes to read • Edit Online
Output Files
The default output file from LINK is an .exe file. If the /DLL option is specified, LINK builds a .dll file. You can
control the output file name with the Output File Name (/OUT) option.
In incremental mode, LINK creates an .ilk file to hold status information for later incremental builds of the
program. For details about .ilk files, see .ilk Files. For more information about incremental linking, see the Link
Incrementally (/INCREMENTAL ) option.
When LINK creates a program that contains exports (usually a DLL ), it also builds a .lib file, unless an .exp file was
used in the build. You can control the import library file name with the /IMPLIB option.
If the Generate Mapfile (/MAP ) option is specified, LINK creates a mapfile.
If the Generate Debug Info (/DEBUG ) option is specified, LINK creates a PDB to contain debugging information
for the program.
Other Output
When you type link without any other command-line input, LINK displays a usage statement that summarizes its
options.
LINK displays a copyright and version message and echoes command-file input, unless the Suppress Startup
Banner (/NOLOGO ) option is used.
You can use the Print Progress Messages (/VERBOSE ) option to display additional details about the build.
LINK issues error and warning messages in the form LNKnnnn. This error prefix and range of numbers are also
used by LIB, DUMPBIN, and EDITBIN.
See also
MSVC linker reference
MSVC Linker Options
Reserved words
3/12/2019 • 2 minutes to read • Edit Online
The following words are reserved by the linker. These names can be used as arguments in module-definition
statements only if the name is enclosed in double quotation marks ("").
INCLUDE2 OLD1
1 The linker emits a warning ("ignored") when it encounters this term. However, the word is still reserved.
2
2 The linker ignores this word but emits no warning.
See also
MSVC linker reference
MSVC Linker Options
@ (Specify a Linker Response File)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
@response_file
Arguments
response_file
A text file specifying linker commands.
Remarks
See @ (Specify a Compiler Response File) for more information.
To set this linker option in the Visual Studio development environment
This linker option is not available from the Visual Studio development environment.
To set this linker option programmatically
This linker option cannot be changed programmatically.
See also
MSVC linker reference
MSVC Linker Options
/ALIGN (Section Alignment)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/ALIGN [:number]
Arguments
number
The alignment value in bytes.
Remarks
The /ALIGN option specifies the alignment of each section within the linear address space of the program. The
number argument is in bytes and must be a power of two. The default is 4K (4096). The linker issues a warning if
the alignment produces an invalid image.
Unless you are writing an application such as a device driver, you should not need to modify the alignment.
It is possible to modify the alignment of a particular section with the align parameter to the /SECTION option.
The alignment value that you specify cannot be smaller than the largest section alignment.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Choose the Configuration Properties > Linker > Command Line property page.
3. Enter the option in the Additional Options box. Choose OK or Apply to apply the change.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/ALLOWBIND (Prevent DLL Binding)
3/12/2019 • 2 minutes to read • Edit Online
/ALLOWBIND[:NO]
Remarks
/ALLOWBIND:NO sets a bit in a DLL's header that indicates to Bind.exe that the image is not allowed to be bound.
You may not want a DLL to be bound if it has been digitally signed (binding invalidates the signature).
You can edit an existing DLL for /ALLOWBIND functionality with the /ALLOWBIND option of the EDITBIN utility.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand Configuration Properties, Linker, and select Command Line.
3. Enter /ALLOWBIND:NO into Additional Options.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
BindImage function
BindImageEx function
/ALLOWISOLATION (Manifest Lookup)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/ALLOWISOLATION[:NO]
Remarks
/ALLOWISOLATION:NO indicates DLLs are loaded as if there was no manifest and causes the linker to set the
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION bit in the optional header's DllCharacteristics field.
See also
MSVC linker reference
MSVC Linker Options
/APPCONTAINER (Microsoft Store App)
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether the linker creates an executable image that must be run in an app container.
Syntax
/APPCONTAINER[:NO]
Remarks
By default, /APPCONTAINER is off.
This option modifies an executable to indicate whether the app must be run in the appcontainer process-isolation
environment. Specify /APPCONTAINER for an app that must run in the appcontainer environment—for example,
a Universal Windows Platform (UWP ) or Windows Phone 8.x app. (The option is set automatically in Visual Studio
when you create a Universal Windows app from a template.) For a desktop app, specify /APPCONTAINER:NO or
just omit the option.
The /APPCONTAINER option was introduced in Windows 8.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Command Line property page.
5. In Additional Options, enter /APPCONTAINER or /APPCONTAINER:NO .
See also
MSVC linker reference
MSVC Linker Options
/ASSEMBLYDEBUG (Add DebuggableAttribute)
3/12/2019 • 2 minutes to read • Edit Online
/ASSEMBLYDEBUG[:DISABLE]
/ASSEMBLYDEBUG emits the DebuggableAttribute attribute with debug information tracking and disables JIT
optimizations. This is the same as specifying the following attribute in source:
/ASSEMBLYDEBUG:DISABLE emits the DebuggableAttribute attribute but disables the tracking of debug
information and enables JIT optimizations. This is the same as specifying the following attribute in source:
Remarks
It is necessary to explicitly specify that a managed image be debuggable. Using /Zi alone is not sufficient.
Other linker options that affect assembly generation are:
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/DELAYSIGN
/KEYCONTAINER
/KEYFILE
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debug property page.
4. Modify the Debuggable Assembly property.
To set this linker option programmatically
See AssemblyDebug.
See also
MSVC linker reference
MSVC Linker Options
/ASSEMBLYLINKRESOURCE (Link to .NET
Framework Resource)
3/12/2019 • 2 minutes to read • Edit Online
/ASSEMBLYLINKRESOURCE:filename
Arguments
filename
The .NET Framework resource file to which you want to link from the assembly.
Remarks
The /ASSEMBLYLINKRESOURCE option creates a link to a .NET Framework resource in the output file; the
resource file is not placed in the output file. /ASSEMBLYRESOURCE embeds a resource file in the output file.
Linked resources are public in the assembly when created with the linker.
/ASSEMBLYLINKRESOURCE requires that the compilation include /clr; /LN or /NOASSEMBLY is not allowed
with /ASSEMBLYLINKRESOURCE.
If filename is a .NET Framework resource file created, for example, by Resgen.exe or in the development
environment, it can be accessed with members in the System.Resources namespace. For more information, see
System.Resources.ResourceManager. For all other resources, use the GetManifestResource* methods in the
System.Reflection.Assembly class to access the resource at run time.
filename can be any file format. For example, you may want to make a native DLL part of the assembly, so it can
be installed into the Global Assembly Cache and accessed from managed code in the assembly.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/DELAYSIGN
/KEYCONTAINER
/KEYFILE
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/ASSEMBLYMODULE (Add a MSIL Module to the
Assembly)
3/12/2019 • 2 minutes to read • Edit Online
/ASSEMBLYMODULE:filename
Arguments
filename
The module you want to include in this assembly.
Remarks
The /ASSEMBLYMODULE option allows you to add a module reference to an assembly. Type information in the
module will not be available to the assembly program that added the module reference. However, type
information in the module will be available to any program that references the assembly.
Use #using to both add a module reference to an assembly and make the module's type information available to
the assembly program.
For example, consider the following scenario:
1. Create a module with /LN.
2. Use /ASSEMBLYMODULE in a different project to include the module in the current compilation, which
will create an assembly. This project will not reference the module with #using .
3. Any project that references this assembly can now also use types from the module.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYRESOURCE
/DELAYSIGN
/NOASSEMBLY
/KEYFILE
/KEYCONTAINER
The MSVC linker accepts .netmodule files as input and the output file produced by the linker will be an assembly
or .netmodule with no run-time dependence on any of the .netmodules that were input to the linker. For more
information, see .netmodule Files as Linker Input.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Input property page.
4. Modify the Add Module to Assembly property.
To set this linker option programmatically
See AddModuleNamesToAssembly.
See also
MSVC linker reference
MSVC Linker Options
/ASSEMBLYRESOURCE (Embed a Managed
Resource)
3/12/2019 • 2 minutes to read • Edit Online
/ASSEMBLYRESOURCE:filename[,[name][,PRIVATE]]
Parameters
filename
The managed resource you want to embed in this assembly.
name
Optional. The logical name for the resource; the name used to load the resource. The default is the name of the
file.
Optionally, you can specify if the file should be private in the assembly manifest. By default, name is public in the
assembly.
Remarks
Use the /ASSEMBLYRESOURCE option to embed a resource in an assembly.
Resources are public in the assembly when created with the linker. The linker does not allow you to rename the
resource in the assembly.
If filename is a .NET Framework resource (.resources) file created, for example, by the Resource File Generator
(Resgen.exe) or in the development environment, it can be accessed with members in the System.Resources
namespace (see System.Resources.ResourceManager for more information). For all other resources, use the
GetManifestResource* methods in System.Reflection.Assembly class to access the resource at run time.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/DELAYSIGN
/KEYFILE
/KEYCONTAINER
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Input property page.
4. Modify the Embed Managed Resource File property.
To set this linker option programmatically
1. See EmbedManagedResourceFile.
See also
MSVC linker reference
MSVC Linker Options
/BASE (Base Address)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/BASE:{address[,size] | @filename,key}
Remarks
NOTE
For security reasons, Microsoft recommends you use the /DYNAMICBASE option instead of specifying base addresses for
your executables. This generates an executable image that can be randomly rebased at load time by using the address
space layout randomization (ASLR) feature of Windows. The /DYNAMICBASE option is on by default.
The /BASE option sets a base address for the program, overriding the default location for an .exe or DLL file. The
default base address for an .exe file is 0x400000 for 32-bit images or 0x140000000 for 64-bit images. For a DLL,
the default base address is 0x10000000 for 32-bit images or 0x180000000 for 64-bit images. On operating
systems that do not support address space layout randomization (ASLR ), or when the /DYNAMICBASE:NO
option was set, the operating system first attempts to load a program at its specified or default base address. If
sufficient space is not available there, the system relocates the program. To prevent relocation, use the /FIXED
option.
The linker issues an error if address is not a multiple of 64K. You can optionally specify the size of the program;
the linker issues a warning if the program can't fit in the size you specified.
On the command line, another way to specify the base address is by using a base address response file. A base
address response file is a text file that contains the base addresses and optional sizes of all the DLLs your
program will use, and a unique text key for each base address. To specify a base address by using a response file,
use an at sign (@) followed by the name of the response file, filename, followed by a comma, then the key value
for the base address to use in the file. The linker looks for filename in either the specified path, or if no path is
specified, in the directories specified in the LIB environment variable. Each line in filename represents one DLL
and has the following syntax:
The key is a string of alphanumeric characters and is not case sensitive. It is usually the name of a DLL, but it need
not be. The key is followed by a base address in C -language, hexadecimal, or decimal notation and an optional
maximum size. All three arguments are separated by spaces or tabs. The linker issues a warning if the specified
size is less than the virtual address space required by the program. A comment is specified by a semicolon (;) and
can be on the same or a separate line. The linker ignores all text from the semicolon to the end of the line. This
example shows part of such a file:
Another way to set the base address is by using the BASE argument in a NAME or LIBRARY statement. The
/BASE and /DLL options together are equivalent to the LIBRARY statement.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Advanced property page.
3. Modify the Base Address property.
To set this linker option programmatically
See BaseAddress.
See also
MSVC linker reference
MSVC Linker Options
/CETCOMPAT (Control-flow Enforcement Technology
compatible)
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether to mark an executable image as compatible with Control-flow Enforcement Technology (CET).
Syntax
/CETCOMPAT[:NO ]
Arguments
NO
Specifies that the executable should not be marked compatible with CET.
Remarks
Control-flow Enforcement Technology (CET) is a computer processor feature that provides capabilities to defend
against certain kinds of malware attacks. For more information, see Intel Control-flow Enforcement Technology
Preview.
The /CETCOMPAT linker option tells the linker to mark the binary as CET-compatible. /CETCOMPAT:NO marks
the binary as not compatible with CET. If both options are specified on the command line, the last one specified is
used. This switch is currently only applicable to x86 and x64 architectures.
The /CETCOMPAT option is available beginning in the Visual Studio 2019 Preview 3 toolset.
To set the /CETCOMPAT linker option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Working with Project
Properties.
2. Select the Configuration Properties > Linker > Command Line property page.
3. In the Additional options box, add /CETCOMPAT or /CETCOMPAT:NO and then choose OK or Apply
to save your changes.
To set this linker option programmatically
This option does not have a programmatic equivalent.
See also
Linker Options
/CGTHREADS (Compiler Threads)
3/12/2019 • 2 minutes to read • Edit Online
Sets the number of cl.exe threads to use for optimization and code generation when link-time code generation is
specified.
Syntax
/CGTHREADS:[1-8]
Arguments
number
The maximum number of threads for cl.exe to use, in the range 1 to 8.
Remarks
The /CGTHREADS option specifies the maximum number of threads cl.exe uses in parallel for the optimization
and code-generation phases of compilation when link-time code generation (/LTCG ) is specified. By default, cl.exe
uses four threads, as if /CGTHREADS:4 were specified. If more processor cores are available, a larger number
value can improve build times.
Multiple levels of parallelism can be specified for a build. The msbuild.exe switch /maxcpucount specifies the
number of MSBuild processes that can be run in parallel. The /MP (Build with Multiple Processes) compiler flag
specifies the number of cl.exe processes that simultaneously compile the source files. The /cgthreads compiler
option specifies the number of threads used by each cl.exe process. Because the processor can only run as many
threads at the same time as there are processor cores, it's not useful to specify larger values for all of these options
at the same time, and it can be counterproductive. For more information about how to build projects in parallel, see
Building Multiple Projects in Parallel.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties, Linker folder.
3. Select the Command Line property page.
4. Modify the Additional Options property to include /CGTHREADS: number , where number is a value from
1 to 8, and then choose OK.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC Linker Options
MSVC linker reference
/CLRIMAGETYPE (Specify Type of CLR Image)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/CLRIMAGETYPE:{IJW|PURE|SAFE|SAFE32BITPREFERRED }
Remarks
The linker accepts native objects and also MSIL objects that are compiled by using /clr. The /clr:pure and
/clr:safe compiler options were deprecated in Visual Studio 2015 and are unsupported in Visual Studio 2017.
When mixed objects in the same build are passed, the verifiability of the resulting output file is, by default, equal to
the lowest level of verifiability of the input modules. For example, if you pass a native image and a mixed mode
image (compiled by using /clr), the resulting image will be a mixed mode image.
You can use /CLRIMAGETYPE to specify a lower level of verifiability, if that is what you need.
For information about how to determine the CLR image type of a file, see /CLRHEADER.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Advanced property page.
5. Modify the CLR Image Type property.
To set this linker option programmatically
1. See CLRImageType.
See also
MSVC linker reference
MSVC Linker Options
/CLRSUPPORTLASTERROR (Preserve Last Error
Code for PInvoke Calls)
3/12/2019 • 2 minutes to read • Edit Online
/CLRSUPPORTLASTERROR, which is on by default, preserves the last error code of functions called through the
P/Invoke mechanism, which allows you to call native functions in DLLS, from code compiled with /clr.
Syntax
/CLRSUPPORTLASTERROR{:NO | SYSTEMDLL}
Remarks
Preserving the last error code implies a decrease in performance. If you do not want to incur the performance
impact of preserving the last error code, link with /CLRSUPPORTLASTERROR:NO.
You can minimize the performance impact by linking with /CLRSUPPORTLASTERROR:SYSTEMDLL, which
only preserves the last error code for functions in system DLLs. A system DLL is defined as one of the following:
NOTE
Preserving the last error is not supported for unmanaged functions that are consumed by CLR code, in the same module.
Example
The following sample defines a native DLL with one exported function that modifies last error.
// CLRSUPPORTLASTERROR_dll.cpp
// compile with: /LD
#include <windows.h>
#include <math.h>
#pragma unmanaged
__declspec(dllexport) double MySqrt(__int64 n) {
SetLastError(DWORD(-1));
return sqrt(double(n));
}
Example
The following sample consumes the DLL, demonstrating how to use /CLRSUPPORTLASTERROR.
// CLRSUPPORTLASTERROR_client.cpp
// compile with: /clr CLRSUPPORTLASTERROR_dll.lib /link /clrsupportlasterror:systemdll
// processor: x86
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <math.h>
#pragma managed
int main() {
double d = 0.0;
__int64 n = 65;
HANDLE hGroup = NULL;
GROUPID groupID;
DWORD dwSet = 127, dwGet = 37;
SetLastError(dwSet);
d = MySqrt(n);
dwGet = GetLastError();
if (dwGet == DWORD(-1))
printf_s("GetLastError for application call succeeded (%d).\n",
dwGet);
else
printf_s("GetLastError for application call failed (%d).\n",
dwGet);
See also
MSVC linker reference
MSVC Linker Options
/CLRTHREADATTRIBUTE (Set CLR Thread Attribute)
3/12/2019 • 2 minutes to read • Edit Online
Explicitly specify the threading attribute for the entry point of your CLR program.
Syntax
/CLRTHREADATTRIBUTE:{STA|MTA|NONE}
Parameters
MTA
Applies the MTAThreadAttribute attribute to the entry point of your program.
NONE
Same as not specifying /CLRTHREADATTRIBUTE. Lets the Common Language Runtime (CLR ) set the default
threading attribute.
STA
Applies the STAThreadAttribute attribute to the entry point of your program.
Remarks
Setting the thread attribute is only valid when building an .exe, as it affects the entry point of the main thread.
If you use the default entry point (main or wmain, for example) specify the threading model either by using
/CLRTHREADATTRIBUTE or by placing the threading attribute (STAThreadAttribute or MTAThreadAttribute) on
the default entry function.
If you use a non-default entry point, specify the threading model either by using /CLRTHREADATTRIBUTE or by
placing the threading attribute on the non-default entry function, and then specify the non-default entry point with
/ENTRY.
If the threading model specified in source code does not agree with the threading model specified with
/CLRTHREADATTRIBUTE, the linker will ignore /CLRTHREADATTRIBUTE and apply the threading model
specified in source code.
It will be necessary for you to use single-threading, for example, if your CLR program hosts a COM object that
uses single-threading. If your CLR program uses multi-threading, it cannot host a COM object that uses single-
threading.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Advanced property page.
5. Modify the CLR Thread Attribute property.
To set this linker option programmatically
1. See CLRThreadAttribute.
See also
MSVC linker reference
MSVC Linker Options
/CLRUNMANAGEDCODECHECK (Remove
SuppressUnmanagedCodeSecurityAttribute)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/CLRUNMANAGEDCODECHECK[:NO ]
Remarks
By default, the linker applies the SuppressUnmanagedCodeSecurityAttribute to linker-generated PInvoke
calls. When /CLRUNMANAGEDCODECHECK is in effect, SuppressUnmanagedCodeSecurityAttribute is
removed. To explicitly apply the SuppressUnmanagedCodeSecurityAttribute to linker-generated PInvoke
calls, you can use /CLRUNMANAGEDCODECHECK:NO.
The linker only adds the attribute to objects that are compiled using /clr or /clr:pure. However, the /clr:pure
compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
A PInvoke call is generated by the linker when the linker cannot find a managed symbol to satisfy a reference
from a managed caller but can find a native symbol to satisfy that reference. For more information about PInvoke ,
see Calling Native Functions from Managed Code.
Note that if you use AllowPartiallyTrustedCallersAttribute in your code, you should explicitly set
/CLRUNMANAGEDCODECHECK to remove the SuppressUnmanagedCodeSecurity attribute. It is a
potential security vulnerability if an image contains both the SuppressUnmanagedCodeSecurity and
AllowPartiallyTrustedCallers attributes.
See Secure Coding Guidelines for Unmanaged Code for more information about the implications of using
SuppressUnmanagedCodeSecurityAttribute.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Advanced property page.
5. Modify the CLR Unmanaged Code Check property.
To set this linker option programmatically
1. See CLRUnmanagedCodeCheck.
See also
MSVC linker reference
MSVC Linker Options
/DEBUG (Generate Debug Info)
3/12/2019 • 3 minutes to read • Edit Online
/DEBUG[:{FASTLINK|FULL|NONE}]
Remarks
The /DEBUG option creates debugging information for the executable.
The linker puts the debugging information into a program database (PDB ) file. It updates the PDB during
subsequent builds of the program.
An executable (.exe file or DLL ) created for debugging contains the name and path of the corresponding PDB.
The debugger reads the embedded name and uses the PDB when you debug the program. The linker uses the
base name of the program and the extension .pdb to name the program database, and embeds the path where it
was created. To override this default, set /PDB and specify a different file name.
The /DEBUG:FASTLINK option is available in Visual Studio 2017 and later. This option leaves private symbol
information in the individual compilation products used to build the executable. It generates a limited PDB that
indexes into the debug information in the object files and libraries used to build the executable instead of making
a full copy. This option can link from two to four times as fast as full PDB generation, and is recommended when
you are debugging locally and have the build products available. This limited PDB can't be used for debugging
when the required build products are not available, such as when the executable is deployed on another
computer. In a developer command prompt, you can use the mspdbcmf.exe tool to generate a full PDB from this
limited PDB. In Visual Studio, use the Project or Build menu items for generating a full PDB file to create a full
PDB for the project or solution.
The /DEBUG:FULL option moves all private symbol information from individual compilation products (object
files and libraries) into a single PDB, and can be the most time-consuming part of the link. However, the full PDB
can be used to debug the executable when no other build products are available, such as when the executable is
deployed.
The /DEBUG:NONE option does not generate a PDB.
When you specify /DEBUG with no additional options, the linker defaults to /DEBUG:FULL for command line
and makefile builds, for release builds in the Visual Studio IDE, and for both debug and release builds in Visual
Studio 2015 and earlier versions. Beginning in Visual Studio 2017, the build system in the IDE defaults to
/DEBUG:FASTLINK when you specify the /DEBUG option for debug builds. Other defaults are unchanged to
maintain backward compatibility.
The compiler's C7 Compatible (/Z7) option causes the compiler to leave the debugging information in the .obj
files. You can also use the Program Database (/Zi) compiler option to store the debugging information in a PDB
for the .obj file. The linker looks for the object's PDB first in the absolute path written in the .obj file, and then in
the directory that contains the .obj file. You cannot specify an object's PDB file name or location to the linker.
/INCREMENTAL is implied when /DEBUG is specified.
/DEBUG changes the defaults for the /OPT option from REF to NOREF and from ICF to NOICF, so if you want
the original defaults, you must explicitly specify /OPT:REF or /OPT:ICF.
It is not possible to create an .exe or .dll that contains debug information. Debug information is always placed in a
.obj or .pdb file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debugging property page.
4. Modify the Generate Debug Info property to enable PDB generation. This enables /DEBUG:FASTLINK
by default in Visual Studio 2017.
5. Modify the Generate Full Program Database File property to enable /DEBUG:FULL for full PDB
generation for every incremental build.
To set this linker option programmatically
1. See GenerateDebugInformation.
See also
MSVC linker reference
MSVC Linker Options
/DEBUGTYPE (Debug Info Options)
3/12/2019 • 2 minutes to read • Edit Online
The /DEBUGTYPE option specifies the types of debugging information generated by the /DEBUG option.
Arguments
CV
Tells the linker to emit debug information for symbols, line numbers, and other object compilation information in
the PDB file. By default, this option is enabled when /DEBUG is specified and /DEBUGTYPE is not specified.
PDATA
Tells the linker to add .pdata and .xdata entries to the debug stream information in the PDB file. By default, this
option is enabled when both the /DEBUG and /DRIVER options are specified. If /DEBUGTYPE:PDATA is
specified by itself, the linker automatically includes debugging symbols in the PDB file. If
/DEBUGTYPE:PDATA,FIXUP is specified, the linker does not include debugging symbols in the PDB file.
FIXUP
Tells the linker to add relocation table entries to the debug stream information in the PDB file. By default, this
option is enabled when both the /DEBUG and /PROFILE options are specified. If /DEBUGTYPE:FIXUP or
/DEBUGTYPE:FIXUP,PDATA is specified, the linker does not include debugging symbols in the PDB file.
Arguments to /DEBUGTYPE may be combined in any order by separating them with a comma. The
/DEBUGTYPE option and its arguments are not case sensitive.
Remarks
Use the /DEBUGTYPE option to specify inclusion of relocation table data or .pdata and .xdata header information
in the debugging stream. This causes the linker to include information about user-mode code that is visible in a
kernel debugger when breaking in kernel-mode code. To make debugging symbols available when FIXUP is
specified, include the CV argument.
To debug code in user mode, which is typical for applications, the /DEBUGTYPE option isn't needed. By default,
the compiler switches that specify debugging output (/Z7, /Zi, /ZI) emit all the information needed by the Visual
Studio debugger. Use /DEBUGTYPE:PDATA or /DEBUGTYPE:CV,PDATA,FIXUP to debug code that combines
user-mode and kernel-mode components, such as a configuration app for a device driver. For more information
about kernel mode debuggers, see Debugging Tools for Windows (WinDbg, KD, CDB, NTSD )
See also
/DEBUG (Generate Debug Info)
/DRIVER (Windows NT Kernel Mode Driver)
/PROFILE (Performance Tools Profiler)
Debugging Tools for Windows (WinDbg, KD, CDB, NTSD )
/DEF (Specify Module-Definition File)
3/12/2019 • 2 minutes to read • Edit Online
/DEF:filename
Arguments
filename
The name of a module-definition file (.def) to be passed to the linker.
Remarks
The /DEF option passes a module-definition file (.def) to the linker. Only one .def file can be specified to LINK. For
details about .def files, see Module-Definition Files.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Input property page.
4. Modify the Module Definition File property.
To specify a .def file from within the development environment, you should add it to the project along with other
files and then specify the file to the /DEF option.
To set this linker option programmatically
See ModuleDefinitionFile.
See also
MSVC linker reference
MSVC Linker Options
/DEFAULTLIB (Specify Default Library)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/DEFAULTLIB:library
Arguments
library
The name of a library to search when resolving external references.
Remarks
The /DEFAULTLIB option adds one library to the list of libraries that LINK searches when resolving references. A
library specified with /DEFAULTLIB is searched after libraries specified explicitly on the command line and before
default libraries named in .obj files.
When used without arguments, the /NODEFAULTLIB (Ignore All Default Libraries) option overrides all
/DEFAULTLIB:library options. The /NODEFAULTLIB:library option overrides /DEFAULTLIB:library when the
same library name is specified in both.
To set this linker option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. In Additional Options, enter a /DEFAULTLIB:library option for each library to search. Choose OK to
save your changes.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/DELAY (Delay Load Import Settings)
3/12/2019 • 2 minutes to read • Edit Online
/DELAY:UNLOAD
/DELAY:NOBIND
Remarks
The /DELAY option controls delayed loading of DLLs:
The UNLOAD qualifier tells the delay-load helper function to support explicit unloading of the DLL. The
Import Address Table (IAT) is reset to its original form, invalidating IAT pointers and causing them to be
overwritten.
If you do not select UNLOAD, any call to FUnloadDelayLoadedDLL will fail.
The NOBIND qualifier tells the linker not to include a bindable IAT in the final image. The default is to
create the bindable IAT for delay-loaded DLLs. The resulting image cannot be statically bound. (Images with
bindable IATs may be statically bound prior to execution.) See /BIND.
If the DLL is bound, the helper function will attempt to use the bound information instead of calling
GetProcAddress on each of the referenced imports. If either the timestamp or the preferred address does
not match those of the loaded DLL, the helper function will assume the bound IAT is out of date and will
proceed as if the bound IAT does not exist.
NOBIND causes your program image to be larger but can speed load time of the DLL. If you never intend
to bind the DLL, NOBIND will prevent the bound IAT from being generated.
To specify DLLs to delay load, use the /DELAYLOAD option.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For information, see Set C++ compiler and build properties
in Visual Studio.
2. Expand Configuration Properties, Linker, and then select Advanced.
3. Modify the Delay Loaded DLL property.
To set this linker option programmatically
See DelayLoadDLLs.
See also
MSVC linker reference
MSVC Linker Options
/DELAYLOAD (Delay Load Import)
3/12/2019 • 2 minutes to read • Edit Online
/DELAYLOAD:dllname
Parameters
dllname
The name of a DLL that you want to delay load.
Remarks
The /DELAYLOAD option causes the DLL that's specified by dllname to be loaded only on the first call by the
program to a function in that DLL. For more information, see Linker Support for Delay-Loaded DLLs. You can use
this option as many times as necessary to specify as many DLLs as you choose. You must use Delayimp.lib when
you link your program, or you can implement your own delay-load helper function.
The /DELAY option specifies binding and loading options for each delay-loaded DLL.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. In the Linker folder, select the Input property page.
3. Modify the Delay Loaded DLLs property.
To set this linker option programmatically
See DelayLoadDLLs.
See also
MSVC linker reference
MSVC Linker Options
/DELAYSIGN (Partially Sign an Assembly)
3/12/2019 • 2 minutes to read • Edit Online
/DELAYSIGN[:NO]
Arguments
NO
Specifies that the assembly should not be partially signed.
Remarks
Use /DELAYSIGN if you only want to place the public key in the assembly. The default is /DELAYSIGN:NO.
The /DELAYSIGN option has no effect unless used with /KEYFILE or /KEYCONTAINER.
When you request a fully signed assembly, the compiler hashes the file that contains the manifest (assembly
metadata) and signs that hash with the private key. The resulting digital signature is stored in the file that
contains the manifest. When an assembly is delay signed, the linker does not compute and store the signature,
but reserves space in the file so the signature can be added later.
For example, using /DELAYSIGN allows a tester to put the assembly in the global cache. After testing, you can
fully sign the assembly by placing the private key in the assembly.
See Strong Name Assemblies (Assembly Signing) (C++/CLI) and Delay Signing an Assembly for more
information on signing an assembly.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/DEPENDENTLOADFLAG (Set default dependent
load flags)
3/12/2019 • 2 minutes to read • Edit Online
Sets the default load flags used when LoadLibrary is used to load DLLs.
Syntax
/DEPENDENTLOADFLAG[:loadflags]
Arguments
loadflags
An optional "C"-style 16-bit integer value in decimal, octal with a leading zero, or hexadecimal with a leading 0x ,
that specifies the dependent load flags to apply to all LoadLibrary calls. The default value is 0.
Remarks
This option is new in Visual Studio 2017, and applies only to apps running on Windows 10 RS1 and later versions.
This option is ignored by other operating systems that run the app.
On supported operating systems, this option has the effect of changing calls to LoadLibrary("dependent.dll") to
the equivalent of LoadLibraryEx("dependent.dll", 0, loadflags) . Calls to LoadLibraryEx are unaffected. This option
does not apply recursively to DLLs loaded by your app.
This flag can be used to prevent DLL planting attacks. For example, if an app uses LoadLibrary to load a
dependent DLL, an attacker could plant a DLL with the same name in the search path used by LoadLibrary , such
as the current directory, which may be checked before system directories if safe DLL search mode is disabled. Safe
DLL search mode places the user's current directory later in the search order, and is enabled by default on
Windows XP SP2 and later versions. For more information, see Dynamic-Link Library Search Order.
If you specify the link option /DEPENDENTLOADFLAG:0xA00(the value of the combined flags
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 ), then even if safe DLL search mode is
disabled on the user's computer, the DLL search path is limited to protected directories that are more difficult for
an attacker to change. For information on the flags available, and their symbolic and numeric values, see the
dwFlags parameter description in LoadLibraryEx.
To set the DEPENDENTLOADFLAG linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. Enter the option in Additional Options.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
Link an executable to a DLL
Link an executable to a DLL
LoadLibraryEx
Dynamic-Link Library Search Order
/DLL (Build a DLL)
3/12/2019 • 2 minutes to read • Edit Online
/DLL
Remarks
The /DLL option builds a DLL as the main output file. A DLL usually contains exports that can be used by another
program. There are three methods for specifying exports, listed in recommended order of use:
1. __declspec(dllexport) in the source code
2. An EXPORTS statement in a .def file
3. An /EXPORT specification in a LINK command
A program can use more than one method.
Another way to build a DLL is with the LIBRARY module-definition statement. The /BASE and /DLL options
together are equivalent to the LIBRARY statement.
Do not specify this option within the development environment; this option is for use only on the command line.
This option is set when you create a DLL project with an Application Wizard.
Note that if you create your import library in a preliminary step, before creating your .dll, you must pass the same
set of object files when building the .dll, as you passed when building the import library.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Configuration Properties folder.
3. Click the General property page.
4. Modify the Configuration Type property.
To set this linker option programmatically
See ConfigurationType.
See also
MSVC linker reference
MSVC Linker Options
/DRIVER (Windows NT Kernel Mode Driver)
3/12/2019 • 2 minutes to read • Edit Online
Remarks
Use the /DRIVER linker option to build a Windows NT kernel mode driver.
/DRIVER:UPONLY causes the linker to add the IMAGE_FILE_UP_SYSTEM_ONLY bit to the characteristics in
the output header to specify that it is a uniprocessor (UP ) driver. The operating system will refuse to load a UP
driver on a multiprocessor (MP ) system.
/DRIVER:WDM causes the linker to set the IMAGE_DLLCHARACTERISTICS_WDM_DRIVER bit in the
optional header's DllCharacteristics field.
If /DRIVER is not specified, these bits are not set by the linker.
If /DRIVER is specified:
/FIXED:NO is in effect. For more information, see /FIXED (Fixed Base Address).
The extension of the output file is set to .sys. Use /OUT to change the default filename and extension. For
more information, see /OUT (Output File Name).
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the System property page.
4. Modify the Driver property.
To set this linker option programmatically
See VCLinkerTool.driver Property.
See also
MSVC linker reference
MSVC Linker Options
/DYNAMICBASE (Use address space layout
randomization)
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether to generate an executable image that can be randomly rebased at load time by using the
address space layout randomization (ASLR ) feature of Windows that was first available in Windows Vista.
Syntax
/DYNAMICBASE [:NO ]
Remarks
The /DYNAMICBASE option modifies the header of an executable image, a .dll or .exe file, to indicate whether
the application should be randomly rebased at load time, and enables virtual address allocation randomization,
which affects the virtual memory location of heaps, stacks, and other operating system allocations. The
/DYNAMICBASE option applies to both 32-bit and 64-bit images. ASLR is supported on Windows Vista and
later operating systems. The option is ignored by earlier operating systems.
By default, /DYNAMICBASE is enabled. To disable this option, use /DYNAMICBASE:NO. The
/DYNAMICBASE option is required for the /HIGHENTROPYVA option to have an effect.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Select the Configuration Properties > Linker > Advanced property page.
3. Modify the Randomized Base Address property.
To set this linker option programmatically
See RandomizedBaseAddress.
See also
MSVC linker reference
MSVC Linker Options
/HIGHENTROPYVA
Windows ISV Software Security Defenses
/ENTRY (Entry-Point Symbol)
3/12/2019 • 2 minutes to read • Edit Online
/ENTRY:function
Arguments
function
A function that specifies a user-defined starting address for an .exe file or DLL.
Remarks
The /ENTRY option specifies an entry point function as the starting address for an .exe file or DLL.
The function must be defined to use the __stdcall calling convention. The parameters and return value depend
on if the program is a console application, a windows application or a DLL. It is recommended that you let the
linker set the entry point so that the C run-time library is initialized correctly, and C++ constructors for static
objects are executed.
By default, the starting address is a function name from the C run-time library. The linker selects it according to
the attributes of the program, as shown in the following table.
If the /DLL or /SUBSYSTEM option is not specified, the linker selects a subsystem and entry point depending on
whether main or WinMain is defined.
The functions main , WinMain , and DllMain are the three forms of the user-defined entry point.
When creating a managed image, the function specified to /ENTRY must have a signature of (LPVOID var1,
DWORD var2, LPVOID var3).
For information on how to define your own DllMain entry point, see DLLs and Visual C++ run-time library
behavior .
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Entry Point property.
To set this linker option programmatically
See EntryPointSymbol.
See also
MSVC linker reference
MSVC Linker Options
/ERRORREPORT (Report Internal Linker Errors)
3/12/2019 • 2 minutes to read • Edit Online
Arguments
none
Reports about internal compiler errors will not be collected or sent to Microsoft.
prompt
Prompts you to send a report when you receive an internal compiler error. prompt is the default when an
application is compiled in the development environment.
queue
Queues the error report. When you log in with administrator privileges, a window is displayed so that you can
report any failures since the last time you were logged in (you will not be prompted to send reports for failures
more than once every three days). queue is the default when an application is compiled at a command prompt.
send
Automatically sends reports of internal compiler errors to Microsoft if reporting is enabled by the Windows Error
Reporting service settings.
Remarks
The /ERRORREPORT option lets you provide internal compiler error (ICE ) information directly to Microsoft.
The option /errorreport:send automatically sends error information to Microsoft, if enabled by Windows Error
Reporting service settings.
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Open the Configuration Properties > Linker > Advanced property page.
3. Modify the Error Reporting property.
To set this compiler option programmatically
See ErrorReporting.
See also
/errorReport (Report Internal Compiler Errors)
MSVC linker reference
MSVC Linker Options
/EXPORT (Exports a Function)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/EXPORT:entryname[,@ordinal[,NONAME ]][,DATA ]
Remarks
The /EXPORT option specifies a function or data item to export from your program so that other programs can
call the function or use the data. Exports are usually defined in a DLL.
The entryname is the name of the function or data item as it is to be used by the calling program. ordinal specifies
an index into the exports table in the range 1 through 65,535; if you do not specify ordinal, LINK assigns one. The
NONAME keyword exports the function only as an ordinal, without an entryname.
The DATA keyword specifies that the exported item is a data item. The data item in the client program must be
declared using extern __declspec(dllimport).
There are four methods for exporting a definition, listed in recommended order of use:
1. __declspec(dllexport) in the source code
2. An EXPORTS statement in a .def file
3. An /EXPORT specification in a LINK command
4. A comment directive in the source code, of the form #pragma comment(linker, "/export: definition ") .
All these methods can be used in the same program. When LINK builds a program that contains exports, it also
creates an import library, unless an .exp file is used in the build.
LINK uses decorated forms of identifiers. The compiler decorates an identifier when it creates the .obj file. If
entryname is specified to the linker in its undecorated form (as it appears in the source code), LINK attempts to
match the name. If it cannot find a unique match, LINK issues an error message. Use the DUMPBIN tool to get
the decorated name form of an identifier when you need to specify it to the linker.
NOTE
Do not specify the decorated form of C identifiers that are declared __cdecl or __stdcall .
If you need to export an undecorated function name, and have different exports depending on the build
configuration (for example, in 32-bit or 64-bit builds), you can use different DEF files for each configuration.
(Preprocessor conditional directives are not allowed in DEF files.) As an alternative, you can use a
#pragma comment directive before a function declaration as shown here, where PlainFuncName is the undecorated
name, and _PlainFuncName@4 is the decorated name of the function:
See also
MSVC linker reference
MSVC Linker Options
/FILEALIGN (Align sections in files)
3/12/2019 • 2 minutes to read • Edit Online
The /FILEALIGN linker option lets you specify the alignment of sections written to your output file as a multiple
of an specified size.
Syntax
/FILEALIGN:size
Parameters
size
The section alignment size in bytes, which must be a power of two.
Remarks
The /FILEALIGN option causes the linker to align each section in the output file on a boundary that is a multiple
of the size value. By default, the linker does not use a fixed alignment size.
The /FILEALIGN option can be used to make disk utilization more efficient, or to make page loads from disk
faster. A smaller section size may be useful for apps that run on smaller devices, or to keep downloads smaller.
Section alignment on disk does not affect alignment in memory.
Use DUMPBIN to see information about sections in your output file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Command Line property page in the Linker folder.
3. Type the option name /FILEALIGN: and the size in the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/FIXED (Fixed Base Address)
3/12/2019 • 2 minutes to read • Edit Online
/FIXED[:NO]
Remarks
Tells the operating system to load the program only at its preferred base address. If the preferred base address is
unavailable, the operating system does not load the file. For more information, see /BASE (Base Address).
/FIXED:NO is the default setting for a DLL, and /FIXED is the default setting for any other project type.
When /FIXED is specified, LINK does not generate a relocation section in the program. At run time, if the
operating system is unable to load the program at the specified address, it issues an error message and does not
load the program.
Specify /FIXED:NO to generate a relocation section in the program.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Command Line property page.
4. Type the option name and setting in the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/FORCE (Force File Output)
3/12/2019 • 2 minutes to read • Edit Online
/FORCE:[MULTIPLE|UNRESOLVED]
Remarks
The /FORCE option tells the linker to create a valid .exe file or DLL even if a symbol is referenced but not defined
or is multiply defined.
The /FORCE option can take an optional argument:
Use /FORCE:MULTIPLE to create an output file whether or not LINK finds more than one definition for a
symbol.
Use /FORCE:UNRESOLVED to create an output file whether or not LINK finds an undefined symbol.
/FORCE:UNRESOLVED is ignored if the entry point symbol is unresolved.
/FORCE with no arguments implies both multiple and unresolved.
A file created with this option may not run as expected. The linker will not link incrementally when the /FORCE
option is specified.
If a module is compiled with /clr, /FORCE will not create an image.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/FUNCTIONPADMIN (Create Hotpatchable Image)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/FUNCTIONPADMIN [:space]
Arguments
space
The amount of padding to add to the beginning of each function in bytes. On x86 this defaults to 5 bytes of
padding and on x64 this defaults to 6 bytes. On other targets a value must be provided.
Remarks
In order for the linker to produce a hotpatchable image, the .obj files must have been compiled with /hotpatch
(Create Hotpatchable Image).
When you compile and link an image with a single invocation of cl.exe, /hotpatch implies /functionpadmin.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. Enter the /FUNCTIONPADMIN option in Additional Options. Choose OK to save your changes.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/GENPROFILE, /FASTGENPROFILE (Generate
Profiling Instrumented Build)
3/12/2019 • 3 minutes to read • Edit Online
Specifies generation of a .pgd file by the linker to support profile-guided optimization (PGO ). /GENPROFILE and
/FASTGENPROFILE use different default parameters. Use /GENPROFILE to favor precision over speed and
memory usage during profiling. Use /FASTGENPROFILE to favor smaller memory usage and speed over
precision.
Syntax
/GENPROFILE [:{[COUNTER32|COUNTER64]|[EXACT|NOEXACT]|MEMMAX=#|MEMMIN=#|
[PATH|NOPATH ]|[TRACKEH |NOTRACKEH ]|PGD=filename}]
/FASTGENPROFILE [:{[COUNTER32|COUNTER64]|[EXACT|NOEXACT]|MEMMAX=#|MEMMIN=#|
[PATH|NOPATH ]|[TRACKEH |NOTRACKEH ]|PGD=filename}]
Arguments
Any of the following arguments may be specified to /GENPROFILE or /FASTGENPROFILE. Arguments listed
here separated by a pipe (|) character are mutually exclusive. Use a comma (,) character to separate options.
COUNTER32 | COUNTER64
Use COUNTER32 to specify the use of 32-bit probe counters, and COUNTER64 to specify 64-bit probe
counters. When you specify /GENPROFILE, the default is COUNTER64. When you specify
/FASTGENPROFILE, the default is COUNTER32.
EXACT | NOEXACT
Use EXACT to specify thread-safe interlocked increments for probes. NOEXACT specifies unprotected increment
operations for probes. The default is NOEXACT.
MEMMAX=value, MEMMIN=value
Use MEMMAX and MEMMIN to specify the maximum and minimum reservation sizes for training data in
memory. The value is the amount of memory to reserve in bytes. By default, these values are determined by an
internal heuristic.
PATH | NOPATH
Use PATH to specify a separate set of PGO counters for each unique path to a function. Use NOPATH to specify
only one set of counters for each function. When you specify /GENPROFILE, the default is PATH . When you
specify /FASTGENPROFILE, the default is NOPATH .
TRACKEH | NOTRACKEH
Specifies whether to use extra counters to keep an accurate count when exceptions are thrown during training.
Use TRACKEH to specify extra counters for an exact count. Use NOTRACKEH to specify single counters for code
that does not use exception handling or that does not encounter exceptions in your training scenarios. When you
specify /GENPROFILE, the default is TRACKEH . When you specify /FASTGENPROFILE, the default is
NOTRACKEH .
PGD=filename
Specifies a base file name for the .pgd file. By default, the linker uses the base executable image file name with a
.pgd extension.
Remarks
The /GENPROFILE and /FASTGENPROFILE options tell the linker to generate the profiling instrumentation file
needed to support application training for profile-guided optimization (PGO ). These options are new in Visual
Studio 2015. Prefer these options to the deprecated /LTCG:PGINSTRUMENT, /PGD and /POGOSAFEMODE
options and the PogoSafeMode, VCPROFILE_ALLOC_SCALE and VCPROFILE_PATH environment variables.
The profiling information generated by application training is used as input to perform targeted whole-program
optimizations during builds. You can set additional options to control various profiling features for performance
during app training and builds. The default options specified by /GENPROFILE give most accurate results,
especially for large, complex multi-threaded apps. The /FASTGENPROFILE option uses different defaults for a
lower memory footprint and faster performance during training, at the expense of accuracy.
Profiling information is captured when you run the instrumented app after you build by using /GENPROFILE of
/FASTGENPROFILE. This information is captured when you specify the /USEPROFILE linker option to perform
the profiling step and then used to guide the optimized build step. For more information on how to train your app
and details on the collected data, see Profile-Guided Optimizations.
You must also specify /LTCG when you specify /GENPROFILE or /FASTGENPROFILE.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. Enter the /GENPROFILE or /FASTGENPROFILE options and arguments into the Additional Options
box. Choose OK to save your changes.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/LTCG (Link-time Code Generation)
/GUARD (Enable Guard Checks)
3/12/2019 • 2 minutes to read • Edit Online
Specifies support for Control Flow Guard checks in the executable image.
Syntax
/GUARD:{CF|NO}
Remarks
When /GUARD:CF is specified, the linker modifies the header of a .dll or .exe to indicate support for Control Flow
Guard (CFG ) runtime checks. The linker also adds the required control flow target address data to the header. By
default, /GUARD:CF is disabled. It can be explicitly disabled by using /GUARD:NO. To be effective, /GUARD:CF
also requires the /DYNAMICBASE (Use address space layout randomization) linker option, which is on by default.
When source code is compiled by using the /guard:cf option, the compiler analyzes the control flow by examining
all indirect calls for possible target addresses. The compiler inserts code to verify the target address of an indirect
call instruction is in the list of known target addresses at runtime. Operating systems that support CFG stop a
program that fails a CFG runtime check. This makes it more difficult for an attacker to execute malicious code by
using data corruption to change a call target.
The /GUARD:CF option must be specified to both the compiler and linker to create CFG -enabled executable
images. Code compiled but not linked by using /GUARD:CF incurs the cost of runtime checks, but does not enable
CFG protection. When the /GUARD:CF option is specified to the cl command to compile and link in one step, the
compiler passes the flag to the linker. When the Control Flow Guard property is set in Visual Studio, the
/GUARD:CF option is passed to both the compiler and linker. When object files or libraries have been compiled
separately, the option must be explicitly specified in the link command.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand Configuration Properties, Linker, Command Line.
3. In Additional Options, enter /GUARD:CF .
See also
/guard (Enable Control Flow Guard)
MSVC linker reference
MSVC Linker Options
/HEAP (Set Heap Size)
3/12/2019 • 2 minutes to read • Edit Online
/HEAP:reserve[,commit]
Remarks
The /HEAP option sets the size of the heap in bytes. This option is only for use when building an .exe file.
The reserve argument specifies the total heap allocation in virtual memory. The default heap size is 1 MB. The
linker rounds up the specified value to the nearest 4 bytes.
The optional commit argument specifies the amount of physical memory to allocate at a time. Committed virtual
memory causes space to be reserved in the paging file. A higher commit value saves time when the application
needs more heap space, but increases the memory requirements and possibly the startup time.
Specify the reserve and commit values in decimal or C -language notation.
This functionality is also available via a module definition file with HEAPSIZE.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the System property page.
4. Modify the Heap Commit Size property.
To set this linker option programmatically
See HeapReserveSize and HeapCommitSize.
See also
MSVC linker reference
MSVC Linker Options
/HIGHENTROPYVA (Support 64-Bit ASLR)
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether the executable image supports high-entropy 64-bit address space layout randomization
(ASLR ).
Syntax
/HIGHENTROPYVA [:NO ]
Remarks
/HIGHENTROPYVA modifies the header of an executable image, a .dll file or .exe file, to indicate whether ASLR
can use the entire 64-bit address space. When this option is set on an executable and all of the modules that it
depends on, an operating system that supports 64-bit ASLR can rebase the segments of the executable image at
load time by using randomized addresses in a 64-bit virtual address space. This large address space makes it
more difficult for an attacker to guess the location of a particular memory region.
By default, /HIGHENTROPYVA is enabled for 64-bit executable images. This option requires
/LARGEADDRESSAWARE, which is also enabled by default for 64-bit images. /HIGHENTROPYVA is not
applicable to 32-bit executable images, where the linker ignores the option. To explicitly disable this option, use
/HIGHENTROPYVA:NO.
For /HIGHENTROPYVA to have an effect at load time, /DYNAMICBASE must also be enabled.
/DYNAMICBASE is enabled by default, and is required to enable ASLR in Windows Vista and later operating
systems. Earlier versions of Windows ignore this flag.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. In Additional Options, enter /HIGHENTROPYVA or /HIGHENTROPYVA:NO .
See also
MSVC linker reference
MSVC Linker Options
/DYNAMICBASE
/LARGEADDRESSAWARE
Windows ISV Software Security Defenses
/IDLOUT (Name MIDL Output Files)
3/12/2019 • 2 minutes to read • Edit Online
/IDLOUT:[path\]filename
Parameters
path
An absolute or relative path specification. By specifying a path, you affect only the location of an .idl file; all other
files are placed in the project directory.
filename
Specifies the name of the .idl file created by the MIDL compiler. No file extension is assumed; specify filename.idl if
you want an .idl extension.
Remarks
The /IDLOUT option specifies the name and extension of the .idl file.
The MIDL compiler is called by the MSVC linker when linking projects that have the module attribute.
/IDLOUT also specifies the file names of the other output files associated with the MIDL compiler:
filename.tlb
filename_p.c
filename_i.c
filename.h
filename is the parameter that you pass to /IDLOUT. If /TLBOUT is specified, the .tlb file will get its name from
/TLBOUT filename.
If you specify neither /IDLOUT nor /TLBOUT, the linker will create vc70.tlb, vc70.idl, vc70_p.c, vc70_i.c, and vc70.h.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Embedded IDL property page.
4. Modify the Merge IDL Base File Name property.
To set this linker option programmatically
See MergedIDLBaseFileName.
See also
MSVC linker reference
MSVC Linker Options
/IGNOREIDL (Don't Process Attributes into MIDL )
/MIDL (Specify MIDL Command Line Options)
Building an Attributed Program
/IGNORE (Ignore Specific Warnings)
3/12/2019 • 2 minutes to read • Edit Online
/IGNORE:warning[,warning]
Parameters
warning
The number of the linker warning to suppress, in the range 4000 to 4999.
Remarks
By default, LINK reports all warnings. Specify /IGNORE: warning to tell the linker to suppress a specific warning
number. To ignore multiple warnings, separate the warning numbers with commas.
The linker does not allow some warnings to be ignored. This table lists the warnings that are not suppressed by
/IGNORE:
LINKER WARNING
LNK4062 ' option ' not compatible with ' architecture ' target
machine; option ignored
LNK4075 ignoring " option1 " due to " option2 " specification
LNK4086 entrypoint ' function ' is not __stdcall with ' number ' bytes of
arguments; image may not run
LNK4088 image being generated due to /FORCE option; image may not
run
LNK4105 no argument specified with option ' option '; ignoring switch
LNK4203 error reading program database ' filename '; linking object as
if no debug info
LNK4206 precompiled type information not found; ' filename ' not
linked or overwritten; linking object as if no debug info
LINKER WARNING
LNK4207 ' filename ' compiled /Yc /Yu /Z7; cannot create PDB;
recompile with /Zi; linking object as if no debug info
LNK4208 incompatible PDB format in ' filename '; delete and rebuild;
linking object as if no debug info
In general, linker warnings that can't be ignored represent build failures, command line errors or configuration
errors that you should fix.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. In the Linker folder, select the Command Line property page.
3. Modify the Additional Options property.
To set this linker option programmatically
See AdditionalOptions.
/IGNOREIDL (Don't Process Attributes into MIDL)
3/12/2019 • 2 minutes to read • Edit Online
/IGNOREIDL
Remarks
The /IGNOREIDL option specifies that any IDL attributes in source code should not be processed into an .idl file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Embedded IDL property page.
4. Modify the Ignore Embedded IDL property.
To set this linker option programmatically
See IgnoreEmbeddedIDL.
See also
MSVC linker reference
MSVC Linker Options
/IDLOUT (Name MIDL Output Files)
/TLBOUT (Name .TLB File)
/MIDL (Specify MIDL Command Line Options)
Building an Attributed Program
/IMPLIB (Name Import Library)
3/12/2019 • 2 minutes to read • Edit Online
/IMPLIB:filename
Parameters
filename
A user-specified name for the import library. It replaces the default name.
Remarks
The /IMPLIB option overrides the default name for the import library that LINK creates when it builds a program
that contains exports. The default name is formed from the base name of the main output file and the extension
.lib. A program contains exports if one or more of the following are specified:
The __declspec(dllexport) keyword in the source code
EXPORTS statement in a .def file
An /EXPORT specification in a LINK command
LINK ignores /IMPLIB when an import library is not being created. If no exports are specified, LINK does not
create an import library. If an export file is used in the build, LINK assumes that an import library already exists
and does not create one. For information on import libraries and export files, see LIB Reference.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Import Library property.
To set this linker option programmatically
See ImportLibrary.
See also
MSVC linker reference
MSVC Linker Options
/INCLUDE (Force Symbol References)
3/12/2019 • 2 minutes to read • Edit Online
/INCLUDE:symbol
Parameters
symbol
Specifies a symbol to be added to the symbol table.
Remarks
The /INCLUDE option tells the linker to add a specified symbol to the symbol table.
To specify multiple symbols, type a comma (,), a semicolon (;), or a space between the symbol names. On the
command line, specify /INCLUDE: symbol once for each symbol.
The linker resolves symbol by adding the object that contains the symbol definition to the program. This feature is
useful for including a library object that otherwise would not be linked to the program.
Specifying a symbol with this option overrides the removal of that symbol by /OPT:REF.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Input property page.
4. Modify the Force Symbol References property.
To set this linker option programmatically
See ForceSymbolReferences.
See also
MSVC linker reference
MSVC Linker Options
/INCREMENTAL (Link Incrementally)
3/12/2019 • 2 minutes to read • Edit Online
/INCREMENTAL[:NO]
Remarks
Controls how the linker handles incremental linking.
By default, the linker runs in incremental mode. To override a default incremental link, specify
/INCREMENTAL:NO.
An incrementally linked program is functionally equivalent to a program that is non-incrementally linked.
However, because it is prepared for subsequent incremental links, an incrementally linked executable, static
library, or dynamic-link library file:
Is larger than a non-incrementally linked program because of padding of code and data. Padding enables
the linker to increase the size of functions and data without recreating the file.
May contain jump thunks to handle relocation of functions to new addresses.
NOTE
To ensure that your final release build does not contain padding or thunks, link your program non-incrementally.
To link incrementally regardless of the default, specify /INCREMENTAL. When this option is selected, the linker
issues a warning if it cannot link incrementally, and then links the program non-incrementally. Certain options
and situations override /INCREMENTAL.
Most programs can be linked incrementally. However, some changes are too great, and some options are
incompatible with incremental linking. LINK performs a full link if any of the following options are specified:
Link Incrementally is not selected (/INCREMENTAL:NO )
/OPT:REF is selected
/OPT:ICF is selected
/OPT:LBR is selected
/ORDER is selected
/INCREMENTAL is implied when /DEBUG is specified.
Additionally, LINK performs a full link if any of the following situations occur:
The incremental status (.ilk) file is missing. (LINK creates a new .ilk file in preparation for subsequent
incremental linking.)
There is no write permission for the .ilk file. (LINK ignores the .ilk file and links non-incrementally.)
The .exe or .dll output file is missing.
The timestamp of the .ilk, .exe, or .dll is changed.
A LINK option is changed. Most LINK options, when changed between builds, cause a full link.
An object (.obj) file is added or omitted.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the General property page.
4. Modify the Enable Incremental Linking property.
To set this linker option programmatically
1. See LinkIncremental.
See also
MSVC linker reference
MSVC Linker Options
/INTEGRITYCHECK (Require Signature Check)
3/12/2019 • 2 minutes to read • Edit Online
Specifies that the digital signature of the binary image must be checked at load time.
/INTEGRITYCHECK[:NO]
Remarks
By default, /INTEGRITYCHECK is off.
The /INTEGRITYCHECK option sets—in the PE header of the DLL file or executable file—a flag for the memory
manager to check for a digital signature in order to load the image in Windows. This option must be set for both
32-bit and 64-bit DLLs that implement kernel-mode code loaded by certain Windows features, and is
recommended for all device drivers on Windows Vista, Windows 7, Windows 8, Windows Server 2008, and
Windows Server 2012. Versions of Windows prior to Windows Vista ignore this flag. For more information, see
Forced Integrity Signing of Portable Executable (PE ) files.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Command Line property page.
5. In Additional Options, enter /INTEGRITYCHECK or /INTEGRITYCHECK:NO .
See also
MSVC linker reference
MSVC Linker Options
Forced Integrity Signing of Portable Executable (PE ) files
Kernel-Mode Code Signing Walkthrough
AppInit DLLs in Windows 7 and Windows Server 2008
/KEYCONTAINER (Specify a Key Container to Sign
an Assembly)
3/12/2019 • 2 minutes to read • Edit Online
/KEYCONTAINER:name
Arguments
name
Container that contains the key. Place the string in double quotation marks (" ") if it contains a space.
Remarks
The linker creates a signed assembly by inserting a public key into the assembly manifest and signing the final
assembly with the private key. To generate a key file, type sn -k filename at the command line. sn -i installs the
key pair into a container.
If you compile with /LN, the name of the key file is held in the module and incorporated into the assembly that is
created when you compile an assembly that includes an explicit reference to the module, via #using, or when
linking with /ASSEMBLYMODULE.
You can also pass your encryption information to the compiler with /KEYFILE. Use /DELAYSIGN if you want a
partially signed assembly. See Strong Name Assemblies (Assembly Signing) (C++/CLI) for more information on
signing an assembly.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/KEYFILE (Specify Key or Key Pair to Sign an
Assembly)
3/12/2019 • 2 minutes to read • Edit Online
/KEYFILE:filename
Arguments
filename
File that contains the key. Place the string in double quotation marks (" ") if it contains a space.
Remarks
The linker inserts the public key into the assembly manifest and then signs the final assembly with the private
key. To generate a key file, type sn -k filename at the command line. A signed assembly is said to have a strong
name.
If you compile with /LN, the name of the key file is held in the module and incorporated into the assembly that is
created when you compile an assembly that includes an explicit reference to the module, via #using, or when
linking with /ASSEMBLYMODULE.
You can also pass your encryption information to the linker with /KEYCONTAINER. Use /DELAYSIGN if you
want a partially signed assembly. See Strong Name Assemblies (Assembly Signing) (C++/CLI) for more
information on signing an assembly.
In case both /KEYFILE and /KEYCONTAINER are specified (either by command line option or by custom
attribute), the linker will first try the key container. If that succeeds, then the assembly is signed with the
information in the key container. If the linker does not find the key container, it will try the file specified with
/KEYFILE. If that succeeds, the assembly is signed with the information in the key file and the key information
will be installed in the key container (similar to sn -i) so that on the next compilation, the key container will be
valid.
Note that a key file might contain only the public key.
See Creating and Using Strong-Named Assemblies for more information on signing an assembly.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/NOASSEMBLY
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/LARGEADDRESSAWARE (Handle Large Addresses)
3/12/2019 • 2 minutes to read • Edit Online
/LARGEADDRESSAWARE[:NO]
Remarks
The /LARGEADDRESSAWARE option tells the linker that the application can handle addresses larger than 2
gigabytes. In the 64-bit compilers, this option is enabled by default. In the 32-bit compilers,
/LARGEADDRESSAWARE:NO is enabled if /LARGEADDRESSAWARE is not otherwise specified on the linker
line.
If an application was linked with /LARGEADDRESSAWARE, DUMPBIN /HEADERS will display information to
that effect.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the System property page.
4. Modify the Enable Large Addresses property.
To set this linker option programmatically
See LargeAddressAware.
See also
MSVC linker reference
MSVC Linker Options
/LIBPATH (Additional Libpath)
3/12/2019 • 2 minutes to read • Edit Online
/LIBPATH:dir
Parameters
dir
Specifies a path that the linker will search before it searches the path specified in the LIB environment option.
Remarks
Use the /LIBPATH option to override the environment library path. The linker will first search in the path specified
by this option, and then search in the path specified in the LIB environment variable. You can specify only one
directory for each /LIBPATH option you enter. If you want to specify more than one directory, you must specify
multiple /LIBPATH options. The linker will then search the specified directories in order.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the General property page.
4. Modify the Additional Library Directories property.
To set this linker option programmatically
See AdditionalLibraryDirectories.
See also
MSVC linker reference
MSVC Linker Options
/LTCG (Link-time Code Generation)
3/12/2019 • 4 minutes to read • Edit Online
Syntax
/LTCG[:{INCREMENTAL|NOSTATUS|STATUS|OFF}]
/LTCG:{PGINSTRUMENT|PGOPTIMIZE|PGUPDATE }
Arguments
INCREMENTAL
(Optional) Specifies that the linker only applies whole program optimization or link-time code generation
(LTCG ) to the set of files affected by an edit, instead of the entire project. By default, this flag is not set when
/LTCG is specified, and the entire project is linked by using whole program optimization.
NOSTATUS | STATUS
(Optional) Specifies whether the linker displays a progress indicator that shows what percentage of the link is
complete. By default, this status information is not displayed.
OFF
(Optional) Disables link-time code generation. This behavior is the same as when /LTCG is not specified on
the command line.
PGINSTRUMENT
(Optional) This option is deprecated starting in Visual Studio 2015. Instead, use /LTCG and /GENPROFILE or
/FASTGENPROFILE to generate an instrumented build for profile-guided optimization. The data that is
collected from instrumented runs is used to create an optimized image. For more information, see Profile-
Guided Optimizations. The short form of this option is /LTCG:PGI.
PGOPTIMIZE
(Optional) This option is deprecated starting in Visual Studio 2015. Instead, use /LTCG and /USEPROFILE to
build an optimized image. For more information, see Profile-Guided Optimizations. The short form of this
option is /LTCG:PGO.
PGUPDATE
(Optional) This option is deprecated starting in Visual Studio 2015. Instead, use /LTCG and /USEPROFILE to
rebuild an optimized image. For more information, see Profile-Guided Optimizations. The short form of this
option is /LTCG:PGU.
Remarks
The /LTCG option tells the linker to call the compiler and perform whole-program optimization. You can also
do profile guided optimization. For more information, see Profile-Guided Optimizations.
With the following exceptions, you cannot add linker options to the PGO combination of /LTCG and
/USEPROFILE that were not specified in the previous PGO initialization combination of /LTCG and
/GENPROFILE options:
/BASE
/FIXED
/LTCG
/MAP
/MAPINFO
/NOLOGO
/OUT
/PGD
/PDB
/PDBSTRIPPED
/STUB
/VERBOSE
Any linker options that are specified together with the /LTCG and /GENPROFILE options to initialize PGO
do not have to be specified when you build by using /LTCG and /USEPROFILE; they are implied.
The rest of this article discusses /LTCG in terms of link-time code generation.
/LTCG is implied with /GL.
The linker invokes link-time code generation if it is passed a module that was compiled by using /GL or an
MSIL module (see .netmodule Files as Linker Input). If you do not explicitly specify /LTCG when you pass /GL
or MSIL modules to the linker, the linker eventually detects this and restarts the link by using /LTCG. Explicitly
specify /LTCG when you pass /GL and MSIL modules to the linker for the fastest possible build performance.
For even faster performance, use /LTCG:INCREMENTAL. This option tells the linker to only re-optimize the
set of files that is affected by a source file change, instead of the entire project. This can significantly reduce
the link time required. This is not the same option as incremental linking.
/LTCG is not valid for use with /INCREMENTAL.
When /LTCG is used to link modules compiled by using /Og, /O1, /O2, or /Ox, the following optimizations
are performed:
Cross-module inlining
Interprocedural register allocation (64-bit operating systems only)
Custom calling convention (x86 only)
Small TLS displacement (x86 only)
Stack double alignment (x86 only)
Improved memory disambiguation (better interference information for global variables and input
parameters)
NOTE
The linker determines which optimizations were used to compile each function and applies the same optimizations at
link time.
NOTE
If you use /LTCG and redefine mainCRTStartup , your application can have unpredictable behavior that relates to user
code that executes before global objects are initialized. There are three ways to address this issue: do not redefine
mainCRTStartup , do not compile the file that contains mainCRTStartup by using /LTCG, or initialize global variables
and objects statically.
See also
MSVC linker reference
MSVC Linker Options
/MACHINE (Specify Target Platform)
3/12/2019 • 2 minutes to read • Edit Online
/MACHINE:{ARM|EBC|X64|X86}
Remarks
The /MACHINE option specifies the target platform for the program.
Usually, you don't have to specify the /MACHINE option. LINK infers the machine type from the .obj files.
However, in some circumstances, LINK cannot determine the machine type and issues a linker tools error
LNK1113. If such an error occurs, specify /MACHINE.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Target Machine property.
To set this linker option programmatically
1. See TargetMachine.
See also
MSVC linker reference
MSVC Linker Options
/MANIFEST (Create Side-by-Side Assembly Manifest)
3/12/2019 • 2 minutes to read • Edit Online
/MANIFEST[:{EMBED[,ID=#]|NO}]
Remarks
/MANIFEST specifies that the linker should create a side-by-side manifest file. For more information about
manifest files, see Manifest Files Reference.
The default is /MANIFEST.
The /MANIFEST:EMBED option specifies that the linker should embed the manifest file in the image as a resource
of type RT_MANIFEST. The optional ID parameter is the resource ID to use for the manifest. Use a value of 1 for
an executable file. Use a value of 2 for a DLL to enable it to specify private dependencies. If the ID parameter is
not specified, the default value is 2 if the /DLL option is set; otherwise, the default value is 1.
Beginning with Visual Studio 2008, manifest files for executables contain a section that specifies User Account
Control (UAC ) information. If you specify /MANIFEST but specify neither /MANIFESTUAC nor /DLL, a default
UAC fragment that has the UAC level set to asInvoker is inserted into the manifest. For more information about
UAC levels, see /MANIFESTUAC (Embeds UAC information in manifest).
To change the default behavior for UAC, do one of these:
Specify the /MANIFESTUAC option and set the UAC level to the desired value.
Or specify the /MANIFESTUAC:NO option if you do not want to generate a UAC fragment in the manifest.
If you do not specify /MANIFEST but do specify /MANIFESTDEPENDENCY comments, a manifest file is created.
A manifest file is not created if you specify /MANIFEST:NO.
If you specify /MANIFEST, the name of the manifest file is the same as the name of your output file, but with
.manifest appended to the file name. For example, if your output file name is MyFile.exe, the manifest file name is
MyFile.exe.manifest. If you specify /MANIFESTFILE:name, the name of the manifest is what you specify in name.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Manifest File property page.
5. Modify the Generate Manifest property.
To set this linker option programmatically
1. See GenerateManifest.
See also
MSVC linker reference
MSVC Linker Options
/MANIFESTDEPENDENCY (Specify Manifest
Dependencies)
3/12/2019 • 2 minutes to read • Edit Online
/MANIFESTDEPENDENCY:manifest_dependency
Remarks
/MANIFESTDEPENDENCY lets you specify attributes that will be placed in the <dependency> section of the
manifest file.
See /MANIFEST (Create Side-by-Side Assembly Manifest) for information on how to create a manifest file.
For more information on the <dependency> section of the manifest file, see Publisher Configuration Files.
/MANIFESTDEPENDENCY information can be passed to the linker in one of two ways:
Directly on the command line (or in a response file) with /MANIFESTDEPENDENCY.
Via the comment pragma.
The following example shows a /MANIFESTDEPENDENCY comment passed via pragma,
<dependency>
<dependentAssembly>
<assemblyIdentity type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0'
processorArchitecture='X86' publicKeyToken='0000000000000000' language='*' />
</dependentAssembly>
</dependency>
The same /MANIFESTDEPENDENCY comments can be passed at the command line as follows:
The linker will collect /MANIFESTDEPENDENCY comments, eliminate duplicate entries, and then add the
resulting XML string to the manifest file. If the linker finds conflicting entries, the manifest file will become corrupt
and the application will fail to launch (an entry may be added to the event log, indicating the source of the failure).
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Manifest File property page.
3. Modify the Additional Manifest Dependencies property.
To set this linker option programmatically
1. See AdditionalManifestDependencies.
See also
MSVC linker reference
MSVC Linker Options
/MANIFESTFILE (Name Manifest File)
3/12/2019 • 2 minutes to read • Edit Online
/MANIFESTFILE:filename
Remarks
/MANIFESTFILE lets you change the default name of the manifest file. The default name of the manifest file is the
file name with .manifest appended.
/MANIFESTFILE will have no effect if you do not also link with /MANIFEST.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Manifest File property page.
5. Modify the Manifest File property.
To set this linker option programmatically
1. See ManifestFile.
See also
MSVC linker reference
MSVC Linker Options
/MANIFESTINPUT (Specify Manifest Input)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a manifest input file to include in the manifest that's embedded in the image.
Syntax
/MANIFESTINPUT:filename
Parameters
filename
The manifest file to include in the embedded manifest.
Remarks
The /MANIFESTINPUT option specifies the path of an input file to use to create the embedded manifest in an
executable image. If you have multiple manifest input files, use the switch multiple times—once for each input file.
The manifest input files are merged to create the embedded manifest. This option requires the
/MANIFEST:EMBED option.
This option can’t be set directly in Visual Studio. Instead, use the Additional Manifest Files property of the
project to specify additional manifest files to include. For more information, see Input and Output, Manifest Tool,
Configuration Properties, <Projectname> Property Pages Dialog Box.
See also
MSVC linker reference
MSVC Linker Options
/MANIFESTUAC (Embeds UAC information in
manifest)
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether User Account Control (UAC ) information is embedded in the program manifest.
Syntax
/MANIFESTUAC
/MANIFESTUAC:NO
/MANIFESTUAC:fragment
/MANIFESTUAC:level=_level
/MANIFESTUAC:uiAccess=_uiAccess
Parameters
fragment
A string that contains the level and uiAccess values. For more information, see the Remarks section later in this
topic.
_level
One of asInvoker, highestAvailable, or requireAdministrator. Defaults to asInvoker. For more information, see the
Remarks section later in this topic.
_uiAccess
true if you want the application to bypass user interface protection levels and drive input to higher-permission
windows on the desktop; otherwise, false. Defaults to false. Set to true only for user interface accessibility
applications.
Remarks
If you specify multiple /MANIFESTUAC options on the command-line, the last one entered takes precedence.
The choices for /MANIFESTUAC:level are as follows:
asInvoker : The application will run with the same permissions as the process that started it. The
application can be elevated to a higher permission level by selecting Run as Administrator.
highestAvailable: The application will run with the highest permission level that it can. If the user who starts
the application is a member of the Administrators group, this option is the same as requireAdministrator. If
the highest available permission level is higher than the level of the opening process, the system will
prompt for credentials.
requireAdministrator: The application will run with administrator permissions. The user who starts the
application must be a member of the Administrators group. If the opening process is not running with
administrative permissions, the system will prompt for credentials.
You can specify the level and uiAccess values in one step by using the /MANIFESTUAC:fragment option. The
fragment must be in the following form:
See also
MSVC linker reference
MSVC Linker Options
/MAP (Generate Mapfile)
3/12/2019 • 2 minutes to read • Edit Online
/MAP[:filename]
Arguments
filename
A user-specified name for the mapfile. It replaces the default name.
Remarks
The /MAP option tells the linker to create a mapfile.
By default, the linker names the mapfile with the base name of the program and the extension .map. The optional
filename allows you to override the default name for a mapfile.
A mapfile is a text file that contains the following information about the program being linked:
The module name, which is the base name of the file
The timestamp from the program file header (not from the file system)
A list of groups in the program, with each group's start address (as section:offset), length, group name, and
class
A list of public symbols, with each address (as section:offset), symbol name, flat address, and .obj file where
the symbol is defined
The entry point (as section:offset)
The /MAPINFO option specifies additional information to be included in the mapfile.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debug property page.
4. Modify the Generate Map File property.
To set this linker option programmatically
1. See GenerateMapFile and MapFileName.
See also
MSVC linker reference
MSVC Linker Options
/MAPINFO (Include Information in Mapfile)
3/12/2019 • 2 minutes to read • Edit Online
/MAPINFO:EXPORTS
Remarks
The /MAPINFO option tells the linker to include the specified information in a mapfile, which is created if you
specify the /MAP option. EXPORTS tells the linker to include exported functions.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debug property page.
4. Modify of the Map Exports properties:
To set this linker option programmatically
See MapExports.
See also
MSVC linker reference
MSVC Linker Options
/MERGE (Combine Sections)
3/12/2019 • 2 minutes to read • Edit Online
/MERGE:from=to
Remarks
The /MERGE option combines the first section (from) with the second section (to), naming the resulting section to.
For example, /merge:.rdata=.text .
If the second section does not exist, LINK renames the section from as to.
The /MERGE option is useful for creating VxDs and overriding the compiler-generated section names.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Merge Sections property.
To set this linker option programmatically
1. See MergeSections.
See also
MSVC linker reference
MSVC Linker Options
/MIDL (Specify MIDL Command Line Options)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/MIDL:@file
Arguments
file
The name of the file that contains MIDL command line options.
Remarks
All options for the conversion of an IDL file to a TLB file must be given in file; MIDL command-line options cannot
be specified on the linker's command line. If /MIDL is not specified, the MIDL compiler will be invoked with only
the IDL file name and no other options.
The file should contain one MIDL command-line option per line.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Embedded IDL property page.
3. Modify the MIDL Commands property.
To set this linker option programmatically
See MidlCommandFile.
See also
MSVC linker reference
MSVC Linker Options
/IDLOUT (Name MIDL Output Files)
/IGNOREIDL (Don't Process Attributes into MIDL )
/TLBOUT (Name .TLB File)
Building an Attributed Program
/NATVIS (Add Natvis to PDB)
3/12/2019 • 2 minutes to read • Edit Online
/NATVIS:filename
Parameters
filename
A Natvis file to add to the PDB file. It embeds the debugger visualizations in the Natvis file into the PDB.
Remarks
The /NATVIS option embeds the debugger visualizations defined in the Natvis file filename into the PDB file
generated by LINK. This allows the debugger to display the visualizations independently of the .natvis file. You can
use multiple /NATVIS options to embed more than one Natvis file in the generated PDB file.
LINK ignores /NATVIS when a PDB file is not created by using a /DEBUG option. For information on creation and
use of .natvis files, see Create custom views of native objects in the Visual Studio debugger.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Command Line property page in the Linker folder.
3. Add the /NATVIS option to the Additional Options text box.
To set this linker option programmatically
This option does not have a programmatic equivalent.
See also
MSVC linker reference
MSVC Linker Options
/NOASSEMBLY (Create a MSIL Module)
3/12/2019 • 2 minutes to read • Edit Online
/NOASSEMBLY
Remarks
The /NOASSEMBLY option tells the linker to create an image for the current output file without a .NET
Framework assembly. An MSIL output file without an assembly manifest is called a module.
By default, an assembly is created. You can also use the /LN (Create MSIL Module) compiler option to create a
module.
Other linker options that affect assembly generation are:
/ASSEMBLYDEBUG
/ASSEMBLYLINKRESOURCE
/ASSEMBLYMODULE
/ASSEMBLYRESOURCE
/DELAYSIGN
/KEYFILE
/KEYCONTAINER
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Turn Off Assembly Generation property.
To set this linker option programmatically
See TurnOffAssemblyGeneration.
See also
MSVC linker reference
MSVC Linker Options
/NODEFAULTLIB (Ignore Libraries)
3/12/2019 • 2 minutes to read • Edit Online
/NODEFAULTLIB[:library]
Arguments
library
A library that you want the linker to ignore when it resolves external references.
Remarks
The /NODEFAULTLIB option tells the linker to remove one or more default libraries from the list of libraries it
searches when resolving external references.
To create an .obj file that does not contain references to default libraries, use /Zl (Omit Default Library Name).
By default, /NODEFAULTLIB removes all default libraries from the list of libraries it searches when resolving
external references. The optional library parameter lets you remove a specified library or libraries from the list of
libraries it searches when resolving external references. Specify one /NODEFAULTLIB option for each library you
want to exclude.
The linker resolves references to external definitions by searching first in libraries that you explicitly specify, then
in default libraries specified with the /DEFAULTLIB option, and then in default libraries named in .obj files.
/NODEFAULTLIB:library overrides /DEFAULTLIB:library when the same library name is specified in both.
If you use /NODEFAULTLIB, for example, to build your program without the C run-time library, you may have to
also use /ENTRY to specify the entry point (function) in your program. For more information, see CRT Library
Features.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Inputproperty page.
4. Select the Ignore All Default Libraries property or specify a list of the libraries you want to ignore in the
Ignore Specific Library property. The Command Line property page will show the effect of the changes
you make to these properties.
To set this linker option programmatically
See IgnoreDefaultLibraryNames and IgnoreAllDefaultLibraries.
See also
MSVC linker reference
MSVC Linker Options
/NOENTRY (No Entry Point)
3/12/2019 • 2 minutes to read • Edit Online
/NOENTRY
Remarks
The /NOENTRY option is required for creating a resource-only DLL that contains no executable code. For more
information, see Creating a Resource-Only DLL.
Use this option to prevent LINK from linking a reference to _main into the DLL.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Advanced property page.
4. Modify the No Entry Point property.
To set this linker option programmatically
1. See ResourceOnlyDLL.
See also
Creating a Resource-Only DLL
MSVC linker reference
MSVC Linker Options
/NOLOGO (Suppress Startup Banner) (Linker)
3/12/2019 • 2 minutes to read • Edit Online
/NOLOGO
Remarks
The /NOLOGO option prevents display of the copyright message and version number.
This option also suppresses echoing of command files. For details, see LINK Command Files.
By default, this information is sent by the linker to the Output window. On the command line, it is sent to standard
output and can be redirected to a file.
To set this linker option in the Visual Studio development environment
1. This option should only be used from the command line.
To set this linker option programmatically
1. This linker option cannot be changed programmatically.
See also
MSVC linker reference
MSVC Linker Options
/NXCOMPAT (Compatible with Data Execution
Prevention)
3/12/2019 • 2 minutes to read • Edit Online
Indicates that an executable is compatible with the Windows Data Execution Prevention feature.
Syntax
/NXCOMPAT[:NO ]
Remarks
By default, /NXCOMPAT is on.
/NXCOMPAT:NO can be used to explicitly specify an executable as incompatible with Data Execution Prevention.
For more information about Data Execution Prevention, see these articles:
A detailed description of the Data Execution Prevention (DEP ) feature
Data Execution Prevention
Data Execution Prevention (Windows Embedded)
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Choose the Configuration Properties > Linker > Command Line property page.
3. Enter the option in the Additional Options box. Choose OK or Apply to apply the change.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/OPT (Optimizations)
3/12/2019 • 4 minutes to read • Edit Online
Syntax
/OPT:{REF | NOREF}
/OPT:{ICF[=iterations] | NOICF}
/OPT:{LBR | NOLBR}
Arguments
REF | NOREF
/OPT:REF eliminates functions and data that are never referenced; /OPT:NOREF keeps functions and data that
are never referenced.
When /OPT:REF is enabled, LINK removes unreferenced packaged functions and data, known as COMDATs.
This optimization is known as transitive COMDAT elimination. The /OPT:REF option also disables incremental
linking.
Inlined functions and member functions defined inside a class declaration are always COMDATs. All of the
functions in an object file are made into COMDATs if it is compiled by using the /Gy option. To place const data
in COMDATs, you must declare it by using __declspec(selectany) . For information about how to specify data for
removal or folding, see selectany.
By default, /OPT:REF is enabled by the linker unless /OPT:NOREF or /DEBUG is specified. To override this
default and keep unreferenced COMDATs in the program, specify /OPT:NOREF. You can use the /INCLUDE
option to override the removal of a specific symbol.
If /DEBUG is specified, the default for /OPT is NOREF, and all functions are preserved in the image. To override
this default and optimize a debug build, specify /OPT:REF. This can reduce the size of your executable, and can
be a useful optimization even in debug builds. We recommend that you also specify /OPT:NOICF to preserve
identical functions in debug builds. This makes it easier to read stack traces and set breakpoints in functions that
would otherwise be folded together.
ICF[=iterations] | NOICF
Use ICF[=iterations] to perform identical COMDAT folding. Redundant COMDATs can be removed from the
linker output. The optional iterations parameter specifies the number of times to traverse the symbols for
duplicates. The default number of iterations is 1. Additional iterations may locate more duplicates that are
uncovered through folding in the previous iteration.
By default, /OPT:ICF is enabled by the linker unless /OPT:NOICF or /DEBUG is specified. To override this
default and prevent COMDATs from being folded in the program, specify /OPT:NOICF.
In a debug build, you must explicitly specify /OPT:ICF to enable COMDAT folding. However, because /OPT:ICF
can merge identical data or functions, it can change the function names that appear in stack traces. It can also
make it impossible to set breakpoints in certain functions or to examine some data in the debugger, and can take
you into unexpected functions when you single-step through your code. The behavior of the code is identical, but
the debugger presentation can be very confusing. Therefore, we do not recommend that you use /OPT:ICF in
debug builds unless the advantages of smaller code outweigh these disadvantages.
NOTE
Because /OPT:ICF can cause the same address to be assigned to different functions or read-only data members (that is,
const variables when compiled by using /Gy), it can break a program that depends on unique addresses for functions or
read-only data members. For more information, see /Gy (Enable Function-Level Linking).
LBR | NOLBR
The /OPT:LBR and /OPT:NOLBR options apply only to ARM binaries. Because certain ARM processor branch
instructions have a limited range, if the linker detects a jump to an out-of-range address, it replaces the branch
instruction’s destination address with the address of a code "island" that contains a branch instruction that
targets the actual destination. You can use /OPT:LBR to optimize the detection of long branch instructions and
the placement of intermediate code islands to minimize overall code size. /OPT:NOLBR instructs the linker to
generate code islands for long branch instructions as they are encountered, without optimization.
By default, the /OPT:LBR option is set when incremental linking is not enabled. If you want a non-incremental
link but not long branch optimizations, specify /OPT:NOLBR. The /OPT:LBR option disables incremental
linking.
Remarks
When used at the command line, the linker defaults to /OPT:REF,ICF,LBR. If /DEBUG is specified, the default is
/OPT:NOREF,NOICF,NOLBR.
The /OPT optimizations generally decrease the image size and increase the program speed. These
improvements can be substantial in larger programs, which is why they are enabled by default for retail builds.
Linker optimization does take extra time up front, but the optimized code also saves time when the linker has
fewer relocations to fix up and creates a smaller final image, and it saves even more time when it has less debug
information to process and write into the PDB. When optimization is enabled, it can result in a faster link time
overall, as the small additional cost in analysis may be more than offset by the time savings in linker passes over
smaller binaries.
The /OPT arguments may be specified together, separated by commas. For example, instead of /OPT:REF
/OPT:NOICF, you can specify /OPT:REF,NOICF.
You can use the /VERBOSE linker option to see the functions that are removed by /OPT:REF and the functions
that are folded by /OPT:ICF.
The /OPT arguments are often set for projects created by using the New Project dialog in the Visual Studio
IDE, and usually have different values for debug and release configurations. If no value is set for these linker
options in your project, then you may get the project defaults, which can be different from the default values
used by the linker at the command line.
To set the OPT:ICF or OPT:REF linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Optimization property page.
3. Modify one of these properties:
Enable COMDAT Folding
References
To set the OPT:LBR linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. Enter the option in Additional Options:
/opt:lbr or /opt:nolbr
See also
MSVC linker reference
MSVC Linker Options
/ORDER (Put Functions in Order)
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/ORDER:@filename
Parameters
filename
A text file that specifies the link order for COMDAT functions.
Remarks
The /ORDER compiler option allows you to optimize your program's paging behavior by grouping a function
together with the functions it calls. You can also group frequently called functions together. These techniques,
known as swap tuning or paging optimization, increase the probability that a called function is in memory when it
is needed and does not have to be paged from disk.
When you compile your source code into an object file, you can tell the compiler to put each function into its own
section, called a COMDAT, by using the /Gy (Enable function-level linking) compiler option. The /ORDER linker
option tells the linker to place COMDATs into the executable image in the order you specify.
To specify the COMDAT order, create a response file, a text file that lists each COMDAT by name, one per line, in
the order you want them to be placed by the linker. Pass the name of this file as the filename parameter of the
/ORDER option. For C++ functions, the name of a COMDAT is the decorated form of the function name. Use the
undecorated name for C functions, main , and for C++ functions declared as extern "C" . Function names and
decorated names are case sensitive. For more information on decorated names, see Decorated Names.
To find the decorated names of your COMDATs, use the DUMPBIN tool's /SYMBOLS option on the object file.
The linker automatically prepends an underscore (_) to function names in the response file unless the name starts
with a question mark (?) or at sign (@). For example, if a source file, example.cpp, contains functions
int cpp_func(int) , extern "C" int c_func(int) and int main(void) , the command
DUMPBIN /SYMBOLS example.obj lists these decorated names:
...
088 00000000 SECT1A notype () External | ?cpp_func@@YAHH@Z (int __cdecl cpp_func(int))
089 00000000 SECT22 notype () External | _c_func
08A 00000000 SECT24 notype () External | _main
...
In this case, specify the names as ?cpp_func@@YAHH@Z , c_func , and main in your response file.
If more than one /ORDER option appears in the linker options, the last one specified takes effect.
The /ORDER option disables incremental linking. You may see linker warning LNK4075 when you specify this
option if incremental linking is enabled, or if you have specified the /ZI (Incremental PDB ) compiler option. To
silence this warning, you can use the /INCREMENTAL:NO linker option to turn off incremental linking, and use
the /Zi (Generate PDB ) compiler option to generate a PDB without incremental linking.
NOTE
LINK cannot order static functions because static function names are not public symbol names. When /ORDER is specified,
linker warning LNK4037 is generated for each symbol in the order response file that is either static or not found.
See also
MSVC linker reference
MSVC Linker Options
/OUT (Output File Name)
3/12/2019 • 2 minutes to read • Edit Online
/OUT:filename
Arguments
filename
A user-specified name for the output file. It replaces the default name.
Remarks
The /OUT option overrides the default name and location of the program that the linker creates.
By default, the linker forms the file name using the base name of the first .obj file specified and the appropriate
extension (.exe or .dll).
This option the default base name for a .mapfile or import library. For details, see Generate Mapfile (/MAP ) and
/IMPLIB.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the General property page.
4. Modify the Output File property.
To set this linker option programmatically
See OutputFile.
See also
MSVC linker reference
MSVC Linker Options
/PDB (Use Program Database)
3/12/2019 • 2 minutes to read • Edit Online
/PDB:filename
Arguments
filename
A user-specified name for the program database (PDB ) that the linker creates. It replaces the default name.
Remarks
By default, when /DEBUG is specified, the linker creates a program database (PDB ) which holds debugging
information. The default file name for the PDB has the base name of the program and the extension .pdb.
Use /PDB:filename to specify the name of the PDB file. If /DEBUG is not specified, the /PDB option is ignored.
A PDB file can be up to 2GB.
For more information, see .pdb Files as Linker Input.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debug property page.
4. Modify the Generate Program Database File property.
To set this linker option programmatically
See ProgramDatabaseFile.
See also
MSVC linker reference
MSVC Linker Options
/PDBALTPATH (Use Alternate PDB Path)
3/12/2019 • 2 minutes to read • Edit Online
/PDBALTPATH:pdb_file_name
Arguments
pdb_file_name
The path and file name for the .pdb file.
Remarks
Use this option to provide an alternate location for the Program Database (.pdb) file in a compiled binary file.
Normally, the linker records the location of the .pdb file in the binaries that it produces. You can use this option to
provide a different path and file name for the .pdb file. The information provided with /PDBALTPATH does not
change the location or name of the actual .pdb file; it changes the information that the linker writes in the binary
file. This enables you to provide a path that is independent of the file structure of the build computer. Two common
uses for this option are to provide a network path or a file that has no path information.
The value of pdb_file_name can be an arbitrary string, an environment variable, or %_PDB%. The linker will
expand an environment variable, such as %SystemRoot%, to its value. The linker defines the environment
variables %_PDB% and %_EXT%. %_PDB% expands to the file name of the actual .pdb file without any path
information and %_EXT% is the extension of the generated executable.
See also
DUMPBIN Options
/PDBPATH
/PDBSTRIPPED (Strip Private Symbols)
3/12/2019 • 2 minutes to read • Edit Online
/PDBSTRIPPED:pdb_file_name
Arguments
pdb_file_name
A user-specified name for the stripped program database (PDB ) that the linker creates.
Remarks
The /PDBSTRIPPED option creates a second program database (PDB ) file when you build your program image
with any of the compiler or linker options that generate a PDB file (/DEBUG, /Z7, /Zd, or /Zi). This second PDB file
omits symbols that you would not want to ship to your customers. The second PDB file will only contain:
Public symbols
The list of object files and the portions of the executable to which they contribute
Frame pointer optimization (FPO ) debug records used to traverse the stack
The stripped PDB file will not contain:
Type information
Line number information
Per-object file CodeView symbols such as those for functions, locals, and static data
The full PDB file will still be generated when you use /PDBSTRIPPED.
If you do not create a PDB file, /PDBSTRIPPED is ignored.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Debug property page.
4. Modify the Strip Private Symbols property.
To set this linker option programmatically
See StripPrivateSymbols.
See also
MSVC linker reference
MSVC Linker Options
/PGD (Specify Database for Profile-Guided
Optimizations)
3/12/2019 • 2 minutes to read • Edit Online
The /PGD option is deprecated. Starting in Visual Studio 2015, prefer the /GENPROFILE or
/FASTGENPROFILE linker options instead. This option is used to specify the name of the .pgd file used by the
profile-guided optimization process.
Syntax
/PGD:filename
Argument
filename
Specifies the name of the .pgd file that is used to hold information about the running program.
Remarks
When using the deprecated /LTCG:PGINSTRUMENT option, use /PGD to specify a nondefault name or location
for the .pgd file. If you do not specify /PGD, the .pgd file base name is the same as the output file (.exe or .dll) base
name and is created in the same directory from which the link was invoked.
When using the deprecated /LTCG:PGOPTIMIZE option, use the /PGD option to specify the name of the .pgd
file to use to create the optimized image. The filename argument should match the filename specified to
/LTCG:PGINSTRUMENT.
For more information, see Profile-Guided Optimizations.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Optimization property page.
3. Modify the Profile Guided Database property. Choose OK to save your changes.
To set this linker option programmatically
1. See ProfileGuidedDatabase.
See also
MSVC linker reference
MSVC Linker Options
/POGOSAFEMODE (Run PGO in thread safe mode)
3/12/2019 • 2 minutes to read • Edit Online
The /POGOSAFEMODE option is deprecated starting in Visual Studio 2015. Use the /GENPROFILE:EXACT
and /GENPROFILE:NOEXACT options instead. The /POGOSAFEMODE linker option specifies that the
instrumented build is created to use thread-safe mode for profile data capture during profile-guided optimization
(PGO ) training runs.
Syntax
/POGOSAFEMODE
Remarks
Profile-guided optimization (PGO ) has two possible modes during the profiling phase: fast mode and safe mode.
When profiling is in fast mode, it uses an increment instruction to increase data counters. The increment
instruction is faster but is not thread-safe. When profiling is in safe mode, it uses the interlocked-increment
instruction to increase data counters. This instruction has the same functionality as the increment instruction has,
and is thread-safe, but it is slower.
The /POGOSAFEMODE option sets the instrumented build to use safe mode. This option can only be used when
the deprecated /LTCG:PGINSTRUMENT is specified, during the PGO instrumentation linker phase.
By default, PGO profiling operates in fast mode. /POGOSAFEMODE is only required if you want to use safe
mode.
To run PGO profiling in safe mode, you must use either /GENPROFILE:EXACT (preferred), or use the
environment variable PogoSafeMode or the linker switch /POGOSAFEMODE, depending on the system. If you
are performing the profiling on an x64 computer, you must use the linker switch. If you are performing the
profiling on an x86 computer, you may use the linker switch or define the environment variable to any value before
you start the PGO instrumentation process.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Optimization property page.
3. In the Link Time Code Generation property, choose Profile Guided Optimization - Instrument
(/LTCG:PGInstrument).
4. Select the Configuration Properties > Linker > Command Line property page.
5. Enter the /POGOSAFEMODE option into the Additional Options box. Choose OK to save your changes.
To set this linker option programmatically
See AdditionalOptions.
See also
/GENPROFILE and /FASTGENPROFILE
/LTCG
Profile-Guided Optimizations
Environment Variables for Profile-Guided Optimizations
/PROFILE (Performance Tools Profiler)
3/12/2019 • 2 minutes to read • Edit Online
Produces an output file that can be used with the Performance Tools profiler.
Syntax
/PROFILE
Remarks
/PROFILE implies the following linker options:
/OPT:REF
/OPT:NOICF
/INCREMENTAL:NO
/FIXED:NO
/PROFILE causes the linker to generate a relocation section in the program image. A relocation section allows the
profiler to transform the program image to get profile data.
/PROFILE is only available only in Enterprise (team development) versions. For more information on PREfast, see
Code Analysis for C/C++ Overview.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Expand the Configuration Properties node.
3. Expand the Linker node.
4. Select the Advanced property page.
5. Modify the Profile property.
To set this linker option programmatically
1. See Profile.
See also
MSVC linker reference
MSVC Linker Options
/RELEASE (Set the Checksum)
3/12/2019 • 2 minutes to read • Edit Online
/RELEASE
Remarks
The /RELEASE option sets the Checksum in the header of an .exe file.
The operating system requires the Checksum for device drivers. Set the Checksum for release versions of your
device drivers to ensure compatibility with future operating systems.
The /RELEASE option is set by default when the /SUBSYSTEM:NATIVE option is specified.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Advanced property page.
4. Modify the Set Checksum property.
To set this linker option programmatically
See SetChecksum.
See also
MSVC linker reference
MSVC Linker Options
/SAFESEH (Image has Safe Exception Handlers)
3/12/2019 • 2 minutes to read • Edit Online
/SAFESEH[:NO]
When /SAFESEH is specified, the linker will only produce an image if it can also produce a table of the image's
safe exception handlers. This table specifies for the operating system which exception handlers are valid for the
image.
/SAFESEH is only valid when linking for x86 targets. /SAFESEH is not supported for platforms that already have
the exception handlers noted. For example, on x64 and ARM, all exception handlers are noted in the PDATA.
ML64.exe has support for adding annotations that emit SEH information (XDATA and PDATA) into the image,
allowing you to unwind through ml64 functions. See MASM for x64 (ml64.exe) for more information.
If /SAFESEH is not specified, the linker will produce an image with a table of safe exceptions handlers if all
modules are compatible with the safe exception handling feature. If any modules were not compatible with safe
exception handling feature, the resulting image will not contain a table of safe exception handlers. If /SUBSYSTEM
specifies WINDOWSCE or one of the EFI_* options, the linker will not attempt to produce an image with a table of
safe exceptions handlers, as neither of those subsystems can make use of the information.
If /SAFESEH:NO is specified, the linker will not produce an image with a table of safe exceptions handlers even if
all modules are compatible with the safe exception handling feature.
The most common reason for the linker not to be able to produce an image is because one or more of the input
files (modules) to the linker was not compatible with the safe exception handlers feature. A common reason for a
module to not be compatible with safe exception handlers is because it was created with a compiler from a
previous version of Visual C++.
You can also register a function as a structured exception handler by using .SAFESEH.
It is not possible to mark an existing binary as having safe exception handlers (or no exception handlers);
information on safe exception handling must be added at build time.
The linker's ability to build a table of safe exception handlers depends on the application using the C runtime
library. If you link with /NODEFAULTLIB and you want a table of safe exception handlers, you need to supply a
load config struct (such as can be found in loadcfg.c CRT source file) that contains all the entries defined for Visual
C++. For example:
#include <windows.h>
extern DWORD_PTR __security_cookie; /* /GS security cookie */
/*
* The following two names are automatically created by the linker for any
* image that has the safe exception table present.
*/
See also
MSVC linker reference
MSVC Linker Options
/SECTION (Specify Section Attributes)
3/12/2019 • 2 minutes to read • Edit Online
/SECTION:name,[[!]{DEKPRSW }][,ALIGN=number]
Remarks
The /SECTION option changes the attributes of a section, overriding the attributes set when the .obj file for the
section was compiled.
A section in a portable executable (PE ) file is a named contiguous block of memory that contains either code or
data. Some sections contain code or data that your program declared and uses directly, while other data sections
are created for you by the linker and library manager (lib.exe) and contain information vital to the operating
system. For more information, see PE Format.
Specify a colon (:) and a section name. The name is case sensitive.
Do not use the following names, as they conflict with standard names. For example, .sdata is used on RISC
platforms:
.arch
.bss
.data
.edata
.idata
.pdata
.rdata
.reloc
.rsrc
.sbss
.sdata
.srdata
.text
.xdata
Specify one or more attributes for the section. The attribute characters, listed below, are not case sensitive. You
must specify all attributes that you want the section to have; an omitted attribute character causes that attribute bit
to be turned off. If you do not specify R, W, or E, the existing read, write, or executable status remains unchanged.
To negate an attribute, precede its character with an exclamation point (!). The meanings of the attribute characters
are shown in this table:
CHARACTER ATTRIBUTE MEANING
K and P are unusual in that the section flags that correspond to them are used in the negative sense. If you specify
one of them on the .text section by using the /SECTION:.text,K option, there is no difference in the section flags
when you run DUMPBIN with the /HEADERS option; the section was already implicitly cached. To remove the
default, specify /SECTION:.text,!K instead. DUMPBIN reveals section characteristics, including "Not Cached."
A section in the PE file that does not have E, R, or W set is probably invalid.
The ALIGN=number argument lets you specify an alignment value for a particular section. The number argument
is in bytes and must be a power of two. See /ALIGN for more information.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Choose the Configuration Properties > Linker > Command Line property page.
3. Enter the option in the Additional Options box. Choose OK or Apply to apply the change.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/SOURCELINK (Include Source Link file in PDB)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a Source Link configuration file to include in the PDB file generated by the linker.
Syntax
/SOURCELINK:filename
Arguments
filename
Specifies a JSON -formatted configuration file that contains a simple mapping of local file paths to URLs where the
source file can be retrieved for display by the debugger. For more information on the format of this file, see Source
Link JSON Schema.
Remarks
Source Link is a language- and source-control agnostic system for providing source debugging for binaries.
Source Link is supported for native C++ binaries starting in Visual Studio 2017 version 15.8. For an overview of
Source Link, see Source Link. For information on how to use Source Link in your projects and how to generate the
SourceLink file as part of your project, see Using Source Link.
To set the /SOURCELINK linker option in Visual Studio
1. Open the Property Pages dialog box for the project. For more information, see Set C++ compiler and
build properties in Visual Studio.
2. Select the Configuration Properties > Linker > Command Line property page.
3. In the Additional options box, add /SOURCELINK:filename and then choose OK or Apply to save your
changes.
To set this linker option programmatically
This option does not have a programmatic equivalent.
See also
MSVC linker reference
MSVC Linker Options
/STACK (Stack Allocations)
3/12/2019 • 2 minutes to read • Edit Online
/STACK:reserve[,commit]
Remarks
The /STACK option sets the size of the stack in bytes. Use this option only when you build an .exe file.
The reserve value specifies the total stack allocation in virtual memory. For ARM, x86 and x64 machines, the
default stack size is 1 MB.
commit is subject to interpretation by the operating system. In Windows WindowsRT it specifies the amount of
physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A
higher commit value saves time when the application needs more stack space, but increases the memory
requirements and possibly the startup time. For ARM, x86 and x64 machines, the default commit value is 4 KB.
Specify the reserve and commit values in decimal or C -language notation.
Another way to set the size of the stack is with the STACKSIZE statement in a module-definition (.def) file.
STACKSIZE overrides the Stack Allocations (/STACK) option if both are specified. You can change the stack size
after the .exe file is built by using the EDITBIN tool.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the System property page.
4. Modify one of the following properties:
Stack Commit Size
Stack Reserve Size
To set this linker option programmatically
1. See StackCommitSize and StackReserveSize properties.
See also
MSVC linker reference
MSVC Linker Options
/STUB (MS-DOS Stub File Name)
3/12/2019 • 2 minutes to read • Edit Online
/STUB:filename
Arguments
filename
An MS -DOS application.
Remarks
The /STUB option attaches an MS -DOS stub program to a Win32 program.
A stub program is invoked if the file is executed in MS -DOS. It usually displays an appropriate message; however,
any valid MS -DOS application can be a stub program.
Specify a filename for the stub program after a colon (:) on the command line. The linker checks filename and
issues an error message if the file is not an executable. The program must be an .exe file; a .com file is invalid for a
stub program.
If this option is not used, the linker attaches a default stub program that issues the following message:
When building a virtual device driver, filename allows the user to specify a file name that contains an
IMAGE_DOS_HEADER structure (defined in WINNT.H) to be used in the VXD, rather than the default header.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
/SUBSYSTEM (Specify Subsystem)
3/12/2019 • 2 minutes to read • Edit Online
/SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION|
EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|
POSIX|WINDOWS)
[,major[.minor]]
Arguments
BOOT_APPLICATION
An application that runs in the Windows boot environment. For more information about boot applications, see
About BCD.
CONSOLE
Win32 character-mode application. The operating system provides a console for console applications. If main or
wmain is defined for native code, int main(array<String ^> ^) is defined for managed code, or you build the
application completely by using /clr:safe , CONSOLE is the default.
EFI_APPLICATION
EFI_BOOT_SERVICE_DRIVER
EFI_ROM
EFI_RUNTIME_DRIVER
The Extensible Firmware Interface subsystems. See the EFI specification for more information. For examples, see
the Intel Web site. The minimum version and default version is 1.0.
NATIVE
Kernel mode drivers for Windows NT. This option is usually reserved for Windows system components. If
/DRIVER:WDM is specified, NATIVE is the default.
POSIX
Application that runs with the POSIX subsystem in Windows NT.
WINDOWS
Application does not require a console, probably because it creates its own windows for interaction with the user.
If WinMain or wWinMain is defined for native code, or WinMain(HISTANCE *, HINSTANCE *, char *, int) or
wWinMain(HINSTANCE *, HINSTANCE *, wchar_t *, int) is defined for managed code, WINDOWS is the default.
Remarks
The /SUBSYSTEM option specifies the environment for the executable.
The choice of subsystem affects the entry point symbol (or entry point function) that the linker will select.
The optional minimum and default major and minor version numbers for the subsystems are as follows.
SUBSYSTEM MINIMUM DEFAULT
CONSOLE 5.01 (x86) 5.02 (x64) 6.02 (ARM) 6.00 (x86, x64) 6.02 (ARM)
WINDOWS 5.01 (x86) 5.02 (x64) 6.02 (ARM) 6.00 (x86, x64) 6.02 (ARM)
NATIVE (with DRIVER:WDM) 1.00 (x86) 1.10 (x64, ARM) 1.00 (x86) 1.10 (x64, ARM)
NATIVE (without /DRIVER:WDM) 4.00 (x86) 5.02 (x64) 6.02 (ARM) 4.00 (x86) 5.02 (x64) 6.02 (ARM)
See also
MSVC linker reference
MSVC Linker Options
/SWAPRUN (Load Linker Output to Swap File)
3/12/2019 • 2 minutes to read • Edit Online
/SWAPRUN:{NET|CD}
Remarks
The /SWAPRUN option tells the operating system to first copy the linker output to a swap file, and then run the
image from there. This is a Windows NT 4.0 (and later) feature.
If NET is specified, the operating system will first copy the binary image from the network to a swap file and load it
from there. This option is useful for running applications over the network. When CD is specified, the operating
system will copy the image on a removable disk to a page file and then load it.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the System property page.
4. Modify one of the following properties:
Swap Run From CD
Swap Run From Network
To set this linker option programmatically
1. See SwapRunFromCD and SwapRunFromNet properties.
See also
MSVC linker reference
MSVC Linker Options
/TLBID (Specify Resource ID for TypeLib)
3/12/2019 • 2 minutes to read • Edit Online
/TLBID:id
Arguments
id
A user-specified value for a linker-created type library. It overrides the default resource ID of 1.
Remarks
When compiling a program that uses attributes, the linker will create a type library. The linker will assign a
resource ID of 1 to the type library.
If this resource ID conflicts with one of your existing resources, you can specify another ID with /TLBID. The range
of values that you can pass to id is 1 to 65535.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Embedded IDL property page.
4. Modify the TypeLib Resource ID property.
To set this linker option programmatically
1. See TypeLibraryResourceID.
See also
MSVC linker reference
MSVC Linker Options
/TLBOUT (Name .TLB File)
3/12/2019 • 2 minutes to read • Edit Online
/TLBOUT:[path\]filename
Arguments
path
An absolute or relative path specification for where the .tlb file should be created.
filename
Specifies the name of the .tlb file created by the MIDL compiler. No file extension is assumed; specify filename.tlb
if you want a .tlb extension.
Remarks
The /TLBOUT option specifies the name and extension of the .tlb file.
The MIDL compiler is called by the MSVC linker when linking projects that have the module attribute.
If /TLBOUT is not specified, the .tlb file will get its name from /IDLOUT filename. If /IDLOUT is not specified, the
.tlb file will be called vc70.tlb.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Embedded IDL property page.
4. Modify the Type Library property.
To set this linker option programmatically
1. See TypeLibraryFile.
See also
MSVC linker reference
MSVC Linker Options
/IGNOREIDL (Don't Process Attributes into MIDL )
/MIDL (Specify MIDL Command Line Options)
Building an Attributed Program
/TSAWARE (Create Terminal Server Aware
Application)
3/12/2019 • 2 minutes to read • Edit Online
/TSAWARE[:NO]
Remarks
The /TSAWARE option sets a flag in the IMAGE_OPTIONAL_HEADER DllCharacteristics field in the program
image's optional header. When this flag is set, Terminal Server will not make certain changes to the application.
When an application is not Terminal Server aware (also known as a legacy application), Terminal Server makes
certain modifications to the legacy application to make it work properly in a multiuser environment. For example,
Terminal Server will create a virtual Windows folder, such that each user gets a Windows folder instead of getting
the system's Windows directory. This gives users access to their own INI files. In addition, Terminal Server makes
some adjustments to the registry for a legacy application. These modifications slow the loading of the legacy
application on Terminal Server.
If an application is Terminal Server aware, it must neither rely on INI files nor write to the
HKEY_CURRENT_USER registry during setup.
If you use /TSAWARE and your application still uses INI files, the files will be shared by all users of the system. If
that is acceptable, you can still link your application with /TSAWARE; otherwise you need to use /TSAWARE:NO.
The /TSAWARE option is enabled by default for Windows and console applications. See /SUBSYSTEM and
/VERSION for information.
/TSAWARE is not valid for drivers, VxDs, or DLLs.
If an application was linked with /TSAWARE, DUMPBIN /HEADERS will display information to that effect.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the System property page.
4. Modify the Terminal Server property.
To set this linker option programmatically
See TerminalServerAware.
See also
MSVC linker reference
MSVC Linker Options
Storing User-Specific Information
Legacy Applications in a Terminal Services Environment
/USEPROFILE (Run PGO in thread safe mode)
3/12/2019 • 2 minutes to read • Edit Online
This linker option together with /LTCG (Link-time code generation tells the linker to build by using profile-guided
optimization (PGO ) training data.
Syntax
/USEPROFILE [:{AGGRESSIVE|PGD=filename}]
Arguments
AGGRESSIVE
This optional argument specifies that aggressive speed optimizations should be used during optimized code
generation.
PGD=filename
Specifies a base file name for the .pgd file. By default, the linker uses the base executable file name with a .pgd
extension.
Remarks
The /USEPROFILE linker option is used together with /LTCG to generate or update an optimized build based on
PGO training data. It is the equivalent of the deprecated /LTCG:PGUPDATE and /LTCG:PGOPTIMIZE options.
The optional AGGRESSIVE argument disables size-related heuristics to attempt to optimize for speed. This may
result in optimizations that substantially increase the size of your executable, and may not increase the resulting
speed. You should profile and compare the results of using and not using AGGRESSIVE. This argument must be
specified explicitly; it is not enabled by default.
The PGD argument specifies an optional name for the training data .pgd file to use, the same as in /GENPROFILE
or /FASTGENPROFILE. It is the equivalent of the deprecated /PGD switch. By default, or if no filename is
specified, a .pgd file that has the same base name as the executable is used.
The /USEPROFILE linker option is new in Visual Studio 2015.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Optimization property page.
3. In the Link Time Code Generation property, choose Use Link Time Code Generation (/LTCG).
4. Select the Configuration Properties > Linker > Command Line property page.
5. Enter the /USEPROFILE option and optional arguments into the Additional Options box. Choose OK to
save your changes.
To set this linker option programmatically
See AdditionalOptions.
See also
/GENPROFILE and /FASTGENPROFILE
/LTCG
Profile-Guided Optimizations
Environment Variables for Profile-Guided Optimizations
/VERBOSE (Print Progress Messages)
3/12/2019 • 2 minutes to read • Edit Online
/VERBOSE[:{ICF|INCR|LIB|REF|SAFESEH|UNUSEDLIBS}]
Remarks
The linker sends information about the progress of the linking session to the Output window. On the command
line, the information is sent to standard output and can be redirected to a file.
OPTION DESCRIPTION
/VERBOSE:ICF Display information about linker activity that results from the
use of /OPT:ICF.
/VERBOSE:REF Displays information about linker activity that results from the
use of /OPT:REF.
/VERBOSE:UNUSEDLIBS Displays information about any library files that are unused
when the image is created.
See also
MSVC linker reference
MSVC Linker Options
/VERSION (Version Information)
3/12/2019 • 2 minutes to read • Edit Online
/VERSION:major[.minor]
Arguments
major and minor
The version number you want in the header of the .exe or .dll file.
Remarks
The /VERSION option tells the linker to put a version number in the header of the .exe or .dll file. Use DUMPBIN
/HEADERS to see the image version field of the OPTIONAL HEADER VALUES to see the effect of /VERSION.
The major and minor arguments are decimal numbers in the range 0 through 65,535. The default is version 0.0.
The information specified with /VERSION does not affect the version information that appears for an application
when you view its properties in File Explorer. That version information comes from a resource file that is used to
build the application. See Version Information Editor for more information.
Another way to insert a version number is with the VERSION module-definition statement.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the General property page.
4. Modify the Version property.
To set this linker option programmatically
See Version.
See also
MSVC linker reference
MSVC Linker Options
/WHOLEARCHIVE (Include All Library Object Files)
3/12/2019 • 2 minutes to read • Edit Online
Force the linker to include all object files in the static library in the linked executable.
Syntax
/WHOLEARCHIVE [:library]
Remarks
The /WHOLEARCHIVE option forces the linker to include every object file from either a specified static library, or
if no library is specified, from all static libraries specified to the LINK command. To specify the /WHOLEARCHIVE
option for multiple libraries, you can use more than one /WHOLEARCHIVE switch on the linker command line. By
default, the linker includes object files in the linked output only if they export symbols referenced by other object
files in the executable. The /WHOLEARCHIVE option makes the linker treat all object files archived in a static
library as if they were specified individually on the linker command line.
The /WHOLEARCHIVE option can be used to re-export all the symbols from a static library. This allows you to
make sure that all of your library code, resources, and metadata are included when you create a component from
more than one static library. If you see warning LNK4264 when you create a static library that contains Windows
Runtime components for export, use the /WHOLEARCHIVE option when linking that library into another
component or app.
The /WHOLEARCHIVE option was introduced in Visual Studio 2015 Update 2.
To set this linker option in Visual Studio
1. Open the project Property Pages dialog box. For more information, see Set C++ compiler and build
properties in Visual Studio.
2. Select the Command Line property page under Configuration Properties, Linker.
3. Add the /WHOLEARCHIVE option to the Additional Options text box.
See also
MSVC linker reference
MSVC Linker Options
/WINMD (Generate Windows Metadata)
3/12/2019 • 2 minutes to read • Edit Online
/WINMD [:{NO|ONLY }]
Arguments
/WINMD
The default setting for Universal Windows Platform apps. The linker generates both the binary executable file and
the .winmd metadata file.
/WINMD:NO
The linker generates only the binary executable file, but not a .winmd file.
/WINMD:ONLY
The linker generates only the .winmd file, but not the binary executable file.
Remarks
The /WINMD linker option is used for UWP apps and Windows runtime components to control the creation of a
Windows Runtime metadata (.winmd) file. A .winmd file is a kind of DLL that contains metadata for Windows
runtime types and, in the case of runtime components, the implementations of those types. The metadata follows
the ECMA-335 standard.
By default, the output file name has the form binaryname.winmd. To specify a different file name, use the
/WINMDFILE option.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Configuration Properties > Linker > Windows Metadata property page.
3. In the Generate Windows Metadata drop-down list box, select the option you want.
See also
Walkthrough: Creating a Simple Windows Runtime component and calling it from JavaScript
Introduction to Microsoft Interface Definition Language 3.0
/WINMDFILE (Specify winmd File)
/WINMDKEYFILE (Specify winmd Key File)
/WINMDKEYCONTAINER (Specify Key Container)
/WINMDDELAYSIGN (Partially Sign a winmd)
MSVC linker reference
MSVC Linker Options
/WINMDFILE (Specify winmd File)
3/12/2019 • 2 minutes to read • Edit Online
Specifies the file name for the Windows Runtime Metadata (.winmd) output file that is generated by the /WINMD
linker option.
/WINMDFILE:filename
Remarks
Use the value that is specified in filename to override the default .winmd file name ( binaryname .winmd). Notice
that you do not append ".winmd" to filename . If multiple values are listed on the /WINMDFILE command line,
the last one takes precedence.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Windows Metadata property page.
4. In the Windows Metadata File box, enter the file location.
See also
/WINMD (Generate Windows Metadata)
MSVC linker reference
MSVC Linker Options
/WINMDKEYFILE (Specify winmd Key File)
3/12/2019 • 2 minutes to read • Edit Online
Specifies a key or a key pair to sign a Windows Runtime Metadata (.winmd) file.
/WINMDKEYFILE:filename
Remarks
Resembles the /KEYFILE linker option that is applied to a .winmd file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Windows Metadata property page.
4. In the Windows Metadata Key File box, enter the file location.
See also
MSVC linker reference
MSVC Linker Options
/WINMDKEYCONTAINER (Specify Key Container)
3/12/2019 • 2 minutes to read • Edit Online
/WINMDKEYCONTAINER:name
Remarks
Resembles the /KEYCONTAINER linker option that is applied to a (.winmd) file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Windows Metadata property page.
4. In the Windows Metadata Key Container box, enter the location.
See also
MSVC linker reference
MSVC Linker Options
/WINMDDELAYSIGN (Partially Sign a winmd)
3/12/2019 • 2 minutes to read • Edit Online
Enables partial signing of a Windows Runtime Metadata (.winmd) file by putting the public key in the file.
/WINMDDELAYSIGN[:NO]
Remarks
Resembles the /DELAYSIGN linker option that is applied to the .winmd file. Use /WINMDDELAYSIGN if you
want to put only the public key in the .winmd file. By default, the linker acts as if /WINMDDELAYSIGN:NO were
specified; that is, it does not sign the winmd file.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Select the Linker folder.
3. Select the Windows Metadata property page.
4. In the Windows Metadata Delay Sign drop-down list box, select the option you want.
See also
MSVC linker reference
MSVC Linker Options
/WX (Treat Linker Warnings as Errors)
3/12/2019 • 2 minutes to read • Edit Online
/WX[:NO]
Remarks
/WX causes no output file to be generated if the linker generates a warning.
This is similar to /WX for the compiler (see /w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we,
/wo, /Wv, /WX (Warning Level) for more information). However, specifying /WX for the compilation does not
imply that /WX will also be in effect for the link phase; you must explicitly specify /WX for each tool.
By default, /WX is not in effect. To treat linker warnings as errors, specify /WX. /WX:NO is the same as not
specifying /WX.
To set this linker option in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Click the Linker folder.
3. Click the Command Line property page.
4. Type the option into the Additional Options box.
To set this linker option programmatically
1. See AdditionalOptions.
See also
MSVC linker reference
MSVC Linker Options
Decorated Names
3/12/2019 • 4 minutes to read • Edit Online
Functions, data, and objects in C and C++ programs are represented internally by their decorated names. A
decorated name is an encoded string created by the compiler during compilation of an object, data, or function
definition. It records calling conventions, types, function parameters and other information together with the
name. This name decoration, also known as name mangling, helps the linker find the correct functions and objects
when linking an executable.
The decorated naming conventions have changed in various versions of Visual C++, and can also be different on
different target architectures. To link correctly with source files created by using Visual C++, C and C++ DLLs and
libraries should be compiled by using the same compiler toolset, flags, and target architecture.
Undecoration of :- "?func1@a@@AAEXH@Z"
is :- "private: void __thiscall a::func1(int)"
See also
Additional MSVC Build Tools
Using extern to Specify Linkage
Module-Definition (.Def ) Files
3/12/2019 • 2 minutes to read • Edit Online
Module-definition (.def) files provide the linker with information about exports, attributes, and other information
about the program to be linked. A .def file is most useful when building a DLL. Because there are MSVC Linker
Options that can be used instead of module-definition statements, .def files are generally not necessary. You can
also use __declspec(dllexport) as a way to specify exported functions.
You can invoke a .def file during the linker phase with the /DEF (Specify Module-Definition File) linker option.
If you are building an .exe file that has no exports, using a .def file will make your output file larger and slower
loading.
For an example, see Exporting from a DLL Using DEF Files.
See the following sections for more information:
Rules for Module-Definition Statements
EXPORTS
HEAPSIZE
LIBRARY
NAME
SECTIONS
STACKSIZE
STUB
VERSION
Reserved words
See also
C/C++ Building Reference
MSVC Linker Options
Rules for Module-Definition Statements
3/12/2019 • 2 minutes to read • Edit Online
The following syntax rules apply to all statements in a .def file. Other rules that apply to specific statements are
described with each statement.
Statements, attribute keywords, and user-specified identifiers are case sensitive.
Long file names containing spaces or semicolons (;) must be enclosed in quotation marks (").
Use one or more spaces, tabs, or newline characters to separate a statement keyword from its arguments
and to separate statements from each other. A colon (:) or equal sign (=) that designates an argument is
surrounded by zero or more spaces, tabs, or newline characters.
A NAME or LIBRARY statement, if used, must precede all other statements.
The SECTIONS and EXPORTS statements can appear more than once in the .def file. Each statement can
take multiple specifications, which must be separated by one or more spaces, tabs, or newline characters.
The statement keyword must appear once before the first specification and can be repeated before each
additional specification.
Many statements have an equivalent LINK command-line option. See the description of the corresponding
LINK option for additional details.
Comments in the .def file are designated by a semicolon (;) at the beginning of each comment line. A
comment cannot share a line with a statement, but it can appear between specifications in a multiline
statement. (SECTIONS and EXPORTS are multiline statements.)
Numeric arguments are specified in base 10 or hexadecimal.
If a string argument matches a reserved word, it must be enclosed in double quotation marks (").
See also
Module-Definition (.Def) Files
EXPORTS
3/12/2019 • 3 minutes to read • Edit Online
Introduces a section of one or more export definitions that specify the exported names or ordinals of functions or
data. Each definition must be on a separate line.
EXPORTS
definition
Remarks
The first definition can be on the same line as the EXPORTS keyword or on a subsequent line. The .DEF file can
contain one or more EXPORTS statements.
The syntax for an export definition is:
entryname is the function or variable name that you want to export. This is required. If the name that you export
differs from the name in the DLL, specify the export's name in the DLL by using internal_name. For example, if
your DLL exports a function func1 and you want callers to use it as func2 , you would specify:
EXPORTS
func2=func1
If the name that you export is from some other module, specify the export's name in the DLL by using
other_module.exported_name. For example, if your DLL exports a function other_module.func1 and you want
callers to use it as func2 , you would specify:
EXPORTS
func2=other_module.func1
If the name that you export is from another module that exports by ordinal, specify the export's ordinal in the DLL
by using other_module.#ordinal. For example, if your DLL exports a function from the other module where it is
ordinal 42, and you want callers to use it as func2 , you would specify:
EXPORTS
func2=other_module.#42
Because the MSVC compiler uses name decoration for C++ functions, you must either use the decorated name
internal_name or define the exported functions by using extern "C" in the source code. The compiler also
decorates C functions that use the __stdcall calling convention with an underscore (_) prefix and a suffix composed
of the at sign (@) followed by the number of bytes (in decimal) in the argument list.
To find the decorated names produced by the compiler, use the DUMPBIN tool or the linker /MAP option. The
decorated names are compiler-specific. If you export the decorated names in the .DEF file, executables that link to
the DLL must also be built by using the same version of the compiler. This ensures that the decorated names in
the caller match the exported names in the .DEF file.
You can use @ordinal to specify that a number, and not the function name, goes into the DLL's export table. Many
Windows DLLs export ordinals to support legacy code. It was common to use ordinals in 16-bit Windows code,
because it can help minimize the size of a DLL. We don’t recommend exporting functions by ordinal unless your
DLL’s clients need it for legacy support. Because the .LIB file will contain the mapping between the ordinal and
the function, you can use the function name as you normally would in projects that use the DLL.
By using the optional NONAME keyword, you can export by ordinal only and reduce the size of the export table
in the resulting DLL. However, if you want to use GetProcAddress on the DLL, you must know the ordinal
because the name will not be valid.
The optional keyword PRIVATE prevents entryname from being included in the import library generated by
LINK. It does not affect the export in the image also generated by LINK.
The optional keyword DATA specifies that an export is data, not code. This example shows how you could export
a data variable named exported_global :
EXPORTS
exported_global DATA
The #pragma directive is useful if you need to export an undecorated function name, and have different exports
depending on the build configuration (for example, in 32-bit or 64-bit builds).
All four methods can be used in the same program. When LINK builds a program that contains exports, it also
creates an import library, unless an .EXP file is used in the build.
Here's an example of an EXPORTS section:
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllWindowName = WindowName DATA
DllGetClassObject @4 NONAME PRIVATE
DllRegisterServer @7
DllUnregisterServer
When you export a variable from a DLL by using a .DEF file, you do not have to specify __declspec(dllexport) on
the variable. However, in any file that uses the DLL, you must still use __declspec(dllimport) on the declaration of
data.
See also
Rules for Module-Definition Statements
LIBRARY
3/12/2019 • 2 minutes to read • Edit Online
Tells LINK to create a DLL. At the same time, LINK creates an import library, unless an .exp file is used in the build.
LIBRARY [library][BASE=address]
Remarks
The library argument specifies the name of the DLL. You can also use the /OUT linker option to specify the DLL's
output name.
The BASE=address argument sets the base address that the operating system uses to load the DLL. This
argument overrides the default DLL location of 0x10000000. See the description of the /BASE option for details
about base addresses.
Remember to use the /DLL linker option when you build a DLL.
See also
Rules for Module-Definition Statements
HEAPSIZE
3/12/2019 • 2 minutes to read • Edit Online
/HEAP:reserve[,commit]
See also
Rules for Module-Definition Statements
NAME (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
NAME [application][BASE=address]
Remarks
An equivalent way to specify an output file name is with the /OUT linker option, and an equivalent way to set the
base address is with the /BASE linker option. If both are specified, /OUT overrides NAME.
If you build a DLL, NAME will only affect the DLL name.
See also
Rules for Module-Definition Statements
SECTIONS (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
Introduces a section of one or more definitions that are access specifiers on sections in your project's output file.
SECTIONS
definitions
Remarks
Each definition must be on a separate line. The SECTIONS keyword can be on the same line as the first definition or
on a preceding line. The .def file can contain one or more SECTIONS statements.
This SECTIONS statement sets attributes for one or more sections in the image file, and can be used to override the
default attributes for each type of section.
The format for definitions is:
.section_name specifier
where .section_name is the name of a section in your program image and specifier is one or more of the
following access modifiers:
MODIFIER DESCRIPTION
SHARED Shares the section among all processes that load the image
SECTIONS
.rdata READ WRITE
SECTIONS marks the beginning of a list of section definitions . Each definition must be on a separate line. The
SECTIONS keyword can be on the same line as the first definition or on a preceding line. The .def file can contain
one or more SECTIONS statements. The SEGMENTS keyword is supported as a synonym for SECTIONS .
Older versions of Visual C++ supported:
STACKSIZE reserve[,commit]
Remarks
An equivalent way to set the stack is with the Stack Allocations (/STACK) option. See the documentation on that
option for details about the reserve and commit arguments.
This option has no effect on DLLs.
See also
Rules for Module-Definition Statements
STUB
3/12/2019 • 2 minutes to read • Edit Online
When used in a module definition file that builds a virtual device driver (VxD ), allows you to specify a file name
that contains an IMAGE_DOS_HEADER structure (defined in WINNT.H) to be used in the virtual device driver
(VxD ), rather than the default header.
STUB:filename
Remarks
An equivalent way to specify filename is with the /STUB linker option.
STUB is valid in a module definition file only when building a VxD.
See also
Rules for Module-Definition Statements
VERSION (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
Tells LINK to put a number in the header of the .exe file or DLL.
VERSION major[.minor]
Remarks
The major and minor arguments are decimal numbers in the range 0 through 65,535. The default is version 0.0.
An equivalent way to specify a version number is with the Version Information (/VERSION ) option.
See also
Rules for Module-Definition Statements
Linker Support for Delay-Loaded DLLs
3/12/2019 • 2 minutes to read • Edit Online
The MSVC linker now supports the delayed loading of DLLs. This relieves you of the need to use the Windows
SDK functions LoadLibrary and GetProcAddress to implement DLL delayed loading.
Before Visual C++ 6.0, the only way to load a DLL at run time was by using LoadLibrary and GetProcAddress;
the operating system would load the DLL when the executable or DLL using it was loaded.
Beginning with Visual C++ 6.0, when implicitly linking with a DLL, the linker provides options to delay load the
DLL until the program calls a function in that DLL.
An application can delay load a DLL using the /DELAYLOAD (Delay Load Import) linker option with a helper
function (default implementation provided by Visual C++). The helper function will load the DLL at run time by
calling LoadLibrary and GetProcAddress for you.
You should consider delay loading a DLL if:
Your program may not call a function in the DLL.
A function in the DLL may not get called until late in your program's execution.
The delayed loading of a DLL can be specified during the build of either a .EXE or .DLL project. A .DLL project
that delays the loading of one or more DLLs should not itself call a delay-loaded entry point in Dllmain.
The following topics describe delay loading DLLs:
Specifying DLLs to Delay Load
Explicitly Unloading a Delay-Loaded DLL
Loading All Imports for a Delay-Loaded DLL
Binding Imports
Error Handling and Notification
Dumping Delay-Loaded Imports
Constraints of Delay Loading DLLs
Understanding the Helper Function
Developing Your Own Helper Function
See also
DLLs in Visual C++
MSVC linker reference
Specifying DLLs to Delay Load
3/12/2019 • 2 minutes to read • Edit Online
You can specify which DLLs to delay load with the /delayload: dllname linker option. If you do not plan to use your
own version of a helper function, you must also link your program with delayimp.lib (for desktop applications) or
dloadhelper.lib (for store apps).
The following is a simple example of delay loading a DLL:
int main() {
// user32.dll will load at this point
MessageBox(NULL, "Hello", "Hello", MB_OK);
}
Build the DEBUG version of the project. Step through the code using the debugger and you will notice that
user32.dll is loaded only when you make the call to MessageBox .
See also
Linker Support for Delay-Loaded DLLs
Explicitly Unloading a Delay-Loaded DLL
3/12/2019 • 2 minutes to read • Edit Online
The /delay:unload linker option allows you to unload a DLL that was delay loaded. By default, when your code
unloads the DLL (using /delay:unload and __FUnloadDelayLoadedDLL2), the delay-loaded imports remain in
the import address table (IAT). However, if you use /delay:unload on the linker command line, the helper function
will support the explicit unloading of the DLL, resetting the IAT to its original form; the now -invalid pointers will be
overwritten. The IAT is a field in the ImgDelayDescr that contains the address of a copy of the original IAT (if it
exists).
Example
Code
if (TestReturn)
printf_s("\nDLL was unloaded");
else
printf_s("\nDLL was not unloaded");
}
Comments
Important notes on unloading a delay-loaded DLL:
You can find the implementation of the __FUnloadDelayLoadedDLL2 function in the file
\VC7\INCLUDE\DELAYHLP.CPP.
The name parameter of the __FUnloadDelayLoadedDLL2 function must exactly match (including case)
what the import library contains (that string is also in the import table in the image). You can view the
contents of the import library with DUMPBIN /DEPENDENTS. If a case-insensitive string match is desired,
you can update __FUnloadDelayLoadedDLL2 to use one of the CRT string functions or a Windows API
call.
See Unloading a Delay-Loaded DLL for more information.
See also
Linker Support for Delay-Loaded DLLs
Binding Imports
3/12/2019 • 2 minutes to read • Edit Online
The default linker behavior is to create a bindable import address table for the delay-loaded DLL. If the DLL is
bound, the helper function will attempt to use the bound information instead of calling GetProcAddress on each
of the referenced imports. If either the timestamp or the preferred address do not match those of the loaded DLL,
the helper function will assume the bound import address table is out of date and will proceed as if it does not
exist.
If you never intend to bind the DLL's delay-loaded imports, specifying /delay:nobind on the linker's command line
will prevent the bound import address table from being generated and consuming space in the image file.
See also
Linker Support for Delay-Loaded DLLs
Loading All Imports for a Delay-Loaded DLL
3/12/2019 • 2 minutes to read • Edit Online
The __HrLoadAllImportsForDll function, which is defined in delayhlp.cpp, tells the linker to load all imports from
a DLL that was specified with the /delayload linker option.
Loading all imports allows you to put error handling in one place in your code and not have to use exception
handling around the actual calls to the imports. It also avoids a situation where your application fails partially
through a process as a result of the helper code failing to load an import.
Calling __HrLoadAllImportsForDll does not change the behavior of hooks and error handling; see Error
Handling and Notification for more information.
The DLL name passed to __HrLoadAllImportsForDll is compared to the name stored inside the DLL itself and is
case sensitive.
The following example shows how to call __HrLoadAllImportsForDll:
if (FAILED(__HrLoadAllImportsForDll("delay1.dll"))) {
printf ( "failed on snap load, exiting\n" );
exit(2);
}
See also
Linker Support for Delay-Loaded DLLs
Error Handling and Notification
3/12/2019 • 2 minutes to read • Edit Online
For more information on error handling and notification, see Understanding the Helper Function.
For more information on hook functions, see Structure and Constant Definitions.
If your program uses delay-loaded DLLs, it must handle errors robustly since failures that occur while the
program is running will result in unhandled exceptions. Failure handling is comprised of two portions:
Recovery through a hook. If your code needs to recover or provide an alternate library and/or routine on failure, a
hook can be provided to the helper function that can supply or remedy the situation. The hook routine needs to
return a suitable value, so that processing can continue (an HINSTANCE or FARPROC ) or 0 to indicate that an
exception should be thrown. It could also throw its own exception or longjmp out of the hook. There are
notification hooks and failure hooks.
Reporting via an exception. If all that is necessary for handling the error is to abort the procedure, no hook is
necessary as long as the user code can handle the exception.
The following topics discuss error handling and notification:
Notification Hooks
Failure Hooks
Exceptions
See also
Linker Support for Delay-Loaded DLLs
Notification Hooks
3/12/2019 • 2 minutes to read • Edit Online
The notification hooks are called just before the following actions are taken in the helper routine:
The stored handle to the library is checked to see if it has already been loaded.
LoadLibrary is called to attempt the load of the DLL.
GetProcAddress is called to attempt to get the address of the procedure.
Return to the delay import load thunk.
The notification hook is enabled:
By supplying a new definition of the pointer __pfnDliNotifyHook2 that is initialized to point to your own
function that receives the notifications.
-or-
By setting the pointer __pfnDliNotifyHook2 to your hook function before any calls to the DLL that the
program is delay loading.
If the notification is dliStartProcessing, the hook function can return:
NULL
The default helper handles the loading of the DLL. This is useful to be called just for informational purposes.
function pointer
Bypass the default delay-load handling. This lets you supply your own load handler.
If the notification is dliNotePreLoadLibrary, the hook function can return:
0, if it just wants informational notifications.
The HMODULE for the loaded DLL, if it loaded the DLL itself.
If the notification is dliNotePreGetProcAddress, the hook function can return:
0, if it just wants informational notifications.
The imported function's address, if the hook function gets the address itself.
If the notification is dliNoteEndProcessing, the hook function's return value is ignored.
If this pointer is initialized (nonzero), the delay load helper will invoke the function at certain notification points
throughout its execution. The function pointer has the following definition:
// The "notify hook" gets called for every call to the
// delay load helper. This allows a user to hook every call and
// skip the delay load helper entirely.
//
// dliNotify == {
// dliStartProcessing |
// dliNotePreLoadLibrary |
// dliNotePreGetProc |
// dliNoteEndProcessing}
// on this call.
//
ExternC
PfnDliHook __pfnDliNotifyHook2;
The notifications pass in a DelayLoadInfo structure to the hook function along with the notification value. This
data is identical to that used by the delay load helper routine. The notification value will be one of the values
defined in Structure and Constant Definitions.
See also
Error Handling and Notification
Failure Hooks
3/12/2019 • 2 minutes to read • Edit Online
The failure hook is enabled in the same manner as the notification hook. The hook routine needs to return a
suitable value so that processing can continue (an HINSTANCE or FARPROC ) or 0 to indicate that an exception
should be thrown.
The pointer variable that refers to the user-defined function is:
The DelayLoadInfo structure contains all the pertinent data necessary for accurate reporting of the error,
including the value from GetLastError .
If the notification is dliFailLoadLib, the hook function can return:
0, if it cannot handle the failure.
An HMODULE, if the failure hook fixed the problem and loaded the library itself.
If the notification is dliFailGetProc, the hook function can return:
0, if it cannot handle the failure.
A valid proc address (import function address), if the failure hook succeeded in getting the address itself.
See also
Error Handling and Notification
Exceptions (C/C++)
3/12/2019 • 2 minutes to read • Edit Online
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
See also
Error Handling and Notification
Dumping Delay-Loaded Imports
3/12/2019 • 2 minutes to read • Edit Online
Delay-loaded imports can be dumped using dumpbin /imports and show up with slightly different information
than standard imports. They are segregated into their own section of the /imports dumping and are explicitly
labeled as delay-loaded imports. If there is unload information present in the image, that is noted. If there is bind
information present, the time/date stamp of the target DLL is noted along with the bound addresses of the
imports.
See also
Linker Support for Delay-Loaded DLLs
Constraints of Delay Loading DLLs
3/12/2019 • 2 minutes to read • Edit Online
Delay loading Kernel32.dll is not supported. This DLL is necessary for the delay-load helper routines to
perform the delay loading.
Binding of entry points that are forwarded is not supported.
Delay loading of a DLL may not result in the same behavior of the process if there are per-process
initializations that occur in the entry point of the delay-loaded DLL. Other cases include static TLS (thread
local storage), declared using __declspec(thread), which is not handled when the DLL is loaded via
LoadLibrary . Dynamic TLS, using TlsAlloc , TlsFree , TlsGetValue , and TlsSetValue , is still available for
use in either static or delay-loaded DLLs.
Static (global) function pointers should be reinitialized to imported functions after the first call to the
function. This is because the first use of the function pointer will point to the thunk.
There is no way currently to delay the loading of only specific procedures from a DLL while using the
normal import mechanism.
Custom calling conventions (such as using condition codes on x86 architectures) are not supported. Also,
the floating-point registers are not saved on any platform. If your custom helper routine or hook routines
use floating-point types, they need to completely save and restore the floating-point state on machines with
register calling conventions with floating-point parameters. Be careful about delay loading the CRT DLL if
you call CRT functions that take floating-point parameters on a numeric data processor (NDP ) stack in the
help function.
See also
Linker Support for Delay-Loaded DLLs
LoadLibrary function
GetModuleHandle function
GetProcAddress function
TlsAlloc function
TlsFree function
TlsGetValue function
TlsSetValue function
Understanding the Helper Function
3/12/2019 • 2 minutes to read • Edit Online
The helper function for linker-supported delayed loading is what actually loads the DLL at run time. You can
modify the helper function to customize its behavior by writing your own function and linking it to your program
instead of using the supplied helper function in Delayimp.lib. One helper function serves all delay loaded DLLs.
You can provide your own version of the helper function if you want to do specific processing based on the names
of the DLL or imports.
The helper function performs the following actions:
Checks the stored handle to the library to see if it has already been loaded
Calls LoadLibrary to attempt loading of the DLL
Calls GetProcAddress to attempt getting the address of the procedure
Returns to the delay import load thunk to call the now -loaded entry point
The helper function can call back to a notification hook in your program after each of the following actions:
When the helper function starts up
Just before LoadLibrary is called in the helper function
Just before GetProcAddress is called in the helper function
If the call to LoadLibrary in the helper function failed
If the call to GetProcAddress in the helper function failed
After the helper function is done processing
Each of these hook points can return a value that will alter normal processing of the helper routine in some
manner except the return to the delay import load thunk.
The default helper code can be found in Delayhlp.cpp and Delayimp.h (in vc\include) and is compiled in
Delayimp.lib (in vc\lib). You will need to include this library in your compilations unless you write your own helper
function.
The following topics describe the helper function:
Changes in the DLL Delayed Loading Helper Function Since Visual C++ 6.0
Calling Conventions, Parameters, and Return Type
Structure and Constant Definitions
Calculating Necessary Values
Unloading a Delay-Loaded DLL
See also
Linker Support for Delay-Loaded DLLs
Changes in the DLL Delayed Loading Helper
Function Since Visual C++ 6.0
3/12/2019 • 2 minutes to read • Edit Online
If you have multiple versions of Visual C++ on your computer or if you defined your own helper function, you may
be affected by changes made to the DLL delayed loading helper function. For example:
__delayLoadHelper is now __delayLoadHelper2
__pfnDliNotifyHook is now __pfnDliNotifyHook2
__pfnDliFailureHook is now __pfnDliFailureHook2
__FUnloadDelayLoadedDLL is now __FUnloadDelayLoadedDLL2
NOTE
If you are using the default helper function, these changes will not affect you. There are no changes regarding how you
invoke the linker.
See also
Understanding the Helper Function
Calling Conventions, Parameters, and Return Type
3/12/2019 • 3 minutes to read • Edit Online
Parameters
pidd
A const pointer to a ImgDelayDescr that contains the offsets of various import-related data, a timestamp for
binding information, and a set of attributes that provide further information about the descriptor content.
Currently there's only one attribute, dlattrRva , which indicates that the addresses in the descriptor are relative
virtual addresses. For more information, see the declarations in delayimp.h.
For the definition of the PCImgDelayDescr structure, see Structure and Constant Definitions.
ppfnIATEntry
A pointer to the slot in the delay load import address table (IAT) that's updated with the address of the imported
function. The helper routine needs to store the same value that it returns into this location.
Remarks
The calling convention for the helper function is __stdcall . The type of the return value isn't relevant, so
FARPROC is used. This function has C linkage.
The return value of the delay load helper needs to be stored in the passed-in function pointer location, unless you
want your helper routine to be used as a notification hook. In that case, your code is responsible for finding the
appropriate function pointer to return. The thunk code the linker generates then takes that return value as the real
target of the import and jumps directly to it.
Sample
The following code shows how to implement a simple hook function.
break;
case dliNotePreLoadLibrary :
break;
case dliNotePreGetProcAddress :
break;
case dliFailLoadLib :
// LoadLibrary failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_MOD_NOT_FOUND) and exit.
// If you want to handle the failure by loading an alternate
// DLL (for example), then return the HMODULE for
// the alternate DLL. The helper will continue execution with
// this alternate DLL and attempt to find the
// requested entrypoint via GetProcAddress.
break;
case dliFailGetProc :
// GetProcAddress failed.
// If you don't want to handle this failure yourself, return 0.
// In this case the helper will raise an exception
// (ERROR_PROC_NOT_FOUND) and exit.
// If you choose you may handle the failure by returning
// an alternate FARPROC function address.
break;
case dliNoteEndProcessing :
break;
default :
return NULL;
}
return NULL;
}
/*
/*
and then at global scope somewhere
const PfnDliHook __pfnDliNotifyHook2 = delayHook;
*/
See also
Understanding the Helper Function
Structure and Constant Definitions
3/12/2019 • 2 minutes to read • Edit Online
The default helper routine uses several structures to communicate with the hook functions and during any
exceptions. Here are the notification and failure values, information structures, and the pointer-to-hook-function
type passed to the hooks:
//
// Delay load import hook notifications
//
enum {
dliStartProcessing, // used to bypass or note helper only
dliNotePreLoadLibrary, // called just before LoadLibrary, can
// override w/ new HMODULE return val
dliNotePreGetProcAddress, // called just before GetProcAddress, can
// override w/ new FARPROC return value
dliFailLoadLib, // failed to load library, fix it by
// returning a valid HMODULE
dliFailGetProc, // failed to get proc address, fix it by
// returning a valid FARPROC
dliNoteEndProcessing, // called after all processing is done, no
// bypass possible at this point except
// by longjmp()/throw()/RaiseException.
};
Two critical pieces of information need to be calculated by the delay helper routine. To that end, there are two inline
functions in delayhlp.cpp for calculating this information.
The first calculates the index of the current import into the three different tables (import address table (IAT),
bound import address table (BIAT), and unbound import address table (UIAT)).
The second counts the number of imports in a valid IAT.
// utility function for calculating the count of imports given the base
// of the IAT. NB: this only works on a valid IAT!
__inline unsigned
CountOfImports(PCImgThunkData pitdBase) {
unsigned cRet = 0;
PCImgThunkData pitd = pitdBase;
while (pitd->u1.Function) {
pitd++;
cRet++;
}
return cRet;
}
See also
Understanding the Helper Function
Unloading a Delay-Loaded DLL
3/5/2019 • 2 minutes to read • Edit Online
The default-supplied delay-load helper checks to see if the delay-load descriptors have a pointer and a copy of the
original import address table (IAT) in the pUnloadIAT field. If so, it will save a pointer in a list to the import delay
descriptor. This enables the helper function to find the DLL by name to support unloading that DLL explicitly.
Here are the associated structures and functions for explicitly unloading a delay-loaded DLL:
//
// Unload support from delayimp.h
//
ExternC
BOOL WINAPI
__FUnloadDelayLoadedDLL2(LPCSTR szDll);
// from delayhlp.cpp
// the default delay load helper places the unloadinfo records in the
// list headed by the following pointer.
ExternC
PUnloadInfo __puiHead;
The UnloadInfo structure is implemented using a C++ class that uses LocalAlloc and LocalFree implementations
as its operator new and operator delete respectively. These options are kept in a standard linked list using
__puiHead as the head of the list.
Calling __FUnloadDelayLoadedDLL will attempt to find the name you provide in the list of loaded DLLs (an exact
match is required). If found, the copy of the IAT in pUnloadIAT is copied over the top of the running IAT to restore
the thunk pointers, the library is freed with FreeLibrary, the matching UnloadInfo record is unlinked from the list
and deleted, and TRUE is returned.
The argument to the function __FUnloadDelayLoadedDLL2 is case sensitive. For example, you would specify:
__FUnloadDelayLoadedDLL2("user32.DLL");
and not:
__FUnloadDelayLoadedDLL2("User32.DLL");.
See also
Understanding the Helper Function
Developing Your Own Helper Function
3/12/2019 • 2 minutes to read • Edit Online
You may want to provide your own version of the routine to do specific processing based on the names of the DLL
or imports. There are two methods of doing this: coding your own, possibly based on the supplied code, or merely
hooking the supplied version using the notification hooks detailed previously.
See also
Linker Support for Delay-Loaded DLLs
Additional MSVC Build Tools
3/12/2019 • 2 minutes to read • Edit Online
Visual C++ provides the following command-line utilities for viewing or manipulating build output:
LIB.EXE is used to create and manage a library of Common Object File Format (COFF ) object files. It can
also be used to create export files and import libraries to reference exported definitions.
EDITBIN.EXE is used to modify COFF binary files.
DUMPBIN.EXE displays information (such as a symbol table) about COFF binary files.
NMAKE reads and executes makefiles.
ERRLOOK, the Error Lookup utility, retrieves a system error message or module error message based on
the value entered.
XDCMake. A toolfor processing source code files that contain documentation comments marked up with
XML tags.
BSCMAKE.EXE (provided for backward compatibility only) builds a browse information file (.bsc) that
contains information about the symbols (classes, functions, data, macros, and types) in your program. You
view this information in browse windows within the development environment. (A .bsc file can also be
built in the development environment.)
See also
C/C++ Building Reference
Decorated Names
MSVC Compiler Options
MSVC Linker Options
NMAKE Reference
3/12/2019 • 2 minutes to read • Edit Online
The Microsoft Program Maintenance Utility (NMAKE.EXE ) is a command-line tool included with Visual Studio
that builds projects based on commands that are contained in a description file.
To use NMAKE, you must run it in a Developer Command Prompt window. A Developer Command Prompt
window has the environment variables set for the tools, libraries, and include file paths required to build at the
command line. For details on how to open a Developer Command Prompt window, see Use the MSVC toolset
from the command line.
See also
Use the MSVC toolset from the command line
Additional MSVC Build Tools
Visual Studio Projects - C++
Debugging in Visual Studio
C/C++ Building Reference
Create a C++ makefile project
3/12/2019 • 4 minutes to read • Edit Online
A makefile is a text file that contains instructions for how to compile and link (or build) a set of C++ source code
files. A make program reads the makefile and invokes a compiler, linker and possibly other programs to make an
executable file. Microsoft's implementation of the make program is called NMAKE;
If you have an existing makefile project, you have these choices if you want to code and/or debug it in the Visual
Studio IDE:
Create a makefile project in Visual Studio that uses your existing makefile to configure a .vcxproj file that Visual
Studio will use for IntelliSense. (You will not have all the IDE features that you get with a native MSBuild
project.) See To create a makefile project below.
Use the Create New Project from Existing Code Files wizard to create a native MSBuild project from your
source code. The original makefile will not be used after this. For more information, see How to: Create a C++
Project from Existing Code.
Visual Studio 2017 and later: Use the Open Folder feature to edit and build a makefile project as-is without
any involvement of the MSBuild system. For more information, see Open Folder projects for C++.
See Also
Using IntelliSense
NMAKE Reference
How to: Create a C++ Project from Existing Code Special Characters in a Makefile
Contents of a Makefile
Running NMAKE
3/12/2019 • 2 minutes to read • Edit Online
Syntax
NMAKE [option ...] [macros ...] [targets ...] [@commandfile ...]
Remarks
NMAKE builds only specified targets or, if none is specified, the first target in the makefile. The first makefile target
can be a pseudotarget that builds other targets. NMAKE uses makefiles specified with /F; if /F is not specified, it
uses the Makefile file in the current directory. If no makefile is specified, it uses inference rules to build command-
line targets.
The commandfile text file (or response file) contains command-line input. Other input can precede or follow
@commandfile. A path is permitted. In commandfile, line breaks are treated as spaces. Enclose macro definitions
in quotation marks if they contain spaces.
See also
NMAKE Reference
NMAKE Options
3/12/2019 • 3 minutes to read • Edit Online
NMAKE options are described in the following table. Options are preceded by either a slash (/) or a dash (-) and
are not case sensitive. Use !CMDSWITCHES to change option settings in a makefile or in Tools.ini.
OPTION PURPOSE
/ERRORREPORT[NONE | PROMPT | QUEUE | SEND ] If nmake.exe fails at runtime, you can use /ERRORREPORT to
send information to Microsoft about these internal errors.
See also
Running NMAKE
Tools.ini and NMAKE
3/12/2019 • 2 minutes to read • Edit Online
NMAKE reads Tools.ini before it reads makefiles, unless /R is used. It looks for Tools.ini first in the current directory
and then in the directory specified by the INIT environment variable. The section for NMAKE settings in the
initialization file begins with [NMAKE] and can contain any makefile information. Specify a comment on a separate
line beginning with a number sign (#).
See also
Running NMAKE
Exit Codes from NMAKE
3/12/2019 • 2 minutes to read • Edit Online
CODE MEANING
See also
Running NMAKE
Contents of a Makefile
3/12/2019 • 2 minutes to read • Edit Online
A makefile contains:
Description blocks
Commands
Macros
Inference rules
Dot directives
Preprocessing directives
Remarks
Other features you can use in a makefile are wildcards, long filenames, comments, and special characters.
For a sample, see Sample Makefile.
See Also
NMAKE Reference
Wildcards and NMAKE
3/12/2019 • 2 minutes to read • Edit Online
NMAKE expands filename wildcards (* and ?) in dependency lines. A wildcard specified in a command is passed to
the command; NMAKE does not expand it.
See also
Contents of a Makefile
Long Filenames in a Makefile
3/12/2019 • 2 minutes to read • Edit Online
all : "VeryLongFileName.exe"
See also
Contents of a Makefile
Comments in a Makefile
3/12/2019 • 2 minutes to read • Edit Online
Precede a comment with a number sign (#). NMAKE ignores text from the number sign to the next newline
character. Examples:
See also
Contents of a Makefile
Special Characters in a Makefile
3/12/2019 • 2 minutes to read • Edit Online
To use an NMAKE special character as a literal character, place a caret (^) in front of it. NMAKE ignores carets that
precede other characters. The special characters are:
: ; # ( ) $ ^ \ { } ! @ —
A caret (^) within a quoted string is treated as a literal caret character. A caret at the end of a line inserts a literal
newline character in a string or macro.
In macros, a backslash (\) followed by a newline character is replaced by a space.
In commands, a percent symbol (%) is a file specifier. To represent % literally in a command, specify a double
percent sign (%%) in place of a single one. In other situations, NMAKE interprets a single % literally, but it always
interprets a double %% as a single %. Therefore, to represent a literal %%, specify either three percent signs, %%%,
or four percent signs, %%%%.
To use the dollar sign ($) as a literal character in a command, specify two dollar signs ($$). This method can also be
used in other situations where ^$ works.
See also
Contents of a Makefile
Sample Makefile
3/12/2019 • 2 minutes to read • Edit Online
Sample
Code
# Sample makefile
!include <win32.mak>
.c.obj:
$(cc) $(cdebug) $(cflags) $(cvars) $*.c
simple.exe: simple.obj
$(link) $(ldebug) $(conflags) -out:simple.exe simple.obj $(conlibs) lsapi32.lib
See also
Contents of a Makefile
Description Blocks
3/12/2019 • 2 minutes to read • Edit Online
targets... : dependents...
commands...
A dependency line specifies one or more targets and zero or more dependents. A target must be at the start of the
line. Separate targets from dependents by a colon (:); spaces or tabs are allowed. To split the line, use a backslash (\
) after a target or dependent. If a target does not exist, has an earlier timestamp than a dependent, or is a
pseudotarget, NMAKE executes the commands. If a dependent is a target elsewhere and does not exist or is out-
of-date with respect to its own dependents, NMAKE updates the dependent before updating the current
dependency.
See also
NMAKE Reference
Targets
3/12/2019 • 2 minutes to read • Edit Online
In a dependency line, specify one or more targets, using any valid filename, directory name, or pseudotarget.
Separate multiple targets with one or more spaces or tabs. Targets are not case sensitive. Paths are permitted with
filenames. A target cannot exceed 256 characters. If the target preceding the colon is a single character, use a
separating space; otherwise, NMAKE interprets the letter-colon combination as a drive specifier.
See Also
Description Blocks
Pseudotargets
3/12/2019 • 2 minutes to read • Edit Online
A pseudotarget is a label used in place of a filename in a dependency line. It is interpreted as a file that does not
exist, and so is out-of-date. NMAKE assumes a pseudotarget's timestamp is the most recent of all its dependents.
If it has no dependents, the current time is assumed. If a pseudotarget is used as a target, its commands are
always executed. A pseudotarget used as a dependent must also appear as a target in another dependency.
However, that dependency does not need to have a commands block.
Pseudotarget names follow the filename syntax rules for targets. However, if the name does not have an extension
(that is, does not contain a period), it can exceed the 8-character limit for filenames and can be up to 256
characters long.
See also
Targets
Multiple Targets
3/12/2019 • 2 minutes to read • Edit Online
NMAKE evaluates multiple targets in a single dependency as if each were specified in a separate description block.
For example, this...
bounce.exe : jump.obj
echo Building...
leap.exe : jump.obj
echo Building...
See also
Targets
Cumulative Dependencies
3/12/2019 • 2 minutes to read • Edit Online
bounce.exe : jump.obj
bounce.exe : up.obj
echo Building bounce.exe...
is evaluated as this:
Multiple targets in multiple dependency lines in a single description block are evaluated as if each were specified in
a separate description block, but targets that are not in the last dependency line do not use the commands block.
NMAKE attempts to use an inference rule for such targets.
For example, this set of rules,
is evaluated as this:
leap.exe : jump.obj
# invokes an inference rule
bounce.exe : jump.obj up.obj
echo Building bounce.exe...
climb.exe : up.obj
echo Building bounce.exe...
See also
Targets
Targets in Multiple Description Blocks
3/12/2019 • 2 minutes to read • Edit Online
To update a target in more than one description block using different commands, specify two consecutive colons (::)
between targets and dependents.
See also
Targets
Dependency Side Effects
3/12/2019 • 2 minutes to read • Edit Online
If a target is specified with a colon (:) in two dependency lines in different locations, and if commands appear after
only one of the lines, NMAKE interprets the dependencies as if adjacent or combined. It does not invoke an
inference rule for the dependency that has no commands, but instead assumes that the dependencies belong to
one description block and executes the commands specified with the other dependency. For example, this set of
rules:
bounce.exe : jump.obj
echo Building bounce.exe...
bounce.exe : up.obj
is evaluated as this:
This effect does not occur if a double colon ( :: ) is used. For example, this set of rules:
bounce.exe :: jump.obj
echo Building bounce.exe...
bounce.exe :: up.obj
is evaluated as this:
bounce.exe : jump.obj
echo Building bounce.exe...
bounce.exe : up.obj
# invokes an inference rule
See also
Targets
/DEPENDENTS
3/12/2019 • 2 minutes to read • Edit Online
/DEPENDENTS
Remarks
Dumps the names of the DLLs from which the image imports functions. Does not dump the names of the imported
functions.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
Inferred Dependents
3/12/2019 • 2 minutes to read • Edit Online
An inferred dependent is derived from an inference rule and is evaluated before explicit dependents. If an inferred
dependent is out-of-date with respect to its target, NMAKE invokes the commands block for the dependency. If an
inferred dependent does not exist or is out-of-date with respect to its own dependents, NMAKE first updates the
inferred dependent. For more information about inferred dependents, see Inference Rules.
See also
Dependents
Search Paths for Dependents
3/12/2019 • 2 minutes to read • Edit Online
Syntax
{directory[;directory...]}dependent
Remarks
NMAKE looks for a dependent first in the current directory, and then in directories in the order specified. A macro
can specify part or all of a search path. Enclose directory names in braces ({ }); separate multiple directories with a
semicolon (;). No spaces or tabs are allowed.
See also
Dependents
Commands in a Makefile
3/12/2019 • 2 minutes to read • Edit Online
A description block or inference rule specifies a block of commands to run if the dependency is out-of-date.
NMAKE displays each command before running it, unless /S, .SILENT, !CMDSWITCHES, or @ is used. NMAKE
looks for a matching inference rule if a description block is not followed by a commands block.
A commands block contains one or more commands, each on its own line. No blank line can appear between the
dependency or rule and the commands block. However, a line containing only spaces or tabs can appear; this line
is interpreted as a null command, and no error occurs. Blank lines are permitted between command lines.
A command line begins with one or more spaces or tabs. A backslash ( \ ) followed by a newline character is
interpreted as a space in the command; use a backslash at the end of a line to continue a command onto the next
line. NMAKE interprets the backslash literally if any other character, including a space or tab, follows the backslash.
A command preceded by a semicolon (;) can appear on a dependency line or inference rule, whether or not a
commands block follows:
See also
NMAKE Reference
Command Modifiers
3/12/2019 • 2 minutes to read • Edit Online
You can specify one or more command modifiers preceding a command, optionally separated by spaces or tabs. As
with commands, modifiers must be indented.
MODIFIER PURPOSE
-[number] command Turns off error checking for command. By default, NMAKE
halts when a command returns a nonzero exit code. If
-number is used, NMAKE stops if the exit code exceeds
number. Spaces or tabs cannot appear between the dash and
number. At least one space or tab must appear between
number and command. Use /I to turn off error checking for
the entire makefile; use .IGNORE to turn off error checking for
part of the makefile.
See also
Commands in a Makefile
Filename-Parts Syntax
3/12/2019 • 2 minutes to read • Edit Online
Filename-parts syntax in commands represents components of the first dependent filename (which may be an
implied dependent). Filename components are the file's drive, path, base name, and extension as specified, not as it
exists on disk. Use %s to represent the complete filename. Use %|[parts]F (a vertical bar character follows the
percent symbol) to represent parts of the filename, where parts can be zero or more of the following letters, in any
order.
LETTER DESCRIPTION
d Drive
p Path
e File extension
See also
Commands in a Makefile
Inline Files in a Makefile
3/12/2019 • 2 minutes to read • Edit Online
An inline file contains text you specify in the makefile. Its name can be used in commands as input (for example, a
LINK command file), or it can pass commands to the operating system. The file is created on disk when a
command that creates the file is run.
See also
Commands in a Makefile
Specifying an Inline File
3/12/2019 • 2 minutes to read • Edit Online
Specify two angle brackets (<<) in the command where filename is to appear. The angle brackets cannot be a
macro expansion.
Syntax
<<[filename]
Remarks
When the command is run, the angle brackets are replaced by filename, if specified, or by a unique NMAKE -
generated name. If specified, filename must follow angle brackets without a space or tab. A path is permitted. No
extension is required or assumed. If filename is specified, the file is created in the current or specified directory,
overwriting any existing file by that name; otherwise, it is created in the TMP directory (or the current directory, if
the TMP environment variable is not defined). If a previous filename is reused, NMAKE replaces the previous file.
See also
Inline Files in a Makefile
Creating Inline File Text
3/12/2019 • 2 minutes to read • Edit Online
Syntax
inlinetext
.
.
.
<<[KEEP | NOKEEP]
Remarks
Specify inlinetext on the first line after the command. Mark the end with double angle brackets (<<) at the
beginning of a separate line. The file contains all inlinetext before the delimiting brackets. The inlinetext can have
macro expansions and substitutions, but not directives or makefile comments. Spaces, tabs, and newline characters
are treated literally.
A temporary file exists for the duration of the session and can be reused by other commands. Specify KEEP after
the closing angle brackets to retain the file after the NMAKE session; an unnamed file is preserved on disk with the
generated filename. Specify NOKEEP or nothing for a temporary file. KEEP and NOKEEP are not case sensitive.
See also
Inline Files in a Makefile
Reusing Inline Files
3/12/2019 • 2 minutes to read • Edit Online
To reuse an inline file, specify <<filename where the file is defined and first used, then reuse filename without <<
later in the same or another command. The command to create the inline file must run before all commands that
use the file.
See also
Inline Files in a Makefile
Multiple Inline Files
3/12/2019 • 2 minutes to read • Edit Online
Syntax
command << <<
inlinetext
<<[KEEP | NOKEEP]
inlinetext
<<[KEEP | NOKEEP]
Remarks
For each file, specify one or more lines of inline text followed by a closing line containing the delimiter. Begin the
second file's text on the line following the delimiting line for the first file.
See also
Inline Files in a Makefile
Macros and NMAKE
3/12/2019 • 2 minutes to read • Edit Online
Macros replace a particular string in the makefile with another string. Using macros, you can:
Create a makefile that can build different projects.
Specify options for commands.
Set environment variables.
You can define your own macros or use NMAKE's predefined macros.
See also
NMAKE Reference
Defining an NMAKE Macro
3/12/2019 • 2 minutes to read • Edit Online
Syntax
macroname=string
Remarks
The macroname is a combination of letters, digits, and underscores (_) up to 1,024 characters, and is case
sensitive. The macroname can contain an invoked macro. If macroname consists entirely of an invoked macro, the
macro being invoked cannot be null or undefined.
The string can be any sequence of zero or more characters. A null string contains zero characters or only spaces
or tabs. The string can contain a macro invocation.
See also
Macros and NMAKE
Special Characters in Macros
3/12/2019 • 2 minutes to read • Edit Online
A number sign (#) after a definition specifies a comment. To specify a literal number sign in a macro, use a caret
(^), as in ^#.
A dollar sign ($) specifies a macro invocation. To specify a literal $, use $$.
To extend a definition to a new line, end the line with a backslash (\). When the macro is invoked, the backslash plus
newline character is replaced with a space. To specify a literal backslash at the end of the line, precede it with a caret
(^), or follow it with a comment specifier (#).
To specify a literal newline character, end the line with a caret (^), as in:
CMDS = cls^
dir
See also
Defining an NMAKE Macro
Null and Undefined Macros
3/12/2019 • 2 minutes to read • Edit Online
Both null and undefined macros expand to null strings, but a macro defined as a null string is considered defined in
preprocessing expressions. To define a macro as a null string, specify no characters except spaces or tabs after the
equal sign (=) in a command line or command file, and enclose the null string or definition in double quotation
marks (" "). To undefine a macro, use !UNDEF. For more information, see Makefile Preprocessing Directives.
See also
Defining an NMAKE Macro
Where to Define Macros
3/12/2019 • 2 minutes to read • Edit Online
Define macros in a command line, command file, makefile, or the Tools.ini file.
In a makefile or the Tools.ini file, each macro definition must appear on a separate line and cannot start with a
space or tab. Spaces or tabs around the equal sign are ignored. All string characters are literal, including
surrounding quotation marks and embedded spaces.
In a command line or command file, spaces and tabs delimit arguments and cannot surround the equal sign. If
string has embedded spaces or tabs, enclose either the string itself or the entire macro in double quotation
marks (" ").
See also
Defining an NMAKE Macro
Precedence in Macro Definitions
3/12/2019 • 2 minutes to read • Edit Online
If a macro has multiple definitions, NMAKE uses the highest-precedence definition. The following list shows the
order of precedence, from highest to lowest:
1. A macro defined on the command line
2. A macro defined in a makefile or include file
3. An inherited environment-variable macro
4. A macro defined in the Tools.ini file
5. A predefined macro, such as CC and AS
Use /E to cause macros inherited from environment variables to override makefile macros with the same name.
Use !UNDEF to override a command line.
See also
Defining an NMAKE Macro
Using an NMAKE Macro
3/12/2019 • 2 minutes to read • Edit Online
To use a macro, enclose its name in parentheses preceded by a dollar sign ($) as follows.
Syntax
$(macroname)
Remarks
No spaces are allowed. The parentheses are optional if macroname is a single character. The definition string
replaces $(macroname); an undefined macro is replaced by a null string.
See also
Macros and NMAKE
Macro Substitution
3/12/2019 • 2 minutes to read • Edit Online
When macroname is invoked, each occurrence of string1 in its definition string is replaced by string2.
Syntax
$(macroname:string1=string2)
Remarks
Macro substitution is case sensitive and is literal; string1 and string2 cannot invoke macros. Substitution does not
modify the original definition. You can substitute text in any predefined macro except $$@.
No spaces or tabs precede the colon; any after the colon are interpreted as literal. If string2 is null, all occurrences
of string1 are deleted from the macro's definition string.
See also
Using an NMAKE Macro
Special NMAKE Macros
3/12/2019 • 2 minutes to read • Edit Online
NMAKE provides several special macros to represent various filenames and commands. One use for some of
these macros is in the predefined inference rules. Like all macros, the macros provided by NMAKE are case
sensitive.
Filename macros
Recursion macros
Command macros and options macros
Environment-Variable Macros
See also
Macros and NMAKE
Filename Macros
3/12/2019 • 2 minutes to read • Edit Online
Filename macros are predefined as filenames specified in the dependency (not full filename specifications on disk).
These macros do not need to be enclosed in parentheses when invoked; specify only a $ as shown.
MACRO MEANING
$< Dependent file with a later timestamp than the current target.
Valid only in commands in inference rules.
To specify part of a predefined filename macro, append a macro modifier and enclose the modified macro in
parentheses.
B Base name
See also
Special NMAKE Macros
Recursion Macros
3/12/2019 • 2 minutes to read • Edit Online
Use recursion macros to call NMAKE recursively. Recursive sessions inherit command-line and environment-
variable macros and Tools.ini information. They do not inherit makefile-defined inference rules or .SUFFIXES and
.PRECIOUS specifications. To pass macros to a recursive NMAKE session, either set an environment variable with
SET before the recursive call, define a macro in the command for the recursive call, or define a macro in Tools.ini.
MACRO DEFINITION
See also
Special NMAKE Macros
Command Macros and Options Macros
3/12/2019 • 2 minutes to read • Edit Online
Command macros are predefined for Microsoft products. Options macros represent options to these products
and are undefined by default. Both are used in predefined inference rules and can be used in description blocks or
user-defined inference rules. Command macros can be redefined to represent part or all of a command line,
including options. Options macros generate a null string if left undefined.
C Compiler CC cl CFLAGS
See also
Special NMAKE Macros
Environment-Variable Macros
3/12/2019 • 2 minutes to read • Edit Online
NMAKE inherits macro definitions for environment variables that exist before the start of the session. If a variable
was set in the operating-system environment, it is available as an NMAKE macro. The inherited names are
converted to uppercase. Inheritance occurs before preprocessing. Use the /E option to cause macros inherited
from environment variables to override any macros with the same name in the makefile.
Environment-variable macros can be redefined in the session, and this changes the corresponding environment
variable. You can also change environment variables with the SET command. Using the SET command to change
an environment variable in a session does not change the corresponding macro, however.
For example:
PATH=$(PATH);\nonesuch
all:
echo %PATH%
In this example, changing PATH changes the corresponding environment variable PATH ; it appends \nonesuch to
your path.
If an environment variable is defined as a string that would be syntactically incorrect in a makefile, no macro is
created and no warning is generated. If a variable's value contains a dollar sign ($), NMAKE interprets it as the
beginning of a macro invocation. Using the macro can cause unexpected behavior.
See also
Special NMAKE Macros
Inference Rules
3/12/2019 • 2 minutes to read • Edit Online
Inference rules supply commands to update targets and to infer dependents for targets. Extensions in an
inference rule match a single target and dependent that have the same base name. Inference rules are user-
defined or predefined; predefined rules can be redefined.
If an out-of-date dependency has no commands, and if .SUFFIXES contains the dependent's extension, NMAKE
uses a rule whose extensions match the target and an existing file in the current or specified directory. If more
than one rule matches existing files, the .SUFFIXES list determines which to use; list priority descends from left to
right. If a dependent file does not exist and is not listed as a target in another description block, an inference rule
can create the missing dependent from another file with the same base name. If a description block's target has
no dependents or commands, an inference rule can update the target. Inference rules can build a command-line
target even if no description block exists. NMAKE may invoke a rule for an inferred dependent even if an explicit
dependent is specified.
See Also
NMAKE Reference
Defining a Rule
3/12/2019 • 2 minutes to read • Edit Online
The fromext represents the extension of a dependent file, and toext represents the extension of a target file.
.fromext.toext:
commands
Remarks
Extensions are not case sensitive. Macros can be invoked to represent fromext and toext; the macros are expanded
during preprocessing. The period (.) preceding fromext must appear at the beginning of the line. The colon (:) is
preceded by zero or more spaces or tabs. It can be followed only by spaces or tabs, a semicolon (;) to specify a
command, a number sign (#) to specify a comment, or a newline character. No other spaces are allowed.
Commands are specified as in description blocks.
See also
Inference Rules
Search Paths in Rules
3/12/2019 • 2 minutes to read • Edit Online
{frompath}.fromext{topath}.toext:
commands
Remarks
An inference rule applies to a dependency only if paths specified in the dependency exactly match the inference-
rule paths. Specify the dependent's directory in frompath and the target's directory in topath; no spaces are
allowed. Specify only one path for each extension. A path on one extension requires a path on the other. To specify
the current directory, use either a period (.) or empty braces ({ }). Macros can represent frompath and topath; they
are invoked during preprocessing.
Example
Code
{dbi\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $(YUDBI) $<
{ilstore\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $<
{misc\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $(YUPDB) $<
{misc\}.c{$(ODIR)}.obj::
$(CC) $(CFLAGS) $<
{msf\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $<
{bsc\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $(YUPDB) $<
{mre\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $(YUPDB) $<
{namesrvr\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $(YUPDB) $<
{src\cvr\}.cpp{$(ODIR)}.obj::
$(CC) $(CFLAGS) $<
See also
Defining a Rule
Batch-Mode Rules
3/12/2019 • 2 minutes to read • Edit Online
{frompath}.fromext{topath}.toext::
commands
Batch-mode inference rules provide only one invocation of the inference rule when N commands go through this
inference rule. Without batch-mode inference rules, it would require N commands to be invoked. N is the number
of dependents that trigger the inference rule.
Makefiles that contain batch-mode inference rules must use NMAKE version 1.62 or higher. To check the NMAKE
version, run the _NMAKE_VER macro available with NMAKE version 1.62 or higher. This macro returns a string
representing the Visual C++ product version.
The only syntactical difference from the standard inference rule is that the batch-mode inference rule is terminated
with a double colon (::).
NOTE
The tool being invoked must be able to handle multiple files. The batch-mode inference rule must use $< as the macro to
access dependent files.
The batch-mode inference rules can speed up the build process. It is faster to supply files to the compiler in batch,
because the compiler driver is invoked only once. For example, the C and C++ compiler performs better when
handling a set of files because it can remain memory resident during the process.
The following example shows how to use batch-mode inference rules:
#
# sample makefile to illustrate batch-mode inference rules
#
O = .
S = .
Objs = $O/foo1.obj $O/foo2.obj $O/foo2.obj $O/foo3.obj $O/foo4.obj
CFLAGS = -nologo
all : $(Objs)
!ifdef NOBatch
{$S}.cpp{$O}.obj:
!else
{$S}.cpp{$O}.obj::
!endif
$(CC) $(CFLAGS) -Fd$O\ -c $<
$(Objs) :
#end of makefile
NMAKE produces the following result with the batch-mode inference rules:
See also
Inference Rules
Predefined Rules
3/12/2019 • 2 minutes to read • Edit Online
Predefined inference rules use NMAKE -supplied command and options macros.
DEFAULT BATCH
PLATFORM NMAKE
RULE COMMAND ACTION RULE RUNS ON
See also
Inference Rules
Inferred Dependents and Rules
3/12/2019 • 2 minutes to read • Edit Online
NMAKE assumes an inferred dependent for a target if an applicable inference rule exists. A rule applies if:
toext matches the target's extension.
fromext matches the extension of a file that has the target's base name and that exists in the current or
specified directory.
fromext is in .SUFFIXES; no other fromext in a matching rule has a higher .SUFFIXES priority.
No explicit dependent has a higher .SUFFIXES priority.
Inferred dependents can cause unexpected side effects. If the target's description block contains commands,
NMAKE executes those commands instead of the commands in the rule.
See also
Inference Rules
Precedence in Inference Rules
3/12/2019 • 2 minutes to read • Edit Online
If an inference rule is multiply defined, NMAKE uses the highest-precedence definition. The following list shows
the order of precedence from highest to lowest:
1. An inference rule defined in a makefile; later definitions have precedence.
2. An inference rule defined in Tools.ini; later definitions have precedence.
3. A predefined inference rule.
See also
Inference Rules
Dot Directives
3/12/2019 • 2 minutes to read • Edit Online
Specify dot directives outside a description block, at the start of a line. Dot directives begin with a period ( . ) and
are followed by a colon (:). Spaces and tabs are allowed. Dot directive names are case sensitive and are
uppercase.
DIRECTIVE PURPOSE
To change the .SUFFIXES list order or to specify a new list, clear the list and specify a new setting. To clear the
list, specify no extensions after the colon:
.SUFFIXES :
.SUFFIXES : suffixlist
where suffixlist is a list of the additional suffixes, separated by one or more spaces or tabs. To see the current
setting of .SUFFIXES, run NMAKE with /P.
See also
NMAKE Reference
Makefile Preprocessing
3/12/2019 • 2 minutes to read • Edit Online
You can control the NMAKE session by using preprocessing directives and expressions. Preprocessing instructions
can be placed in the makefile or in Tools.ini. Using directives, you can conditionally process your makefile, display
error messages, include other makefiles, undefine a macro, and turn certain options on or off.
See also
NMAKE Reference
Makefile Preprocessing Directives
3/12/2019 • 2 minutes to read • Edit Online
Preprocessing directives are not case sensitive. The initial exclamation point (!) must appear at the beginning of
the line. Zero or more spaces or tabs can appear after the exclamation point, for indentation.
!CMDSWITCHES {+ | -}option ...
Turns each option listed on or off. Spaces or tabs must appear before the + or - operator; none can appear
between the operator and the option letters. Letters are not case sensitive and are specified without a slash
( / ). To turn some options on and others off, use separate specifications of !CMDSWITCHES.
Only /D, /I, /N, and /S can be used in a makefile. In Tools.ini, all options are allowed except /F, /HELP,
/NOLOGO, /X, and /?. Changes specified in a description block do not take effect until the next description
block. This directive updates MAKEFLAGS; changes are inherited during recursion if MAKEFLAGS is
specified.
!ERROR text
Displays text in error U1050, then halts NMAKE, even if /K, /I, .IGNORE, !CMDSWITCHES, or the dash (-
) command modifier is used. Spaces or tabs before text are ignored.
!MESSAGE text
Displays text to standard output. Spaces or tabs before text are ignored.
!INCLUDE [ < ] filename [ > ]
Reads filename as a makefile, then continues with the current makefile. NMAKE searches for filename first
in the specified or current directory, then recursively through directories of any parent makefiles, then, if
filename is enclosed by angle brackets (< >), in directories specified by the INCLUDE macro, which is
initially set to the INCLUDE environment variable. Useful to pass .SUFFIXES settings, .PRECIOUS, and
inference rules to recursive makefiles.
!IF constant_expression
Processes statements between !IF and the next !ELSE or !ENDIF if constant_expression evaluates to a
nonzero value.
!IFDEF macroname
Processes statements between !IFDEF and the next !ELSE or !ENDIF if macroname is defined. A null
macro is considered to be defined.
!IFNDEF macroname
Processes statements between !IFNDEF and the next !ELSE or !ENDIF if macroname is not defined.
!ELSE [IF constant_expression | IFDEF macroname | IFNDEF macroname]
Processes statements between !ELSE and the next !ENDIF if the prior !IF, !IFDEF, or !IFNDEF statement
evaluated to zero. The optional keywords give further control of preprocessing.
!ELSEIF
Synonym for !ELSE IF.
!ELSEIFDEF
Synonym for !ELSE IFDEF.
!ELSEIFNDEF
Synonym for !ELSE IFNDEF.
!ENDIF
Marks the end of an !IF, !IFDEF, or !IFNDEF block. Any text after !ENDIF on the same line is ignored.
!UNDEF macroname
Undefines macroname.
See also
Makefile Preprocessing
Expressions in Makefile Preprocessing
3/12/2019 • 2 minutes to read • Edit Online
The !IF or !ELSE IF constantexpression consists of integer constants (in decimal or C -language notation), string
constants, or commands. Use parentheses to group expressions. Expressions use C -style signed long integer
arithmetic; numbers are in 32-bit two's-complement form in the range - 2147483648 to 2147483647.
Expressions can use operators that act on constant values, exit codes from commands, strings, macros, and file-
system paths.
See also
Makefile Preprocessing
Makefile Preprocessing Operators
3/12/2019 • 2 minutes to read • Edit Online
Makefile preprocessing expressions can use operators that act on constant values, exit codes from commands,
strings, macros, and file-system paths. To evaluate the expression, the preprocessor first expands macros, and then
executes commands, and then performs the operations. Operations are evaluated in the order of explicit grouping
in parentheses, and then in the order of operator precedence. The result is a constant value.
The DEFINED operator is a logical operator that acts on a macro name. The expression DEFINED (macroname)
is true if macroname is defined, even if it does not have an assigned value. DEFINED in combination with !IF or
!ELSE IF is equivalent to !IFDEF or !ELSE IFDEF. However, unlike these directives, DEFINED can be used in
complex expressions.
The EXIST operator is a logical operator that acts on a file-system path. EXIST(path) is true if path exists. The
result from EXIST can be used in binary expressions. If path contains spaces, enclose it in double quotation marks.
To compare two strings, use the equality (==) operator or the inequality (!=) operator. Enclose strings in double
quotation marks.
Integer constants can use the unary operators for numerical negation (-), one's complement (~), and logical
negation (!).
Expressions can use the following operators. The operators of equal precedence are grouped together, and the
groups are listed in decreasing order of precedence. Unary operators associate with the operand to the right.
Binary operators of equal precedence associate operands from left to right.
OPERATOR DESCRIPTION
DEFINED( macroname ) Produces a logical value for the current definition state of
macroname.
EXIST( path ) Produces a logical value for the existence of a file at path.
- Unary negation.
* Multiplication.
/ Division.
% Modulus (remainder).
+ Addition.
OPERATOR DESCRIPTION
- Subtraction.
== Equality.
!= Inequality.
^ Bitwise XOR.
| Bitwise OR.
|| Logical OR.
NOTE
The bitwise XOR operator (^) is the same as the escape character, and must be escaped (as ^^) when it is used in an
expression.
See also
Expressions in Makefile Preprocessing
Executing a Program in Preprocessing
3/12/2019 • 2 minutes to read • Edit Online
To use a command's exit code during preprocessing, specify the command, with any arguments, within brackets ([
]). Any macros are expanded before the command is executed. NMAKE replaces the command specification with
the command's exit code, which can be used in an expression to control preprocessing.
See also
Expressions in Makefile Preprocessing
LIB Reference
3/12/2019 • 2 minutes to read • Edit Online
The Microsoft Library Manager (LIB.exe) creates and manages a library of Common Object File Format (COFF )
object files. LIB can also be used to create export files and import libraries to reference exported definitions.
NOTE
You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt
or from File Explorer.
Overview of LIB
How to: Set LIB.EXE Options in the Visual Studio Development Environment
Running LIB
Managing a Library
Extracting a Library Member
Working with Import Libraries and Export Files
See also
Additional MSVC Build Tools
Overview of LIB
3/12/2019 • 2 minutes to read • Edit Online
LIB creates standard libraries, import libraries, and export files you can use with LINK when building a program.
LIB runs from a command prompt.
You can use LIB in the following modes:
Building or modifying a COFF library
Extracting a member object to a file
Creating an export file and an import library
These modes are mutually exclusive; you can use LIB in only one mode at a time.
Lib Options
The following table lists the options for lib.exe, with a link to more information.
OPTION DESCRIPTION
/NODEFAULTLIB Removes one or more default libraries from the list of libraries
it searches when resolving external references.
See also
LIB Reference
LIB Input Files
LIB Output Files
Other LIB Output
Structure of a Library
How to: Set LIB.EXE Options in the Visual Studio
Development Environment
3/12/2019 • 2 minutes to read • Edit Online
See also
LIB Reference
LIB Input Files
3/12/2019 • 2 minutes to read • Edit Online
The input files expected by LIB depend on the mode in which it is being used, as shown in the following table.
MODE INPUT
Default (building or modifying a library) COFF object (.obj) files, COFF libraries (.lib), 32-bit Object
Model Format (OMF) object (.obj) files
Building an export file and import library with /DEF Module-definition (.def) file, COFF object (.obj) files, COFF
libraries (.lib), 32-bit OMF object (.obj) files
NOTE
OMF libraries created by the 16-bit version of LIB cannot be used as input to the 32-bit version of LIB.
See also
Overview of LIB
LIB Output Files
3/12/2019 • 2 minutes to read • Edit Online
The output files produced by LIB depend on the mode in which it is being used, as shown in the following table.
MODE OUTPUT
Building an export file and import library with /DEF Import library (.lib) and export (.exp) file
See also
Overview of LIB
Other LIB Output
3/12/2019 • 2 minutes to read • Edit Online
In the default mode, you can use the /LIST option to display information about the resulting library. You can
redirect this output to a file.
LIB displays a copyright and version message and echoes command files unless the /NOLOGO option is used.
When you type lib with no other input, LIB displays a usage statement that summarizes its options.
Error and warning messages issued by LIB have the form LNKnnnn. The LINK, DUMPBIN, and EDITBIN tools
also use this range of errors. Help is available by selecting the error in the Output window and pressing F1.
See also
Overview of LIB
Structure of a Library
3/12/2019 • 2 minutes to read • Edit Online
A library contains COFF objects. Objects in a library contain functions and data that can be referenced externally
by other objects in a program. An object in a library is sometimes referred to as a library member.
You can get additional information about the contents of a library by running the DUMPBIN tool with the
/LINKERMEMBER option. For more information about this option, see DUMPBIN Reference.
See also
Overview of LIB
Running LIB
3/12/2019 • 3 minutes to read • Edit Online
NOTE
If you are accustomed to the LINK32.exe and LIB32.exe tools provided with the Microsoft Win32 Software Development Kit
for Windows NT, you may have been using either the command link32 -lib or the command lib32 for managing
libraries and creating import libraries. Be sure to change your makefiles and batch files to use the lib command instead.
LIB @commandfile
The file commandfile is a text file. No space or tab is allowed between the at sign (@) and the file name. There is
no default extension; you must specify the full file name, including any extension. Wildcards cannot be used. You
can specify an absolute or relative path with the file name.
In the command file, arguments can be separated by spaces or tabs, as they can on the command line; they can
also be separated by newline characters. Use a semicolon (;) to mark a comment. LIB ignores all text from the
semicolon to the end of the line.
You can specify either all or part of the command line in a command file, and you can use more than one
command file in a LIB command. LIB accepts the command-file input as if it were specified in that location on the
command line. Command files cannot be nested. LIB echoes the contents of command files unless the
/NOLOGO option is used.
/LTCG
"LTCG" stands for link-time code generation. This feature requires cooperation between the compiler (cl.exe), LIB,
and the linker (LINK) in order to optimize code beyond what any component can do by itself.
For LIB, the /LTCG option specifies that the inputs from cl.exe include object files that were generated by using
the /GL compiler option. If LIB encounters such inputs and /LTCG is not specified, it will restart with /LTCG
enabled after displaying an informational message. In other words, it is not necessary to explicitly set this option,
but it speeds up build performance to do so because LIB does not have to restart itself.
In the build process, the output from LIB is sent to LINK. LINK has its own separate /LTCG option which is used
to perform various optimizations, including whole-program optimization and profile-guided optimization (PGO )
instrumentation. For more information about the LINK option, see /LTCG.
/MACHINE
Specifies the target platform for the program. Usually, you do not need to specify /MACHINE. LIB infers the
machine type from the .obj files. However, in some circumstances, LIB cannot determine the machine type and
issues an error message. If such an error occurs, specify /MACHINE. In /EXTRACT mode, this option is for
verification only. Use lib /? at the command line to see available machine types.
/NOLOGO
Suppresses display of the LIB copyright message and version number and prevents echoing of command files.
/VERBOSE
Displays details about the progress of the session, including names of the .obj files being added. The information
is sent to standard output and can be redirected to a file.
/WX[:NO ]
Treat warnings as errors. See /WX (Treat Linker Warnings as Errors) for more information.
Other options apply only to specific modes of LIB. These options are discussed in the sections describing each
mode.
See also
LIB Reference
Managing a Library
3/12/2019 • 3 minutes to read • Edit Online
The default mode for LIB is to build or modify a library of COFF objects. LIB runs in this mode when you do not
specify /EXTRACT (to copy an object to a file) or /DEF (to build an import library).
To build a library from objects and/or libraries, use the following syntax:
This command creates a library from one or more input files. The files can be COFF object files, 32-bit OMF
object files, or existing COFF libraries. LIB creates one library that contains all objects in the specified files. If an
input file is a 32-bit OMF object file, LIB converts it to COFF before building the library. LIB cannot accept a 32-
bit OMF object that is in a library created by the 16-bit version of LIB. You must first use the 16-bit LIB to extract
the object; then you can use the extracted object file as input to the 32-bit LIB.
By default, LIB names the output file using the base name of the first object or library file and the extension .lib.
The output file is put in the current directory. If a file already exists with the same name, the output file replaces
the existing file. To preserve an existing library, use the /OUT option to specify a name for the output file.
The following options apply to building and modifying a library:
/LIBPATH: dir
Overrides the environment library path. For details, see the description of the LINK /LIBPATH option.
/LIST
Displays information about the output library to standard output. The output can be redirected to a file. You can
use /LIST to determine the contents of an existing library without modifying it.
/NAME: filename
When building an import library, specifies the name of the DLL for which the import library is being built.
/NODEFAULTLIB
Removes one or more default libraries from the list of libraries it searches when resolving external references.
See /NODEFAULTLIB for more information.
/OUT: filename
Overrides the default output filename. By default, the output library is created in the current directory, with the
base name of the first library or object file on the command line and the extension .lib.
/REMOVE: object
Omits the specified object from the output library. LIB creates an output library by combining all objects
(whether in object files or libraries), and then deleting any objects specified with /REMOVE.
/SUBSYSTEM:{CONSOLE | EFI_APPLICATION | EFI_BOOT_SERVICE_DRIVER | EFI_ROM |
EFI_RUNTIME_DRIVER | NATIVE | POSIX | WINDOWS | WINDOWSCE }[,#[.##]]
Tells the operating system how to run a program created by linking to the output library. For more information,
see the description of the LINK /SUBSYSTEM option.
LIB options specified on the command line are not case sensitive.
You can use LIB to perform the following library-management tasks:
To add objects to a library, specify the file name for the existing library and the filenames for the new
objects.
To combine libraries, specify the library file names. You can add objects and combine libraries with a
single LIB command.
To replace a library member with a new object, specify the library containing the member object to be
replaced and the file name for the new object (or the library that contains it). When an object that has the
same name exists in more than one input file, LIB puts the last object specified in the LIB command into
the output library. When you replace a library member, be sure to specify the new object or library after
the library that contains the old object.
To delete a member from a library, use the /REMOVE option. LIB processes any specifications of
/REMOVE after combining all input objects, regardless of command-line order.
NOTE
You cannot both delete a member and extract it to a file in the same step. You must first extract the member object using
/EXTRACT, then run LIB again using /REMOVE. This behavior differs from that of the 16-bit LIB (for OMF libraries)
provided in other Microsoft products.
See also
LIB Reference
Extracting a Library Member
3/12/2019 • 2 minutes to read • Edit Online
You can use LIB to create an object (.obj) file that contains a copy of a member of an existing library. To extract a
copy of a member, use the following syntax:
This command creates an .obj file called objectfile that contains a copy of a member of a library. The member name
is case sensitive. You can extract only one member in a single command. The /OUT option is required; there is no
default output name. If a file called objectfile already exists in the specified directory (or the current directory, if no
directory is specified with objectfile), the extracted objectfile replaces the existing file.
See also
LIB Reference
Working with Import Libraries and Export Files
3/12/2019 • 2 minutes to read • Edit Online
You can use LIB with the /DEF option to create an import library and an export file. LINK uses the export file to
build a program that contains exports (usually a dynamic-link library (DLL )), and it uses the import library to
resolve references to those exports in other programs.
Note that if you create your import library in a preliminary step, before creating your .dll, you must pass the same
set of object files when building the .dll, as you passed when building the import library.
In most situations, you do not need to use LIB to create your import library. When you link a program (either an
executable file or a DLL ) that contains exports, LINK automatically creates an import library that describes the
exports. Later, when you link a program that references those exports, you specify the import library.
However, when a DLL exports to a program that it also imports from, whether directly or indirectly, you must use
LIB to create one of the import libraries. When LIB creates an import library, it also creates an export file. You
must use the export file when linking one of the DLLs.
See also
LIB Reference
Building an Import Library and Export File
3/12/2019 • 2 minutes to read • Edit Online
To build an import library and export file, use the following syntax:
When /DEF is specified, LIB creates the output files from export specifications that are passed in the LIB
command. There are three methods for specifying exports, listed in recommended order of use:
1. A __declspec(dllexport) definition in one of the objfiles or libraries
2. A specification of /EXPORT:name on the LIB command line
3. A definition in an EXPORTS statement in a deffile
These are the same methods you use to specify exports when linking an exporting program. A program can use
more than one method. You can specify parts of the LIB command (such as multiple objfiles or /EXPORT
specifications) in a command file in the LIB command, just as you can in a LINK command.
The following options apply to building an import library and export file:
/OUT: import
Overrides the default output file name for the import library being created. When /OUT is not specified, the
default name is the base name of the first object file or library in the LIB command and the extension .lib. The
export file is given the same base name as the import library and the extension .exp.
Exports a function from your program to allow other programs to call the function. You can also export data (using
the DATA keyword). Exports are usually defined in a DLL.
The entryname is the name of the function or data item as it is to be used by the calling program. Optionally, you
can specify the internalname as the function known in the defining program; by default, internalname is the same
as entryname. The ordinal specifies an index into the export table in the range 1 through 65,535; if you do not
specify ordinal, LIB assigns one. The NONAME keyword exports the function only as an ordinal, without an
entryname. The DATA keyword is used to export data-only objects.
/INCLUDE: symbol
Adds the specified symbol to the symbol table. This option is useful for forcing the use of a library object that
otherwise would not be included.
Note that if you create your import library in a preliminary step, before creating your .dll, you must pass the same
set of object files when building the .dll, as you passed when building the import library.
See also
Working with Import Libraries and Export Files
Using an Import Library and Export File
3/12/2019 • 2 minutes to read • Edit Online
When a program (either an executable file or a DLL ) exports to another program that it also imports from, or if
more than two programs both export to and import from each other, the commands to link these programs must
accommodate circular exports.
In a situation without circular exports, when linking a program that uses exports from another program, you must
specify the import library for the exporting program. The import library for the exporting program is created when
you link that exporting program. Therefore, you must link the exporting program before the importing program.
For example, if TWO.dll imports from ONE.dll, you must first link ONE.dll and get the import library ONE.lib.
Then, you specify ONE.lib when linking TWO.dll. When the linker creates TWO.dll, it also creates its import library,
TWO.lib. Use TWO.lib when linking programs that import from TWO.dll.
However, in a circular export situation, it is not possible to link all of the interdependent programs using import
libraries from the other programs. In the example discussed earlier, if TWO.dll also exports to ONE.dll, the import
library for TWO.dll won't exist yet when ONE.dll is linked. When circular exports exist, you must use LIB to create
an import library and export file for one of the programs.
To begin, choose one of the programs on which to run LIB. In the LIB command, list all objects and libraries for the
program and specify /DEF. If the program uses a .def file or /EXPORT specifications, specify these as well.
After you create the import library (.lib) and the export file (.exp) for the program, you use the import library when
linking the other program or programs. LINK creates an import library for each exporting program it builds. For
example, if you run LIB on the objects and exports for ONE.dll, you create ONE.lib and ONE.exp. You can now use
ONE.lib when linking TWO.dll; this step also creates the import library TWO.lib.
Finally, link the program you began with. In the LINK command, specify the objects and libraries for the program,
the .exp file that LIB created for the program, and the import library or libraries for the exports used by the
program. To continue the example, the LINK command for ONE.dll contains ONE.exp and TWO.lib, as well as the
objects and libraries that go into ONE.dll. Do not specify the .def file or /EXPORT specifications in the LINK
command; these are not needed, because the export definitions are contained in the .exp file. When you link using
an .exp file, LINK does not create an import library, because it assumes that one was created when the .exp file was
created.
See also
Working with Import Libraries and Export Files
EDITBIN Reference
3/12/2019 • 2 minutes to read • Edit Online
The Microsoft COFF Binary File Editor (EDITBIN.EXE ) modifies Common Object File Format (COFF ) binary files.
You can use EDITBIN to modify object files, executable files, and dynamic-link libraries (DLL ).
NOTE
You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt
or from File Explorer.
EDITBIN is not available for use on files produced with the /GL compiler option. Any modifications to binary files
produced with /GL will have to be achieved by recompiling and linking.
EDITBIN command line
EDITBIN options
See also
Additional MSVC Build Tools
EDITBIN Command Line
3/12/2019 • 2 minutes to read • Edit Online
Specify one or more files for the objects or images to be changed, and one or more options for changing the files.
When you type the command editbin without any other command-line input, EDITBIN displays a usage
statement that summarizes its options.
See also
Additional MSVC Build Tools
EDITBIN Reference
EDITBIN Options
3/12/2019 • 2 minutes to read • Edit Online
You can use EDITBIN to modify object files, executable files, and dynamic-link libraries (DLLs). Options specify
the changes that EDITBIN makes.
An option consists of an option specifier, which is either a dash ( - ) or a forward slash ( / ), followed by the name
of the option. Option names cannot be abbreviated. Some options take arguments that are specified after a
colon ( : ). No spaces or tabs are allowed within an option specification. Use one or more spaces or tabs to
separate option specifications on the command line. Option names and their keyword arguments or file name
arguments are not case-sensitive. For example, -bind and /BIND mean the same thing.
EDITBIN has the following options:
OPTION PURPOSE
/BIND Sets the addresses for the entry points in the specified
objects to speed load time.
See also
Additional MSVC Build Tools
EDITBIN Reference
/ALLOWISOLATION
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/ALLOWISOLATION[:NO]
Remarks
/ALLOWISOLATION causes the operating system to do manifest lookups and loads.
/ALLOWISOLATION is the default.
/ALLOWISOLATION:NO indicates that executables are loaded as if there were no manifest, and causes EDITBIN
Reference to set the IMAGE_DLLCHARACTERISTICS_NO_ISOLATION bit in the optional header's DllCharacteristics field.
When isolation is disabled for an executable, the Windows loader doesn't try to find an application manifest for the
newly created process. The new process doesn't have a default activation context, even if there is a manifest in the
executable itself or if there is a manifest that has the name executable-name.exe.manifest.
See also
EDITBIN Options
/ALLOWISOLATION (Manifest Lookup)
Manifest Files Reference
/ALLOWBIND
3/12/2019 • 2 minutes to read • Edit Online
/ALLOWBIND[:NO]
Remarks
The /ALLOWBIND option sets a bit in a DLL's header that indicates to Bind.exe that the image is allowed to be
bound. Binding can allow an image to load faster when the loader doesn't have to rebase and perform address
fixup for each referenced DLL. You may not want a DLL to be bound if it has been digitally signed—binding
invalidates the signature. Binding has no effect if address space layout randomization (ASLR ) is enabled for the
image by using /DYNAMICBASE on versions of Windows that support ASLR.
Use /ALLOWBIND:NO to prevent Bind.exe from binding the DLL.
For more information, see the /ALLOWBIND linker option.
See also
EDITBIN Options
/APPCONTAINER
3/12/2019 • 2 minutes to read • Edit Online
Marks an executable that must run in an app container—for example, a Microsoft Store or Universal Windows app.
/APPCONTAINER[:NO]
Remarks
An executable that has the /APPCONTAINER option set can only be run in an app container, which is the
process-isolation environment introduced in Windows 8. For Microsoft Store and Universal Windows apps, this
option must be set.
See also
EDITBIN Options
What's a Universal Windows App?
/BIND
3/12/2019 • 2 minutes to read • Edit Online
/BIND[:PATH=path]
Remarks
This option sets the addresses of the entry points in the import address table for an executable file or DLL. Use
this option to reduce load time of a program.
Specify the program's executable file and DLLs in the files argument on the EDITBIN command line. The optional
path argument to /BIND specifies the location of the DLLs used by the specified files. Separate multiple directories
with a semicolon (;). If path is not specified, EDITBIN searches the directories specified in the PATH environment
variable. If path is specified, EDITBIN ignores the PATH variable.
By default, the program loader sets the addresses of entry points when it loads a program. The amount of time
this process takes varies, depending on the number of DLLs and the number of entry points referenced in the
program. If a program has been modified with /BIND, and if the base addresses for the executable file and its
DLLs do not conflict with DLLs that are already loaded, the operating system does not need to set these addresses.
In a situation where the files are incorrectly based, the operating system relocates the program's DLLs and
recalculates the entry-point addresses, which adds to the program's load time.
See also
EDITBIN Options
/DYNAMICBASE
3/12/2019 • 2 minutes to read • Edit Online
Specifies whether to generate an executable image that can be randomly rebased at load time by using the
address space layout randomization (ASLR ) feature of Windows that was first available in Windows Vista.
Syntax
/DYNAMICBASE [:NO ]
Remarks
The /DYNAMICBASE option modifies the header of an executable image, a .dll or .exe file, to indicate whether
the application should be randomly rebased at load time, and enables virtual address allocation randomization,
which affects the virtual memory location of heaps, stacks, and other operating system allocations. The
/DYNAMICBASE option applies to both 32-bit and 64-bit images. ASLR is supported on Windows Vista and
later operating systems. The option is ignored by earlier operating systems.
By default, /DYNAMICBASE is enabled. To disable this option, use /DYNAMICBASE:NO. The
/DYNAMICBASE option is required for the /HIGHENTROPYVA option to have an effect.
See also
EDITBIN Options
Windows ISV Software Security Defenses
/ERRORREPORT (editbin.exe)
3/12/2019 • 2 minutes to read • Edit Online
Remarks
If editbin.exe fails at runtime, you can use /ERRORREPORT to send information to Microsoft about these internal
errors.
For more information about /ERRORREPORT, see /errorReport (Report Internal Compiler Errors).
See also
EDITBIN Options
/HEAP
3/12/2019 • 2 minutes to read • Edit Online
Sets the size of the heap in bytes. This option only applies to executable files.
/HEAP:
reserve[,commit]
Remarks
The reserve argument specifies the total initial heap allocation in virtual memory. By default, the heap size is 1
MB. EDITBIN Reference rounds up the specified value to the nearest multiple of 4 bytes.
The optional commit argument is subject to interpretation by the operating system. On a Windows operating
system, it specifies the initial amount of physical memory to allocate, and the amount of additional memory to
allocate when the heap must be expanded. Committed virtual memory causes space to be reserved in the paging
file. A higher commit value allows the system to allocate memory less often when the app needs more heap space
but increases the memory requirements and possibly the app startup duration. The commit value must be less
than or equal to the reserve value.
Specify the reserve and commit values in decimal or C -language hexadecimal or octal notation. For example, a
value of 1 MB can be specified as 1048576 in decimal, or as 0x100000 in hexadecimal, or as 04000000 in octal.
See also
EDITBIN Options
/HIGHENTROPYVA
10/31/2018 • 2 minutes to read • Edit Online
Specifies whether the executable image supports high-entropy 64-bit address space layout randomization (ASLR ).
Syntax
/HIGHENTROPYVA [:NO ]
Remarks
This option modifies the header of an executable image, a .dll file or .exe file, to indicate whether ASLR with 64-bit
addresses is supported. When this option is set on an executable and all of the modules that it depends on, an
operating system that supports 64-bit ASLR can rebase the segments of the executable image at load time by
using randomized addresses in a 64-bit virtual address space. This large address space makes it more difficult for
an attacker to guess the location of a particular memory region.
By default, the linker enables /HIGHENTROPYVA for 64-bit executable images. This option requires
/LARGEADDRESSAWARE, which is also enabled by default for 64-bit images. /HIGHENTROPYVA is not
applicable to 32-bit executable images, where the option is ignored. To explicitly disable this option, use
/HIGHENTROPYVA:NO. For this option to have an effect, the /DYNAMICBASE option must also be set.
See also
EDITBIN Options
/DYNAMICBASE
Windows ISV Software Security Defenses
/INTEGRITYCHECK
3/12/2019 • 2 minutes to read • Edit Online
Specifies that the digital signature of the binary image must be checked at load time.
/INTEGRITYCHECK[:NO ]
Remarks
In the header of the DLL file or executable file, this option sets a flag that requires a digital signature check by the
memory manager to load the image in Windows. Versions of Windows prior to Windows Vista ignore this flag.
This option must be set for 64-bit DLLs that implement kernel-mode code, and is recommended for all device
drivers. For more information, see Kernel-Mode Code Signing Requirements.
See also
EDITBIN Options
/LARGEADDRESSAWARE
3/12/2019 • 2 minutes to read • Edit Online
/LARGEADDRESSAWARE
Remarks
This option edits the image to indicate that the application can handle addresses larger than 2 gigabytes.
See also
EDITBIN Options
/NOLOGO (EDITBIN)
3/12/2019 • 2 minutes to read • Edit Online
/NOLOGO
Remarks
This option suppresses display of the EDITBIN copyright message and version number.
See also
EDITBIN Options
/NXCOMPAT
3/12/2019 • 2 minutes to read • Edit Online
/NXCOMPAT[:NO]
Remarks
Indicates that an executable was tested to be compatible with the Windows Data Execution Prevention feature.
For more information, see /NXCOMPAT (Compatible with Data Execution Prevention).
See also
EDITBIN Options
/REBASE
3/12/2019 • 2 minutes to read • Edit Online
/REBASE[:modifiers]
Remarks
This option sets the base addresses for the specified files. EDITBIN assigns new base addresses in a contiguous
address space according to the size of each file rounded up to the nearest 64 KB. For details about base addresses,
see the Base Address (/BASE ) linker option.
Specify the program's executable files and DLLs in the files argument on the EDITBIN command line in the order
in which they are to be based. You can optionally specify one or more modifiers, each separated by a comma (,):
MODIFIER ACTION
See also
EDITBIN Options
/RELEASE
3/12/2019 • 2 minutes to read • Edit Online
/RELEASE
Remarks
This option sets the checksum in the header of an executable file.
The operating system requires the checksum for device drivers. It is recommended that you set the checksum for
release versions of your device drivers to ensure compatibility with future operating systems.
See also
EDITBIN Options
/SECTION (EDITBIN)
3/12/2019 • 2 minutes to read • Edit Online
/SECTION:name[=newname][,attributes][alignment]
Remarks
This option changes the attributes of a section, overriding the attributes that were set when the object file for the
section was compiled or linked.
After the colon ( : ), specify the name of the section. To change the section name, follow name with an equal sign
(=) and a newname for the section.
To set or change the section's attributes , specify a comma (,) followed by one or more attributes characters. To
negate an attribute, precede its character with an exclamation point (!). The following characters specify memory
attributes:
ATTRIBUTE SETTING
c code
d discardable
e executable
i initialized data
m link remove
o link info
r read
s shared
u uninitialized data
w write
To control alignment, specify the character A followed by one of the following characters to set the size of
alignment in bytes, as follows:
CHARACTER ALIGNMENT SIZE IN BYTES
1 1
2 2
4 4
8 8
p 16
t 32
s 64
x no alignment
Specify the attributes and alignment characters as a string with no white space. The characters are not case
sensitive.
See also
EDITBIN Options
/STACK
3/12/2019 • 2 minutes to read • Edit Online
/STACK:reserve[,commit]
Remarks
This option sets the size of the stack in bytes and takes arguments in decimal or C -language notation. The /STACK
option applies only to an executable file.
The reserve argument specifies the total stack allocation in virtual memory. EDITBIN rounds up the specified value
to the nearest 4 bytes.
The optional commit argument is subject to interpretation by the operating system. In Windows NT, Windows 95,
and Windows 98, commit specifies the amount of physical memory to allocate at a time. Committed virtual
memory causes space to be reserved in the paging file. A higher commit value saves time when the application
needs more stack space but increases the memory requirements and possibly startup time.
See also
EDITBIN Options
/SUBSYSTEM
3/12/2019 • 2 minutes to read • Edit Online
/SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION|
EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|
NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
Remarks
This option edits the image to indicate which subsystem the operating system must invoke for execution.
You can specify any of the following subsystems:
BOOT_APPLICATION
An application that runs in the Windows boot environment. For more information about boot applications, see
About the BCD WMI Provider.
CONSOLE
A Windows character-mode application. The operating system provides a console for console applications.
EFI_APPLICATION
EFI_BOOT_SERVICE_DRIVER
EFI_ROM
EFI_RUNTIME_DRIVER
Extensible Firmware Interface (EFI) Image
The EFI subsystem options describe executable images that run in the Extensible Firmware Interface environment.
This environment is typically provided with the hardware and executes before the operating system is loaded. The
major differences between EFI image types are the memory location that the image is loaded into and the action
that's taken when the call to the image returns. An EFI_APPLICATION image is unloaded when control returns. An
EFI_BOOT_SERVICE_DRIVER or EFI_RUNTIME_DRIVER is unloaded only if control returns with an error code.
An EFI_ROM image is executed from ROM. For more information, see the specifications on the Unified EFI Forum
website.
NATIVE
Code that runs without a subsystem environment—for example, kernel mode device drivers and native system
processes. This option is usually reserved for Windows system features.
POSIX
An app that runs in the POSIX subsystem in Windows.
WINDOWS
An app that runs in the Windows graphical environment. This includes both desktop apps and Universal Windows
Platform (UWP ) apps.
WINDOWSCE
The WINDOWSCE subsystem indicates that the app is intended to run on a device that has a version of the
Windows CE kernel. Versions of the kernel include PocketPC, Windows Mobile, Windows Phone 7, Windows CE
V1.0-6.0R3, and Windows Embedded Compact 7.
The optional major and minor values specify the minimum required version of the specified subsystem:
The whole number part of the version number—the portion to the left of the decimal point—is represented
by major .
The fractional part of the version number—the portion to the right of the decimal point—is represented by
minor .
See also
EDITBIN Options
/SWAPRUN
3/12/2019 • 2 minutes to read • Edit Online
/SWAPRUN:{[!]NET|[!]CD}
Remarks
This option edits the image to tell the operating system to copy the image to a swap file and run it from there. Use
this option for images that reside on networks or removable media.
You can add or remove the NET or CD qualifiers:
NET indicates that the image resides on a network.
CD indicates that the image resides on a CD -ROM or similar removable medium.
Use !NET and !CD to reverse the effects of NET and CD.
See also
EDITBIN Options
/TSAWARE
3/12/2019 • 2 minutes to read • Edit Online
/TSAWARE[:NO]
Remarks
The /TSAWARE option to the EDITBIN utility allows you to modify a program image the same way as if you had
used the /TSAWARE linker option.
See also
EDITBIN Options
/VERSION
3/12/2019 • 2 minutes to read • Edit Online
/VERSION:left[,right]
Remarks
This option places a version number into the header of the image.
The whole number part of the version number, the portion to the left of the decimal point, is represented by left .
The fractional part of the version number, the portion to the right of the decimal point, is represented by right .
See also
EDITBIN Options
DUMPBIN Reference
3/12/2019 • 2 minutes to read • Edit Online
The Microsoft COFF Binary File Dumper (DUMPBIN.EXE ) displays information about Common Object File
Format (COFF ) binary files. You can use DUMPBIN to examine COFF object files, standard libraries of COFF
objects, executable files, and dynamic-link libraries (DLLs).
NOTE
You can start this tool only from the Visual Studio command prompt. You cannot start it from a system command prompt
or from File Explorer.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
DUMPBIN command line
DUMPBIN options
See also
Additional MSVC Build Tools
DUMPBIN Command Line
3/12/2019 • 2 minutes to read • Edit Online
Specify one or more binary files, along with any options required to control the information. DUMPBIN displays
the information to standard output. You can either redirect it to a file or use the /OUT option to specify a file name
for the output.
When you run DUMPBIN on a file without specifying an option, DUMPBIN displays the /SUMMARY output.
When you type the command dumpbin without any other command-line input, DUMPBIN displays a usage
statement that summarizes its options.
See also
Additional MSVC Build Tools
DUMPBIN Reference
DUMPBIN Options
3/12/2019 • 2 minutes to read • Edit Online
An option consists of an option specifier, which is either a dash ( - ) or a forward slash (/), followed by the name
of the option. Option names cannot be abbreviated. Some options take arguments, specified after a colon (:).
No spaces or tabs are allowed within an option specification. Use one or more spaces or tabs to separate
option specifications on the command line. Option names and their keyword or file name arguments are not
case sensitive. Most options apply to all binary files; a few apply only to certain types of files. By default,
DUMPBIN sends information to standard output. Use the /OUT option to send output to a file.
DUMPBIN has the following options:
/ALL
/ARCHIVEMEMBERS
/CLRHEADER
/DEPENDENTS
/DIRECTIVES
/DISASM
/ERRORREPORT (dumpbin.exe)
/EXPORTS
/FPO
/HEADERS
/IMPORTS
/LINENUMBERS
/LINKERMEMBER
/LOADCONFIG
/OUT
/PDATA
/PDBPATH
/RANGE
/RAWDATA
/RELOCATIONS
/SECTION
/SUMMARY
/SYMBOLS
/TLS
See also
Additional MSVC Build Tools
DUMPBIN Reference
/ALL
3/12/2019 • 2 minutes to read • Edit Online
/ALL
Remarks
This option displays all available information except code disassembly. Use /DISASM to display disassembly. You
can use /RAWDATA:NONE with /ALL to omit the raw binary details of the file.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/ARCHIVEMEMBERS
3/12/2019 • 2 minutes to read • Edit Online
/ARCHIVEMEMBERS
Remarks
This option displays minimal information about member objects in a library.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/CLRHEADER
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/CLRHEADER file
Arguments
file
An image file built with /clr.
Remarks
/CLRHEADER displays information about the .NET headers used in any managed program. The output shows
the location and size, in bytes, of the .NET header and sections in the header.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
When /CLRHEADER is used on a file that was compiled with /clr, there will be a clr Header: section in the
dumpbin output. The value of flags indicates which /clr option was used:
0 -- /clr (image may contain native code).
You can also programmatically check if an image was built for the common language runtime. For more
information, see How to: Determine if an Image is Native or CLR.
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017. Code that must be "pure" or "safe" should be ported to C#.
See also
DUMPBIN Options
/DEPENDENTS
3/12/2019 • 2 minutes to read • Edit Online
/DEPENDENTS
Remarks
Dumps the names of the DLLs from which the image imports functions. Does not dump the names of the
imported functions.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/DIRECTIVES
3/12/2019 • 2 minutes to read • Edit Online
/DIRECTIVES
Remarks
This option dumps the compiler-generated .drective section of an image.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/DISASM
3/12/2019 • 2 minutes to read • Edit Online
Syntax
/DISASM {:[BYTES|NOBYTES ]}
Arguments
BYTES
Includes the instruction bytes together with the interpreted opcodes and arguments in the disassembly output.
This is the default option.
NOBYTES
Does not include the instruction bytes in the disassembly output.
Remarks
The /DISASM option displays disassembly of code sections in the file. It uses debug symbols if they are present in
the file.
/DISASM should only be used on native, not managed, images. The equivalent tool for managed code is
ILDASM.
Only the /HEADERS DUMPBIN option is available for use on files produced by the /GL (Whole program
optimization) compiler option.
See also
DUMPBIN Options
/ERRORREPORT (dumpbin.exe)
3/12/2019 • 2 minutes to read • Edit Online
Remarks
If dumpbin.exe fails at runtime, you can use /ERRORREPORT to send information to Microsoft about these
internal errors.
For more information about /ERRORREPORT, see /errorReport (Report Internal Compiler Errors).
See also
DUMPBIN Options
/EXPORTS
3/12/2019 • 2 minutes to read • Edit Online
/EXPORTS
Remarks
This option displays all definitions exported from an executable file or DLL.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/FPO
3/12/2019 • 2 minutes to read • Edit Online
/FPO
Remarks
This option displays frame pointer optimization (FPO ) records.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/HEADERS
3/12/2019 • 2 minutes to read • Edit Online
/HEADERS
Remarks
This option displays the file header and the header for each section. When used with a library, it displays the
header for each member object.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/IMPORTS (DUMPBIN)
3/12/2019 • 2 minutes to read • Edit Online
/IMPORTS[:file]
This option displays the list of DLLs (both statically linked and delay loaded) that are imported to an executable file
or DLL and all the individual imports from each of these DLLs.
The optional file specification allows you to specify that the imports for only that DLL will be displayed. For
example:
dumpbin /IMPORTS:msvcrt.dll
Remarks
The output displayed by this option is similar to the /EXPORTS output.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/LINENUMBERS
3/12/2019 • 2 minutes to read • Edit Online
/LINENUMBERS
Remarks
This option displays COFF line numbers. Line numbers exist in an object file if it was compiled with Program
Database (/Zi), C7 Compatible (/Z7), or Line Numbers Only (/Zd). An executable file or DLL contains COFF line
numbers if it was linked with Generate Debug Info (/DEBUG ).
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/LINKERMEMBER
3/12/2019 • 2 minutes to read • Edit Online
/LINKERMEMBER[:{1|2}]
Remarks
This option displays public symbols defined in a library. Specify the 1 argument to display symbols in object order,
along with their offsets. Specify the 2 argument to display offsets and index numbers of objects, and then list the
symbols in alphabetical order, along with the object index for each. To get both outputs, specify /LINKERMEMBER
without the number argument.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/LOADCONFIG
3/12/2019 • 2 minutes to read • Edit Online
/LOADCONFIG
Remarks
This option dumps the IMAGE_LOAD_CONFIG_DIRECTORY structure, an optional structure that is used by the
Windows NT loader and defined in WINNT.H.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/OUT (DUMPBIN)
3/12/2019 • 2 minutes to read • Edit Online
/OUT:filename
Remarks
This option specifies a filename for the output. By default, DUMPBIN displays the information to standard output.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/PDATA
3/12/2019 • 2 minutes to read • Edit Online
/PDATA
Remarks
RISC processors only.
This option dumps the exception tables (.pdata) from an image or object.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/PDBPATH
3/12/2019 • 2 minutes to read • Edit Online
/PDBPATH[:VERBOSE] filename
Parameters
filename
The name of the .dll or .exe file for which you want to find the matching .pdb file.
:VERBOSE
(Optional) Reports all directories where an attempt was made to locate the .pdb file.
Remarks
/PDBPATH will search your computer along the same paths that the debugger would search for a .pdb file and will
report which, if any, .pdb files correspond to the file specified in filename.
When using the Visual Studio debugger, you may experience a problem due to the fact that the debugger is using
a .pdb file for a different version of the file you are debugging.
/PDBPATH will search for .pdb files along the following paths:
Check the location where the executable resides.
Check the location of the PDB written into the executable. This is usually the location at the time the image
was linked.
Check along the search path configured in the Visual Studio IDE.
Check along the paths in the _NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH environment variables.
Check in the Windows directory.
See also
DUMPBIN Options
/PDBALTPATH (Use Alternate PDB Path)
/RANGE
3/12/2019 • 2 minutes to read • Edit Online
Modifies the output of dumpbin when used with other dumpbin options, such as /RAWDATA or /DISASM.
Syntax
/RANGE:vaMin[,vaMax]
Parameters
vaMin
The virtual address at which you want the dumpbin operation to begin.
vaMax
(Optional) The virtual address at which you want the dumpbin operation to end. If not specified, dumpbin will go
to the end of the file.
Remarks
To see the virtual addresses for an image, use the map file for the image (RVA + Base), the /DISASM or
/HEADERS option of dumpbin, or the disassembly window in the Visual Studio debugger.
Example
In this example, /range is used to modify the display of the /disasm option. In this example, the starting value is
expressed as a decimal number and the ending value is specified as a hex number.
See also
DUMPBIN Options
/RAWDATA
3/12/2019 • 2 minutes to read • Edit Online
/RAWDATA[:{1|2|4|8|NONE[,number]]
Remarks
This option displays the raw contents of each section in the file. The arguments control the format of the display, as
shown below:
ARGUMENT RESULT
Number Displayed lines are set to a width that holds number values
per line.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/RELOCATIONS
3/12/2019 • 2 minutes to read • Edit Online
/RELOCATIONS
Remarks
This option displays any relocations in the object or image.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/SECTION (DUMPBIN)
3/12/2019 • 2 minutes to read • Edit Online
/SECTION:section
Remarks
This option restricts the output to information on the specified section. Use the /HEADERS option to get a list of
sections in the file.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/SUMMARY
3/12/2019 • 2 minutes to read • Edit Online
/SUMMARY
Remarks
This option displays minimal information about sections, including total size. This option is the default if no other
option is specified.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/SYMBOLS
3/12/2019 • 2 minutes to read • Edit Online
/SYMBOLS
This option displays the COFF symbol table. Symbol tables exist in all object files. A COFF symbol table appears in
an image file only if it is linked with /DEBUG.
The following is a description of the output for /SYMBOLS. Additional information on the meaning of
/SYMBOLS output can be found by looking in winnt.h (IMAGE_SYMBOL and IMAGE_AUX_SYMBOL ), or COFF
documentation.
Given the following sample dump:
Summary
26 .drectve
23 .text
Remarks
The following description, for lines that begin with a symbol number, describes columns that have information
relevant to users:
The first three-digit number is the symbol index/number.
If the third column contains SECTx, the symbol is defined in that section of the object file. But if UNDEF
appears, it is not defined in that object and must be resolved elsewhere.
The fifth column (Static, External) tells whether the symbol is visible only within that object, or whether it is
public (visible externally). A Static symbol, _sym, wouldn't be linked to a Public symbol _sym; these would
be two different instances of functions named _sym.
The last column in a numbered line is the symbol name, both decorated and undecorated.
Only the /HEADERS DUMPBIN option is available for use on files produced with the /GL compiler option.
See also
DUMPBIN Options
/TLS
3/12/2019 • 2 minutes to read • Edit Online
Remarks
/TLS displays the fields of the TLS structure as well as the addresses of the TLS callback functions.
If a program does not use thread local storage, its image will not contain a TLS structure. See thread for more
information.
IMAGE_TLS_DIRECTORY is defined in winnt.h.
See also
DUMPBIN Options
ERRLOOK Reference
3/12/2019 • 2 minutes to read • Edit Online
The ERRLOOK utility, which is available from the Tools menu as Error Lookup, retrieves a system error message
or module error message based on the value entered. ERRLOOK retrieves the error message text automatically if
you drag and drop a hexadecimal or decimal value from the Visual Studio debugger into the Value edit control.
You can also enter a value either by typing it in the Value edit control or by pasting it from the Clipboard and
clicking Look Up.
The accelerator keys for Copy (CTRL+C ), Cut (CTRL+X), and Paste (CTRL+V ) work for both the Value and Error
Message edit controls if you first highlight the text.
In This Section
Value Edit Control
Describes the Value Edit control in ERRLOOK.
Error Message Edit Control
Describes the Error Message Edit control in ERRLOOK.
Modules Button
Describes the Modules button in ERRLOOK.
Look Up Button
Describes the Look Up button in ERRLOOK.
Related Sections
Additional MSVC Build Tools
Provides links to topics discussing the C/C++ build tools provided in Visual C++.
Value Edit Control
3/12/2019 • 2 minutes to read • Edit Online
To use the control, enter a value, paste it from the Clipboard, or drag and drop it from the debugger into this edit
control. Enter the value in hexadecimal or decimal form and then click Look Up. Hexadecimal values should be
preceded by 0x; valid characters are 0-9, A-F, and a-f. Decimal values can be preceded by the minus sign (-); valid
characters are 0-9.
See also
ERRLOOK Reference
Error Message Edit Control
3/12/2019 • 2 minutes to read • Edit Online
The Error Message box contains the text of the system error message or module error message based on the
value entered.
See also
Value Edit Control
Modules Button
3/12/2019 • 2 minutes to read • Edit Online
Click the Modules button to bring up the Additional Modules for Error Searching dialog. Enter the name of
the desired EXE or DLL in the edit box and click Add to include the modules in your error message search.
Remove a module from the list by highlighting it and clicking the Remove button.
See also
Value Edit Control
Look Up Button
3/12/2019 • 2 minutes to read • Edit Online
Click Look Up to retrieve the error message that corresponds to the system or module value entered. Values can
be entered in hexadecimal or decimal form (including negative decimal values). Modules listed in the Additional
Modules for Error Searching dialog are also searched.
See also
Value Edit Control
XDCMake Reference
3/12/2019 • 2 minutes to read • Edit Online
xdcmake.exe is a program that compiles .xdc files into an .xml file. An .xdc file is created by the MSVC compiler for
each source code file when source code is compiled with /doc and when the source code file contains
documentation comments marked up with XML tags.
To use xdcmake.exe in the Visual Studio development environment
1. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
2. Open the Configuration Properties folder.
3. Click the XML Document Comments property page.
NOTE
xdcmake.exe options at the command line differ from the options when xdcmake.exe is used in the development
environment (property pages). For information on using xdcmake.exe in the development environment, see XML Document
Generator Tool Property Pages.
Syntax
xdcmake input_filename options
Parameters
input_filename
The file name of the .xdc files used as input to xdcmake.exe. Specify one or more .xdc files or use *.xdc to use all
.xdc files in the current directory.
options
Zero or more of the following:
OPTION DESCRIPTION
/assembly:filename Lets you specify the value of the <assembly> tag in the .xml
file. By default, the value of the <assembly> tag is the same
as the filename of the .xml file.
/out:filename Lets you specify the name of the .xml file. By default, the
name of the .xml file is the filename of the first .xdc file
processed by xdcmake.exe.
Remarks
Visual Studio will invoke xdcmake.exe automatically when building a project. You can also invoke xdcmake.exe at
the command line.
See Recommended Tags for Documentation Comments for more information on adding documentation
comments to source code files.
See also
XML Documentation
BSCMAKE Reference
3/12/2019 • 2 minutes to read • Edit Online
WARNING
Although BSCMAKE is still installed with Visual Studio, it is no longer used by the IDE. Since Visual Studio 2008, browse and
symbol information is stored automatically in a SQL Server .sdf file in the solution folder.
The Microsoft Browse Information Maintenance Utility (BSCMAKE.EXE ) builds a browse information file (.bsc)
from .sbr files created during compilation. Certain third-party tools use .bsc files for code analysis.
When you build your program, you can create a browse information file for your program automatically, using
BSCMAKE to build the file. You do not need to know how to run BSCMAKE if you create your browse
information file in the Visual C++ development environment. However, you may want to read this topic to
understand the choices available.
If you build your program outside of the development environment, you can still create a custom .bsc that you can
examine in the environment. Run BSCMAKE on the .sbr files that you created during compilation.
NOTE
You can start this tool only from the Visual Studio Developer command prompt. You cannot start it from a system
command prompt or from File Explorer.
See also
Additional MSVC Build Tools
Building Browse Information Files: Overview
3/12/2019 • 2 minutes to read • Edit Online
To create browse information for symbol browsing, the compiler creates an .sbr file for each source file in your
project, then BSCMAKE.EXE concatenates the .sbr files into one .bsc file.
Generating .sbr and .bsc files takes time, so Visual C++ turns these functions off by default. If you want to browse
current information, you must turn the browse options on and build your project again.
Use /FR or /Fr to tell the compiler to create .sbr files. To create .bsc files, you can call BSCMAKE from the
command line. Using BSCMAKE from the command line gives you more precise control over the manipulation of
browse information files. See BSCMAKE Reference for more information.
TIP
You can turn on .sbr file generation but leave .bsc file generation turned off. This provides fast builds but also enables you to
create a fresh .bsc file quickly by turning on .bsc file generation and building the project.
You can reduce the time, memory, and disk space required to build a .bsc file by reducing the size of the .bsc file.
See General Property Page (Project) for information on how to build a browser file in the development
environment.
To create a smaller .bsc file
1. Use BSCMAKE command-line options to exclude information from the browse information file.
2. Omit local symbols in one or more .sbr files when compiling or assembling.
3. If an object file does not contain information needed for your current stage of debugging, omit its .sbr file
from the BSCMAKE command when you rebuild the browse information file.
To combine the browse information from several projects into one browser file (.bsc)
1. Either don't build the .bsc file at the project level or use the /n switch to prevent the .sbr files from being
truncated.
2. After all the projects are built, run BSCMAKE with all of the .sbr files as input. Wildcards are accepted. For
instance, if you had project directories C:\X, C:\Y, and C:\Z with .sbr files in them and you wanted to
combine them all into one .bsc file, then use BSCMAKE C:\X\*.sbr C:\Y\*.sbr C:\Z\*.sbr /o
c:\whatever_directory\combined.bsc to build the combined .bsc file.
See also
Additional MSVC Build Tools
BSCMAKE Reference
Building a .Bsc File
3/12/2019 • 2 minutes to read • Edit Online
BSCMAKE can build a new browse information file from newly created .sbr files. It can also maintain an existing
.bsc file using .sbr files for object files that have changed since the last build.
How to create an .sbr file
How BSCMAKE builds a .bsc file
See also
BSCMAKE Reference
Creating an .Sbr File
3/12/2019 • 2 minutes to read • Edit Online
The input files for BSCMAKE are .sbr files. The compiler creates an .sbr file for each object file (.obj) it compiles.
When you build or update your browse information file, all .sbr files for your project must be available on disk.
To create an .sbr file with all possible information, specify /FR.
To create an .sbr file that doesn't contain local symbols, specify /Fr. If the .sbr files contain local symbols, you can
still omit them from the .bsc file by using BSCMAKE's /El option .
You can create an .sbr file without performing a full compile. For example, you can specify the /Zs option to the
compiler to perform a syntax check and still generate an .sbr file if you specify /FR or /Fr.
The build process can be more efficient if the .sbr files are first packed to remove unreferenced definitions. The
compiler automatically packs .sbr files.
See also
Building a .Bsc File
How BSCMAKE Builds a .Bsc File
3/12/2019 • 2 minutes to read • Edit Online
BSCMAKE builds or rebuilds a .bsc file in the most efficient way it can. To avoid potential problems, it is important
to understand the build process.
When BSCMAKE builds a browse information file, it truncates the .sbr files to zero length. During a subsequent
build of the same file, a zero-length (or empty) .sbr file tells BSCMAKE that the .sbr file has no new contribution to
make. It lets BSCMAKE know that an update of that part of the file is not required and an incremental build will be
sufficient. During every build (unless the /n option is specified), BSCMAKE first attempts to update the file
incrementally by using only those .sbr files that have changed.
BSCMAKE looks for a .bsc file that has the name specified with the /o option. If /o is not specified, BSCMAKE
looks for a file that has the base name of the first .sbr file and a .bsc extension. If the file exists, BSCMAKE performs
an incremental build of the browse information file using only the contributing .sbr files. If the file does not exist,
BSCMAKE performs a full build using all .sbr files. The rules for builds are as follows:
For a full build to succeed, all specified .sbr files must exist and must not be truncated. If an .sbr file is
truncated, you must rebuild it (by recompiling or assembling) before running BSCMAKE.
For an incremental build to succeed, the .bsc file must exist. All contributing .sbr files, even empty files, must
exist and must be specified on the BSCMAKE command line. If you omit an .sbr file from the command line,
BSCMAKE removes its contribution from the file.
See also
Building a .Bsc File
BSCMAKE Command Line
3/12/2019 • 2 minutes to read • Edit Online
Options can appear only in the options field on the command line.
The sbrfiles field specifies one or more .sbr files created by a compiler or assembler. Separate the names of .sbr
files with spaces or tabs. You must specify the extension; there is no default. You can specify a path with the
filename, and you can use operating-system wildcards (* and ?).
During an incremental build, you can specify new .sbr files that were not part of the original build. If you want all
contributions to remain in the browse information file, you must specify all .sbr files (including truncated files) that
were originally used to create the .bsc file. If you omit an .sbr file, that file's contribution to the browse information
file is removed.
Do not specify a truncated .sbr file for a full build. A full build requires contributions from all specified .sbr files.
Before you perform a full build, recompile the project and create a new .sbr file for each empty file.
The following command runs BSCMAKE to build a file called MAIN.bsc from three .sbr files:
For related information, see BSCMAKE Command File and BSCMAKE Options.
See also
BSCMAKE Reference
BSCMAKE Command File (Response File)
3/12/2019 • 2 minutes to read • Edit Online
You can provide part or all of the command-line input in a command file. Specify the command file using the
following syntax:
BSCMAKE @filename
Only one command file is allowed. You can specify a path with filename. Precede filename with an at sign (@).
BSCMAKE does not assume an extension. You can specify additional sbrfiles on the command line after filename.
The command file is a text file that contains the input to BSCMAKE in the same order as you would specify it on
the command line. Separate the command-line arguments with one or more spaces, tabs, or newline characters.
The following command calls BSCMAKE using a command file:
BSCMAKE @prog1.txt
/n /v /o main.bsc /El
/S (
toolbox.h
verdate.h c:\src\inc\screen.h
)
file1.sbr file2.sbr file3.sbr file4.sbr
See also
BSCMAKE Reference
BSCMAKE Options
3/12/2019 • 3 minutes to read • Edit Online
This section describes the options available for controlling BSCMAKE. Several options control the content of the
browse information file by excluding or including certain information. The exclusion options can allow BSCMAKE
to run faster and may result in a smaller .bsc file. Option names are case sensitive (except for /HELP and
/NOLOGO ).
Only /NOLOGO and /o are available from within the Visual Studio development environment. See Set C++
compiler and build properties in Visual Studio for information on access a project's property pages.
/Ei ( filename...)
Excludes the contents of the specified include files from the browse information file. To specify multiple files,
separate the names with a space and enclose the list in parentheses. Parentheses are not necessary if you specify
only one filename. Use /Ei along with the /Es option to exclude files not excluded by /Es.
/El
Excludes local symbols. The default is to include local symbols. For more information about local symbols, see
Creating an .sbr File.
/Em
Excludes symbols in the body of macros. Use /Em to include only the names of macros in the browse information
file. The default is to include both the macro names and the result of the macro expansions.
/Er ( symbol...)
Excludes the specified symbols from the browse information file. To specify multiple symbol names, separate the
names with a space and enclose the list in parentheses. Parentheses are not necessary if you specify only one
symbol.
/Es
Excludes from the browse information file every include file specified with an absolute path or found in an
absolute path specified in the INCLUDE environment variable. (Usually, these are the system include files, which
contain a lot of information that you may not need in your browse information file.) This option does not exclude
files specified without a path or with relative paths or files found in a relative path in INCLUDE. You can use the
/Ei option along with /Es to exclude files that /Es does not exclude. If you want to exclude only some of the files
that /Es excludes, use /Ei instead of /Es and list the files you want to exclude.
/errorreport:[none | prompt | queue | send]
Allows you to send information to Microsoft regarding internal errors in bscmake.exe.
For more information on /errorreport, see /errorReport (Report Internal Compiler Errors).
/HELP
Displays a summary of the BSCMAKE command-line syntax.
/Iu
Includes unreferenced symbols. By default, BSCMAKE does not record any symbols that are defined but not
referenced. If an .sbr file has been packed, this option has no effect for that input file because the compiler has
already removed the unreferenced symbols.
/n
Forces a nonincremental build. Use /n to force a full build of the browse information file whether or not a .bsc file
exists and to prevent .sbr files from being truncated. See How BSCMAKE Builds a .bsc File.
/NOLOGO
Suppresses the BSCMAKE copyright message.
/o filename
Specifies a name for the browse information file. By default, BSCMAKE gives the browse information file the base
name of the first .sbr file and a .bsc extension.
/S ( filename...)
Tells BSCMAKE to process the specified include file the first time it is encountered and to exclude it otherwise.
Use this option to save processing time when a file (such as a header, or .h, file for a .c or .cpp source file) is
included in several source files but is unchanged by preprocessing directives each time. You may also want to use
this option if a file is changed in ways that are unimportant for the browse information file you are creating. To
specify multiple files, separate the names with a space and enclose the list in parentheses. Parentheses are not
necessary if you specify only one filename. If you want to exclude the file every time it is included, use the /Ei or
/Es option.
/v
Provides verbose output, which includes the name of each .sbr file being processed and information about the
complete BSCMAKE run.
/?
Displays a brief summary of BSCMAKE command-line syntax.
The following command line tells BSCMAKE to do a full build of MAIN.bsc from three .sbr files. It also tells
BSCMAKE to exclude duplicate instances of TOOLBOX.h:
See also
BSCMAKE Reference
BSCMAKE Exit Codes
3/12/2019 • 2 minutes to read • Edit Online
BSCMAKE returns an exit code (also called a return code or error code) to the operating system or the calling
program.
CODE MEANING
0 No error
1 Command-line error
See also
BSCMAKE Reference
C/C++ Build Errors
10/31/2018 • 2 minutes to read • Edit Online
The articles in this section of the documentation explain diagnostic error and warning messages that are generated
by the build tools.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
See also
C/C++ Building Reference
Debugging in Visual Studio
Compiler Fatal Errors C999 through C1999
3/14/2019 • 10 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Fatal Error C999 UNKNOWN MESSAGE Please choose the Technical Support
command on the Visual C++ Help menu, or open the
Technical Support help file for more information
Fatal Error C1010 unexpected end of file while looking for precompiled header.
Did you forget to add '#include <file>' to your source?
Fatal Error C1023 'file': unexpected error with pch, try rebuilding the pch
Fatal Error C1036 cannot overwrite earlier program database format, delete 'file'
and recompile
Fatal Error C1038 compiler limit: 'function': control flow state too complex;
simplify function
Fatal Error C1041 cannot open program database 'file'; if multiple CL.EXE write
to the same .PDB file, please use /FS
Fatal Error C1045 compiler limit: linkage specifications nested too deeply
Fatal Error C1047 The object or library file 'file' was created with an older
compiler than other objects; rebuild old objects and libraries
Fatal Error C1051 program database file, 'file', has an obsolete format, delete it
and recompile
Fatal Error C1052 program database file, 'filename', was generated by the linker
with /DEBUG:fastlink; compiler cannot update such PDB files;
please delete it or use /Fd to specify a different PDB filename
Fatal Error C1067 compiler limit: 64K limit on size of a type record has been
exceeded
Fatal Error C1074 'IDB' is illegal extension for PDB file: file
Fatal Error C1075 the left token was unmatched at the end of the file
Fatal Error C1076 compiler limit: internal heap limit reached; use /Zm to specify a
higher limit
Fatal Error C1077 compiler limit: cannot have more than number command line
options
Fatal Error C1079 compiler limit: PCH file size limit exceeded
Fatal Error C1080 compiler limit: command line option exceeded limit of number
characters
Fatal Error C1090 PDB API call failed, error code 'code': 'message'
Fatal Error C1091 compiler limit: string exceeds number bytes in length
Fatal Error C1092 Edit and Continue does not support changes to data types;
build required
Fatal Error C1094 '-Zmnumber': command line option is inconsistent with value
used to build precompiled header ('-Zmnumber')
Fatal Error C1098 Version mismatch with Edit and Continue engine
ERROR MESSAGE
Fatal Error C1107 could not find assembly 'assembly': please specify the
assembly search path using /AI or by setting the LIBPATH
environment variable
Fatal Error C1112 compiler limit: 'number ' too many macro arguments, only
number allowed
Fatal Error C1114 'file': WinRT does not support #using of a managed assembly
Fatal Error C1128 number of sections exceeded object file format limit: compile
with /bigobj
Fatal Error C1195 use of /Yu and /Yc on the same command line is incompatible
with the /clr option
Fatal Error C1196 'identifier' : identifier found in type library 'typelib' is not a
valid C++ identifier
Fatal Error C1197 cannot reference 'file' as the program has already referenced
'file'
Fatal Error C1201 unable to continue after syntax error in class template
definition
Fatal Error C1202 recursive type or function dependency context too complex
Fatal Error C1205 Generics are not supported by the version of the runtime
installed
Fatal Error C1206 Per-appdomain data is not supported by the version of the
runtime installed
Fatal Error C1207 Managed templates not supported by the version of the
runtime installed
Fatal Error C1208 Allocating reference classes on the stack is not supported by
the version of the runtime installed
Fatal Error C1209 Friend assemblies not supported by the version of the runtime
installed
Fatal Error C1210 /clr:pure and /clr:safe are not supported by the version of the
runtime installed
Fatal Error C1301 error accessing program database file, invalid format, please
delete and rebuild
Fatal Error C1302 no profile data for module 'module' in profile database 'file'
Fatal Error C1306 last change to profile data base 'file' was not optimization
analysis; optimization decisions may be out of date
Fatal Error C1307 program has been edited since profile data was collected
Fatal Error C1310 profile guided optimizations are not available with OpenMP
Fatal Error C1311 COFF format cannot statically initialize 'symbol' with number
byte(s) of an address
Fatal Error C1312 Too many conditional branches in function. Simplify or refactor
source code.
Fatal Error C1313 compiler limit: type blocks may not be nested deeper than
number levels
Fatal Error C1350 error loading dll 'file': dll not found
Fatal Error C1352 Invalid or corrupt MSIL in function 'function' from module
'module'
Fatal Error C1353 metadata operation failed: runtime not installed or version
mismatch
Fatal Error C1382 the PCH file 'file' has been rebuilt since 'obj' was generated.
Please rebuild this object
Fatal Error C1383 compiler option /GL is incompatible with the installed version
of common language runtime
Fatal Error C1451 Failed to generate debug information when compiling the call
graph for the concurrency::parallel_for_each at: 'callsite'
Fatal Error C1508 compiler limit: 'function': more than 65535 argument bytes
Fatal Error C1509 compiler limit: too many exception handler states in function
'function'; simplify function
Fatal Error C1603 inline assembly branch target out of range by number bytes
Fatal Error C1853 'file' precompiled header file is from a previous version of the
compiler, or the precompiled header is C++ and you are using
it from C (or vice versa)
Fatal Error C1854 cannot overwrite information formed during creation of the
precompiled header in object file: 'file'
Fatal Error C1900 Il mismatch between 'tool' version 'number' and 'tool' version
'number'
Fatal Error C1902 Program database manager mismatch; please check your
installation
Fatal Error C1903 unable to recover from previous error(s); stopping compilation
Fatal Error C1905 Front end and back end not compatible (must target same
processor).
Fatal Error C999
10/31/2018 • 2 minutes to read • Edit Online
UNKNOWN MESSAGE Please choose the Technical Support command on the Visual C++ Help menu, or open
the Technical Support help file for more information
This error usually means that you have mixed files from different versions of the compiler, or your compiler
installation is corrupted. Use the Programs and Features applet in the Control Panel to repair or reinstall the
product.
Fatal Error C1001
3/12/2019 • 2 minutes to read • Edit Online
The compiler cannot generate correct code for a construct, often due to the combination of a particular expression
and an optimization option, or an issue in parsing. If the compiler file listed has a utc or C2 path segment, it is
probably an optimization error. If the file has a cxxfe or c1xx path segment, or is msc1.cpp, it is probably a parser
error. If the file named is cl.exe, there is no other information available.
You can often fix an optimization problem by removing one or more optimization options. To determine which
option is at fault, remove options one at a time and recompile until the error message goes away. The options most
commonly responsible are /Og (Global optimizations) and /Oi (Generate Intrinsic Functions). Once you determine
which optimization option is responsible, you can disable it around the function where the error occurs by using
the optimize pragma, and continue to use the option for the rest of the module. For more information about
optimization options, see Optimization best practices.
If optimizations are not responsible for the error, try rewriting the line where the error is reported, or several lines
of code surrounding that line. To see the code the way the compiler sees it after preprocessing, you can use the /P
(Preprocess to a file) option.
For more information about how to isolate the source of the error and how to report an internal compiler error to
Microsoft, see How to Report a Problem with the Visual C++ Toolset.
Fatal Error C1002
10/31/2018 • 2 minutes to read • Edit Online
// C1004.cpp
#if TEST
int main() {}
// C1004
Possible resolution:
// C1004b.cpp
#if TEST
#endif
int main() {}
Fatal Error C1005
10/31/2018 • 2 minutes to read • Edit Online
unexpected end of file while looking for precompiled header. Did you forget to add '#include name' to your source?
An include file specified with /Yu is not listed in the source file. This option is enabled by default in most Visual
C++ Project types and "stdafx.h" is the default include file specified by this option.
In the Visual Studio environment, use one of the following methods to resolve this error:
If you do not use precompiled headers in your project, set the Create/Use Precompiled Header property
of source files to Not Using Precompiled Headers. To set this compiler option, follow these steps:
1. In the Solution Explorer pane of the project, right-click the project name, and then click Properties.
2. In the left pane, click the C/C++ folder.
3. Click the Precompiled Headers node.
4. In the right pane, click Create/Use Precompiled Header, and then click Not Using Precompiled
Headers.
Make sure you have not inadvertently deleted, renamed or removed header file (by default, stdafx.h) from
the current project. This file also needs to be included before any other code in your source files using
#include "stdafx.h". (This header file is specified as Create/Use PCH Through File project property)
Fatal Error C1012
10/31/2018 • 2 minutes to read • Edit Online
// C1016.cpp
#ifdef // C1016
#define FC1016
#endif
int main() {}
Possible resolution:
// C1016b.cpp
#ifdef X
#define FC1016
#endif
int main() {}
Fatal Error C1017
10/31/2018 • 2 minutes to read • Edit Online
// C1017.cpp
#define CONSTANT_NAME "YES"
#if CONSTANT_NAME // C1017
#endif
Possible resolution:
// C1017b.cpp
// compile with: /c
#define CONSTANT_NAME 1
#if CONSTANT_NAME
#endif
Because CONSTANT_NAME evaluates to a string and not an integer, the #if directive generates fatal error C1017.
In other cases, the preprocessor evaluates an undefined constant as zero. This can cause unintended results, as
shown in the following sample. YES is undefined, so it evaluates to zero. The expression #if CONSTANT_NAME
evaluates to false and the code to be used on YES is removed by the preprocessor. NO is also undefined (zero), so
#elif CONSTANT_NAME==NO evaluates to true ( 0 == 0 ), causing the preprocessor to leave the code in the #elif
portion of the statement — exactly the opposite of the intended behavior.
// C1017c.cpp
// compile with: /c
#define CONSTANT_NAME YES
#if CONSTANT_NAME
// Code to use on YES...
#elif CONSTANT_NAME==NO
// Code to use on NO...
#endif
To see exactly how the compiler handles preprocessor directives, use /P, /E, or /EP.
Fatal Error C1018
10/31/2018 • 2 minutes to read • Edit Online
unexpected #elif
The #elif directive appears outside an #if , #ifdef , or #ifndef construct. Use #elif only within one of these
constructs.
The following sample generates C1018:
// C1018.cpp
#elif // C1018
#endif
int main() {}
Possible resolution:
// C1018b.cpp
#if 1
#elif
#endif
int main() {}
Fatal Error C1019
10/31/2018 • 2 minutes to read • Edit Online
unexpected #else
The #else directive appears outside an #if , #ifdef , or #ifndef construct. Use #else only within one of these
constructs.
The following sample generates C1019:
// C1019.cpp
#else // C1019
#endif
int main() {}
Possible resolution:
// C1019b.cpp
#if 1
#else
#endif
int main() {}
Fatal Error C1020
10/31/2018 • 2 minutes to read • Edit Online
unexpected #endif
The #endif directive has no matching #if , #ifdef , or #ifndef directive. Be sure each #endif has a matching
directive.
The following sample generates C1020:
// C1020.cpp
#endif // C1020
Possible resolution:
// C1020b.cpp
// compile with: /c
#if 1
#endif
Fatal Error C1021
10/31/2018 • 2 minutes to read • Edit Online
// C1021.cpp
#BadPreProcName // C1021 delete line
Fatal Error C1022
10/31/2018 • 2 minutes to read • Edit Online
expected #endif
An #if , #ifdef , or #ifndef directive has no matching #endif directive. Be sure each #if , #ifdef , or #ifndef
has a matching #endif .
The following sample generates C1022:
// C1022.cpp
#define true 1
#if (true)
#else
#else // C1022
Possible resolution:
// C1022b.cpp
// compile with: /c
#define true 1
#if (true)
#else
#endif
Fatal Error C1023
10/31/2018 • 2 minutes to read • Edit Online
compiler limit : function : control flow state too complex; simplify function
The function has more control-flow states than the compiler can handle. Simplify control flow or split the function
into smaller functions.
Fatal Error C1045
10/31/2018 • 2 minutes to read • Edit Online
The object or library file 'file' was created with an older compiler than other objects; rebuild old objects and
libraries
C1047 is caused when object files or libraries built with /LTCG are linked together, but where those object files or
libraries are built with different versions of the Visual C++ toolset.
This can happen if you begin using a new version of the compiler but do not do a clean rebuild of existing object
files or libraries.
To resolve C1047, rebuild all object files or libraries.
Fatal Error C1051
10/31/2018 • 2 minutes to read • Edit Online
program database file, 'pdbfile', has an obsolete format, delete it and recompile
The compiler cannot update the program database file, which has an older version number. Delete the file and
recompile your program with /Zi or /ZI. For more information, see /Z7, /Zi, /ZI (Debug Information Format)
Fatal Error C1052
10/31/2018 • 2 minutes to read • Edit Online
program database file, 'filename', was generated by the linker with /DEBUG:fastlink; compiler cannot update
such PDB files; please delete it or use /Fd to specify a different PDB filename
The compiler cannot update the same program database (PDB ) files which are generated by the linker when the
/DEBUG:fastlink option is specified. Normally the compiler-generated PDB files and the linker-generated PDB files
have different names. However, if they are set to use the same names, this error can result.
To fix this issue, you can explicitly delete the PDB files before you compile again, or you can create different names
for the compiler-generated and linker-generated PDB files.
To specify the compiler-generated PDB file name on the command line, use the /Fd compiler option. To specify the
compiler-generated PDB file name in the IDE, open the Property Pages dialog for your project, and in the
Configuration Properties, C/C++, Output Files page, set the Program Database File Name property. By
default, this property is $(IntDir)vc$(PlatformToolsetVersion).pdb .
Alternatively, you can set the linker-generated PDB file name. To specify the linker-generated PDB file name on the
command line, use the /PDB linker option. To specify the linker-generated PDB file name in the IDE, open the
Property Pages dialog for your project, and in the Configuration Properties, Linker, Debugging page, set the
Generate Program Database File property. By default, this property is set to $(OutDir)$(TargetName).pdb .
Fatal Error C1053
10/31/2018 • 2 minutes to read • Edit Online
compiler limit : 64K limit on size of a type record has been exceeded
This error could occur if a symbol has a decorated name exceeding 247 characters. To resolve, shorten the symbol
name.
When the compiler generates debug information, it emits type records to define types encountered in source code.
For example, type records include simple structures and argument lists of functions. Some of these type records
can be large lists.
There is a 64K limit on the size of any type record. If that 64K limit is exceeded then this error will occur.
C1067 can also occur if there are many symbols with long names or if a class, struct, or union has too many
members.
Fatal Error C1068
10/31/2018 • 2 minutes to read • Edit Online
// C1070.cpp
#define TEST
#ifdef TEST
#ifdef TEST
#endif
// C1070
Possible resolution:
// C1070b.cpp
// compile with: /c
#define TEST
#ifdef TEST
#endif
#ifdef TEST
#endif
Fatal Error C1071
10/31/2018 • 2 minutes to read • Edit Online
// C1071.cpp
int main() {
}
Internal error involving incremental compilation (compiler file 'filename', line number)
Recompile the file without using incremental compilation.
Fatal Error C1074
10/31/2018 • 2 minutes to read • Edit Online
compiler limit : internal heap limit reached; use /Zm to specify a higher limit
This error can be caused by too many symbols, or too many template instantiations. Starting in Visual Studio
2015, this message may result from Windows virtual memory pressure caused by too many parallel build
processes. In this case, the recommendation to use the /Zm option should be ignored unless you are using a
#pragma hdrstop directive.
compiler limit : cannot have more than number command line options
The number of command-line options exceeds the internal limit.
There may be too many symbols defined with /D. (Place the definitions in a header file instead.)
Fatal Error C1079
10/31/2018 • 2 minutes to read • Edit Online
D:\<very-long-directory-path>\myfile.cpp
Fatal Error C1082
10/31/2018 • 2 minutes to read • Edit Online
The compiler generates a C1083 error when it can’t find a file it requires. There are many possible causes for this
error. An incorrect include search path or missing or misnamed header files are the most common causes, but
other file types and issues can also cause C1083. Here are some of the common reasons why the compiler
generates this error.
might not find the file you intend. Most C++ Standard Library header files do not have a .h file name extension.
The <algorithm> header would not be found by this #include directive. To fix this issue, verify that the correct file
name is entered, as in this example:
#include <algorithm>
Certain C Runtime Library headers are located in a subdirectory of the standard include directory. For example, to
include sys/types.h, you must include the sys subdirectory name in the #include directive:
#include <sys/types.h>
this tells the compiler to look for the file in the same directory that contains the source file first, and then look in
other locations specified by the build environment. If the quotation marks contain an absolute path, the compiler
only looks for the file at that location. If the quotation marks contain a relative path, the compiler looks for the file
in the directory relative to the source directory.
If the name is enclosed by angle brackets,
#include <stdio.h>
the compiler follows a search path that is defined by the build environment, the /I compiler option, the /X compiler
option, and the INCLUDE environment variable. For more information, including specific details about the search
order used to find a file, see #include Directive (C/C++) and #import Directive.
If your include files are in another directory relative to your source directory, and you use a relative path in your
include directives, you must use double quotes instead of angle brackets. For example, if your header file
myheader.h is in a subdirectory of your project sources named headers, then this example fails to find the file and
causes C1083:
#include <headers\myheader.h>
but this example works:
#include "headers\myheader.h"
Relative paths can also be used with directories on the include search path. If you add a directory to the INCLUDE
environment variable or to your Include Directories path in Visual Studio, do not also add part of the path to the
include directives. For example, if your header is located at \path\example\headers\myheader.h, and you add
\path\example\headers\ to your Include Directories path in Visual Studio, but your #include directive refers to
the file as
#include <headers\myheader.h>
then the file is not found. Use the correct path relative to the directory specified in the include search path. In this
example, you could change the include search path to \path\example, or remove the headers\ path segment from
the #include directive.
The file is in your project, but not the include search path
Even when header files are listed in Solution Explorer as part of a project, the files are only found by the compiler
when they are referred to by an #include or #import directive in a source file, and are located in an include search
path. Different kinds of builds might use different search paths. The /X compiler option can be used to exclude
directories from the include search path. This enables different builds to use different include files that have the
same name, but are kept in different directories. This is an alternative to conditional compilation by using
preprocessor commands. For more information about the /X compiler option, see /X (Ignore Standard Include
Paths).
To fix this issue, correct the path that the compiler uses to search for the included or imported file. A new project
uses default include search paths. You may have to modify the include search path to add a directory for your
project. If you are compiling on the command line, add the path to the INCLUDE environment variable or the /I
compiler option to specify the path to the file.
To set the include directory path in Visual Studio, open the project’s Property Pages dialog box. Select VC++
Directories under Configuration Properties in the left pane, and then edit the Include Directories property.
For more information about the per-user and per-project directories searched by the compiler in Visual Studio, see
VC++ Directories Property Page. For more information about the /I compiler option, see /I (Additional Include
Directories).
Additional causes
You have installed an SDK or third-party library, but you have not opened a new developer command
prompt window after the SDK or library is installed. If the SDK or library adds files to the INCLUDE path,
you may need to open a new developer command prompt window to pick up these environment variable
changes.
The file uses managed code, but the compiler option /clr is not specified. For more information, see /clr
(Common Language Runtime Compilation).
The file is compiled by using a different /analyze compiler option setting than is used to precompile the
headers. When the headers for a project are precompiled, all should use the same /analyze settings. For
more information, see /analyze (Code Analysis).
The file or directory was created by the Windows Subsystem for Linux, per-directory case sensitivity is
enabled, and the specified case of a path or file does not match the case of the path or file on disk.
The file, the directory, or the disk is read-only.
Visual Studio or the command line tools do not have sufficient permissions to read the file or the directory.
This can happen, for example, when the project files have different ownership than the process running
Visual Studio or the command line tools. Sometimes this issue can be fixed by running Visual Studio or the
developer command prompt as Administrator.
There are not enough file handles. Close some applications and then recompile. This condition is unusual
under typical circumstances. However, it can occur when large projects are built on a computer that has
limited physical memory.
Example
The following example generates a C1083 error when the header file "test.h" does not exist in the source
directory or on the include search path.
// C1083.cpp
// compile with: /c
#include "test.h" // C1083 test.h does not exist
#include "stdio.h" // OK
For information about how to build C/C++ projects in the IDE or on the command line, and information about
setting environment variables, see Projects and build systems.
See also
MSBuild Properties
Fatal Error C1084
10/31/2018 • 2 minutes to read • Edit Online
Edit and Continue does not support changes to data types; build required
You changed or added a data type since the last successful build.
Edit and Continue does not support changes to existing data types, including class, struct, or enum
definitions. You must stop debugging and build the application.
Edit and Continue does not support the addition of new data types if a program database file, such as
vcx0.pdb (where x is the major version of Visual C++ in use) is read-only. To add data types, the compiler
must open the .pdb file in write mode.
To remove this error without ending the current debug session
1. Change the data type back to its state prior to the error.
2. From the Debug menu, choose Apply Code Changes.
To remove this error without changing your source code
1. From the Debug menu, choose Stop Debugging.
2. From the Build menu, choose Build.
For further information, see the Supported Code Changes.
Fatal Error C1093
10/31/2018 • 2 minutes to read • Edit Online
API call 'function name' failed 'location of call' : 'text from run-time'
A call to a .NET function failed. The text from run-time string may or may not be supplied by the COM runtime.
For more information about system error messages, see the winerror.h system file, and FormatMessage.
Fatal Error C1094
10/31/2018 • 2 minutes to read • Edit Online
'-Zmval1' : command line option is inconsistent with value used to build precompiled header ('-Zmval2')
The value that is passed to /Yc must be the same value that is passed to /Yu (/Zm values must be the same in all
compilations that use or create the same precompiled header file).
The following sample generates C1094:
// C1094.h
int func1();
And then,
// C1094.cpp
// compile with: /Yc"C1094.h" /Zm200
int u;
int main() {
int sd = 32;
}
#include "C1094.h"
And then,
// C1094b.cpp
// compile with: /Yu"C1094.h" /Zm300 /c
#include "C1094.h" // C1094 compile with /Zm200
void Test() {}
Fatal Error C1098
10/31/2018 • 2 minutes to read • Edit Online
// C1103.cpp
#import "progid:a.b.id.1.5" no_registry auto_search // C1103
Fatal Error C1104
10/31/2018 • 2 minutes to read • Edit Online
// C1104.cpp
#import "libid:11111111.1111.1111.1111.111111111111" version("4.0") lcid("9") no_registry auto_search //
C1104
Fatal Error C1107
10/31/2018 • 2 minutes to read • Edit Online
could not find assembly 'file': please specify the assembly search path using /AI or by setting the LIBPATH
environment variable
A metadata file was passed to a #using directive that the compiler was unable to locate.
LIBPATH, which is described in the topic for #using , and the /AI compiler option allow you to specify directories in
which the compiler will look for referenced metadata files.
Fatal Error C1108
10/31/2018 • 2 minutes to read • Edit Online
The specified DLL (dll name) could not be found in the path.
To resolve this error, reinstall Visual C++ or copy the appropriate .dll file from the installation to your computer.
Fatal Error C1109
10/31/2018 • 2 minutes to read • Edit Online
number of sections exceeded object file format limit : compile with /bigobj
An .obj file exceeded the number of allowable sections, a COFF object file format limitation.
Reaching this section limitation can be the result of using /Gy and a debug build; /Gy causes functions to go into
their own COMDAT sections. In a debug build, there is a debug info section for each COMDAT function.
C1128 can also be caused when there are too many inline functions.
To correct this error, divide your source file into multiple source code files, compile without /Gy, or compile with
/bigobj (Increase Number of Sections in .Obj file). If you do not compile with /Gy, you will need to specify the
optimizations individually, since /O2 and /O1 both imply /Gy.
If possible, compile without debugging information.
You may also need to have specific instantiations of templates in separate source code files, rather than having the
compiler emit them.
When porting code, C1128 will likely appear first when using the x64 compiler, and much later with the x86
compiler. x64 will have at least 4 sections associated with each function compiled /Gy or inlined from templates or
class-inline: code, pdata, and debug info, and possibly xdata. X86 won’t have the pdata.
Fatal Error C1189
10/31/2018 • 2 minutes to read • Edit Online
Remarks
C1189 is generated by the #error directive. The developer who codes the directive specifies the text of the error
message. For more information, see #error Directive (C/C++).
Example
The following sample generates C1189. In the sample, the developer issues a custom error message because the
_WIN32 identifier is not defined:
// C1189.cpp
#undef _WIN32
#if !defined(_WIN32)
#error _WIN32 must be defined // C1189
#endif
See also
#define Directive (C/C++)
Fatal Error C1190
10/31/2018 • 2 minutes to read • Edit Online
// C1190.cpp
// compile with: /c
__gc class A {}; // C1190
ref class A {};
Fatal Error C1191
10/31/2018 • 2 minutes to read • Edit Online
// C1191.cpp
// compile with: /clr
namespace sample {
#using <mscorlib.dll> // C1191 not at global scope
}
Possible resolution:
// C1191b.cpp
// compile with: /clr /c
#using <mscorlib.dll>
namespace sample {}
Fatal Error C1192
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : identifier found in type library 'typelib' is not a valid C++ identifier
One of the identifiers in your type library is not a valid C++ identifier. The type library is not available for use with
#import.
Fatal Error C1197
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C1197:
// C1197.cpp
// compile with: /clr /c
// processor: x86
#using "C:\Windows\Microsoft.NET\Framework\v1.1.4322\mscorlib.dll" // C1197
// try the following line instead
// #using "mscorlib.dll"
Fatal Error C1201
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C1202.
// C1202.cpp
// processor: x86 IPF
template<int n>
class Factorial : public Factorial<n-1> { // C1202
public:
operator int () {
return Factorial <n-1>::operator int () * n;
}
};
Factorial<7> facSeven;
Example
Possible resolution.
// C1202b.cpp
// compile with: /c
template<int n>
class Factorial : public Factorial<n-1> {
public:
operator int () {
return Factorial <n-1>::operator int () * n;
}
};
template <>
class Factorial<0> {
public:
operator int () {
return 1;
}
};
Factorial<7> facSeven;
Fatal Error C1205
10/31/2018 • 2 minutes to read • Edit Online
Allocating reference classes on the stack is not supported by the version of the runtime installed
C1208 occurs when you have a compiler for the current release, but a common language runtime from a previous
release.
Some functionality of the compiler may not work on a previous version of the run time.
Install the common language runtime version that is intended for use with your compiler.
Fatal Error C1209
10/31/2018 • 2 minutes to read • Edit Online
/clr:pure and /clr:safe are not supported by the version of the runtime installed
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
C1210 occurs when you have a compiler for the current release, but a common language runtime from a previous
release.
Some functionality of the compiler may not work on a previous version of the run time.
To resolve C1210 install the common language runtime version that is intended for use with your compiler.
Fatal Error C1211
10/31/2018 • 2 minutes to read • Edit Online
The TypeForwardedTo Custom Attribute is not supported by the version of the runtime installed
C1211 occurs when you have a compiler for the current release, but a common language runtime from a previous
release.
Some functionality of the compiler may not work on a previous version of the run time.
To resolve C1211 install the common language runtime that shipped with the compiler you are using.
For more information, see Type Forwarding (C++/CLI).
Fatal Error C1305
3/12/2019 • 2 minutes to read • Edit Online
// C1308.cpp
// compile with: /clr:safe /LD
public ref class MyClass {
public:
int i;
};
and then,
// C1308b.cpp
// compile with: /clr /link C1308b.obj C1308.dll
// C1308 expected
#using "C1308.dll"
int main() {
MyClass ^ my = gcnew MyClass();
}
Fatal Error C1309
3/12/2019 • 2 minutes to read • Edit Online
// C1310.cpp
// compile with: /openmp /GL /link /LTCG:PGI
// C1310 expected
int main()
{
int i = 0, j = 10;
COFF format cannot statically initialize 'var' with number byte(s) of an address
An address whose value is not known at compile time cannot be statically assigned to a variable whose type has
storage of less than four bytes.
This error can occur on code that is otherwise valid C++.
The following example shows one condition that might cause C1311.
compiler limit : type blocks may not be nested deeper than number levels
Exception handling (or structured exception handling) blocks were nested too deeply. Simplify your code.
Fatal Error C1350
10/31/2018 • 2 minutes to read • Edit Online
the PCH file 'file' has been rebuilt since 'obj' was generated. Please rebuild this object
When using /LTCG, the compiler detected a .pch file that is newer than a CIL .obj that points to it. The information
in the CIL .obj file is out of date. Rebuild the object.
C1382 can also occur if you compile with /Yc, but also pass multiple source code files to the compiler. To resolve,
do not use /Yc when passing multiple source code files to the compiler. For more information, see /Yc (Create
Precompiled Header File).
Fatal Error C1383
10/31/2018 • 2 minutes to read • Edit Online
compiler option /GL is incompatible with the installed version of common language runtime
C1383 occurs when you are using a previous version of the common language runtime with a newer compiler, and
when you compile with /clr and /GL.
To resolve, either do not use /GL with /clr or install the version of the common language runtime that shipped with
your compiler.
For more information, see /clr (Common Language Runtime Compilation) and /GL (Whole Program
Optimization).
Fatal Error C1506
10/31/2018 • 2 minutes to read • Edit Online
compiler limit : too many exception handler states in function 'function'. simplify function
The code exceeds an internal limit on exception handler states (32,768 states).
The most common cause is that the function contains a complex expression of user-defined class variables and
arithmetic operators.
To fix by using the following possible solutions
1. Simplify expressions by assigning common subexpressions to temporary variables.
2. Split the function into smaller functions.
Fatal Error C1510
10/31/2018 • 2 minutes to read • Edit Online
unsupported intrinsic
This error indicates a mismatch in your compiler .exe files, which may have occurred because of an incomplete
installation. For example, you may have installed a service pack but not the Processor Pack. Install all required
products.
Fatal Error C1603
10/31/2018 • 2 minutes to read • Edit Online
'filename' precompiled header file is from a previous version of the compiler, or the precompiled header is
C++ and you are using it from C (or vice versa)
Possible causes:
The precompiled header was compiled with a previous compiler version. Try recompiling the header with
the current compiler.
The precompiled header is C++ and you are using it from C. Try recompiling the header for use with C by
specifying one of the /Tc compiler options, or changing the suffix of the source file to "c". For more
information, see Two Choices for Precompiling Code.
Fatal Error C1854
3/12/2019 • 2 minutes to read • Edit Online
cannot overwrite information formed during creation of the precompiled header in object file: 'filename'
You specified the /Yu (Use Precompiled Header File) option after specifying the /Yc (Create Precompiled Header
File) option for the same file.
To fix this issue, in general, set only one file in your project to be compiled by using the /Yc option, and set all other
files to compile by using the /Yu option. For details on the use of the /Yc option, and how to set it in the Visual
Studio IDE, see /Yc (Create Precompiled Header File). For more information on using precompiled headers, see
Creating Precompiled Header Files.
Fatal Error C1900
10/31/2018 • 2 minutes to read • Edit Online
Tools run in various passes of the compiler do not match. number1 and number2 refer to the dates on the files. For
example, in pass 1, the compiler front end runs (c1.dll) and in pass 2, the compiler back end runs (c2.dll). The dates
on the files must match.
To fix this issue, make sure that all updates have been applied to Visual Studio. If the problem persists, use
Programs and Features in the Windows Control Panel to repair or reinstall Visual Studio.
Fatal Error C1902
10/31/2018 • 2 minutes to read • Edit Online
Front end and back end not compatible (must target same processor)
This error occurs when a .obj file is generated by a compiler front end (C1.dll) that targets one processor, such as
x86, ARM, or x64, but is being read by a back end (C2.dll) that targets a different processor.
To fix this issue, ensure that you are using a matching front end and back end. This is the default for projects
created in Visual Studio. This error may occur if you have edited the project file and used different paths to the
compiler tools. If you have not specifically set the path for the compiler tools, then this error may occur if your
Visual Studio installation is corrupt. For example, you may have copied the compiler .dll files from one location to
another. Use Programs and Features in the Windows Control Panel to repair or reinstall Visual Studio.
Compiler Errors C2000 through C2099
10/31/2018 • 6 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2000 UNKNOWN ERROR Please choose the Technical Support
command on the Visual C++ Help menu, or open the
Technical Support help file for more information
Compiler Error C2014 preprocessor command must start as first nonwhite space
Compiler Error C2016 C requires that a struct or union has at least one member
Compiler Error C2024 'alignas' attribute applies to variables, data members and tag
types only
Compiler Error C2025 invalid or corrupted binary module interface file: 'filename'
Compiler Error C2034 'identifier': type of bit field too small for number of bits
Compiler Error C2055 expected formal parameter list, not a type list
Compiler Error C2064 term does not evaluate to a function taking number
arguments
Compiler Error C2068 illegal use of overloaded function. Missing argument list?
Compiler Error C2073 'identifier': elements of partially initialized array must have a
default constructor
Compiler Error C2080 'identifier': the type for 'type' can only be deduced from a
single initializer expression
Compiler Error C2095 'function': actual parameter has type 'void': parameter number
newline in constant
A string constant cannot be continued on a second line unless you do the following:
End the first line with a backslash.
Close the string on the first line with a double quotation mark and open the string on the next line with
another double quotation mark.
Ending the first line with \n is not sufficient.
Example
The following sample generates C2001:
// C2001.cpp
// C2001 expected
#include <stdio.h>
int main()
{
printf_s("Hello,
world");
printf_s("Hello,\n
world");
}
Example
Spaces at the beginning of the next line after a line-continuation character are included in the string constant. None
of the examples shown above embed a newline character into the string constant. You can embed a newline
character as shown here:
// C2001b.cpp
#include <stdio.h>
int main()
{
printf_s("Hello,\n\
world");
printf_s("Hello,\
\nworld");
printf_s("Hello,\n"
"world");
printf_s("Hello,"
"\nworld");
printf_s("Hello,"
" world");
printf_s("Hello,\
world");
}
Compiler Error C2002
10/31/2018 • 2 minutes to read • Edit Online
L'mbconst'
5. For Microsoft C++, the text arguments of a preprocessor directive must be ASCII. For example, the
directive, #pragma message(L"string") , is not valid.
Compiler Error C2003
10/31/2018 • 2 minutes to read • Edit Online
expected 'defined(id)'
An identifier must appear in the parentheses following the preprocessor keyword.
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003: missing parenthesis in preprocessor directive. If the closing parenthesis is missing from a preprocessor
directive, the compiler will generate an error.
Example
The following sample generates C2004:
// C2004.cpp
// compile with: /DDEBUG
#include <stdio.h>
int main()
{
#if defined(DEBUG // C2004
printf_s("DEBUG defined\n");
#endif
}
Example
Possible resolution:
// C2004b.cpp
// compile with: /DDEBUG
#include <stdio.h>
int main()
{
#if defined(DEBUG)
printf_s("DEBUG defined\n");
#endif
}
Compiler Error C2005
10/31/2018 • 2 minutes to read • Edit Online
// C2005.cpp
int main() {
int i = 0;
#line i // C2005
}
Possible resolution:
// C2005b.cpp
int main() {
int i = 0;
#line 0
}
Compiler Error C2006
10/31/2018 • 2 minutes to read • Edit Online
// C2006.cpp
#include stdio.h // C2006
Possible resolution:
// C2006b.cpp
// compile with: /c
#include <stdio.h>
Compiler Error C2007
10/31/2018 • 2 minutes to read • Edit Online
#define syntax
No identifier appears after a #define . To resolve the error, use an identifier.
The following sample generates C2007:
// C2007.cpp
#define // C2007
Possible resolution:
// C2007b.cpp
// compile with: /c
#define true 1
Compiler Error C2008
10/31/2018 • 2 minutes to read • Edit Online
// C2008.cpp
#define TEST1"mytest1" // C2008
Possible resolution:
// C2008b.cpp
// compile with: /c
#define TEST2 "mytest2"
Compiler Error C2009
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2009:
// C2009.cpp
#include <stdio.h>
int main()
{
printf_s("%d\n", macro1(2));
}
Example
Possible resolution:
// C2009b.cpp
#include <stdio.h>
int main()
{
printf_s("%d\n", macro2(2));
printf_s("%d\n", macro3(2,4));
}
Compiler Error C2010
10/31/2018 • 2 minutes to read • Edit Online
// C2010.cpp
// compile with: /c
#define mymacro(a|) (2*a) // C2010
#define mymacro(a) (2*a) // OK
Compiler Error C2011
10/31/2018 • 2 minutes to read • Edit Online
// C2011.cpp
// compile with: /c
struct S;
union S; // C2011
union S2; // OK
Compiler Error C2012
10/31/2018 • 2 minutes to read • Edit Online
// C2012.cpp
#include < // C2012 include the filename to resolve
Possible resolution:
// C2012b.cpp
// compile with: /c
#include <stdio.h>
Compiler Error C2013
10/31/2018 • 2 minutes to read • Edit Online
missing '>'
An #include directive lacks a closing angle bracket. Add the closing bracket to resolve the error.
The following sample generates C2013:
// C2013.cpp
#include <stdio.h // C2013
Possible resolution:
// C2013b.cpp
// compile with: /c
#include <stdio.h>
Compiler Error C2014
10/31/2018 • 2 minutes to read • Edit Online
// C2014.cpp
int k; #include <stdio.h> // C2014
Possible resolution:
// C2014b.cpp
// compile with: /c
int k;
#include <stdio.h>
Compiler Error C2015
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2015:
// C2015.cpp
// compile with: /c
Example
C2015 can also occur when using a Microsoft extension, character constants converted to integers. The following
sample generates C2015:
// C2015b.cpp
#include <stdio.h>
int main()
{
int a = 'abcde'; // C2015
// C2017.cpp
int main() {
char test1='a'\n; // C2017
char test2='a\n'; // ok
}
C2017 can occur when the stringize operator is used with strings that include escape sequences.
The following sample generates C2017:
// C2017b.cpp
#define TestDfn(x) AfxMessageBox(#x)
TestDfn(CString("\\") + CString(".h\"\n\n")); // C2017
Compiler Error C2018
10/31/2018 • 2 minutes to read • Edit Online
// C2019.cpp
#!define TRUE 1 // C2019
Possible resolution:
// C2019b.cpp
// compile with: /c
#define TRUE 1
Compiler Error C2020
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2021:
// C2021.cpp
float test1=1.175494351E; // C2021
Example
Possible resolution:
// C2021b.cpp
// compile with: /c
float test2=1.175494351E8;
Compiler Error C2022
10/31/2018 • 2 minutes to read • Edit Online
char sz[] =
"\
imagine a really, really \
long string here\
";
char sz[] =
"\
imagine a really, really "
"long string here\
";
You may want to store exceptionally large string literals (32K or more) in a custom resource or an external file. See
Creating a New Custom or Data Resource for more information.
Compiler Error C2027
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2027.
// C2027.cpp
class C;
class D {
public:
void func() {
}
};
int main() {
C *pC;
pC->func(); // C2027
D *pD;
pD->func();
}
Example
It is possible to declare a pointer to a declared but undefined type. But Visual C++ does not allow a reference to an
undefined type.
The following sample generates C2027.
// C2027_b.cpp
class A;
A& CreateA();
class B;
B* CreateB();
int main() {
CreateA(); // C2027
CreateB(); // OK
}
Compiler Error C2028
10/31/2018 • 2 minutes to read • Edit Online
a destructor with 'protected private' accessibility cannot be a member of a class declared 'sealed'
A Windows Runtime class declared as sealed cannot have a protected private destructor. Only public virtual and
private non-virtual destructors are allowed on sealed types. For more information, see Ref classes and structs.
To fix this error, change the accessibility of the destructor.
Compiler Error C2032
10/31/2018 • 2 minutes to read • Edit Online
// C2032.c
struct z {
int i;
void func(); // C2032
};
Possible resolution:
// C2032b.c
// compile with: /c
struct z {
int i;
};
Compiler Error C2033
10/31/2018 • 2 minutes to read • Edit Online
// C2033.cpp
struct S {
int *b : 1; // C2033
};
Possible resolution:
// C2033b.cpp
// compile with: /c
struct S {
int b : 1;
};
Compiler Error C2034
10/31/2018 • 2 minutes to read • Edit Online
// C2034.cpp
struct A {
char test : 9; // C2034, char has 8 bits
};
Possible resolution:
// C2034b.cpp
// compile with: /c
struct A {
char test : 8;
};
Compiler Error C2036
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2036.
// C2036.c
// a C program
struct A* pA;
struct B { int i; } *pB;
int main() {
pA++; // C2036, size of A not known
((char*)pA)++; // OK
pB++; // OK
}
Example
The following sample generates C2036.
// C2036_2.cpp
// a C++ program
struct A* pA;
int main() {
pA++; // C2036, size of A not known
((char*&)pA)++; // OK, if sizeof(A) == sizeof(char)
}
Compiler Error C2039
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2039.
// C2039.cpp
struct S {
int mem0;
} s, *pS = &s;
int main() {
pS->mem1 = 0; // C2039 mem1 is not a member
pS->mem0 = 0; // OK
}
Example
The following sample generates C2039.
// C2039_b.cpp
// compile with: /clr
using namespace System;
int main() {
Console::WriteLine( "{0}", DateTime::get_Now()); // C2039
Console::WriteLine( "{0}", DateTime::Now); // OK
Console::WriteLine( "{0}", DateTime::Now::get()); // OK
}
Example
The following sample generates C2039.
// C2039_c.cpp
// compile with: /clr /c
ref struct S {
property int Count {
int get();
void set(int i){}
};
};
Example
C2039 can also occur if you attempt to access a default indexer incorrectly. The following sample defines a
component authored in C#.
// C2039_d.cs
// compile with: /target:library
// a C# program
[System.Reflection.DefaultMember("Item")]
public class B {
public int Item {
get { return 13; }
set {}
}
};
Example
The following sample generates C2039.
// C2039_e.cpp
// compile with: /clr
using namespace System;
#using "c2039_d.dll"
int main() {
B ^ b = gcnew B;
int n = b->default; // C2039
// try the following line instead
// int n = b->Item;
Console::WriteLine(n);
}
Example
C2039 can also occur if you use generics. The following sample generates C2039.
// C2039_f.cpp
// compile with: /clr
interface class I {};
int main() {
f(gcnew R());
}
Example
C2039 can occur when you try to release managed or unmanaged resources. For more information, see
Destructors and finalizers.
The following sample generates C2039.
// C2039_g.cpp
// compile with: /clr
using namespace System;
using namespace System::Threading;
int main() {
ManualResetEvent^ event = gcnew ManualResetEvent( false );
TimerCallback^ timerDelegate = gcnew TimerCallback( &CheckStatus );
Timer^ stateTimer = gcnew Timer( timerDelegate, event, 1000, 250 );
stateTimer->~Timer(); // OK
}
Compiler Error C2040
10/31/2018 • 2 minutes to read • Edit Online
// C2040.cpp
// Compile by using: cl /c /W3 C2040.cpp
bool test() {
char c = '3';
return c == "3"; // C2446, C2040
// return c == '3'; // OK
}
Compiler Error C2041
10/31/2018 • 2 minutes to read • Edit Online
// C2041.cpp
int i = 081; // C2041 8 is not a base 8 digit
Possible resolution:
// C2041b.cpp
// compile with: /c
int j = 071;
Compiler Error C2042
10/31/2018 • 2 minutes to read • Edit Online
// C2042.cpp
unsigned signed int i; // C2042
Possible resolution:
// C2042b.cpp
// compile with: /c
unsigned int i;
signed int ii;
Compiler Error C2043
10/31/2018 • 2 minutes to read • Edit Online
illegal break
A break is legal only within a do , for , while , or switch statement.
Compiler Error C2044
10/31/2018 • 2 minutes to read • Edit Online
illegal continue
A continue is legal only within a do , for , or while statement.
Compiler Error C2045
10/31/2018 • 2 minutes to read • Edit Online
// C2045.cpp
int main() {
label: {
}
goto label;
label: {} // C2045
}
Compiler Error C2046
10/31/2018 • 2 minutes to read • Edit Online
illegal case
The keyword case can appear only in a switch statement.
The following sample generates C2046:
// C2046.cpp
int main() {
case 0: // C2046
}
Possible resolution:
// C2046b.cpp
int main() {
int i = 0;
switch(i) {
case 0:
break;
default:
break;
}
}
Compiler Error C2047
10/31/2018 • 2 minutes to read • Edit Online
illegal default
The keyword default can appear only in a switch statement.
The following sample generates C2047:
// C2047.cpp
int main() {
int i = 0;
default: // C2047
switch(i) {
case 0:
break;
}
}
Possible resolution:
// C2047b.cpp
int main() {
int i = 0;
switch(i) {
case 0:
break;
default:
break;
}
}
Compiler Error C2048
10/31/2018 • 2 minutes to read • Edit Online
// C2048.cpp
int main() {
int a = 1;
switch (a) {
case 1:
a = 0;
default:
a = 2;
default: // C2048
a = 3;
}
}
Possible resolution:
// C2048b.cpp
int main() {
int a = 1;
switch (a) {
case 1:
a = 0;
default:
a = 2;
}
}
Compiler Error C2050
10/31/2018 • 2 minutes to read • Edit Online
// C2050.cpp
int main() {
int a = 1;
switch ("a") { // C2050
case 1:
a = 0;
default:
a = 2;
}
}
Possible resolution:
// C2050b.cpp
int main() {
int a = 1;
switch (a) {
case 1:
a = 0;
default:
a = 2;
}
}
Compiler Error C2051
10/31/2018 • 2 minutes to read • Edit Online
// C2051.cpp
class X {};
int main() {
static X x;
int i = 0;
switch (i) {
case x: // C2051 use constant expression to resolve error
break;
default:
break;
}
}
Possible resolution:
// C2051b.cpp
class X {};
int main() {
static X x;
int i = 0;
switch (i) {
case 1:
break;
default:
break;
}
}
Compiler Error C2052
10/31/2018 • 2 minutes to read • Edit Online
// C2052.cpp
int main() {
int index = 0;
switch (index) {
case 1:
return 24;
case 1.0: // C2052
// try the following line instead
// case 2:
return 23;
}
}
Compiler Error C2053
10/31/2018 • 2 minutes to read • Edit Online
// C2053.c
int main() {
char array[] = L"Rika"; // C2053
}
Compiler Error C2054
10/31/2018 • 2 minutes to read • Edit Online
// C2054.c
int array1[] { 1, 2, 3 }; // C2054, missing =
Possible resolution:
// C2054b.c
int main() {
int array2[] = { 1, 2, 3 };
}
Compiler Error C2055
10/31/2018 • 2 minutes to read • Edit Online
// C2055.c
// compile with: /c
void func(int, char) {} // C2055
void func (int i, char c) {} // OK
Compiler Error C2056
10/31/2018 • 2 minutes to read • Edit Online
illegal expression
An expression was invalid because of a previous error.
Compiler Error C2057
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2057 and shows how to fix it:
// C2057.cpp
int i;
int b[i]; // C2057 - value of i is unknown at compile time
int main() {
const int i = 8;
int b[i]; // OK - value of i is fixed and known to compiler
}
Example
C has more restrictive rules for constant expressions. The following sample generates C2057 and shows how to fix
it:
// C2057b.c
#define ArraySize1 10
int main() {
const int ArraySize2 = 10;
int h[ArraySize2]; // C2057 - C does not allow variables here
int h[ArraySize1]; // OK - uses preprocessor constant
}
Compiler Error C2058
10/31/2018 • 2 minutes to read • Edit Online
// C2059e.cpp
// compile with: /c
// C2143 expected
// Error caused by the incorrect use of '*'.
int j*; // C2059
To determine the cause of the error, examine not only the line that's listed in the error message, but also the lines
above it. If examining the lines yields no clue about the problem, try commenting out the line that's listed in the
error message and perhaps several lines above it.
If the error message occurs on a symbol that immediately follows a typedef variable, make sure that the variable
is defined in the source code.
You may get C2059 if a symbol evaluates to nothing, as can occur when /D symbol = is used to compile.
// C2059a.cpp
// compile with: /DTEST=
#include <stdio.h>
int main() {
#ifdef TEST
printf_s("\nTEST defined %d", TEST); // C2059
#else
printf_s("\nTEST not defined");
#endif
}
Another case in which C2059 can occur is when you compile an application that specifies a structure in the default
arguments for a function. The default value for an argument must be an expression. An initializer list—for example,
one that used to initialize a structure—is not an expression. To resolve this problem, define a constructor to
perform the required initialization.
The following example generates C2059:
// C2059b.cpp
// compile with: /c
struct ag_type {
int a;
float b;
// Uncomment the following line to resolve.
// ag_type(int aa, float bb) : a(aa), b(bb) {}
};
// C2059c.cpp
// compile with: /clr
using namespace System;
ref class From {};
ref class To : public From {};
int main() {
From^ refbase = gcnew To();
To^ refTo = safe_cast<To^>(From^); // C2059
To^ refTo2 = safe_cast<To^>(refbase); // OK
}
C2059 can also occur if you attempt to create a namespace name that contains a period.
The following sample generates C2059:
// C2059d.cpp
// compile with: /c
namespace A.B {} // C2059
// OK
namespace A {
namespace B {}
}
C2059 can occur when an operator that can qualify a name ( :: , -> , and . ) must be followed by the keyword
template , as shown in this example:
By default, C++ assumes that AY::Rebind isn't a template; therefore, the following < is interpreted as a less-than
sign. You must tell the compiler explicitly that Rebind is a template so that it can correctly parse the angle bracket.
To correct this error, use the template keyword on the dependent type's name, as shown here:
// C2061.cpp
// compile with: /c
template < A a > // C2061
// try the following line instead
// template < typename b >
class c{};
// C2061b.cpp
// compile with: /clr
ref struct G {
int i;
};
int main() {
G ^ pG = gcnew G;
System::Type ^ pType = typeid<pG>; // C2061
System::Type ^ pType2 = typeid<G>; // OK
}
Compiler Error C2062
10/31/2018 • 2 minutes to read • Edit Online
// C2062.cpp
// compile with: /c
struct A { : int l; }; // C2062
struct B { private: int l; }; // OK
C2062 can also occur due to the way the compiler handles undefined types in a constructor's parameter list. If the
compiler encounters an undefined (misspelled?) type, it assumes the constructor is an expression, and issues
C2062. To resolve, only use defined types in a constructor parameter list.
Compiler Error C2063
10/31/2018 • 2 minutes to read • Edit Online
// C2063.c
int main() {
int i, j;
j = i(); // C2063, i is not a function
}
Possible resolution:
// C2063b.c
int i() { return 0;}
int main() {
int j;
j = i();
}
Compiler Error C2064
11/9/2018 • 2 minutes to read • Edit Online
// C2064.cpp
int i, j;
char* p;
void func() {
j = i(); // C2064, i is not a function
p(); // C2064, p doesn't point to a function
}
You must call pointers to non-static member functions from the context of an object instance. The following sample
generates C2064, and shows how to fix it:
// C2064b.cpp
struct C {
void func1(){}
void func2(){}
};
int main() {
C c;
pFunc funcArray[2] = {&C::func1, &C::func2};
(funcArray[0])(); // C2064
(c.*funcArray[0])(); // OK - function called in instance context
}
Within a class, member function pointers must also indicate the calling object context. The following sample
generates C2064 and shows how to fix it:
// C2064d.cpp
// Compile by using: cl /c /W4 C2064d.cpp
struct C {
typedef void (C::*pFunc)();
pFunc funcArray[2];
void func1(){}
void func2(){}
C() {
funcArray[0] = &C::func1;
funcArray[1] = &C::func2;
}
void func3() {
(funcArray[0])(); // C2064
(this->*funcArray[0])(); // OK - called in this instance context
}
};
Compiler Error C2065
10/31/2018 • 7 minutes to read • Edit Online
The compiler can't find the declaration for an identifier. There are many possible causes for this error. The most
common causes of C2065 are that the identifier hasn't been declared, the identifier is misspelled, the header where
the identifier is declared is not included in the file, or the identifier is missing a scope qualifier, for example, cout
instead of std::cout . For more information on declarations in C++, see Declarations and Definitions (C++).
Here are some common issues and solutions in greater detail.
If the identifier is a member of a class or struct, or declared in a namespace, it must be qualified by the class or
struct name, or the namespace name, when used outside the struct, class, or namespace scope. Alternatively, the
namespace must be brought into scope by a using directive such as using namespace std; , or the member name
must be brought into scope by a using declaration, such as using std::string; . Otherwise, the unqualified name
is considered to be an undeclared identifier in the current scope.
If the identifier is the tag for a user-defined type, for example, a class or struct , the type of the tag must be
declared before it can be used. For example, the declaration struct SomeStruct { /*...*/ }; must exist before you
can declare a variable SomeStruct myStruct; in your code.
If the identifier is a type alias, the type must be declared by using a using declaration or typedef before it can be
used. For example, you must declare using my_flags = std::ios_base::fmtflags; before you can use my_flags as a
type alias for std::ios_base::fmtflags .
// C2065_spell.cpp
// compile with: cl /EHsc C2065_spell.cpp
#include <iostream>
using namespace std;
int main() {
int someIdentifier = 42;
cout << "Some Identifier: " << SomeIdentifier << endl;
// C2065: 'SomeIdentifier': undeclared identifier
// To fix, correct the spelling:
// cout << "Some Identifier: " << someIdentifier << endl;
}
// C2065_scope.cpp
// compile with: cl /EHsc C2065_scope.cpp
#include <iostream>
// using namespace std; // Uncomment this line to fix
int main() {
cout << "Hello" << endl; // C2065 'cout': undeclared identifier
// C2065 'endl': undeclared identifier
// Or try the following line instead
std::cout << "Hello" << std::endl;
}
Identifiers that are declared inside of class , struct , or enum class types must also be qualified by the name of
their enclosing scope when you use them outside of that scope.
// stdafx.h
#include <stdio.h>
// stdafx.cpp
// Compile by using: cl /EHsc /W4 /c /Ycstdafx.h stdafx.cpp
#include <stdafx.h>
// C2065_pch.cpp
// compile with: cl /EHsc /W4 /Yustdafx.h C2065_pch.cpp
#include <iostream>
#include "stdafx.h"
using namespace std;
int main() {
cout << "Hello" << endl; // C2065 'cout': undeclared identifier
// C2065 'endl': undeclared identifier
}
To fix this issue, add the #include of <iostream> into the precompiled header file, or move it after the precompiled
header file is included in your source file.
// C2065_header.cpp
// compile with: cl /EHsc C2065_header.cpp
//#include <stdio.h>
int main() {
fpos_t file_position = 42; // C2065: 'fpos_t': undeclared identifier
// To fix, uncomment the #include <stdio.h> line
// to include the header where fpos_t is defined
}
Another possible cause is if you use an initializer list without including the <initializer_list> header.
// C2065_initializer.cpp
// compile with: cl /EHsc C2065_initializer.cpp
// #include <initializer_list>
int main() {
for (auto strList : {"hello", "world"})
if (strList == "hello") // C2065: 'strList': undeclared identifier
return 1;
// To fix, uncomment the #include <initializer_list> line
}
You may see this error in Windows Desktop app source files if you define VC_EXTRALEAN , WIN32_LEAN_AND_MEAN , or
WIN32_EXTRA_LEAN . These preprocessor macros exclude some header files from windows.h and afxv_w32.h to speed
compiles. Look in windows.h and afxv_w32.h for an up-to-date description of what's excluded.
// C2065_quote.cpp
// compile with: cl /EHsc C2065_quote.cpp
#include <iostream>
int main() {
// Fix this issue by adding the closing quote to "Aaaa"
char * first = "Aaaa, * last = "Zeee";
std::cout << "Name: " << first
<< " " << last << std::endl; // C2065: 'last': undeclared identifier
}
int main() {
// char last = '!';
std::string letters{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
for (const char& c : letters) {
if ('Q' == c) {
std::cout << "Found Q!" << std::endl;
}
// last = c;
}
std::cout << "Last letter was " << c << std::endl; // C2065
// Fix by using a variable declared in an outer scope.
// Uncomment the lines that declare and use 'last' for an example.
// std::cout << "Last letter was " << last << std::endl; // C2065
}
// C2065_defined.cpp
// Compile with: cl /EHsc /W4 /MT C2065_defined.cpp
#include <iostream>
#include <crtdbg.h>
#ifdef _DEBUG
_CrtMemState oldstate;
#endif
int main() {
_CrtMemDumpStatistics(&oldstate);
std::cout << "Total count " << oldstate.lTotalCount; // C2065
// Fix by guarding references the same way as the declaration:
// #ifdef _DEBUG
// std::cout << "Total count " << oldstate.lTotalCount;
// #endif
}
int main() {
// global generic function call
G<T>(10); // C2065
G<int>(10); // OK - fix with a specific type argument
}
// C2065_attributes.cpp
// compile with: cl /c /clr C2065_attributes.cpp
[module(DLL, name=MyLibrary)]; // C2065
// try the following line instead
// [module(dll, name="MyLibrary")];
[export]
struct MyStruct {
int i;
};
Compiler Error C2066
10/31/2018 • 2 minutes to read • Edit Online
// C2070.cpp
void func() {}
int main() {
int a;
a = sizeof(func); // C2070
}
Possible resolution:
// C2070b.cpp
void func() {}
int main() {
int a;
a = sizeof(a);
}
Compiler Error C2071
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2071.
// C2071.cpp
// compile with: /c
struct C {
extern int i; // C2071
};
struct D {
int i; // OK, no extern on an automatic
};
Example
The following sample generates C2071.
// C2071_b.cpp
// compile with: /c
typedef int x(int i) { return i; } // C2071
typedef int (x)(int); // OK, no local definition in typedef
Compiler Error C2072
10/31/2018 • 2 minutes to read • Edit Online
// C2073.cpp
class A {
public:
A( int ); // constructor for ints only
};
A a[3] = { A(1), A(2) }; // C2073, no default constructor
// C2073b.cpp
// compile with: /c
class B {
public:
B(); // default constructor declared
B( int );
};
B b[3] = { B(1), B(2) }; // OK
Compiler Error C2074
10/31/2018 • 2 minutes to read • Edit Online
// C2075.c
int main() {
int i[] = 1, 2, 3 }; // C2075
}
Possible resolution:
// C2075b.c
int main() {
int j[] = { 1, 2, 3 };
}
Compiler Error C2077
10/31/2018 • 2 minutes to read • Edit Online
// C2078.cpp
// Compile by using: cl /c /W4 C2078.cpp
struct S {
struct {
int x, y;
} z[2];
};
int main() {
int d[2] = {1, 2, 3}; // C2078
int e[2] = {1, 2}; // OK
S s1{1, 2, 3, 4}; // OK
S s2{{1, 2}, {3, 4}}; // C2078
S s3{{1, 2, 3, 4}}; // OK
S s4{{{1, 2}, {3, 4}}}; // OK
}
Compiler Error C2079
10/31/2018 • 2 minutes to read • Edit Online
// C2079.cpp
// compile with: /EHsc
#include <iostream>
int main() {
std::ifstream g; // C2079
}
Possible resolution:
// C2079b.cpp
// compile with: /EHsc
#include <fstream>
int main( ) {
std::ifstream g;
}
C2079 can also occur if you attempt to declare an object on the stack of a type whose forward declaration is only
in scope.
// C2079c.cpp
class A;
class B {
A a; // C2079
};
class A {};
Possible resolution:
// C2079d.cpp
// compile with: /c
class A;
class C {};
class B {
A * a;
C c;
};
class A {};
Compiler Error C2081
10/31/2018 • 2 minutes to read • Edit Online
// C2081.c
void func( int i, j ) {} // C2081, no type specified for j
Possible resolution:
// C2081b.c
// compile with: /c
void func( int i, int j ) {}
Compiler Error C2082
10/31/2018 • 2 minutes to read • Edit Online
// C2082.cpp
void func(int i) {
int i; // C2082
int ii; // OK
}
Compiler Error C2083
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2084:
// C2084.cpp
void Func(int);
void Func(int) {} // define function
void Func(int) {} // C2084 second definition
// C2084b.cpp
// compile with: /c
void Func(int);
void Func(int) {}
Compiler Error C2085
10/31/2018 • 2 minutes to read • Edit Online
// C2085.c
void func1( void )
int main( void ) {} // C2085
Possible resolution:
// C2085b.c
void func1( void );
int main( void ) {}
With the semicolon missing, func1() looks like a function definition, not a prototype, so main is defined within
func1() , generating Error C2085 for identifier main .
Compiler Error C2086
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : redefinition
The identifier is defined more than once, or a subsequent declaration differs from a previous one.
C2086 can also be the result of incremental building for a referenced C# assembly. Rebuild the C# assembly to
resolve this error.
The following sample generates C2086:
// C2086.cpp
main() {
int a;
int a; // C2086 not an error in ANSI C
}
Compiler Error C2087
10/31/2018 • 2 minutes to read • Edit Online
// C2087.cpp
int main() {
char a[10][]; // C2087
}
Possible resolution:
// C2087b.cpp
int main() {
char b[4][5];
}
Compiler Error C2088
10/31/2018 • 2 minutes to read • Edit Online
// C2088.c
struct S {
int m_i;
} s;
int main() {
int i = s * 1; // C2088
struct S s2 = +s; // C2088
s++; // C2088
}
Compiler Error C2089
10/31/2018 • 2 minutes to read • Edit Online
// C2090.cpp
int func1(void)[] {} // C2090
Possible resolution:
// C2090b.cpp
// compile with: /c
int* func2(int * i) {
return i;
}
Compiler Error C2091
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2092:
// C2092.cpp
typedef void (F) ();
typedef F AT[10]; // C2092
Example
Possible resolution:
// C2092b.cpp
// compile with: /c
typedef void (F) ();
typedef F * AT[10];
Compiler Error C2093
10/31/2018 • 2 minutes to read • Edit Online
// C2093.c
// compile with: /Za /c
void func() {
int li; // an implicit auto variable
int * s[]= { &li }; // C2093 address is not a constant
// OK
static int li2;
int * s2[]= { &li2 };
}
Compiler Error C2094
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2094:
// C2094.c
int main() {
goto test;
} // C2094
Possible resolution:
// C2094b.c
int main() {
goto test;
test:
{
}
}
Compiler Error C2095
10/31/2018 • 2 minutes to read • Edit Online
illegal initialization
To fix by checking the following possible causes
1. Initialization of a variable using a nonconstant value.
2. Initialization of a short address with a long address.
3. Initialization of a local structure, union, or array with a nonconstant expression when compiling with /Za.
4. Initialization with an expression containing a comma operator.
5. Initialization with an expression that is neither constant nor symbolic.
Compiler Error C2099
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2099.
// C2099.c
int j;
int *p;
j = *p; // C2099 *p is not a constant
Example
C2099 can also occur because the compiler is not able to perform constant folding on an expression under
/fp:strict because the floating point precision environment settings (see _controlfp_s for more information) may
differ from compile to run time.
When constant folding fails, the compiler invokes dynamic initialization, which is not allowed in C.
To resolve this error, compile the module as a .cpp file or simplify the expression.
For more information, see /fp (Specify Floating-Point Behavior).
The following sample generates C2099.
// C2099_2.c
// compile with: /fp:strict /c
float X = 2.0 - 1.0; // C2099
float X2 = 1.0; // OK
Compiler Errors C2100 through C2199
3/5/2019 • 7 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2112 '-': pointer subtraction requires integral or pointer operand
Compiler Error C2113 '-': pointer can only be subtracted from another pointer
Compiler Error C2114 'operator': pointer on left; needs integral value on right
Compiler Error C2119 'identifier': the type for 'type' cannot be deduced from an
empty initializer
Compiler Error C2121 '#': invalid character: possibly the result of a macro expansion
Compiler Error C2127 'identifier': illegal initialization of 'constexpr' entity with a non-
constant expression
Compiler Error C2129 static function 'identifier' declared but not defined
Compiler Error C2130 #line expected a string containing the filename, found 'token'
ERROR MESSAGE
Compiler Error C2134 'function': call does not result in a constant expression
Compiler Error C2140 'type': a type that is dependent on a generic type parameter is
not allowed as an argument to compiler intrinsic type trait
'trait'
Compiler Error C2142 function declarations differ, variable parameters specified only
in one of them
Compiler Error C2146 syntax error: missing 'token' before identifier 'identifier'
Compiler Error C2148 total size of array must not exceed 0xvalue bytes
Compiler Error C2149 'identifier': named bit field cannot have zero width
Compiler Error C2150 'identifier': bit field must have type 'int', 'signed int', or
'unsigned int'
Compiler Error C2153 integer literals must have at least one digit
ERROR MESSAGE
Compiler Error C2155 '?': invalid left operand, expected arithmetic or pointer type
Compiler Error C2157 'identifier': must be declared before use in pragma list
Compiler Error C2160 '##' cannot occur at the beginning of a macro definition
Compiler Error C2161 '##' cannot occur at the end of a macro definition
Compiler Error C2167 'function': too many actual parameters for intrinsic function
Compiler Error C2168 'function': too few actual parameters for intrinsic function
Compiler Error C2174 'function': actual parameter has type 'void': parameter
number, parameter list number
Compiler Error C2176 a return statement cannot appear in the handler of a function-
try-block associated with a constructor
ERROR MESSAGE
Compiler Error C2179 'type': an attribute argument cannot use type parameters
Compiler Error C2199 syntax error: found 'identifier (' at global scope (was a
declaration intended?)
Compiler Error C2100
10/31/2018 • 2 minutes to read • Edit Online
illegal indirection
Indirection operator ( * ) is applied to a nonpointer value.
The following sample generates C2100:
// C2100.cpp
int main() {
int r = 0, *s = 0;
s = &r;
*r = 200; // C2100
*s = 200; // OK
}
Compiler Error C2101
10/31/2018 • 2 minutes to read • Edit Online
'&' on constant
The address-of operator ( & ) must have an l-value as operand.
The following sample generates C2101:
// C2101.cpp
int main() {
char test;
test = &'a'; // C2101
test = 'a'; // OK
}
Compiler Error C2102
10/31/2018 • 2 minutes to read • Edit Online
// C2104.cpp
struct X {
int sb : 1;
};
int main() {
X x;
&x.sb; // C2104
x.sb; // OK
}
Compiler Error C2105
10/31/2018 • 2 minutes to read • Edit Online
// C2105.cpp
int main() {
unsigned char * p1 = 0;
unsigned int * p2 = (unsigned int *)p1;
p2++;
unsigned int * p = 0;
p++; // ok
// C2105b.cpp
int main() {
int a[10] = {0};
int b[10] = {0};
++(a , b); // C2105
// OK
++(a[0] , b[0]);
++a[0];
}
Compiler Error C2106
10/31/2018 • 2 minutes to read • Edit Online
// C2106.cpp
int main() {
int a;
1 = a; // C2106
a = 1; // OK
}
Compiler Error C2107
10/31/2018 • 2 minutes to read • Edit Online
Example
C2107 can occur if you incorrectly use the this pointer of a value type to access the type's default indexer. For
more information, see Semantics of the this pointer.
The following sample generates C2107.
// C2107.cpp
// compile with: /clr
using namespace System;
value struct B {
property String ^ default[String ^] {
String ^ get(String ^ data) {
return "abc";
}
}
void Test() {
Console::WriteLine("{0}", this["aa"]); // C2107
Console::WriteLine("{0}", this->default["aa"]); // OK
}
};
int main() {
B ^ myb = gcnew B();
myb->Test();
}
Compiler Error C2108
10/31/2018 • 2 minutes to read • Edit Online
Example
C2108 can occur if you incorrectly use the this pointer of a value type to access the type's default indexer. For
more information, see Semantics of the this pointer.
The following sample generates C2108.
// C2108.cpp
// compile with: /clr
using namespace System;
value struct B {
property Double default[Double] {
Double get(Double data) {
return data*data;
}
}
void Test() {
Console::WriteLine("{0}", this[3.3]); // C2108
Console::WriteLine("{0}", this->default[3.3]); // OK
}
};
int main() {
B ^ myb = gcnew B();
myb->Test();
}
Compiler Error C2109
10/31/2018 • 2 minutes to read • Edit Online
// C2109.cpp
int main() {
int a, b[10] = {0};
a[0] = 1; // C2109
b[0] = 1; // OK
}
Compiler Error C2110
10/31/2018 • 2 minutes to read • Edit Online
// C2110.cpp
int main() {
int a = 0;
int *pa;
int *pb;
a = pa + pb; // C2110
}
Compiler Error C2111
10/31/2018 • 2 minutes to read • Edit Online
// C2111.cpp
int main() {
int *a = 0, *pa = 0, b = 0;
double d = 0.00;
a = pa + d; // C2111
a = pa + b; // OK
}
Compiler Error C2112
10/31/2018 • 2 minutes to read • Edit Online
// C2117.cpp
int main() {
char abc[4] = "abcd"; // C2117
char def[4] = "abd"; // OK
}
Compiler Error C2118
10/31/2018 • 2 minutes to read • Edit Online
negative subscript
The value defining the array size is larger than the maximum array size or smaller than zero.
The following sample generates C2118:
// C2118.cpp
int main() {
int array1[-1]; // C2118
int array2[3]; // OK
}
Compiler Error C2120
10/31/2018 • 2 minutes to read • Edit Online
// C2120.cpp
int main() {
void int i; // C2120
int j; // OK
}
Compiler Error C2121
10/31/2018 • 2 minutes to read • Edit Online
// C2124.cpp
int main() {
int i = 1 / 0; // C2124 do not divide by zero
int i2 = 12 / 2; // OK
}
Compiler Error C2128
10/31/2018 • 2 minutes to read • Edit Online
// C2128.cpp
// compile with: /c
extern "C" {
void func();
}
// C2130.cpp
int main() {
#line 1000 test // C2130
#line 1000 "test" // OK
}
Compiler Error C2131
3/5/2019 • 2 minutes to read • Edit Online
An expression declared as const or constexpr didn't evaluate to a constant at compile time. The compiler must be
able to determine the value of the expression at the point it's used.
Example
This example shows a way to cause error C2131, and how to fix it.
// c2131.cpp
// compile by using: cl /EHsc /W4 /c c2131.cpp
struct test
{
static const int array_size; // To fix, init array_size here.
int size_array[array_size]; // C2131
};
c2131.cpp
c2131.cpp(7): error C2131: expression did not evaluate to a constant
c2131.cpp(7): note: failure was caused by non-constant arguments or reference to a non-constant symbol
c2131.cpp(7): note: see usage of 'array_size'
See also
const
constexpr
Compiler Error C2132
10/31/2018 • 2 minutes to read • Edit Online
// C2133.cpp
// compile with: /Za
struct X {
int a[0]; // C2133 unsized array
};
Possible resolution:
// C2133b.cpp
// compile with: /c
struct X {
int a[0]; // no /Za
};
Compiler Error C2134
10/31/2018 • 2 minutes to read • Edit Online
// C2134.cpp
// compile with: /c
int A() {
return 42;
};
Possible resolution:
// C2134b.cpp
constexpr int A() { // add constexpr to A, since it meets the requirements of constexpr.
return 42;
};
// C2135.cpp
struct S {
int i : 1;
};
struct T {
int j;
};
int main() {
&S::i; // C2135 address of a bit field
&T::j; // OK
}
Compiler Error C2137
10/31/2018 • 2 minutes to read • Edit Online
// C2137.cpp
int main() {
char c = ''; // C2137
char d = ' '; // OK
}
Compiler Error C2138
10/31/2018 • 2 minutes to read • Edit Online
'type' : an undefined class is not allowed as an argument to compiler intrinsic type trait 'trait'
An invalid argument was passed to a type trait.
For more information, see Compiler Support for Type Traits.
Example
The following sample generates C2139.
// C2139.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class C;
class D {};
class E {
public:
virtual void Test() {}
};
int main() {
cout << is_polymorphic<C>::value << endl; // C2139
cout << is_polymorphic<D>::value << endl; // OK
cout << is_polymorphic<E>::value << endl; // OK
}
Compiler Error C2140
10/31/2018 • 2 minutes to read • Edit Online
'type' : a type that is dependent on a generic type parameter is not allowed as an argument to compiler intrinsic
type trait 'trait'
An invalid type specifier was passed to a type trait.
For more information, see Compiler Support for Type Traits.
Example
The following sample generates C2140.
// C2140.cpp
// compile with: /clr /c
template <class T>
struct is_polymorphic {
static const bool value = __is_polymorphic(T);
};
class x {};
System::Console::WriteLine(__is_polymorphic(x)); // OK
System::Console::WriteLine(is_polymorphic<x>::value); // OK
}
};
Compiler Error C2141
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2141.
// C2141.cpp
// processor: IPF
class A {
short m_n;
};
int main()
{
A* pA = (A*)(-1);
pA = new A[0x8000000000000001]; // C2141
A* pA2 = (A*)(-1);
pA2 = new A[0x80000000000000F]; // OK
}
Compiler Error C2142
10/31/2018 • 2 minutes to read • Edit Online
// C2142.c
// compile with: /Za /c
void func();
void func( int, ... ); // C2142
void func2( int, ... ); // OK
Compiler Error C2143
11/9/2018 • 2 minutes to read • Edit Online
class MyClass
{
template<class Ty, typename PropTy>
struct PutFuncType : public Ty::PutFuncType<Ty, PropTy> // error C2143
{
};
};
By default, C++ assumes that Ty::PutFuncType isn't a template; therefore, the following < is interpreted as a less-
than sign. You must tell the compiler explicitly that PutFuncType is a template so that it can correctly parse the
angle bracket. To correct this error, use the template keyword on the dependent type's name, as shown here:
class MyClass
{
template<class Ty, typename PropTy>
struct PutFuncType : public Ty::template PutFuncType<Ty, PropTy> // correct
{
};
};
C2143 can occur when /clr is used and a using directive has a syntax error:
// C2143a.cpp
// compile with: /clr /c
using namespace System.Reflection; // C2143
using namespace System::Reflection;
It can also occur when you are trying to compile a source code file by using CLR syntax without also using /clr:
// C2143b.cpp
ref struct A { // C2143 error compile with /clr
void Test() {}
};
int main() {
A a;
a.Test();
}
The first non-whitespace character that follows an if statement must be a left parenthesis. The compiler cannot
translate anything else:
// C2143c.cpp
int main() {
int j = 0;
// OK
if (j < 25)
;
C2143 can occur when a closing brace, parenthesis, or semicolon is missing on the line where the error is detected
or on one of the lines just above:
// C2143d.cpp
// compile with: /c
class X {
int member1;
int member2 // C2143
} x;
// C2143e.cpp
class X {
int member;
} x;
Or when a label is not attached to a statement. If you must place a label by itself, for example, at the end of a
compound statement, attach it to a null statement:
// C2143f.cpp
// compile with: /c
void func1() {
// OK
end1:
;
end2: // C2143
}
The error can occur when an unqualified call is made to a type in the C++ Standard Library:
// C2143g.cpp
// compile with: /EHsc /c
#include <vector>
static vector<char> bad; // C2143
static std::vector<char> good; // OK
// C2143h.cpp
template <typename T>
struct X {
struct Y {
int i;
};
Y memFunc();
};
template <typename T>
X<T>::Y X<T>::memFunc() { // C2143
// try the following line instead
// typename X<T>::Y X<T>::memFunc() {
return Y();
}
// C2143i.cpp
// compile with: /EHsc /c
// template definition
template <class T>
void PrintType(T i, T j) {}
In a C program, variables must be declared at the beginning of the function, and they cannot be declared after the
function executes non-declaration instructions.
// C2143j.c
int main()
{
int i = 0;
i++;
int j = 0; // C2143
}
Compiler Error C2144
10/31/2018 • 2 minutes to read • Edit Online
Examples
The following sample generates C2144, and shows a way to fix it:
// C2144.cpp
// compile with: /clr /c
#define REF ref
REF struct MyStruct0; // C2144
// OK
#define REF1 ref struct
REF1 MyStruct1;
The following sample generates C2144, and shows a way to fix it:
// C2144_2.cpp
// compile with: /clr /c
ref struct X {
Example
The following sample generates C2146.
// C2146.cpp
class CDeclaredClass {};
class CMyClass {
CUndeclared m_myClass; // C2146
CDeclaredClass m_myClass2; // OK
};
int main() {
int x;
int t x; // C2146 : missing semicolon before 'x'
}
Example
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003: missing typename keyword.
The following sample compiles in Visual Studio .NET 2002 but will fail in Visual Studio .NET 2003:
// C2146b.cpp
// compile with: /c
template <typename T>
struct X {
struct Y {
int i;
};
Y memFunc();
};
// OK
template <typename T>
typename X<T>::Y func() { }
Example
You will also see this error as a result of compiler conformance work that was done for Visual Studio .NET 2003:
explicit specializations no longer find template parameters from primary template.
The use of T from the primary template is not allowed in the explicit specialization. For code to be valid in the
Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, replace all instances of the template
parameter in the specialization with the explicitly specialized type.
The following sample compiles in Visual Studio .NET but will fail in Visual Studio .NET 2003:
// C2146_c.cpp
// compile with: /c
template <class T>
struct S;
template <>
struct S<int> {
T m_t; // C2146
int m_t2; // OK
};
Compiler Error C2147
10/31/2018 • 2 minutes to read • Edit Online
// C2147.cpp
// compile with: /clr
int main() {
int gcnew = 0; // C2147
int i = 0; // OK
}
Compiler Error C2148
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2148:
// C2148.cpp
#include <stdio.h>
#include <stdlib.h>
int main( ) {
char MyArray[0x7ffffffff]; // C2148
char * MyArray2 = (char *)malloc(0x7fffffff);
if (MyArray2)
printf_s("It worked!");
else
printf_s("It didn't work.");
}
Compiler Error C2149
10/31/2018 • 2 minutes to read • Edit Online
// C2149.cpp
// compile with: /c
struct C {
int i : 0; // C2149
int j : 2; // OK
};
Compiler Error C2150
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : bit field must have type 'int', 'signed int', or 'unsigned int'
The base type for a bit-field is required to be int , signed int , or unsigned int .
Example
This sample shows how you might encounter C2150, and how you can fix it:
// C2150.cpp
// compile with: /c
struct A {
float a : 8; // C2150
int i : 8; // OK
};
Compiler Error C2151
10/31/2018 • 2 minutes to read • Edit Online
// C2153.cpp
int main() {
int a= 0x; // C2153
int b= 0xA; // OK
}
Compiler Error C2154
10/31/2018 • 2 minutes to read • Edit Online
'type' : only enumeration type is allowed as an argument to compiler intrinsic type trait '__underlying_type'
You can only get the underlying type of an enumeration type.
For more information, see Compiler Support for Type Traits.
Compiler Error C2155
10/31/2018 • 2 minutes to read • Edit Online
// C2156.cpp
#pragma optimize( "l", on ) // OK
int main() {
#pragma optimize( "l", on ) // C2156
}
Compiler Error C2157
10/31/2018 • 2 minutes to read • Edit Online
// C2157.cpp
// compile with: /c
#pragma alloc_text( "func", func) // C2157
// OK
extern "C" void func();
#pragma alloc_text( "func", func)
Compiler Error C2158
10/31/2018 • 2 minutes to read • Edit Online
'type' : #pragma make_public directive is currently supported for native non-template types only
The make_public pragma can only be applied to a native, non-template type.
Example
The following sample generates C2158.
// C2158.cpp
// compile with: /clr /c
ref class A {};
#pragma make_public(A) // C2158
void C () {}
#pragma make_public(C) // C2158
class D {};
#pragma make_public(D) // OK
Compiler Error C2159
10/31/2018 • 2 minutes to read • Edit Online
// C2159.cpp
// compile with: /c
static int i; // OK
extern static int i; // C2159
Compiler Error C2160
10/31/2018 • 2 minutes to read • Edit Online
// C2160.cpp
// compile with: /c
#define mac(a,b) #a // OK
#define mac(a,b) ##a // C2160
Compiler Error C2161
10/31/2018 • 2 minutes to read • Edit Online
// C2161.cpp
// compile with: /c
#define mac(a,b) a // OK
#define mac(a,b) a## // C2161
Compiler Error C2162
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2162:
// C2162.cpp
// compile with: /c
#include <stdio.h>
// C2164.c
// compile with: /c
// processor: x86
// Uncomment the following line to resolve.
// #include "xmmintrin.h"
void b(float *p) {
_mm_load_ss(p); // C2164
}
Compiler Error C2165
10/31/2018 • 2 minutes to read • Edit Online
// C2165.cpp
// compile with: /c
char __cdecl *p; // C2165
char *p; // OK
Compiler Error C2166
10/31/2018 • 2 minutes to read • Edit Online
// C2166.cpp
int f();
int main() {
( (const int&) 1 ) = 5; // C2166
}
Compiler Error C2167
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2171.
// C2171.cpp
int main() {
double d, d1;
d = ~d1; // C2171
// OK
int d2 = 0, d3 = 0;
d2 = ~d3;
}
Example
The following sample generates C2171.
// C2171_b.cpp
// compile with: /c
class A {
public:
A() { STF( &A::D ); }
void D() {}
void DTF() {
(*TF)(); // C2171
(this->*TF)(); // OK
}
private:
void (A::*TF)();
};
Compiler Error C2172
10/31/2018 • 2 minutes to read • Edit Online
'function' : actual parameter is not a pointer : parameter number1, parameter list number2
Parameter number1 passed to parameter list number2 is not a pointer. The function expects a pointer.
Compiler Error C2174
10/31/2018 • 2 minutes to read • Edit Online
'function' : actual parameter has type 'void' : parameter number1, parameter list number2
Parameter number1 passed to parameter list number2 is a void parameter. Parameters cannot have type void .
Use void* instead.
Compiler Error C2175
10/31/2018 • 2 minutes to read • Edit Online
// C2177.cpp
int main() {
int a=18446744073709551616; // C2177
int b=18446744073709551615; // OK
}
Compiler Error C2178
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample shows how C2178 may occur, and how to fix it.
// C2178.cpp
// compile with: cl /c /W4 C2178.cpp
class S {
mutable const int i; // C2178
// To fix, declare either const or mutable, not both.
};
Example
The following sample generates C2179.
// C2179.cpp
// compile with: /clr
using namespace System;
Type ^ x;
};
generic<typename T>
public ref class Z {
public:
Type ^ d;
[Attr(T::typeid)] // C2179
// try the following line instead
// [Attr(G::typeid)]
T t;
};
Compiler Error C2180
10/31/2018 • 2 minutes to read • Edit Online
// C2180.c
int main() {
while ((void)1) // C2180
return 1;
while (1) // OK
return 0;
}
Compiler Error C2181
10/31/2018 • 2 minutes to read • Edit Online
// C2181.cpp
int main() {
int i = 0;
else // C2181
i = 1;
}
Possible resolution:
// C2181b.cpp
int main() {
int i = 0;
if(i)
i = 0;
else
i = 1;
}
Compiler Error C2182
10/31/2018 • 2 minutes to read • Edit Online
// C2182.cpp
// compile with: /c
int main() {
int i = 10;
void &ir = i; // C2182 cannot have a reference to type void
int &ir = i; // OK
}
Compiler Error C2183
10/31/2018 • 2 minutes to read • Edit Online
// C2184.cpp
void f() {
int * p;
__try{}
__except(p){}; // C2184
}
Possible resolution:
// C2184b.cpp
// compile with: /c
void f() {
int i = 0;
__try{}
__except(i){};
}
Compiler Error C2185
10/31/2018 • 2 minutes to read • Edit Online
// C2186.cpp
// compile with: /c
void func1( void );
int func2( void );
int i = 2 + func1(); // C2186 func1() is type void
int j = 2 + func2(); // OK both operands are type int
Compiler Error C2188
10/31/2018 • 2 minutes to read • Edit Online
// C2190.c
// compile with: /Za /c
void func( int, float );
void func( int ); // C2190, different parameter list
void func2( int ); // OK
Compiler Error C2191
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2191:
// C2191.c
// compile with: /Za /c
void func( int );
void func( int, float ); // C2191 different parameter list
void func2( int, float ); // OK
Compiler Error C2192
10/31/2018 • 2 minutes to read • Edit Online
// C2192.c
// compile with: /Za /c
void func( float, int );
void func( int, float ); // C2192, different parameter list
void func2( int, float ); // OK
Compiler Error C2193
10/31/2018 • 2 minutes to read • Edit Online
// C2193.cpp
// compile with: /c
extern "C" void MYFUNCTION();
#pragma alloc_text(MYCODE, MYFUNCTION)
#pragma code_seg("MYCODE2")
extern "C" void MYFUNCTION() {} // C2193
extern "C" void MYFUNCTION2() {}
Compiler Error C2194
10/31/2018 • 2 minutes to read • Edit Online
// C2194.cpp
// compile with: /c
#pragma code_seg("MYCODE")
#pragma data_seg("MYCODE") // C2194
#pragma data_seg("MYCODE2") // OK
Compiler Error C2195
10/31/2018 • 2 minutes to read • Edit Online
// C2195.cpp
#pragma data_seg("MYDATA")
#pragma code_seg("MYDATA") // C2195
#pragma code_seg("MYDATA2") // OK
Compiler Error C2196
10/31/2018 • 2 minutes to read • Edit Online
// C2196.cpp
int main() {
int i = 0;
switch( i ) {
case 0:
break;
case 0: // C2196
// try the following line instead
// case 1:
break;
}
}
Compiler Error C2197
10/31/2018 • 2 minutes to read • Edit Online
// C2197.c
// compile with: /Za /c
void func( int );
int main() {
func( 1, 2 ); // C2197 two actual parameters
func( 2 ); // OK
}
Compiler Error C2198
10/31/2018 • 2 minutes to read • Edit Online
// C2198.c
// compile with: /c
void func( int, int );
int main() {
func( 1 ); // C2198 only one actual parameter
func( 1, 1 ); // OK
}
Compiler Error C2199
10/31/2018 • 2 minutes to read • Edit Online
syntax error : found 'identifier (' at global scope (was a declaration intended?)
The specified context caused a syntax error. There may be incorrect declaration syntax.
The following sample generates C2199:
// C2199.cpp
// compile with: /c
int j = int(1) int(1); // C2199
int j = 1; // OK
Compiler Errors C2200 through C2299
10/31/2018 • 7 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2202 'function': not all control paths return a value
Compiler Error C2203 delete operator cannot specify bounds for an array
Compiler Error C2205 'identifier': cannot initialize extern variables with block scope
Compiler Error C2206 'function': typedef cannot be used for function definition
ERROR MESSAGE
Compiler Error C2211 A non-virtual destructor in a ref class derived from a ref class
with a public destructor must also be public
Compiler Error C2212 'identifier': __based not available for pointers to functions
Compiler Error C2214 pointers based on 'void' require the use of:>
Compiler Error C2219 syntax error: type qualifier must be after '*'
Compiler Error C2222 unexpected type 'type': a base-class or member was expected
Compiler Error C2231 '.identifier': left operand points to 'class/struct/union', use '->'
Compiler Error C2232 '->identifier': left operand has 'class/struct/union' type, use '.'
Compiler Error C2233 'identifier': arrays of objects containing zero-size arrays are
illegal
Compiler Error C2236 unexpected token 'token'. Did you forget a ';'?
Compiler Error C2246 'identifier': illegal static data member in locally defined class
Compiler Error C2247 'identifier' not accessible because 'class1' uses 'specifier' to
inherit from 'class2'
Compiler Error C2251 namespace 'namespace' does not have a member 'identifier' -
Did you mean 'member'?
Compiler Error C2253 'function': pure specifier or abstract override specifier only
allowed on virtual function
Compiler Error C2254 'function': pure specifier or abstract override specifier not
allowed on friend function
Compiler Error C2257 'specifier': specifier not allowed in trailing return type
Compiler Error C2261 'string': assembly reference is invalid and cannot be resolved
Compiler Error C2267 'function': static functions with block scope are illegal
Compiler Error C2271 'function': new/delete cannot have formal list modifiers
Compiler Error C2272 'function': modifiers not allowed on static member functions
Compiler Error C2277 'function': cannot take address of this member function
Compiler Error C2281 'class::function': a function can only be deleted on the first
declaration
Compiler Error C2283 'identifer': pure specifier or abstract override specifier not
allowed on unnamed class/struct
Compiler Error C2289 same type qualifier used more than once
Compiler Error C2294 cannot export symbol 'identifier' because it has internal
linkage
Compiler Error C2296 'operator': illegal, left operand has type 'type'
Compiler Error C2297 'operator': illegal, right operand has type 'type'
// C2201.cpp
// compile with: /c
__declspec(dllexport) static void func() {} // C2201 func() is static
__declspec(dllexport) void func2() {} // OK
See Also
Types of Linkage
Compiler Error C2203
10/31/2018 • 2 minutes to read • Edit Online
// C2203.cpp
// compile with: /Za
int main() {
int *ar = new int[10];
delete [4] ar; // C2203
// try the following line instead
// delete [] ar;
}
Compiler Error C2204
10/31/2018 • 2 minutes to read • Edit Online
// C2206.cpp
typedef int functyp();
typedef int MyInt;
functyp func1 {}; // C2206
int main() {
MyInt i = 0; // OK
}
Compiler Error C2207
10/31/2018 • 2 minutes to read • Edit Online
// C2208.cpp
class C {
C; // C2208
C(){} // OK
};
Compiler Error C2212
10/31/2018 • 2 minutes to read • Edit Online
// C2213.cpp
// compile with: /c
int i;
int *j;
char __based(i) *p; // C2213
char __based(j) *p2; // OK
Compiler Error C2216
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2216.
// C2216.cpp
// compile with: /clr /c
ref struct Y1 {
literal
static int staticConst2 = 10; // C2216
};
Example
The following sample generates C2216.
// C2216b.cpp
// compile with: /clr /c
public ref class X {
extern property int i { int get(); } // C2216 extern not allowed on property
typedef property int i2; // C2216 typedef not allowed on property
};
Example
The following sample generates C2216.
// C2216c.cpp
// compile with: /clr /c
public interface struct I {
double f();
double g();
double h();
};
Example
C2217 can also occur if you attempt to bind a delegate to a CLR function that takes a variable number of
arguments. If the function also has e param array overload, use that instead. The following sample generates
C2217.
// C2217.cpp
// compile with: /clr
using namespace System;
delegate void MyDel(String^, Object^, Object^, ...); // C2217
delegate void MyDel2(String ^, array<Object ^> ^); // OK
int main() {
MyDel2^ wl = gcnew MyDel2(Console::WriteLine);
array<Object ^ > ^ x = gcnew array<Object ^>(2);
x[0] = safe_cast<Object^>(0);
x[1] = safe_cast<Object^>(1);
// C2227.cpp
int *pInt;
struct S {
public:
int member;
} s, *pS = &s;
int main() {
pInt->member = 0; // C2227 pInt points to an int
pS->member = 0; // OK
}
Compiler Error C2228
10/31/2018 • 2 minutes to read • Edit Online
// C2228.cpp
int i;
struct S {
public:
int member;
} s, *ps = &s;
int main() {
i.member = 0; // C2228 i is not a class type
ps.member = 0; // C2228 ps is a pointer to a structure
You will also see this error if you use incorrect syntax when using Managed Extensions. Whereas in other Visual
Studio languages, you can use the dot operator to access a member of a managed class, a pointer to the object in
C++ means you have to use the -> operator to access the member:
Wrong: String * myString = checkedListBox1->CheckedItems->Item[0].ToString();
// C2229.cpp
struct S {
int a[0]; // C2229 zero-sized array
int b[1];
};
struct S2 {
int a;
int b[0];
};
int main() {
// allocate 7 elements for b field
S2* s2 = (S2*)new int[sizeof(S2) + 7*sizeof(int)];
s2->b[6] = 100;
}
Compiler Error C2231
10/31/2018 • 2 minutes to read • Edit Online
// C2231.c
struct S {
int member;
} s, *ps = &s;
int main() {
ps.member = 0; // C2231
// OK
ps->member = 0; // crash
s.member = 0;
}
Compiler Error C2232
10/31/2018 • 2 minutes to read • Edit Online
// C2232.c
struct X {
int member;
} x, *px;
int main() {
x->member = 0; // C2232, x is not a pointer
px->member = 0;
x.member = 0;
}
Compiler Error C2233
10/31/2018 • 2 minutes to read • Edit Online
// C2233.cpp
// compile with: /c
class A {
char somearray[1];
};
class B {
char zeroarray[];
};
A array[100]; // OK
B array2[100]; // C2233
Compiler Error C2234
10/31/2018 • 2 minutes to read • Edit Online
// C2234.cpp
int main() {
int i = 0, j = 0, k = 0, l = 0;
int &array[4] = {i,j,k,l}; // C2234
int array2[4] = {i,j,k,l}; // OK
}
Compiler Error C2236
10/31/2018 • 2 minutes to read • Edit Online
// C2236.cpp
// compile with: /c
int class A {}; // C2236 "int class" is unexpected
int i;
class B {};
Compiler Error C2238
10/31/2018 • 2 minutes to read • Edit Online
// C2238.cpp
// compile with: /c
class v {
virtual: int vvv; // C2238
};
Compiler Error C2241
10/31/2018 • 2 minutes to read • Edit Online
// C2243.cpp
// compile with: /c
class B {};
class D : private B {};
class E : public B {};
D d;
B *p = &d; // C2243
E e;
B *p2 = &e;
Base classes with protected or private access are not accessible to clients of the derived class. These levels of
access control are used to indicate that the base class is an implementation detail that should be invisible to clients.
Use public derivation if you want clients of the derived class to have access to implicit conversion of a derived class
pointer to a pointer to the base class.
Compiler Error C2244
10/31/2018 • 2 minutes to read • Edit Online
// C2244.cpp
int func(char) {
return 0;
}
int func(int) {
return 0;
}
int main() {
+func; // C2244
}
C2244 can also occur when an incorrect function signature is used for a member function of a class template.
// C2244b.cpp
// compile with: /c
template<class T>
class XYZ {
void func(T t);
};
template<class T>
void XYZ<T>::func(int i) {} // C2244 wrong function signature
// try the following line instead
// void XYZ<T>::func(T t) {}
C2244 can also occur when an incorrect function signature is used for a member function template.
// C2244c.cpp
// compile with: /c
class ABC {
template<class T>
void func(int i, T t);
};
template<class T>
void ABC::func(int i) {} // C2244 wrong signature
// try the following line instead
// void ABC::func(int i, T t) {}
template<class T>
void QRS<T,int>::func(T t, int u) {} // C2244
Compiler Error C2245
10/31/2018 • 2 minutes to read • Edit Online
non-existent member function 'function' specified as friend (member function signature does not match any
overload)
A function specified as a friend was not found by the compiler.
The following sample generates C2245:
// C2245.cpp
// compile with: /c
class B {
void f(int i);
};
class A {
int m_i;
friend void B::f(char); // C2245
// try the following line instead
// friend void B::f(int);
};
void B::f(int i) {
A a;
a.m_i = 0;
}
Compiler Error C2246
10/31/2018 • 2 minutes to read • Edit Online
// C2246.cpp
// compile with: /c
void func( void ) {
class A { static int i; }; // C2246 i is local to func
static int j; // OK
};
Compiler Error C2247
10/31/2018 • 2 minutes to read • Edit Online
'identifier' not accessible because 'class' uses 'specifier' to inherit from 'class'
identifier is inherited from a class declared with private or protected access.
The following sample generates C2247:
// C2247.cpp
class A {
public:
int i;
};
class B : private A {}; // B inherits a private A
class C : public B {} c; // so even though C's B is public
int j = c.i; // C2247, i not accessible
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003: access control with protected members. A protected member (n) can only be accessed through a member
function of a class (B ) that inherits from the class (A) of which it (n) is a member.
For code that is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, declare
the member to be a friend of the type. Public inheritance could also be used.
// C2247b.cpp
// compile with: /c
// C2247 expected
class A {
public:
void f();
int n;
};
class B: protected A {
// Uncomment the following line to resolve.
// friend void A::f();
};
void A::f() {
B b;
b.n;
}
C2247 can also be generated as a result of compiler conformance work that was done for Visual Studio .NET 2003:
private base classes now inaccessible. A class (A) that is a private base class to a type (B ) should not be accessible
to a type (C ) that uses B as a base class.
For code that is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, use the
scope operator.
// C2247c.cpp
// compile with: /c
struct A {};
struct C : B {
void f() {
A *p1 = (A*) this; // C2247
// try the following line instead
// ::A *p2 = (::A*) this;
}
};
Compiler Error C2248
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2248 when private or protected members of a class are accessed from outside
the class. To fix this issue, do not access these members directly outside the class. Use public member data and
member functions to interact with the class.
// C2248_access.cpp
// compile with: cl /EHsc /W4 C2248_access.cpp
#include <stdio.h>
class X {
public:
int m_publicMember;
void setPrivateMember( int i ) {
m_privateMember = i;
printf_s("\n%d", m_privateMember);
}
protected:
int m_protectedMember;
private:
int m_privateMember;
} x;
int main() {
x.m_publicMember = 4;
printf_s("\n%d", x.m_publicMember);
x.m_protectedMember = 2; // C2248 m_protectedMember is protected
x.m_privateMember = 3; // C2248 m_privMemb is private
x.setPrivateMember(0); // OK uses public access function
}
Another conformance issue that exposes C2248 is the use of template friends and specialization. To fix this issue,
declare friend template functions by using either an empty template parameter list <> or specific template
parameters.
// C2248_template.cpp
// compile with: cl /EHsc /W4 C2248_template.cpp
template<class T>
void f(T t) {
t.i; // C2248
}
struct S {
private:
int i;
public:
S() {}
friend void f(S); // refer to the non-template function void f(S)
// To fix, comment out the previous line and
// uncomment the following line.
// friend void f<S>(S);
};
int main() {
S s;
f<S>(s);
}
Another conformance issue that exposes C2248 is when you attempt to declare a friend of a class and when the
class is not visible to the friend declaration in the scope of the class. To fix this issue, grant friendship to the
enclosing class.
// C2248_enclose.cpp
// compile with: cl /W4 /c C2248_enclose.cpp
class T {
class S {
class E {};
};
friend class S::E; // C2248
};
class A {
class S {
class E {};
friend class A; // grant friendship to enclosing class
};
friend class S::E; // OK
};
Compiler Error C2249
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2249.
// C2249.cpp
class A {
private:
void privFunc( void ) {};
public:
void pubFunc( void ) {};
};
int main() {
b.privFunc(); // C2249, private member of A
b.pubFunc(); // OK
}
Example
C2249 can also occur if you try to assign a stream from the C++ Standard Library to another stream. The
following sample generates C2249.
// C2249_2.cpp
#include <iostream>
using namespace std;
int main() {
cout = cerr; // C2249
#define cout cerr; // OK
}
Compiler Error C2250
10/31/2018 • 2 minutes to read • Edit Online
// C2250.cpp
// compile with: /c
// C2250 expected
struct V {
virtual void vf();
};
struct A : virtual V {
void vf();
};
struct B : virtual V {
void vf();
};
struct D : A, B {
// Uncomment the following line to resolve.
// void vf();
};
Compiler Error C2251
10/31/2018 • 2 minutes to read • Edit Online
namespace 'namespace' does not have a member 'member' - Did you mean 'member'?
The compiler was not able to find an identifier in the specified namespace.
The following sample generates C2251:
// C2251.cpp
// compile with: /c
namespace A {
namespace B {
void f1();
}
using namespace B;
}
// C2252.cpp
class A {
public:
template <class T>
int getit(int i , T * it ) {
return i;
}
template int A::getit<double>(int i, double * it); // C2252
// try the following line instead
// template <> int A::getit<double>(int i, double * it);
};
int main() {
// cannot explicitly instantiate in function
template int A::getit<long>(int i, long * it); // C2252
}
Compiler Error C2253
10/31/2018 • 2 minutes to read • Edit Online
'function' : pure specifier or abstract override specifier only allowed on virtual function
A nonvirtual function is specified as pure virtual .
The following sample generates C2253:
// C2253.cpp
// compile with: /c
class A {
public:
void func1() = 0; // C2253 not virtual
virtual void func2() = 0; // OK
};
// C2253_2.cpp
// compile with: /clr /c
ref struct A {
property int Prop_3 {
int get() abstract; // C2253
// try the following line instead
// virtual int get() abstract;
'function' : pure specifier or abstract override specifier not allowed on friend function
A friend function is specified as pure virtual .
The following sample generates C2254:
// C2254.cpp
// compile with: /c
class A {
public:
friend void func1() = 0; // C2254, func1 is friend
void virtual func2() = 0; // OK, pure virtual
friend void func3(); // OK, friend not virtual nor pure
};
// C2255.cpp
// compile with: /c
class A {
private:
void func1();
friend void func2();
};
// C2256.cpp
// compile with: /c
class C {
public:
friend ~C(); // C2256
~C(); // OK
};
Compiler Error C2258
10/31/2018 • 2 minutes to read • Edit Online
// C2258.cpp
// compile with: /c
class A {
public:
void virtual func1() = 1; // C2258
void virtual func2() = 0; // OK
};
Compiler Error C2259
10/31/2018 • 2 minutes to read • Edit Online
// C2259.cpp
// compile with: /c
class V {
public:
void virtual func() = 0;
};
class A : public V {};
class B : public V {
public:
void func();
};
V v; // C2259, V is an abstract class
A a; // C2259, A inherits func() as pure virtual
B b; // OK, B defines func()
Whenever you derive from an interface and implement the interface methods in the derived class with access
permissions other than public, you may receive C2259. This occurs because the compiler expects the interface
methods implemented in the derived class to have public access. When you implement the member functions for
an interface with more restrictive access permissions, the compiler does not consider them to be implementations
for the interface methods defined in the interface, which in turn makes the derived class an abstract class.
There are two possible workarounds for the problem:
Make the access permissions public for the implemented methods.
Use the scope resolution operator for the interface methods implemented in the derived class to qualify the
implemented method name with the name of the interface.
C2259 can also occur as a result of conformance work that was done in Visual C++ 2005, /Zc:wchar_t is now on
by default. In this situation, C2599 can be resolved either by compiling with /Zc:wchar_t-, to get the behavior from
previous versions, or preferably, by updating your types so they are compatible. For more information, see
/Zc:wchar_t (wchar_t Is Native Type).
The following sample generates C2259:
// C2259b.cpp
// compile with: /c
#include <windows.h>
class MyClass {
public:
// WCHAR now typedef'ed to wchar_t
virtual void func(WCHAR*) = 0;
};
MyClass2 x; // C2259
// OK
class MyClass3 {
public:
virtual void func(WCHAR*) = 0;
virtual void func2(wchar_t*) = 0;
virtual void func3(unsigned short*) = 0;
};
MyClass4 y;
// C2259c.cpp
// compile with: /clr
interface class MyInterface {
void MyMethod();
};
int main() {
MyDerivedClass^ instance = gcnew MyDerivedClass; // C2259
}
Compiler Error C2261
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2261.
// C2261.cpp
// compile with: /clr /c
using namespace System::Runtime::CompilerServices;
[assembly: InternalsVisibleTo("a,a,a")]; // C2261
[assembly: InternalsVisibleTo("a.a")]; // OK
[assembly: InternalsVisibleTo("a")]; // OK
Compiler Error C2262
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2262.
// C2262.cpp
// compile with: /clr /c
using namespace System::Runtime::CompilerServices;
[assembly: InternalsVisibleTo("assembly_name, version=1.2.3.7")]; // C2262
[assembly: InternalsVisibleTo("assembly_name ")]; // OK
Compiler Error C2264
10/31/2018 • 2 minutes to read • Edit Online
// C2264.cpp
struct C {
// Delete the following line to resolve.
operator int(int = 0){} // incorrect declaration
};
struct D {
operator int(){return 0;} // OK
};
int main() {
int i;
C c;
i = c; // C2264
D d;
i = d; // OK
}
Compiler Error C2266
10/31/2018 • 2 minutes to read • Edit Online
// C2267.cpp
static int func2(); // OK
int main() {
static int func1(); // C2267
}
Compiler Error C2268
10/31/2018 • 2 minutes to read • Edit Online
'function' is a compiler predefined library helper. Library helpers are not supported with /GL; compile object file
'file' without /GL.
A function defined in your source code has the same name as an internal compiler function. Compile the module
containing the function without /GL.
The following sample generates C2268:
// C2268.c
// compile with: /c
// processor: x86
extern int SHFusionLoadLibrary(int lpLibFileName);
void* mainCRTStartup(void* p) {
p = main;
return p;
}
and then:
// C2268b.c
// compile with: C2268.c /EHsc /GL /Ob0 /O2 /Fa /GS- /link /nodefaultlib
// processor: x86
extern int SHFusionLoadLibrary(int lpLibFileName);
#define ENTERCONTEXT(fail) \
int ulCookie = 0;\
if (!SHActivateContext(&ulCookie)) \
return fail;\
__try {
#define LEAVECONTEXT \
} __finally {SHDeactivateContext(ulCookie);}
int SHActivateContext(int* a) {
return *a == g || !*a ||_except_handler3();
}
void SHDeactivateContext(int a) {
g = a;
}
return lpLibFileName;
}
int main(void) {
g = SHFusionLoadLibrary(10);
return 0;
}
Compiler Error C2270
10/31/2018 • 2 minutes to read • Edit Online
// C2270.cpp
// compile with: /c
void func1(void) const; // C2270, nonmember function
void func2(void);
class CMyClass {
public:
void func2(void) const;
};
Compiler Error C2271
10/31/2018 • 2 minutes to read • Edit Online
// C2271.cpp
// compile with: /c
void* operator new(size_t) const { // C2271
// try the following line instead
// void* operator new(size_t) {
return 0;
}
struct X {
static void* operator new(size_t) const; // C2271
// try the following line instead
// void * X::operator new(size_t) const; // static member operator new
};
Compiler Error C2272
10/31/2018 • 2 minutes to read • Edit Online
// C2272.cpp
// compile with: /c
class CMyClass {
public:
static void func1() const volatile; // C2272 func1 is static
void func2() const volatile; // OK
};
Compiler Error C2273
10/31/2018 • 2 minutes to read • Edit Online
// C2273.cpp
struct MyClass {
operator int() {
return 0;
}
};
int main() {
MyClass * ClassPtr = new MyClass;
int i = ClassPtr->int(); // C2273
int j = ClassPtr-> operator int(); // OK
}
Compiler Error C2274
10/31/2018 • 2 minutes to read • Edit Online
// C2274.cpp
struct MyClass {
operator int() {
return 0;
}
};
int main() {
MyClass ClassName;
int i = ClassName.int(); // C2274
int j = ClassName.operator int(); // OK
}
Compiler Error C2275
10/31/2018 • 2 minutes to read • Edit Online
// C2275.cpp
typedef struct S {
int mem;
} *S_t;
void func1( int *parm );
void func2() {
func1( &S_t->mem ); // C2275, S_t is a typedef
}
Compiler Error C2276
10/31/2018 • 2 minutes to read • Edit Online
// C2276.cpp
class A {
public:
int func(){return 0;}
} a;
class B {
public:
void mf() {
&this -> mf; // C2276
// try the following line instead
// &B::mf;
}
};
int main() {
A a;
&a.func; // C2276
// try the following line instead
// &A::func;
}
Compiler Error C2277
10/31/2018 • 2 minutes to read • Edit Online
// C2277.cpp
class A {
public:
A();
};
(*pctor)() = &A::A; // C2277
Compiler Error C2279
10/31/2018 • 2 minutes to read • Edit Online
// C2279.cpp
// compile with: /Za /c
typedef int (*xy)() throw(...); // C2279
typedef int (*xyz)(); // OK
Compiler Error C2280
10/31/2018 • 4 minutes to read • Edit Online
// C2280_explicit.cpp
// compile with: cl /c /W4 C2280_explicit.cpp
struct A {
A();
A(int) = delete;
};
struct B {
A a1;
A a2 = A(3); // C2280, calls deleted A::A(int)
// To fix, remove the call to A(int)
};
void f() {
B b; // calls implicit B::B(void)
}
// C2280_uninit.cpp
// compile with: cl /c C2280_uninit.cpp
struct A {
const int i; // uninitialized const-qualified data
// members or reference type data members cause
// the implicit default constructor to be deleted.
// To fix, initialize the value in the declaration:
// const int i = 42;
} a; // C2280
// C2280_ref.cpp
// compile with: cl /c C2280_ref.cpp
extern int k;
struct A {
A();
int& ri = k; // a const or reference data member causes
// implicit copy assignment operator to be deleted.
};
void f() {
A a1, a2;
// To fix, consider removing this assignment.
a2 = a1; // C2280
}
// C2280_move.cpp
// compile with: cl /c C2280_move.cpp
class base
{
public:
base();
~base();
base(base&&);
// Move constructor causes copy constructor to be
// implicitly declared as deleted. To fix this
// issue, you can explicitly declare a copy constructor:
// base(base&);
// If you want the compiler default version, do this:
// base(base&) = default;
};
// C2280_variant.cpp
// compile with: cl /c C2280_variant.cpp
struct A {
A() = default;
A(const A&);
};
struct B {
union {
A a;
int i;
};
// To fix this issue, declare the required
// special member functions:
// B();
// B(const B& b);
};
int main() {
B b1;
B b2(b1); // C2280
}
// C2280_indirect.cpp
// compile with: cl /c C2280_indirect.cpp
class base
{
protected:
base();
~base();
};
'identifier' : pure specifier or abstract override specifier not allowed on unnamed struct
A member function of an unnamed class or structure is declared with a pure specifier, which is not permitted.
The following sample generates C2283:
// C2283.cpp
// compile with: /c
struct {
virtual void func() = 0; // C2283
};
struct T {
virtual void func() = 0; // OK
};
Compiler Error C2285
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2286:
// C2286.cpp
// compile with: /c
class __single_inheritance X;
class __multiple_inheritance X; // C2286
class __multiple_inheritance Y; // OK
Compiler Error C2287
10/31/2018 • 2 minutes to read • Edit Online
'class': inheritance representation: 'representation1' is less general than the required 'representation2'
A class is declared with a simpler representation than required.
The following sample generates C2287:
// C2287.cpp
// compile with: /vmg /c
class __single_inheritance X;
class __single_inheritance Y;
struct A { };
struct B { };
struct X : A, B { }; // C2287 X uses multiple inheritance
struct Y : A { }; // OK
Compiler Error C2289
10/31/2018 • 2 minutes to read • Edit Online
// C2289.cpp
// compile with: /Za /c
volatile volatile int i; // C2289
volatile int j; // OK
Compiler Error C2290
10/31/2018 • 2 minutes to read • Edit Online
'identifier': best case inheritance representation: 'representation1' declared but 'representation2' required
Compiling the following code with /vmb ("Best-case always" representation) causes C2292.
// C2292.cpp
// compile with: /vmb
class __single_inheritance X;
struct A { };
struct B { };
struct X : A, B { }; // C2292, X uses multiple inheritance
Compiler Error C2293
10/31/2018 • 2 minutes to read • Edit Online
// C2293.cpp
// compile with: /c
class A {
static int *i;
void __based(i) *bp; // C2293
void *bp2; // OK
};
Compiler Error C2295
10/31/2018 • 2 minutes to read • Edit Online
// C2296.cpp
struct MyStruct {
struct Help {
Help(float f) : m_f(f) {}
float m_f;
};
private:
float m_f;
};
int main() {
float f1 = 1.0f;
// C2297.cpp
struct MyStruct {
struct Help {
Help(float f) : m_f(f) {}
float m_f;
};
MyStruct(float f) : m_f(f) {}
private:
float m_f;
};
int main() {
float f1 = 1.0f;
Example
The following sample generates C2298.
// C2298.cpp
#include <stdio.h>
struct X {
void mf() {
puts("in X::mf");
}
void mf2() {
puts("in X::mf2");
}
};
X x;
// pointer to member functions with no params and void return in X
typedef void (X::*pmf_t)();
int main() {
int (*pf)();
pf = x.*pmf; // C2298
+(x.*pmf); // C2298
Example
The following sample generates C2298.
// C2298_b.cpp
// compile with: /c
void F() {}
class Measure {
public:
void SetTrackingFunction(void (Measure::*fnc)()) {
TrackingFunction = this->*fnc; // C2298
TrackingFunction = fnc; // OK
GlobalTracker = F; // OK
}
private:
void (Measure::*TrackingFunction)(void);
void (*GlobalTracker)(void);
};
Compiler Error C2299
10/31/2018 • 2 minutes to read • Edit Online
'function' : behavior change: an explicit specialization can not be a copy constructor or copy assignment operator
This error can also be generated as a result of compiler conformance work that was done for Visual C++ 2005:
previous versions of Visual C++ allowed explicit specializations for a copy constructor or a copy assignment
operator.
To resolve C2299, do not make the copy constructor or assignment operator a template function, but rather a non-
template function that takes a class type. Any code that calls the copy constructor or assignment operator by
explicitly specifying the template arguments needs to remove the template arguments.
The following sample generates C2299:
// C2299.cpp
// compile with: /c
class C {
template <class T>
C (T t);
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2300 'class': class does not have a destructor called '~class'
Compiler Error C2305 'file' does not contain debugging information for this module
Compiler Error C2306 'file' does not contain the most recent debugging information
for this module
ERROR MESSAGE
Compiler Error C2307 pragma directive must be moved outside of the function if
incremental compilation is enabled
Compiler Error C2316 'type': cannot be caught as the destructor and/or copy
constructor are inaccessible or deleted
Compiler Error C2317 'try' block starting on line 'number' has no catch handlers
Compiler Error C2318 no try block associated with this catch handler
Compiler Error C2321 'identifier' is a keyword, and cannot be used in this context
Compiler Error C2325 'type1': unexpected type to the right of '->~': expected 'type2'
Compiler Error C2329 'identifier': __ptr64 not available for pointers to functions
ERROR MESSAGE
Compiler Error C2333 'function': error in function declaration; skipping function body
Compiler Error C2340 'identifier': 'static' can only be used within a class definition
Compiler Error C2341 'section': segment must be defined using #pragma data_seg,
code_seg or section prior to use
Compiler Error C2355 'this': can only be referenced inside non-static member
functions or non-static data member initializers
Compiler Error C2356 initialization segment must not change during translation unit
Compiler Error C2363 compiler intrinsic numeric limit function requires a string literal
argument
Compiler Error C2379 formal parameter number has different type when promoted
Compiler Error C2380 type(s) preceding 'identifier' (constructor with return type, or
illegal redefinition of current class-name?)
Compiler Error C2383 'identifier': default-arguments are not allowed on this symbol
Compiler Error C2386 'identifier': a symbol with this name already exists in the
current scope
Compiler Error C2391 'identifier': 'friend' cannot be used during type definition
Compiler Error C2392 'member1': covariant returns types are not supported in
managed/WinRT types, otherwise 'member2' would be
overridden
Compiler Error C2398 Element 'number': conversion from 'type1' to 'type2' requires
a narrowing conversion
// C2309.cpp
// compile with: /EHsc
#include <eh.h>
class C {};
int main() {
try {
throw "ooops!";
}
catch C {} // C2309
// try the following line instead
// catch( C ) {}
}
Compiler Error C2310
10/31/2018 • 2 minutes to read • Edit Online
// C2310.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try {
throw "Out of memory!";
}
catch( int ,int) {} // C2310 two types
// try the following line instead
// catch( int) {}
}
Compiler Error C2311
10/31/2018 • 2 minutes to read • Edit Online
// C2311.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try {
throw "ooops!";
}
catch( ... ) {}
catch( int ) {} // C2311 ellipsis handler not last catch
}
Compiler Error C2312
10/31/2018 • 2 minutes to read • Edit Online
// C2312.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try {
throw "ooops!";
}
catch( signed int ) {}
catch( int ) {} // C2312
}
Compiler Error C2313
10/31/2018 • 2 minutes to read • Edit Online
// C2313.cpp
// compile with: /EHsc
#include <eh.h>
class C {};
int main() {
try {
throw "ooops!";
}
catch( C& ) {}
catch( C ) {} // C2313
}
Compiler Error C2315
10/31/2018 • 2 minutes to read • Edit Online
'exception' : cannot be caught as the destructor and/or copy constructor are inaccessible
An exception was caught by value or by reference but the copy constructor and/or the assignment operator were
inaccessible.
This code was accepted by versions of Visual C++ before Visual Studio 2003, but now gives an error.
Conformance changes in Visual Studio 2015 made this error apply to bad catch statements of MFC exceptions
derived from CException . Because CException has an inherited private copy constructor, the class and its
derivatives are non-copyable, and cannot be passed by value, which also means they cannot be caught by value.
Catch statements that caught MFC exceptions by value previously led to uncaught exceptions at runtime, but now
the compiler correctly identifies this situation and reports error C2316. To fix this issue, we recommend you use
the MFC TRY/CATCH macros rather than write your own exception handlers, but if that's not appropriate for your
code, catch MFC exceptions by reference instead.
Example
The following sample generates C2316:
// C2316.cpp
// compile with: /EHsc
#include <stdio.h>
struct B
{
public:
B() {}
// Delete the following line to resolve.
private:
// copy constructor
B(const B&)
{
}
};
int main()
{
try
{
B aB;
f(aB);
}
catch (B b) { // C2316
printf_s("Caught an exception!\n");
}
}
Compiler Error C2317
10/31/2018 • 2 minutes to read • Edit Online
// C2317.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try {
throw "throw an exception";
}
// C2317, no catch handler
}
Possible resolution:
// C2317b.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try {
throw "throw an exception";
}
catch(char*) {}
}
Compiler Error C2318
10/31/2018 • 2 minutes to read • Edit Online
// C2318.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
// no try block
catch( int ) {} // C2318
}
Possible resolution:
// C2318b.cpp
// compile with: /EHsc
#include <eh.h>
int main() {
try{}
catch( int ) {}
}
Compiler Error C2319
10/31/2018 • 2 minutes to read • Edit Online
// C2319.cpp
// compile with: /EHsc
#include <eh.h>
class C {};
int main() {
try {
throw "ooops!";
}
catch( C ) ; // C2319
// try the following line instead
// catch( C ) {}
}
Compiler Error C2320
10/31/2018 • 2 minutes to read • Edit Online
// C2324.cpp
class A {};
typedef A* pA_t;
int i;
int main() {
pA_t * ppa = new pA_t;
ppa->~i; // C2324
ppa->~pA_t(); // OK
}
Compiler Error C2325
10/31/2018 • 2 minutes to read • Edit Online
// C2325.cpp
// compile with: /c
class A {};
typedef A* pA_t;
void f() {
A** ppa = new A *;
ppa->~A*; // C2325
Example
The following sample generates C2326:
// C2326.cpp
void MyFunc() {
int i;
class MyClass {
public:
void mf() {
i = 4; // C2326 i is inaccessible
}
};
}
Compiler Error C2327
10/31/2018 • 2 minutes to read • Edit Online
// C2327.cpp
int x;
class enclose {
public:
int x;
static int s;
class inner {
void f() {
x = 1; // C2327; enclose::x is not static
s = 1; // ok; enclose::s is static
::x = 1; // ok; ::x refers to global
}
};
};
C2327 can also occur if the name of a type is hidden by the name of a member:
// C2327b.cpp
class X {};
class S {
X X;
// try the following line instead
// X MyX;
X other; // C2327, rename member X
};
C2327 can also fire in this situation, where you need to fully specify the data type of the parameter:
// C2327c.cpp
// compile with: /c
struct A {};
struct B {
int A;
void f(A a) { // C2327
void f2(struct A a) {} // OK
}
};
namespace NA {
public enum class E : Int32 {
one = 1,
two = 2,
three = 3
};
The following sample shows C2327 when a property has the same name as the property type:
// C2327f.cpp
// compile with: /clr /c
public value class Address {};
// C2332.cpp
// compile with: /c
struct S {
int i;
};
int get_S_i(pS p) {
return p->i;
}
Compiler Error C2333
10/31/2018 • 2 minutes to read • Edit Online
// C2333.cpp
struct s1 {
s1(s1) {} // C2333
};
Compiler Error C2334
10/31/2018 • 2 minutes to read • Edit Online
// C2334.cpp
// compile with: /c
// C2059 expected
struct s1 {
s1 {} // C2334
s1() {} // OK
};
Compiler Error C2337
10/31/2018 • 2 minutes to read • Edit Online
// C2337.cpp
// compile with: /c
[emitidl];
[module(name="x")];
[grasshopper] // C2337, not a supported attribute
class a{};
Compiler Error C2338
11/8/2018 • 2 minutes to read • Edit Online
Error message
This error can be caused by a static_assert error during compilation. The message is supplied by the
static_assert parameters.
This error message can also be generated by external providers to the compiler. In most cases, these errors are
reported by an attribute provider DLL, such as ATLPROV. Some common forms of this message include:
'attribute' Atl Attribute Provider : error ATLnumber message
Incorrect usage of attribute 'attribute'
'usage': incorrect format for attribute 'usage'
These errors are often unrecoverable, and may be followed by a fatal compiler error.
To fix these issues, correct the attribute usage. For example, in some cases, attribute parameters must be declared
before they can be used. If an ATL error number is provided, check the documentation for that error for more
specific information.
Compiler Error C2341
10/31/2018 • 2 minutes to read • Edit Online
'section name' : segment must be defined using #pragma data_seg, code_seg or section prior to use
An allocate statement refers to a segment not yet defined by code_seg, data_seg, or section pragmas.
The following sample generates C2341:
// C2341.cpp
// compile with: /c
__declspec(allocate(".test")) // C2341
int j = 1;
Possible resolution:
// C2341b.cpp
// compile with: /c
#pragma data_seg(".test")
__declspec(allocate(".test"))
int j = 1;
Compiler Error C2344
10/31/2018 • 2 minutes to read • Edit Online
// C2344.cpp
// compile with: /c
__declspec(align(3)) int a; // C2344
__declspec(align(4)) int b; // OK
Compiler Error C2345
10/31/2018 • 2 minutes to read • Edit Online
// C2345.cpp
// compile with: /c
__declspec(align(0)) int a; // C2345
__declspec(align(1)) int a; // OK
Compiler Error C2346
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2346.
// C2346.cpp
// processor: x86
// compile with: /clr
// C2346 expected
struct S
{
S()
{
{ __asm { nop } }
}
virtual __clrcall ~S() { }
};
void main()
{
S s;
}
Compiler Error C2348
10/31/2018 • 2 minutes to read • Edit Online
// C2348.cpp
// C2348 error expected
[ module(name="SimpleMidlTest") ];
[export]
struct Point {
// Delete the following two lines to resolve.
Point() : m_i(0), m_j(0) {}
Point(int i, int j) : m_i(i), m_j(j) {}
int m_i;
int m_j;
};
Compiler Error C2349
10/31/2018 • 2 minutes to read • Edit Online
// C2351.cpp
// compile with: /c
class B {
public:
B() : () {} // C2351
B() {} // OK
};
Compiler Error C2352
10/31/2018 • 2 minutes to read • Edit Online
// C2352.cpp
// compile with: /c
class CMyClass {
public:
static void func1();
void func2();
static void func3() {
func2(); // C2352 calls nonstatic func2
func1(); // OK calls static func1
}
};
The following sample generates C2352 and shows how to fix it:
// C2352b.cpp
class MyClass {
public:
void MyFunc() {}
static void MyFunc2() {}
};
int main() {
MyClass::MyFunc(); // C2352
MyClass::MyFunc2(); // OK
}
Compiler Error C2353
10/31/2018 • 2 minutes to read • Edit Online
// C2353.cpp
// compile with: /clr /c
ref class X {
void f() throw(int); // C2353
void f(); // OK
};
Compiler Error C2355
10/31/2018 • 2 minutes to read • Edit Online
'this' : can only be referenced inside non-static member functions or non-static data member initializers
The this pointer is valid only within non-static member functions or in non-static data member initializers. This
error can result when the class scope of a member function definition outside of the class declaration is not
properly qualified. The error can also occur when the this pointer is used in a function that is not declared in the
class.
To fix this issue, make sure the member function definition matches a member function declaration in the class, and
that it is not declared static. For data member initializers, make sure the data member is not declared static.
The following sample generates C2355 and shows how to fix it:
// C2355.cpp
// compile with: /c
class MyClass {};
MyClass *p = this; // C2355
// OK
class MyClass2 {
public:
void Test() {
MyClass2 *p = this;
}
};
Compiler Error C2356
10/31/2018 • 2 minutes to read • Edit Online
To resolve, move the segment initialization code to the beginning of the module. If multiple areas must be
initialized, move them to separate modules.
The following sample generates C2356:
// C2356.cpp
#pragma warning(disable : 4075)
#pragma init_seg(".mine$m",myexit)
#pragma init_seg(".mine$m",myexit2) // C2356
Compiler Error C2357
10/31/2018 • 2 minutes to read • Edit Online
// C2357.cpp
// compile with: /c
// C2357 expected
#pragma warning(disable : 4075)
// Uncomment the following line to resolve.
// int __cdecl myexit(void (__cdecl *)());
#pragma init_seg(".mine$m",myexit)
Compiler Error C2360
10/31/2018 • 2 minutes to read • Edit Online
// C2360.cpp
int main() {
int x = 0;
switch ( x ) {
case 0 :
int i = 1;
{ int j = 1; }
case 1 : // C2360
int k = 1;
}
}
Possible resolution:
// C2360b.cpp
int main() {
int x = 0;
switch ( x ) {
case 0 :
{ int j = 1; int i = 1;}
case 1 :
int k = 1;
}
}
Compiler Error C2361
10/31/2018 • 2 minutes to read • Edit Online
// C2361.cpp
void func( void ) {
int x;
switch (x) {
case 0 :
int i = 1;
{ int j = 1; }
default : // C2361 error
int k = 1;
}
}
Possible resolution:
// C2361b.cpp
// compile with: /c
void func( void ) {
int x = 0;
switch (x) {
case 0 :
{ int j = 1; int i = 1;}
default :
int k = 1;
}
}
Compiler Error C2362
10/31/2018 • 2 minutes to read • Edit Online
// C2362.cpp
// compile with: /Za
int main() {
goto label1;
int i = 1; // C2362, initialization skipped
label1:;
}
Possible resolution:
// C2362b.cpp
// compile with: /Za
int main() {
goto label1;
{
int j = 1; // OK, this block is never entered
}
label1:;
}
Compiler Error C2364
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2364.
// c2364.cpp
// compile with: /clr /c
using namespace System;
[attribute(AttributeTargets::All)]
public ref struct ABC {
public:
// Delete the following line to resolve.
ABC( Enum^ ) {} // C2364
ABC( int ) {} // OK
};
Compiler Error C2365
10/31/2018 • 2 minutes to read • Edit Online
// C2365.cpp
// compile with: /c
class C1 {
int CFunc();
char *CFunc; // C2365, already exists as a member function
int CMem;
char *CMem(); // C2365, already exists as a data member
};
Compiler Error C2368
10/31/2018 • 2 minutes to read • Edit Online
// C2369.cpp
// compile with: /c
int a[10];
int a[20]; // C2369
int b[20]; // OK
Compiler Error C2370
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2370:
// C2370.cpp
// compile with: /Za /c
extern int i;
static int i; // C2370
int i; // OK
Example
The following sample generates C2370:
// C2370b.cpp
#define Thread __declspec( thread )
extern int tls_i;
int Thread tls_i; // C2370 declaration and the definition differ
int tls_i; // OK
Compiler Error C2371
10/31/2018 • 2 minutes to read • Edit Online
// C2371.cpp
int main() {
int i;
float i; // C2371, redefinition
float f; // OK
}
Compiler Error C2372
10/31/2018 • 2 minutes to read • Edit Online
// C2372.cpp
// compile with: /c
extern int *fp;
extern int fp[]; // C2372
extern int fp2[]; // OK
Compiler Error C2373
10/31/2018 • 2 minutes to read • Edit Online
// C2373.h
void __clrcall func( void );
const int i = 20;
And then:
// C2373.cpp
// compile with: /c
#include "C2373.h"
extern void __cdecl func( void ); // C2373
extern void __clrcall func( void ); // OK
// C2374.cpp
// compile with: /c
int i = 0;
int i = 1; // C2374
int j = 1; // OK
Compiler Error C2375
10/31/2018 • 2 minutes to read • Edit Online
// C2375.cpp
// compile with: /Za /c
extern void func( void );
static void func( void ); // C2375
static void func2( void ); // OK
Compiler Error C2376
10/31/2018 • 2 minutes to read • Edit Online
// C2377.cpp
// compile with: /c
typedef int i;
int i; // C2377
int j; // OK
Compiler Error C2378
10/31/2018 • 2 minutes to read • Edit Online
// C2378.cpp
// compile with: /c
int i;
typedef int i; // C2378
typedef int b; // OK
Compiler Error C2379
10/31/2018 • 2 minutes to read • Edit Online
// C2379.c
// compile with: /Za
void func();
void func(char); // C2379, char promotes to int
Compiler Error C2380
10/31/2018 • 2 minutes to read • Edit Online
type(s) preceding 'identifier' (constructor with return type, or illegal redefinition of current class-name?)
A constructor returns a value or redefines the class name.
The following sample generates C2326:
// C2380.cpp
// compile with: /c
class C {
public:
int C(); // C2380, specifies an int return
int C; // C2380, redefinition of i
C(); // OK
};
Compiler Error C2381
10/31/2018 • 2 minutes to read • Edit Online
// C2381.cpp
// compile with: /c
void f1();
void __declspec(noreturn) f1() {} // C2381
void __declspec(noreturn) f2() {} // OK
Compiler Error C2382
10/31/2018 • 2 minutes to read • Edit Online
// C2382.cpp
// compile with: /Za /c
void f1(void) throw(int) {}
void f1(void) throw(char) {} // C2382
void f2(void) throw(char) {} // OK
Compiler Error C2383
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C2383, and shows a possible solution:
// C2383.cpp
// compile with: /c
void (*pf)(int = 0); // C2383
void (*pf)(int); // OK
Compiler Error C2384
10/31/2018 • 2 minutes to read • Edit Online
// C2384.cpp
// compile with: /clr /c
public ref class B {
public:
__declspec( thread ) static int tls_i = 1; // C2384
Example
The following sample generates C2385.
// C2385.cpp
// C2385 expected
#include <stdio.h>
struct A
{
void x(int i)
{
printf_s("\nIn A::x");
}
};
struct B
{
void x(char c)
{
printf_s("\nIn B::x");
}
};
int main()
{
C aC;
aC.x(100);
aC.x('c');
}
struct C : A, B
{
using B::x;
using A::x;
};
Compiler Error C2386
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : a symbol with this name already exists in the current scope
You tried to create a namespace alias, but the name you chose already exists.
The following sample generates C2386:
// C2386.cpp
namespace A {
int k;
}
int i;
namespace i = A; // C2386, i already exists
Compiler Error C2387
10/31/2018 • 2 minutes to read • Edit Online
// C2387.cpp
namespace N1 {
struct B {
virtual void f() {
}
};
}
namespace N2 {
struct B {
virtual void f() {
}
};
}
int main() {
D aD;
aD.f();
}
Compiler Error C2388
10/31/2018 • 2 minutes to read • Edit Online
// C2388.cpp
// compile with: /clr /c
__declspec(process) __declspec(appdomain) int i; // C2388
__declspec(appdomain) int i; // OK
Compiler Error C2389
10/31/2018 • 2 minutes to read • Edit Online
// C2389.cpp
// compile with: /clr
int main() {
throw nullptr; // C2389
}
Compiler Error C2390
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2390:
// C2390.cpp
register int i; // C2390
int main() {
register int j; // OK
}
Compiler Error C2391
10/31/2018 • 2 minutes to read • Edit Online
// C2391.cpp
// compile with: /c
class D {
void func( int );
};
class A {
friend class B { int i; }; // C2391
// OK
friend class C;
friend void D::func(int);
};
Compiler Error C2392
10/31/2018 • 2 minutes to read • Edit Online
'method1' : covariant returns types are not supported in managed or WinRTtypes, otherwise 'method2' would be
overridden
Covariant return types are not allowed for Windows Runtime member functions or when compiling with the /clr
(Common Language Runtime Compilation) option.
Example
The following sample generates C2392 and shows how to fix it.
// C2392.cpp
// compile with: /clr
public ref struct B {
public:
int i;
};
int main() {
B1^ pB1 = gcnew D1;
B^ pB = pB1->mf();
D^ pD = dynamic_cast<D^>(pB);
}
Compiler Error C2393
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
The use of appdomain variables implies that you are compiling with /clr:pure or /clr:safe, and a safe or pure
image cannot contain data segments.
See /clr (Common Language Runtime Compilation) for more information.
Example
The following sample generates C2393. To fix this issue, do not create a data segment.
// C2393.cpp
// compile with: /clr:pure /c
#pragma data_seg("myseg")
int n = 0; // C2393
Compiler Error C2394
10/31/2018 • 2 minutes to read • Edit Online
'your_type::operator'op'" : CLR or WinRToperator not valid. At least one parameter must be of the following types:
'T^', 'T^%', 'T^&', where T = 'your_type'
An operator in a Windows Runtime or managed type did not have at least one parameter whose type is the same
as the type of the operator return value.
The following sample generates C2394:
// C2394.cpp
// compile with: /clr /c
ref struct Y {
static Y^ operator -(int i, char c); // C2394
// OK
static Y^ operator -(Y^ hY, char c);
// or
static Y^ operator -(int i, Y^& rhY);
};
Compiler Error C2395
10/31/2018 • 2 minutes to read • Edit Online
'your_type::operator'op'' : CLR or WinRT operator not valid. At least one parameter must be of the following types:
'T', 'T%', 'T&', 'T^', 'T^%', 'T^&', where T = 'your_type'
An operator in a Windows Runtime or managed type did not have at least one parameter whose type is the same
as the type of the operator return value.
The following sample generates C2395 and shows how to fix it:
// C2395.cpp
// compile with: /clr /c
value struct V {
static V operator *(int i, char c); // C2395
// OK
static V operator *(V v, char c);
// or
static V operator *(int i, V& rv);
};
Compiler Error C2396
10/31/2018 • 2 minutes to read • Edit Online
'your_type::operator'type'' : CLR or WinRT user-defined conversion functionnot valid. Must either convert from or
convert to: 'T^', 'T^%', 'T^&', where T = 'your_type'
A conversion function in a Windows Runtime or managed type did not have at least one parameter whose type is
the same as the type containing the conversion function.
The following sample generates C2396 and shows how to fix it:
// C2396.cpp
// compile with: /clr /c
ref struct Y {
static operator int(char c); // C2396
// OK
static operator int(Y^ hY);
// or
static operator Y^(char c);
};
Compiler Error C2397
10/31/2018 • 2 minutes to read • Edit Online
struct S1 {
int m1;
double m2, m3;
};
std::vector<S1> vS1;
vS1.push_back({ d1, 2, 3 }); // error C2397
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2400 inline assembler syntax error in 'context'; found 'token'
Compiler Error C2429 'language feature' requires compiler flag 'compiler option'
Compiler Error C2435 'var': dynamic initialization requires managed CRT, cannot
compile with /clr:safe
Compiler Error C2438 'identifier': cannot initialize static class data via constructor
Compiler Error C2444 'identifier': used ANSI prototype, found 'type', expected '{' or ';'
Compiler Error C2447 '{': missing function header (old-style formal list?)
Compiler Error C2449 found '{' at file scope (missing function header?)
Compiler Error C2454 'identifier': namespace alias name cannot be declared using a
qualified name
ERROR MESSAGE
Compiler Error C2455 'class' a WinRT ref class that derives from an imported base
class cannot be abstract.
Compiler Error C2456 'class' an unsealed ref class cannot have a public visible
constructor. Seal the class, or specify constructor as 'internal',
'protected private' or 'private' instead.
Compiler Error C2470 'function': looks like a function definition, but there is no
parameter list; skipping apparent body
Compiler Error C2473 'identifier': looks like a function definition, but there is no
parameter list.
Compiler Error C2477 'member': static data member cannot be initialized via derived
class
ERROR MESSAGE
Compiler Error C2479 'identifier': 'allocate( )' is only valid for data items of static
extent
Compiler Error C2480 'identifier': 'thread' is only valid for data items of static extent
Compiler Error C2481 'identifier': thread_local is only valid on static members and
variables at namespace or block scope
Compiler Error C2482 'identifier': dynamic initialization of thread local data not
allowed in managed/WINRT code
Compiler Error C2486 '__LOCAL_SIZE' only allowed in function with the 'naked'
attribute
Compiler Error C2487 'identifier': member of dll interface class may not be declared
with dll interface
Compiler Error C2489 'identifier': initialized auto or register variable not allowed at
function scope in 'naked' function
Compiler Error C2490 'keyword' not allowed in function with 'naked' attribute
Compiler Error C2492 'variable': data with thread storage duration may not have dll
interface
Compiler Error C2494 'keyword' cannot be called from within a filter expression or
__finally/finally block
Compiler Error C2496 'identifier': 'selectany' can only be applied to data items with
external linkage
Compiler Error C2498 'function': 'novtable' can only be applied to class declarations
or definitions
Compiler Error C2499 'class': a class cannot be its own base class
Compiler Error C2400
10/31/2018 • 2 minutes to read • Edit Online
// C2400.cpp
// processor: x86
int main() {
__asm {
heh ax,bx; // C2400, heh is not a valid x86 instruction
mov ax,bx; // OK
}
}
Compiler Error C2401
10/31/2018 • 2 minutes to read • Edit Online
// C2422.cpp
// processor: x86
int main() {
_asm {
mov AX, [BX:ES] // C2422
mov AX, ES // OK
}
}
Compiler Error C2423
10/31/2018 • 2 minutes to read • Edit Online
// C2423.cpp
// processor: x86
int main() {
_asm {
lea EAX, [EAX*3] // C2423
lea EAX, [EAX+EAX*2] // OK
}
}
Compiler Error C2424
10/31/2018 • 2 minutes to read • Edit Online
// C2425.cpp
// processor: x86
int main() {
int i = 3;
__asm {
mov eax, [ebp - i] // C2425
mov eax, [ebp - 3] // OK
}
}
Compiler Error C2426
10/31/2018 • 2 minutes to read • Edit Online
// C2427.cpp
// compile with: /c
template <class T>
struct S {
struct Inner;
};
// OK
template<typename T>
struct S<T>::Inner {};
Compiler Error C2428
10/31/2018 • 2 minutes to read • Edit Online
// C2428.cpp
void g(bool fFlag) {
--fFlag; // C2428
fFlag--; // C2428
}
Compiler Error C2429
10/31/2018 • 2 minutes to read • Edit Online
// C2429a.cpp
namespace a::b { int i; } // C2429 starting in Visual C++ 2015 Update 3.
// Use /std:c++17 to fix, or do this:
// namespace a { namespace b { int i; }}
int main() {
a::b::i = 2;
}
Compiler Error C2430
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2430.
// C2430.cpp
// processor: x86
int main() {
_asm mov eax, [ebx*2+ecx*4] // C2430
}
Compiler Error C2431
10/31/2018 • 2 minutes to read • Edit Online
// C2431.cpp
// processor: x86
int main() {
_asm mov ax, [ESI + 2*ESP] // C2431
_asm mov ax, [esp + esp] // C2431
}
Compiler Error C2432
10/31/2018 • 2 minutes to read • Edit Online
// C2432.cpp
// processor: x86
int main() {
_asm mov eax, DWORD PTR [bx] // C2432
}
Compiler Error C2433
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2433.
// C2433.cpp
class C{};
int main() {
inline C c; // C2433
}
Compiler Error C2434
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : a symbol declared with __declspec(process) cannot be dynamically initialized in /clr:pure mode
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
It is not possible to dynamically initialize a per-process variable under /clr:pure. For more information, see /clr
(Common Language Runtime Compilation) and process.
Example
The following sample generates C2434. To fix this issue, use constants to initialize process variables.
// C2434.cpp
// compile with: /clr:pure /c
int f() { return 0; }
__declspec(process) int i = f(); // C2434
__declspec(process) int i2 = 0; // OK
Compiler Error C2435
10/31/2018 • 2 minutes to read • Edit Online
'var' : dynamic initialization requires managed CRT, cannot compile with /clr:safe
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
Initialization of global per-application domain variable requires the CRT compiled with /clr:pure , which does not
produce a verifiable image.
For more information, see appdomain and process.
Example
The following sample generates C2435:
// C2435.cpp
// compile with: /clr:safe /c
int globalvar = 0; // C2435
__declspec(process)
int globalvar2 = 0;
Compiler Error C2436
10/31/2018 • 2 minutes to read • Edit Online
// C2436.cpp
struct S{
int f();
struct Inner{
int i;
};
S():f(10), Inner(0){} // C2436
};
Compiler Error C2437
10/31/2018 • 2 minutes to read • Edit Online
// C2437.cpp
// compile with: /c
class A {
public:
A(int i) {}
};
class B : A {
B() : A(1), A(2) {} // C2437
B() : A(1) {} // OK
};
Compiler Error C2438
10/31/2018 • 2 minutes to read • Edit Online
// C2438.cpp
struct X {
X(int i) : j(i) {} // C2438
static int j;
};
int X::j;
int main() {
X::j = 1;
}
Compiler Error C2439
10/31/2018 • 2 minutes to read • Edit Online
Example
C2440 can be caused if you attempt to initialize a non-const char* (or wchar_t* ) by using a string literal in C++
code, when the compiler conformance option /Zc:strictStrings is set. In C, the type of a string literal is array of
char , but in C++, it is array of const char . This sample generates C2440:
// C2440s.cpp
// Build: cl /Zc:strictStrings /W3 C2440s.cpp
// When built, the compiler emits:
// error C2440: 'initializing' : cannot convert from 'const char [5]'
// to 'char *'
// Conversion from string literal loses const qualifier (see
// /Zc:strictStrings)
int main() {
char* s1 = "test"; // C2440
const char* s2 = "tests"; // OK
}
Example
C2440 can also be caused if you attempt to convert a pointer to member to void*. The next sample generates
C2440:
// C2440.cpp
class B {
public:
void f(){;}
void f3() {
f2(f);
}
};
Example
C2440 can also be caused if you attempt to cast from a type that is only forward declared but not defined. This
sample generates C2440:
// c2440a.cpp
struct Base { }; // Defined
Base * func(Derived * d) {
return static_cast<Base *>(d); // error C2440: 'static_cast' : cannot convert from 'Derived *' to 'Base *'
}
Example
The C2440 errors on lines 15 and 16 of the next sample are qualified with the
Incompatible calling conventions for UDT return value message. A UDT is a user -defined type, such as a class,
struct, or union. These kinds of incompatibility errors are caused when the calling convention of a UDT specified in
the return type of a forward declaration conflicts with the actual calling convention of the UDT and when a
function pointer is involved.
In the example, first there are forward declarations for a struct and for a function that returns the struct; the
compiler assumes that the struct uses the C++ calling convention. Next is the struct definition, which, by default,
uses the C calling convention. Because the compiler does not know the calling convention of the struct until it
finishes reading the entire struct, the calling convention for the struct in the return type of get_c2 is also assumed
to be C++.
The struct is followed by another function declaration that returns the struct, but at this point, the compiler knows
that the struct's calling convention is C++. Similarly, the function pointer, which returns the struct, is defined after
the struct definition so that the compiler knows that the struct uses the C++ calling convention.
To resolve C2440 that occurs because of incompatible calling conventions, declare functions that return a UDT
after the UDT definition.
// C2440b.cpp
struct MyStruct;
MyStruct get_c1();
struct MyStruct {
int i;
static MyStruct get_C2();
};
MyStruct get_C3();
class CMyClass {
public:
explicit CMyClass( int iBar)
throw() {
}
int main() {
CMyClass myclass = 2; // C2440
// try one of the following
// CMyClass myclass{2};
// CMyClass myclass(2);
int *i;
float j;
j = (float)i; // C2440, cannot cast from pointer to int to float
}
Example
C2440 can also occur if you assign zero to an interior pointer:
// C2440c.cpp
// compile with: /clr
int main() {
array<int>^ arr = gcnew array<int>(100);
interior_ptr<int> ipi = &arr[0];
ipi = 0; // C2440
ipi = nullptr; // OK
}
Example
C2440 can also occur for an incorrect use of a user-defined conversion. For example, when a conversion operator
has been defined as explicit , the compiler can't use it in an implicit conversion. For more information about
user-defined conversions, see User-Defined Conversions (C++/CLI)). This sample generates C2440:
// C2440d.cpp
// compile with: /clr
value struct MyDouble {
double d;
// convert MyDouble to Int32
static explicit operator System::Int32 ( MyDouble val ) {
return (int)val.d;
}
};
int main() {
MyDouble d;
int i;
i = d; // C2440
// Uncomment the following line to resolve.
// i = static_cast<int>(d);
}
Example
C2440 can also occur if you try to create an instance of a Visual C++ array whose type is a Array. For more
information, see Arrays. The next sample generates C2440:
// C2440e.cpp
// compile with: /clr
using namespace System;
int main() {
array<int>^ intArray = Array::CreateInstance(__typeof(int), 1); // C2440
// try the following line instead
// array<int>^ intArray = safe_cast<array<int> ^>(Array::CreateInstance(__typeof(int), 1));
}
Example
C2440 can also occur because of changes in the attributes feature. The following sample generates C2440.
// c2440f.cpp
// compile with: /LD
[ module(name="PropDemoLib", version=1.0) ]; // C2440
// try the following line instead
// [ module(name="PropDemoLib", version="1.0") ];
Example
The Visual C++ compiler no longer allows the const_cast Operator to down cast when source code that uses /clr
programming is compiled.
To resolve this C2440, use the correct cast operator. For more information, see Casting Operators.
This sample generates C2440:
// c2440g.cpp
// compile with: /clr
ref class Base {};
ref class Derived : public Base {};
int main() {
Derived ^d = gcnew Derived;
Base ^b = d;
d = const_cast<Derived^>(b); // C2440
d = dynamic_cast<Derived^>(b); // OK
}
Example
C2440 can occur because of conformance changes to the compiler in Visual Studio 2015 Update 3. Previously, the
compiler incorrectly treated certain distinct expressions as the same type when identifying a template match for a
static_cast operation. Now the compiler distinguishes the types correctly, and code that relied on the previous
static_cast behavior is broken. To fix this issue, change the template argument to match the template parameter
type, or use a reinterpret_cast or C -style cast.
This sample generates C2440:
// c2440h.cpp
template<int *a>
struct S1 {};
int g;
struct S2 : S1<&g> {
};
int main()
{
S2 s;
static_cast<S1<&*&g>>(s); // C2440 in VS 2015 Update 3
// This compiles correctly:
// static_cast<S1<&g>>(s);
}
This error can appear in ATL code that uses the SINK_ENTRY_INFO macro defined in <atlcom.h>.
Example
Copy-list-initialization
Visual Studio 2017 and later correctly raise compiler errors related to object creation using initializer lists that were
not caught in Visual Studio 2015 and could lead to crashes or undefined runtime behavior. In C++17 copy-list-
initialization, the compiler is required to consider an explicit constructor for overload resolution, but must raise an
error if that overload is actually chosen.
The following example compiles in Visual Studio 2015 but not in Visual Studio 2017.
// C2440j.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
const A& a2 = { 1 }; // error C2440: 'initializing': cannot
// convert from 'int' to 'const A &'
}
// C2440k.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
const A& a2{ 1 };
}
Example
cv-qualifiers in class construction
In Visual Studio 2015, the compiler sometimes incorrectly ignores the cv-qualifier when generating a class object
via a constructor call. This can potentially cause a crash or unexpected runtime behavior. The following example
compiles in Visual Studio 2015 but raises a compiler error in Visual Studio 2017 and later:
struct S
{
S(int);
operator int();
};
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
By default, variables are per application domain under /clr:pure. A variable marked __declspec(process) under
/clr:pure is prone to errors if modified in one application domain and read in another.
Therefore, the compiler enforces per process variables be const under /clr:pure, making them read only in all
application domains.
For more information, see process and /clr (Common Language Runtime Compilation).
Example
The following sample generates C2441.
// C2441.cpp
// compile with: /clr:pure /c
__declspec(process) int i; // C2441
__declspec(process) const int j = 0; // OK
Compiler Error C2443
10/31/2018 • 2 minutes to read • Edit Online
// C2443.cpp
// processor: x86
short var;
int main() {
__asm xchg ax,bl // C2443
__asm mov al,red // C2443
__asm mov al,BYTE PTR var // OK
}
Compiler Error C2444
10/31/2018 • 2 minutes to read • Edit Online
// C2447.cpp
int c;
{} // C2447
Compiler Error C2448
10/31/2018 • 2 minutes to read • Edit Online
// C2448.cpp
void func(c)
int c;
{} // C2448
Compiler Error C2449
10/31/2018 • 2 minutes to read • Edit Online
// C2449.c
// compile with: /c
void __stdcall func(void) {} // OK
void __stdcall func(void); // extra semicolon on this line
{ // C2449 detected here
Compiler Error C2450
10/31/2018 • 2 minutes to read • Edit Online
// C2450.cpp
class X {
public:
int i;
} x;
class Y {
public:
int i;
operator int() { return i; } // conversion operator
} y;
int main() {
int j = 1;
switch ( x ) { // C2450, x is not type int
// try the following line instead
// switch ( y ) {
default: ;
}
}
Compiler Error C2451
10/31/2018 • 2 minutes to read • Edit Online
// C2451.cpp
class B {};
int main () {
B b1;
int i = 0;
if (b1) // C2451
// try the following line instead
// if (i)
;
}
Compiler Error C2452
10/31/2018 • 2 minutes to read • Edit Online
// C2452.cpp
// compile with: /clr
struct A {};
struct B : public A {};
int main() {
A a;
safe_cast<B*>(&a); // C2452
// OK
C ^ c = gcnew C;
safe_cast<D^>(c);
}
Compiler Error C2457
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2457 and also shows correct usage:
// C2457.cpp
#include <stdio.h>
int main()
{
printf_s("\n%s", __FUNCTION__); // OK
}
Compiler Error C2458
10/31/2018 • 2 minutes to read • Edit Online
// C2458.cpp
class C {
enum i { C }; // C2458
};
Compiler Error C2459
10/31/2018 • 2 minutes to read • Edit Online
// C2459.cpp
// compile with: /c
class C {
union { int C; }; // C2459
union { int D; };
};
Compiler Error C2460
10/31/2018 • 2 minutes to read • Edit Online
// C2460.cpp
class C {
C aC; // C2460
};
// C2460.cpp
class C {
C * aC; // OK
};
Compiler Error C2461
10/31/2018 • 2 minutes to read • Edit Online
The constructor for the class does not specify any formal parameters. The declaration of a constructor must specify
a formal parameter list. The list can be empty.
To fix this issue, add a pair of parentheses after the declaration of class::*class.
Example
The following sample shows how to fix C2461:
// C2461.cpp
// compile with: /c
class C {
C::C; // C2461
C::C(); // OK
};
Compiler Error C2462
10/31/2018 • 2 minutes to read • Edit Online
// C2462.cpp
int main() {
new struct S { int i; }; // C2462
}
Compiler Error C2464
10/31/2018 • 2 minutes to read • Edit Online
// C2464.cpp
int main() {
new ( int& ir ); // C2464
}
Compiler Error C2465
10/31/2018 • 2 minutes to read • Edit Online
// C2466.cpp
// compile with: /c
int i[0]; // C2466
int j[1]; // OK
char *p;
Compiler Error C2467
10/31/2018 • 2 minutes to read • Edit Online
//C2467.c
// compile with: /Za
int main() {
struct X {
union { int i; }; // C2467, nested declaration
};
}
Compiler Error C2469
10/31/2018 • 2 minutes to read • Edit Online
// C2469.cpp
int main() {
int *i = new void; // C2469
int *i = new int; // OK
}
Compiler Error C2470
10/31/2018 • 2 minutes to read • Edit Online
'function' : looks like a function definition, but there is no parameter list; skipping apparent body
A function definition is missing its argument list.
The following sample generates C2470:
// C2470.cpp
int MyFunc {}; // C2470
void MyFunc2() {}; //OK
int main(){
MyFunc();
MyFunc2();
}
Compiler Error C2471
10/31/2018 • 2 minutes to read • Edit Online
'function' cannot be generated in managed code: 'message'; compile with /clr to generate a mixed image
Remarks
This error will occur when types not supported by managed code are used within a pure common language
runtime (CLR ) environment. Compile with /clr to resolve the error.
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
Example
The following sample generates C2472.
// C2472.cpp
// compile with: /clr:pure
// C2472 expected
#include <cstdlib>
int main()
{
int * __ptr32 p32;
int * __ptr64 p64;
See also
/clr (Common Language Runtime Compilation)
Compiler Error C2473
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2473.
// C2473.cpp
// compile with: /clr /c
class A {
int i {} // C2473
};
class B {
int i() {} // OK
};
Compiler Error C2474
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2474.
// C2474.cpp
// compile with: /clr /c
ref class A {
ref class B {}
property int i; // C2474 error
};
// OK
ref class B {
ref class D {};
property int i;
};
ref class E {
ref class F {} property;
int i;
};
Compiler Error C2477
10/31/2018 • 2 minutes to read • Edit Online
// C2477.cpp
// compile with: /Za /c
template <class T>
struct S {
static int n;
};
struct X {};
struct A: S<X> {};
template<>
int S<X>::n = 0;
Compiler Error C2479
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : 'allocate( )' is only valid for data items of static extent
The __declspec( allocate()) syntax can be used for static data only.
The following sample generates C2479:
// C2479.cpp
// compile with: /c
#pragma section("mycode", read)
static __declspec(allocate("mycode")) void DoNothing() {} // C2479
__declspec(allocate("mycode")) int i = 0; // OK
Compiler Error C2480
10/31/2018 • 2 minutes to read • Edit Online
// C2480.cpp
// compile with: /c
__declspec( thread ) void func(); // C2480
__declspec( thread ) static int i; // OK
Compiler Error C2482
10/31/2018 • 2 minutes to read • Edit Online
Remarks
In managed or WinRT code, variables declared by using the __declspec(thread) storage class modifier attribute or
the thread_local storage class specifier cannot be initialized with an expression that requires evaluation at run-time.
A static expression is required to initialize __declspec(thread) or thread_local data in these runtime
environments.
Example
The following sample generates C2482 in managed (/clr) and in WinRT (/ZW ) code:
// C2482.cpp
// For managed example, compile with: cl /EHsc /c /clr C2482.cpp
// For WinRT example, compile with: cl /EHsc /c /ZW C2482.cpp
#define Thread __declspec( thread )
Thread int tls_i1 = tls_i1; // C2482
To fix this issue, initialize thread-local storage by using a constant, constexpr, or static expression. Perform any
thread-specific initialization separately.
Compiler Error C2483
10/31/2018 • 2 minutes to read • Edit Online
This error message is obsolete in Visual Studio 2015 and later versions. In previous versions, variables declared
with the thread attribute cannot be initialized with a constructor or other expression that requires run-time
evaluation. A static expression is required to initialize thread data.
Example
The following sample generates C2483 in Visual Studio 2013 and earlier versions.
// C2483.cpp
// compile with: /c
__declspec(thread) struct A {
A(){}
~A(){}
} aa; // C2483 error
__declspec(thread) struct B {} b; // OK
See Also
thread
Compiler Error C2485
10/31/2018 • 2 minutes to read • Edit Online
// C2486.cpp
// processor: x86
void __declspec(naked) f1() {
__asm {
mov eax, __LOCAL_SIZE
}
}
void f2() {
__asm {
mov eax, __LOCAL_SIZE // C2486
}
}
Compiler Error C2487
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : member of dll interface class may not be declared with dll interface
You can declare a whole class, or certain members of a non-DLL interface class, with DLL interface. You cannot
declare a class with DLL interface and then declare a member of that class with DLL interface.
Compiler Error C2488
10/31/2018 • 2 minutes to read • Edit Online
// C2488.cpp
// compile with: /c
// processor: x86
__declspec( naked ) void func(); // C2488 declaration, not definition
__declspec( naked ) void i; // C2488 i is not a function
'identifier' : initialized auto or register variable not allowed at function scope in 'naked' function
For more information, see naked.
The following sample generates C2489:
// C2489.cpp
// processor: x86
__declspec( naked ) int func() {
int i = 1; // C2489
register int j = 1; // C2489
}
Compiler Error C2490
10/31/2018 • 2 minutes to read • Edit Online
// C2490.cpp
// processor: x86
__declspec( naked ) int func() {
__try{} // C2490, structured exception handling
}
Compiler Error C2491
10/31/2018 • 2 minutes to read • Edit Online
// C2491.cpp
// compile with: /c
// function definition
void __declspec(dllimport) funcB() {} // C2491
// function declaration
void __declspec(dllimport) funcB(); // OK
Compiler Error C2492
10/31/2018 • 2 minutes to read • Edit Online
'variable': data with thread storage duration may not have dll interface
The variable is declared with the thread attribute and with the DLL interface. The address of the thread variable is
not known until run time, so it cannot be linked to a DLL import or export.
The following sample generates C2492:
// C2492.cpp
// compile with: /c
class C {
public:
char ch;
};
// C2493.cpp
// compile with: /c
char mybase;
int __based(mybase) ptr; // C2493
// OK
char * mybase;
int __based(mybase) * ptr;
Compiler Error C2494
10/31/2018 • 2 minutes to read • Edit Online
// C2494.cpp
#include <malloc.h>
int main() {
__try {}
__except ( _alloca(100), 1 ) {} // C2494
__try {}
__finally {
_alloca(100); // C2494
}
}
// C2494b.cpp
// compile with: /clr
#include <malloc.h>
int main() {
char * buf;
try {}
catch (char * buf2) {}
finally {
_alloca(100); // C2494
}
}
Compiler Error C2495
10/31/2018 • 2 minutes to read • Edit Online
// C2495.cpp
// compile with: /c
__declspec(nothrow) class X { // C2495
int m_data;
} x;
'identifier' : 'selectany' can only be applied to data items with external linkage
The selectany attribute can be applied only to externally visible and global data items.
The following sample generates C2496:
// C2496.cpp
// compile with: /c
__declspec(selectany) int x1 = 1;
const __declspec(selectany) int x2 = 2; // C2496
static __declspec(selectany) int x6 = 6; // C2496
// dynamic initialization of x5
int f();
__declspec(selectany) int x5 = f();
Example
The following sample generates C2498:
// C2498.cpp
// compile with: /c
void __declspec(novtable) f() {} // C2498
class __declspec(novtable) A {}; // OK
Compiler Error C2499
10/31/2018 • 2 minutes to read • Edit Online
// C2499.cpp
// compile with: /c
class CMyClass : public CMyClass {}; // C2499
class CMyClass{}; // OK
Compiler Errors C2500 Through C2599
10/31/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2502 'identifier': too many access modifiers on the base class
Compiler Error C2503 'class': base classes cannot contain zero-sized arrays
Compiler Error C2507 'identifier': too many virtual modifiers on the base class
Compiler Error C2511 'identifier': overloaded member function not found in 'class'
Compiler Error C2515 'identifier': 'vtguard' can only be applied to class declarations
or definitions
Compiler Error C2518 keyword 'keyword' illegal in base class list; ignored
Compiler Error C2519 'identifier': WinRT attributes may only contain public fields
Compiler Error C2526 'identifier1': C linkage function cannot return C++ class
'identifier2'
ERROR MESSAGE
Compiler Error C2541 'identifier': cannot delete objects that are not pointers
Compiler Error C2542 'identifier': class object has no constructor for initialization
Compiler Error C2546 'identifier': when a type is defined in both a PIA and a no-PIA
the PIA must be referenced first
Compiler Error C2548 'function': missing default parameter for parameter parameter
Compiler Error C2550 'identifier': constructor initializer lists are only allowed on
constructor definitions
Compiler Error C2558 class 'class': no copy constructor available or copy constructor
is declared 'explicit'
Compiler Error C2559 'identifier': cannot overload a member function without ref-
qualifier with a member function with ref-qualifier
Compiler Error C2560 'identifier': cannot overload a member function with ref-
qualifier with a member function without ref-qualifier
Compiler Error C2573 'class': cannot delete pointers to objects of this type; the class
has no non-placement overload for 'operator delete'. Use
::delete, or add 'operator delete(void*)' to the class
Compiler Error C2575 'identifier': only member functions and bases can be virtual
Compiler Error C2576 'identifier': cannot introduce a new virtual method as 'public'.
Consider making the method non-virtual, or change the
accessibility to 'internal' or 'protected private'
Compiler Error C2578 'class': type cannot have a 'protected' or 'protected public'
constructor
Compiler Error C2579 unable to resolve type type (offset). It is expected in filename
Compiler Error C2584 'class': direct base 'base_class2' is inaccessible; already a base
of 'base_class1'
Compiler Error C2587 'identifier': illegal use of local variable as default parameter
Compiler Error C2591 ExclusiveTo cannot use 'type' as an argument. Only a 'ref class'
is a valid argument
Compiler Error C2592 'class': 'base_class2' is inherited from 'base_class1' and cannot
be re-specified
Compiler Error C2596 'identifier' A WinRT attribute field can only be a 'public enum
class', 'int', 'unsigned int', 'bool', 'Platform::Type',
'Platform::String' or 'Windows::Foundation::HResult'
// C2500.cpp
// compile with: /c
class A {};
class B : public A, public A {}; // C2500
// OK
class C : public A {};
class D : public A {};
class E : public C, public D {};
Compiler Error C2502
10/31/2018 • 2 minutes to read • Edit Online
// C2502.cpp
// compile with: /c
class A { };
class B { };
class C : private public A { }; // C2502
// OK
class D : private A {};
class E : public A, private B {};
Compiler Error C2503
10/31/2018 • 2 minutes to read • Edit Online
// C2503.cpp
// compile with: /c
class A {
public:
int array [];
};
class C {
public:
int array [10];
};
class D : C {};
Compiler Error C2504
10/31/2018 • 2 minutes to read • Edit Online
// C2504.cpp
// compile with: /c
class A;
class B : public A {}; // C2504
// OK
class C{};
class D : public C {};
Compiler Error C2505
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : '__declspec(modifer)' can only be applied to declarations or definitions of global objects or static data
members
A __declspec modifier that is designed to only be used at global scope was used in a function.
For more information, see appdomain and process.
The following sample generates C2505:
// C2505.cpp
// compile with: /clr
// OK
__declspec(process) int ii;
__declspec(appdomain) int jj;
int main() {
__declspec(process) int i; // C2505
__declspec(appdomain) int j; // C2505
}
Compiler Error C2506
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2506.
// C2506.cpp
// compile with: /clr /c
ref struct R {
__declspec(process) static int n; // C2506
int o; // OK
};
Compiler Error C2507
10/31/2018 • 2 minutes to read • Edit Online
// C2507.cpp
// compile with: /c
class A {};
class B : virtual virtual public A {}; // C2507
class C : virtual public A {}; // OK
Compiler Error C2509
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2509.
// C2509.cpp
// compile with: /c
struct A {
virtual int vfunc() = 0;
virtual int vfunc2() = 0;
};
struct B : private A {
using A::vfunc;
virtual int vfunc2();
};
// C2511.cpp
// compile with: /c
class C {
int c_2;
int Func(char *, char *);
};
A default constructor, a constructor that requires no arguments, is not available for the specified class, structure, or
union. The compiler supplies a default constructor only if no user-defined constructors are provided.
If you provide a constructor that takes a non-void parameter, and you want to allow your class to be created with
no parameters (for example, as the elements of an array), you must also provide a default constructor. The default
constructor can be a constructor with default values for all parameters.
Example
A common cause of error C2512 is when you define a class or struct constructor that takes arguments, and then
you attempt to declare an instance of your class or struct without any arguments. For example, struct B below
declares a constructor that requires a char * argument, but not one that takes no arguments. In main , an instance
of B is declared, but no argument is supplied. The compiler generates C2512 because it can't find a default
constructor for B.
// C2512.cpp
// Compile with: cl /W4 c2512.cpp
// C2512 expected
struct B {
B (char *) {}
// Uncomment the following line to fix.
// B() {}
};
int main() {
B b; // C2512 - This requires a default constructor
}
You can fix this issue by defining a default constructor for your struct or class, such as B() {} , or a constructor
where all the arguments have default values, such as B (char * = nullptr) {} .
Compiler Error C2513
10/31/2018 • 2 minutes to read • Edit Online
// C2513.cpp
int main() {
int = 9; // C2513
int i = 9; // OK
}
This error can also be generated as a result of a compiler conformance work done for Visual Studio .NET 2003:
initialization of a typedef no longer allowed. The initialization of a typedef is not allowed by the standard and now
generates a compiler error.
// C2513b.cpp
// compile with: /c
typedef struct S {
int m_i;
} S = { 1 }; // C2513
// try the following line instead
// } S;
An alternative would be to delete typedef to define a variable with aggregate initializer list, but this is not
recommended because it will create a variable with the same name as the type and hide the type name.
Compiler Error C2514
10/31/2018 • 2 minutes to read • Edit Online
// C2514.cpp
// compile with: /c
class f;
class g {
public:
g (int x);
};
class fmaker {
f *func1() {
return new f(2); // C2514
}
g *func2() {
return new g(2); // OK
}
};
Compiler Error C2516
10/31/2018 • 2 minutes to read • Edit Online
// C2516.cpp
typedef unsigned long ulong;
class C : public ulong {}; // C2516
Compiler Error C2517
10/31/2018 • 2 minutes to read • Edit Online
// C2518.cpp
// compile with: /c
class B {};
class C : public class B {}; // C2518
class D: public B {}; // OK
Compiler Error C2521
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2521.
// C2521.cpp
// compile with: /clr
ref class R {
protected:
!R() {}
public:
void CleanUp() {
this->!R(4); // C2521
this->!R(); // OK
}
};
int main() {
R^ r = gcnew R();
r->CleanUp();
}
Compiler Error C2523
10/31/2018 • 2 minutes to read • Edit Online
// C2523.cpp
// compile with: /c
class A {
~B(); // C2523
~A(); // OK
};
Compiler Error C2524
10/31/2018 • 2 minutes to read • Edit Online
Example
The following code reproduces C2524.
// C2524.cpp
// compile with: /c
class A {
A() {}
~A(int i) {} // C2524
// try the following line instead
// ~A() {}
};
Example
The following code reproduces C2524.
// C2524_b.cpp
// compile with: /clr /c
ref struct I1 {
protected:
!I1(int i); // C2524
// try the following line instead
// !I1();
};
Compiler Error C2526
10/31/2018 • 2 minutes to read • Edit Online
// C2528.cpp
int i;
int &ir = i;
int & (*irptr) = ir; // C2528
Compiler Error C2529
10/31/2018 • 2 minutes to read • Edit Online
// C2529.cpp
// compile with: /c
int i;
int &ri = i;
int &(&rri) = ri; // C2529
Compiler Error C2530
10/31/2018 • 2 minutes to read • Edit Online
// C2530.cpp
int main() {
int i = 0;
int &j; // C2530
int &k = i; // OK
}
Compiler Error C2531
10/31/2018 • 2 minutes to read • Edit Online
// C2531.cpp
// compile with: /c
class P {
int &b1 : 10; // C2531
int b2 : 10; // OK
};
Compiler Error C2532
10/31/2018 • 2 minutes to read • Edit Online
// C2533.cpp
// compile with: /c
class X {
public:
X();
};
// C2534.cpp
class A {
public:
int i;
A() { return i; } // C2534
};
Compiler Error C2535
10/31/2018 • 2 minutes to read • Edit Online
// C2535.cpp
// compile with: /c
class C {
public:
void func(); // forward declaration
void func() {} // C2535
};
Compiler Error C2537
10/31/2018 • 2 minutes to read • Edit Online
// C2537.cpp
// compile with: /c
extern "c" void func(); // C2537
extern "C" void func2(); // OK
Compiler Error C2540
10/31/2018 • 2 minutes to read • Edit Online
// C2540.cpp
void func(int n, int pC[]) {
int i = ((int [n])pC)[1]; // C2540
}
int main() {
int pC[100];
func(100, pC);
func2(100, pC);
}
Compiler Error C2541
10/31/2018 • 2 minutes to read • Edit Online
// C2541.cpp
int main() {
int i;
delete i; // C2541 i not a pointer
// OK
int *ip = new int;
delete ip;
}
Compiler Error C2542
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2548:
// C2548.cpp
// compile with: /c
void func( int = 1, int, int = 3); // C2548
// OK
void func2( int, int, int = 3);
void func3( int, int = 2, int = 3);
Compiler Error C2549
10/31/2018 • 2 minutes to read • Edit Online
// C2549.cpp
// compile with: /c
class X {
public:
int operator int() { return value; } // C2549
// C2550.cpp
// compile with: /c
class C {
public:
C();
};
class D : public C {
public:
D();
void func();
};
struct Pair_Incorrect {
private:
string m_name;
double m_val;
};
struct Pair_Correct1 {
public:
Pair_Correct1(string name, double val)
: m_name(name), m_val(val) {}
private:
string m_name;
double m_val;
};
struct Pair_Correct2 {
public:
string m_name;
double m_val;
};
int main() {
// To fix, add a constructor to this class and use it for
// initializing the data members, see Pair_Correct1 (below)
// or
// Do not have any private or protected non-static data members,
// see Pair_Correct2 (below). Pair_Correct2 is not recommended in
// case your object model requires some non-static data members to
// be private or protected
string name("John");
Pair_Incorrect pair1 = { name, 0.0 }; // C2552
// C2553.cpp
// compile with: /clr /c
ref struct C {
virtual void f();
};
ref struct D : C {
virtual int f() override ; // C2553
' class1::function1': overriding virtual function return type differs and is not covariant from 'class2::function2'
A virtual function and a derived overriding function have identical parameter lists but different return types. An
overriding function in a derived class cannot differ from a virtual function in a base class only by its return type.
To resolve this error, cast the return value after the virtual function has been called.
You may also see this error if you compile with /clr. For example, the Visual C++ equivalent to the following C#
declaration:
is
// C2555.cpp
// compile with: /c
struct X {
virtual void func();
};
struct Y : X {
char func(); // C2555
void func2(); // OK
};
Compiler Error C2556
10/31/2018 • 2 minutes to read • Edit Online
// C2556.cpp
// compile with: /c
class C {
int func();
double func(); // C2556
int func(int i); // ok parameter lists differ
};
Compiler Error C2557
10/31/2018 • 2 minutes to read • Edit Online
// C2561.cpp
int Test(int x) {
if (x) {
return; // C2561
// try the following line instead
// return 1;
}
return 0;
}
int main() {
Test(1);
}
Compiler Error C2562
10/31/2018 • 2 minutes to read • Edit Online
// C2562.cpp
// compile with: /c
void testfunc() {
int i;
return i; // C2562 delete the return to resolve
}
Compiler Error C2563
10/31/2018 • 2 minutes to read • Edit Online
// C2563.cpp
void func( int );
void func( int, int );
int main() {
void *fp();
fp = func; // C2563
}
Compiler Error C2566
10/31/2018 • 2 minutes to read • Edit Online
unable to open metadata in 'file', file may have been deleted or moved
A metadata file that was referenced in source (with #using ) was not found in the same directory by the compiler
back end process as it was by the compiler front end process. See #using Directive for more information.
C2567 could be caused if you compile with /c on one machine and then attempt a link-time code generation on
another machine. For more information, see /LTCG (Link-time Code Generation)).
It might also indicate that your computer had no more memory.
To correct this error, make sure that the metadata file is in the same directory location for all phases of the build
process.
Compiler Error C2568
10/31/2018 • 2 minutes to read • Edit Online
// C2569.cpp
// compile with: /c
union ubase {};
class cHasPubUBase : public ubase {}; // C2569
// OK
struct sbase {};
class cHasPubUBase : public sbase {};
Compiler Error C2570
10/31/2018 • 2 minutes to read • Edit Online
// C2570.cpp
// compile with: /c
class base {};
union hasPubBase : public base {}; // C2570
union hasNoBase {}; // OK
Compiler Error C2571
10/31/2018 • 2 minutes to read • Edit Online
// C2571.cpp
// compile with: /c
union A {
virtual void func1(); // C2571
void func2(); // OK
};
Compiler Error C2572
10/31/2018 • 2 minutes to read • Edit Online
// C2572.cpp
// compile with: /c
void f(int i = 1); // function declaration
// function definition
void f(int i = 1) {} // C2572
'class' : cannot delete pointers to objects of this type; the class has no non-placement overload for 'operator delete'.
The class is missing a non-placement delete operator.
Compiler Error C2574
10/31/2018 • 2 minutes to read • Edit Online
// C2574.cpp
// compile with: /c
class A {
virtual static ~A(); // C2574
// try the following line instead
// virtual ~A();
};
Compiler Error C2575
10/31/2018 • 2 minutes to read • Edit Online
// C2575.cpp
// compile with: /c
virtual void func() {} // C2575
void func2() {}
struct A {
virtual void func2(){}
};
Compiler Error C2577
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2577.
// C2577.cpp
// compile with: /c
class A {
public:
A() {}
~A(){
return 0; // C2577
}
};
Compiler Error C2579
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2581.
// C2581.cpp
// compile with: /clr /c
ref struct Y {
static Y ^ operator = (Y^ me, int i); // C2581
Y^ operator =(int i); // OK
};
Compiler Error C2582
10/31/2018 • 2 minutes to read • Edit Online
// C2582.cpp
// compile with: /clr
using namespace System;
struct N {};
ref struct O {};
ref struct R {
property O prop; // C2582
property O ^ prop2; // OK
};
int main() {
String ^ st1 = gcnew String("");
^st1 = gcnew String(""); // C2582
st1 = "xxx"; // OK
}
Compiler Error C2583
10/31/2018 • 2 minutes to read • Edit Online
// C2583.cpp
// compile with: /c
class A {
public:
int i;
A() const; // C2583
Example
The following sample generates C2584.
// C2584.cpp
// compile with: /c
struct A1 {
virtual int MyFunction();
};
struct A2 {
virtual int MyFunction();
};
// c2586.cpp
// compile with: /c
struct C {
* operator int(); // C2586
operator char(); // OK
};
Compiler Error C2587
10/31/2018 • 2 minutes to read • Edit Online
// C2587.cpp
// compile with: /c
int i;
void func() {
int j;
extern void func2( int k = j ); // C2587 -- local variable
extern void func3( int k = i ); // OK
}
Compiler Error C2588
10/31/2018 • 2 minutes to read • Edit Online
// C2588.cpp
~F(); // C2588
Compiler Error C2589
10/31/2018 • 2 minutes to read • Edit Online
// C2589.cpp
void Test(){}
class A {};
void operator :: (); // C2589
int main() {
::Test();
}
Compiler Error C2592
10/31/2018 • 2 minutes to read • Edit Online
// C2593.cpp
struct A {};
struct B : A {};
struct X {};
struct D : B, X {};
void operator+( X, X );
void operator+( A, B );
D d;
int main() {
d + d; // C2593, D has an A, B, and X
(X)d + (X)d; // OK, uses operator+( X, X )
}
This error can be caused by serializing a floating-point variable using a CArchive object. The compiler identifies
the << operator as ambiguous. The only primitive C++ types that CArchive can serialize are the fixed-size types
BYTE , WORD , DWORD , and LONG . All integer types must be cast to one of these types for serialization. Floating-point
types must be archived using the CArchive::Write() member function.
The following example shows how to archive a floating-point variable ( f ) to archive ar :
// C2594.cpp
// compile with: /c
struct A{};
struct I1 : A {};
struct I2 : A {};
struct D : I1, I2 {};
A *f (D *p) {
return (A*) (p); // C2594
// C2597.cpp
// compile with: /c
struct s1 {
static void func();
static void func2(s1&);
int i;
};
void s1::func() {
i = 1; // C2597 - static function can't access non-static data member
}
// C2598.cpp
// compile with: /c
void func() {
extern "C" int func2(); // C2598
}
// C2599.cpp
// compile with: /clr /c
enum class Status; // C2599
Status2 m_status2; // OK
};
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2603 'function': Too many block scope static objects with
constructor/destructors in function
Compiler Error C2604 'identifier': Cannot implement more than one interface
method
ERROR MESSAGE
Compiler Error C2610 'class::member': is not a special member function which can be
defaulted
Compiler Error C2614 'class': illegal member initialization: 'identifier' is not a base or
member
Compiler Error C2624 'scope::type': local classes cannot be used to declare 'extern'
variables
Compiler Error C2625 'identifier': illegal union member; type 'type' is reference type
Compiler Error C2627 'function': member function not allowed in anonymous union
Compiler Error C2628 'type1' followed by 'type2' is illegal (did you forget a ';'?)
Compiler Error C2633 'identifier': 'inline' is the only legal storage class for
constructors
Compiler Error C2645 no qualified name for pointer to member (found ':: *')
Compiler Error C2648 'identifier': use of member as default parameter requires static
member
Compiler Error C2651 'type': left of '::' must be a class, struct or union
Compiler Error C2652 'identifier': illegal copy constructor: first parameter must not
be a 'type'
Compiler Error C2657 'class::*' found at the start of a statement (did you forget to
specify a type?)
Compiler Error C2660 'function': function does not take number arguments
Compiler Error C2662 'function': cannot convert 'this' pointer from 'type1' to 'type2'
Compiler Error C2663 'function': number overloads have no legal conversion for 'this'
pointer
Compiler Error C2664 'function': cannot convert argument number from 'type1' to
'type2'
Compiler Error C2665 'function': none of the number overloads could convert all the
argument types
Compiler Error C2667 'function': none of number overloads have a best conversion
Compiler Error C2670 'function': the function template cannot convert parameter
number from type 'type'
Compiler Error C2671 'function': static member functions do not have 'this' pointers
ERROR MESSAGE
Compiler Error C2673 'function': global functions do not have 'this' pointers
Compiler Error C2675 unary 'operator': 'type' does not define this operator or a
conversion to a type acceptable to the predefined operator
Compiler Error C2676 binary 'operator': 'type' does not define this operator or a
conversion to a type acceptable to the predefined operator
Compiler Error C2677 binary 'operator': no global operator found which takes type
'type' (or there is no acceptable conversion)
Compiler Error C2678 binary 'operator': no operator found which takes a left-hand
operand of type 'type' (or there is no acceptable conversion)
Compiler Error C2679 binary 'operator': no operator found which takes a right-hand
operand of type 'type' (or there is no acceptable conversion)
Compiler Error C2682 cannot use 'cast' to convert from 'type1' to 'type2'
Compiler Error C2684 'declarator': deleted and defaulted functions are not
supported in managed/WinRT classes
Compiler Error C2685 'declarator': deleted and defaulted functions are not
supported with explicit restriction specifiers
Compiler Error C2686 cannot overload static and non-static member functions with
the same parameter types
Compiler Error C2689 'function': a friend function cannot be defined within a local
class
Compiler Error C2691 'type': a managed/WinRT array cannot have this element type
ERROR MESSAGE
Compiler Error C2698 the using-declaration for 'declaration1' cannot co-exist with
the existing using-declaration for 'declaration2'
Compiler Error C2600
10/31/2018 • 2 minutes to read • Edit Online
'function' : cannot define a compiler-generated special member function (must be declared in the class first)
Before member functions such as constructors or destructors can be defined for a class, they must be declared in
the class. The compiler can generate default constructors and destructors (called special member functions) if none
are declared in the class. However, if you define one of these functions without a matching declaration in the class,
the compiler detects a conflict.
To fix this error, in the class declaration, declare each member function that you define outside the class declaration.
The following sample generates C2600:
// C2600.cpp
// compile with: /c
class C {};
C::~C() {} // C2600
class D {
D::~D();
};
D::~D() {}
Compiler Error C2601
10/31/2018 • 2 minutes to read • Edit Online
// C2601.cpp
int main() {
int i = 0;
// C2602.cpp
// compile with: /c
struct X {
int x;
};
struct A {
int a;
};
struct B : public A {
X::x; // C2602 B is not derived from X
A::a; // OK
};
Compiler Error C2603
10/31/2018 • 2 minutes to read • Edit Online
'function' : Too many block scope static objects with constructor/destructors in function
In versions of the Visual C++ compiler before Visual Studio 2015, or when the /Zc:threadSafeInit- compiler option
is specified, there is a limit of 31 on the number of static objects you can have in an externally visible inline
function.
To resolve this issue, we recommend you adopt more recent version of the Visual C++ compiler toolset, or if
possible, remove the /Zc:threadSafeInit- compiler option. If this is not possible, consider combining your static
objects. If the objects are of the same type, consider use of a single static array of that type, and reference
individual members as required.
Example
The following code generates C2603 and shows one way to fix it:
// C2603.cpp
// Compile by using: cl /W4 /c /Zc:threadSafeInit- C2603.cpp
struct C { C() {} };
extern inline void f1() {
static C C01, C02, C03, C04, C05, C06, C07, C08, C09, C10;
static C C11, C12, C13, C14, C15, C16, C17, C18, C19, C20;
static C C21, C22, C23, C24, C25, C26, C27, C28, C29, C30, C31;
static C C32; // C2603 Comment this line out to avoid error
}
Compiler Error C2605
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2605.
// C2605.cpp
// compile with: /clr /c
ref class R {
protected:
void Finalize() {} // C2605
};
Compiler Error C2611
10/31/2018 • 2 minutes to read • Edit Online
// C2611.cpp
// compile with: /c
class C {
C::~operator int(); // C2611
~C(); // OK
};
Compiler Error C2612
10/31/2018 • 2 minutes to read • Edit Online
// C2612.cpp
class A {
public:
int i;
A( int ia ) : i( ia ) + {}; // C2612
};
Compiler Error C2613
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2614.
// C2614.cpp
// compile with: /c
struct A {
int i;
A( int ia ) : B( i ) {}; // C2614 B is not a member of A
};
struct A2 {
int B;
int i;
A2( int ia ) : B( i ) {}; // OK
};
Compiler Error C2616
10/31/2018 • 2 minutes to read • Edit Online
'conversion' : cannot implicitly convert a non-lvalue 'type1' to a 'type2' that is not const
A reference cannot be initialized from a non-lvalue.
This is an error under ANSI compatibility (/Za) and a warning under Microsoft extensions (/Ze).
Compiler Error C2617
10/31/2018 • 2 minutes to read • Edit Online
// C2617.cpp
int i;
func() { // no return type prototype
if( i ) return; // no return value
else return( 1 ); // C2617 detected on this line
}
Possible resolution:
// C2617b.cpp
// compile with: /c
int i;
int MyF() {
if (i)
return 0;
else
return (1);
}
Compiler Error C2619
10/31/2018 • 2 minutes to read • Edit Online
// C2619.cpp
int main() {
union { static int j; }; // C2619
union { int j; }; // OK
}
Compiler Error C2624
10/31/2018 • 2 minutes to read • Edit Online
// C2624.cpp
int main() {
struct C {};
extern C ac; // C2624
}
Compiler Error C2626
10/31/2018 • 2 minutes to read • Edit Online
'identifier': a private or protected data member is not allowed in an anonymous struct or union
A member of an anonymous struct or union must have public access.
The following sample generates C2626:
// C2626.cpp
int main() {
union {
protected:
int j; // C2626, j is protected
private:
int k; // C2626, k is private
};
}
// C2626b.cpp
int main() {
union {
public:
int i; // OK, i is public
};
}
Compiler Error C2627
10/31/2018 • 2 minutes to read • Edit Online
// C2627.cpp
int main() {
union { void f(){} }; // C2627
union X { void f(){} };
}
Compiler Error C2628
10/31/2018 • 2 minutes to read • Edit Online
// C2628.cpp
class CMyClass {}
int main(){} // C2628 error
Possible resolution:
// C2628b.cpp
class CMyClass {};
int main(){}
Compiler Error C2630
10/31/2018 • 2 minutes to read • Edit Online
// C2630.cpp
// compile with: /c
struct D {
D(int);
};
struct E {
E(int);
};
// C2632.cpp
int float i; // C2632
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003. bool is now a proper type. In previous versions, bool was a typedef, and you could create identifiers with
that name.
The following sample generates C2632:
// C2632_2.cpp
// compile with: /LD
void f(int bool); // C2632
To resolve this error so that the code is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions
of Visual C++, rename the identifier.
Compiler Error C2633
10/31/2018 • 2 minutes to read • Edit Online
// C2633.cpp
// compile with: /c
class C {
extern C(); // C2633, not inline
inline C(); // OK
};
Compiler Error C2634
10/31/2018 • 2 minutes to read • Edit Online
// C2634.cpp
int mem;
struct S {
S() : rf(mem) { }
int &rf;
};
int (S::*pdm) = &S::rf; // C2634
Compiler Error C2635
10/31/2018 • 2 minutes to read • Edit Online
cannot convert an 'identifier1*' to an 'identifier2*'; conversion from a virtual base class is implied
The conversion requires a cast from a virtual base class to a derived class, which is not allowed.
The following sample generates C2635:
// C2635.cpp
class B {};
class D : virtual public B {};
class E : public B {};
int main() {
B b;
D d;
E e;
D * pD = &d;
E * pE = &e;
pD = (D*)&b; // C2635
pE = (E*)&b; // OK
}
Compiler Error C2636
10/31/2018 • 2 minutes to read • Edit Online
// C2636.cpp
struct S {};
int main() {
int &S::*prs; // C2636
int S::*prs1; // OK
int *S::*prs2; // OK
}
Compiler Error C2637
10/31/2018 • 2 minutes to read • Edit Online
// C2637.cpp
// compile with: /c
struct S {};
int __stdcall S::*pms1; // C2637
// OK
int S::*pms2;
int (__stdcall S::*pms3)(...);
Compiler Error C2638
10/31/2018 • 2 minutes to read • Edit Online
// C2638.cpp
void *a;
class C {
public:
int i;
int j;
int func();
};
int __based (a) C::* cpi = &C::i; // C2638
int (__based (a) C::* cpf)() = &C::func; // c2638
Compiler Error C2640
10/31/2018 • 2 minutes to read • Edit Online
// C2640.cpp
void f(int i) {
void *vp;
int _based(vp) &vr = I; // C2640
}
Compiler Error C2645
10/31/2018 • 2 minutes to read • Edit Online
// C2645.cpp
class A {};
int main() {
int B::* bp; // C2645 B not defined
int A::* ap; // OK
}
Compiler Error C2646
10/31/2018 • 2 minutes to read • Edit Online
// C2646.cpp
// compile with: /c
union { int i; }; // C2646 not static
// OK
static union { int j; };
union U { int i; };
Compiler Error C2647
10/31/2018 • 2 minutes to read • Edit Online
// C2647.cpp
class C {};
class D {};
int main() {
D d, *pd;
C c, *pc = 0;
int C::*pmc = 0;
pd->*pmc = 0; // C2647
d.*pmc = 0; // C2647
// OK
pc->*pmc = 0;
c.*pmc = 0;
}
Compiler Error C2648
10/31/2018 • 2 minutes to read • Edit Online
// C2648.cpp
// compile with: /c
class C {
public:
int i;
static int j;
void func1( int i = i ); // C2648 i is not static
void func2( int i = j ); // OK
};
Compiler Error C2649
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2650:
// C2650.cpp
// compile with: /c
class A {
virtual void* operator new( unsigned int ); // C2650
// try the following line instead
// void* operator new( unsigned int );
};
Compiler Error C2651
10/31/2018 • 2 minutes to read • Edit Online
// C2652.cpp
// compile with: /c
class A {
A( A ); // C2652 takes an A
};
class B {
B( B& ); // OK, reference to B
};
Compiler Error C2653
10/31/2018 • 2 minutes to read • Edit Online
The language syntax requires a class, structure, union, or namespace name here.
This error can occur when you use a name that has not been declared as a class, structure, union, or namespace in
front of a scope operator. To fix this issue, declare the name or include the header that declares the name before it
is used.
C2653 is also possible if you try to define a compound namespace, a namespace that contains one or more scope-
nested namespace names. Compound namespace definitions are not allowed in C++ prior to C++17. Compound
namespaces are supported starting in Visual Studio 2015 Update 3 when you specify the /std:c++latest compiler
option. Starting in Visual C++ 2017 version 15.5, the compiler supports compound namespace definitions when
the /std:c++17 option is specified.
Examples
This sample generates C2653 because a scope name is used but not declared. The compiler expects a class,
structure, union, or namespace name before a scope operator (::).
// C2653.cpp
// compile with: /c
class yy {
void func1(int i);
};
In code that is not compiled for C++17 or later standards, nested namespaces must use an explicit namespace
declaration at each nesting level:
// C2653b.cpp
namespace a::b {int i;} // C2653 prior to Visual C++ 2015 Update 3,
// C2429 thereafter. Use /std:c++17 or /std:c++latest to fix.
namespace a { // Use this form for compliant code under /std:c++14 (the default)
namespace b { // or when using compilers before Visual Studio 2015 update 3.
int i;
}
}
int main() {
a::b::i = 2;
}
Compiler Error C2654
10/31/2018 • 2 minutes to read • Edit Online
// C2655.cpp
class A {};
class B {
public:
static int i;
};
int B::i; // OK
int main() {
A B::i; // C2655
}
Compiler Error C2656
10/31/2018 • 2 minutes to read • Edit Online
'class::*' found at the start of a statement (did you forget to specify a type?)
The line began with a pointer-to-member identifier.
This error can be caused by a missing type specifier in the declaration of a pointer to a member.
The following sample generates C2657:
// C2657.cpp
class C {};
int main() {
C::* pmc1; // C2657
int C::* pmc2; // OK
}
Compiler Error C2658
10/31/2018 • 2 minutes to read • Edit Online
// C2658.cpp
// compile with: /c
struct X {
union { // can be struct too
int i;
};
union {
int i; // Under /Za, C2658
// int i not needed here because it is defined in the first union
};
};
struct Z {
union {
char *i;
};
union {
void *i; // C2658 redefinition of 'i'
// try the following line instead
// void *ii;
};
};
Compiler Error C2659
10/31/2018 • 2 minutes to read • Edit Online
// C2659a.cpp
// Compile using: cl /W4 /EHsc C2659a.cpp
#include <string>
using namespace std;
int main()
{
string string1(); // string1 is a function returning string
string string2{}; // string2 is a string initialized to empty
To resolve this issue, change the declaration of the identifier so that it is not parsed as a function declaration.
Error C2659 can also occur when the function has a type that can’t be used in the expression on the left side of the
specified operator. This example generates C2659 when the code assigns a function pointer to a function:
// C2659b.cpp
// Compile using: cl /W4 /EHsc C2659b.cpp
int func0(void) { return 42; }
int (*func1)(void);
int main()
{
func1 = func0;
func0 = func1; // C2659
}
Compiler Error C2660
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2660.
// C2660.cpp
void func( int, int ) {}
int main() {
func( 1 ); // C2660 func( int ) not declared
func( 1, 0 ); // OK
}
Example
C2660 can also occur if you attempt to directly call the Dispose method of a managed type. For more information,
see Destructors and finalizers. The following sample generates C2660.
// C2660_a.cpp
// compile with: /clr
using namespace System;
using namespace System::Threading;
int main() {
ManualResetEvent^ event = gcnew ManualResetEvent( false );
TimerCallback^ timerDelegate = gcnew TimerCallback( &CheckStatus );
Timer^ stateTimer = gcnew Timer( timerDelegate, event, 1000, 250 );
stateTimer->Dispose(); // C2660
stateTimer->~Timer(); // OK
}
Example
C2660 will occur if a derived class hides a function.
// C2660b.cpp
// C2660 expected
#include <stdio.h>
class f {
public:
void bar() {
printf_s("in f::bar\n");
}
};
class f2 : public f {
public:
void bar(int i){printf("in f2::bar\n");}
// Uncomment the following line to resolve.
// using f::bar; // - using declaration added
// or
// void bar(){__super::bar();}
};
int main() {
f2 fObject;
fObject.bar();
}
Example
C2660 can occur if you invoke an indexed property incorrectly.
// C2660c.cpp
// compile with: /clr
ref class X {
double d;
public:
X() : d(1.9) {}
property double MyProp[] {
double get(int i) {
return d;
}
} // end MyProp definition
};
int main() {
X ^ MyX = gcnew X();
System::Console::WriteLine(MyX->MyProp(1)); // C2660
System::Console::WriteLine(MyX->MyProp[1]); // OK
}
Example
C2660 can occur if you invoke an indexed property incorrectly.
// C2660d.cpp
// compile with: /clr
ref class A{
public:
property int default[int,int] {
int get(int a, int b) {
return a + b;
}
}
};
int main() {
A^ a = gcnew A;
int x = a[3][5]; // C2660
int x2 = a[3,5]; // OK
}
Example
C2660 can occur if you define a new operator in a template class, but where the new operator creates an object
whose type is other than the enclosing type.
// C2660e.cpp
// compile with: /c
#include <malloc.h>
public:
CA () { new (1) T(); } // C2660
// try the following line instead
// CA () { new (1) CA<int>(); }
};
void AAA() {
int_CA list;
}
Compiler Error C2661
10/31/2018 • 2 minutes to read • Edit Online
// C2661.cpp
void func( int ){}
void func( int, int ){}
int main() {
func( ); // C2661 func( void ) was not declared
func( 1 ); // OK func( int ) was declared
}
Compiler Error C2662
10/31/2018 • 2 minutes to read • Edit Online
// C2662.cpp
class C {
public:
void func1();
void func2() const{}
} const c;
int main() {
c.func1(); // C2662
c.func2(); // OK
}
When compiling with /clr, you cannot call a function on a const or volatile qualified managed type. You cannot
declare a const member function of a managed class, so you cannot call methods on const managed objects.
// C2662_b.cpp
// compile with: /c /clr
ref struct M {
property M^ Type {
M^ get() { return this; }
}
ref struct N {
property N^ Type {
N^ get() { return this; }
}
void operator=(N % n) {
N ^ prop = n.Type; // OK
}
};
class LXBASE {
protected:
BYTE *m_rgb;
};
class LXISXVD:LXBASE {
public:
// Delete the following line to resolve.
ISXVD *PMin() { return (ISXVD *)m_rgb; }
isxvd = plxisxvd->PMin2()[iDim];
}
Compiler Error C2663
10/31/2018 • 2 minutes to read • Edit Online
// C2663.cpp
struct C {
void f() volatile {}
void f() {}
};
struct D {
void f() volatile;
void f() const {}
};
const C *pcc;
const D *pcd;
int main() {
pcc->f(); // C2663
pcd->f(); // OK
}
Compiler Error C2664
10/31/2018 • 4 minutes to read • Edit Online
Example
The following sample generates C2664 and shows how to fix it.
// C2664.cpp
// C2664
struct A {
void f(int i) {};
};
struct B : public A {
// To fix, uncomment the following line.
// using A::f;
void f(A a) {};
};
int main() {
B b;
int i = 1;
b.f(i); // B::F hides A::f Uncomment the using declaration in B.
}
Example
This sample also generates C2664 and shows how to fix it.
// C2664b.cpp
// C2664 expected
struct A {
// To fix, uncomment the following line.
// A(int i){}
};
int main() {
func( 1, 1 ); // No conversion from int to A.
}
Example
The next sample demonstrates C2664 by using a string literal to call Test , and shows how to fix it. Because the
parameter is an szString reference, an object must be created by the appropriate constructor. The result is a
temporary object that cannot be used to initialize the reference.
// C2664c.cpp
// compile with: /EHsc
// C2664 expected
#include <iostream>
#include <string.h>
using namespace std;
class szString {
int slen;
char *str;
public:
szString(const char *);
int len() const {
return slen;
}
};
int main() {
Test("hello");
}
Example
The compiler enforces the C++ standard requirements for applying const . This sample generates C2664:
// C2664d.cpp
// C2664 expected
#include <windows.h>
int main()
{
return 0;
}
Example
Here's a more complex situation where C2664 is generated, including directions on how to fix it:
// C2664e.cpp
// compile with: /EHsc
// C2664 expected
#define _INTL
#include <locale>
#include <iostream>
int main( ) {
char* pszExt = "This is the string to be converted!";
wchar_t pwszInt [LEN+1];
memset(&pwszInt[0], 0, (sizeof(wchar_t))*(LEN+1));
wchar_t* pwszNext;
mbstate_t state;
locale loc("C");
int res = use_facet<codecvt<wchar_t, char, mbstate_t> >
( loc ).in( state,
pszExt, &pszExt[strlen(pszExt)], pszNext,
pwszInt, &pwszInt[strlen(pszExt)], pwszNext );
// See earlier comment.
pwszInt[strlen(pszExt)] = 0;
wcout << ( (res!=codecvt_base::error) ?
L"It worked! " : L"It didn't work! " )
<< L"The converted string is:\n ["
<< &pwszInt[0]
<< L"]" << endl;
exit(-1);
}
Example
An enum variable is not converted to its underlying type such that a function call will be satisfied. For more
information, see enum class. The following sample generates C2664 and shows how to fix it.
// C2664f.cpp
// compile with: /clr
using namespace System;
public enum class A : Char {
None = 0,
NonSilent = 1,
};
void Test(Char c) {}
int main() {
A aa = A::None;
Test(aa); // C2664
Test(Char(aa)); // OK - fix by using a conversion cast
}
Example
A bug in the midl compiler causes a wchar_t type to be emitted as an unsigned short in the type library. To resolve
this error, either cast the type in your C++ source code or define the type as a string in the idl file.
// C2664g.idl
import "prsht.idl";
[ object, uuid(8402B8F1-BF7F-4B49-92D4-C2B9DF4543E9) ]
[ uuid(44463307-CBFC-47A6-8B4F-13CD0A83B436) ]
library myproj1 {
[ version(1.0), uuid(D8622C12-5448-42B8-8F0E-E3AD6B8470C1) ]
coclass CMyObj1 { interface IMyObj1; };
}
C2664 is also raised by using wchar_t when porting code from Visual C++ 6.0 to later versions. In Visual C++
6.0 and earlier, wchar_t was a typedef for unsigned short and was therefore implicitly convertible to that type.
After Visual C++ 6.0, wchar_t is its own built-in type, as specified in the C++ standard, and is no longer implicitly
convertible to unsigned short . See /Zc:wchar_t (wchar_t Is Native Type).
Example
The following sample generates C2664 and shows how to fix it.
// C2664h.cpp
#import "C2664g.tlb"
using namespace myproj1;
int main() {
IMyObj1Ptr ptr;
wchar_t * mybuff = 0;
BSTR bstr = 0;
int len;
ptr->teststr(mybuff);
ptr->testbstr(bstr);
ptr->testarr(mybuff, len); // C2664
ptr->testarr((unsigned short *)mybuff, len); // OK - Fix by using a cast
}
Example
C2664 is also caused if the compiler cannot deduce template arguments.
// C2664i.cpp
#include <stdio.h>
template <class T, int iType=0>
class CTypedImg {
public:
CTypedImg() {}
void run() {}
operator CTypedImg<T>& () {
return *((CTypedImg<T>*)this);
}
};
int main() {
CTypedImg<float,2> img;
test((CTypedImg<float>&)img); // OK
test<float>(img); // OK
test(img); // C2664 - qualify as above to fix
}
Compiler Error C2665
10/31/2018 • 2 minutes to read • Edit Online
'function' : none of the number1 overloads can convert parameter number2 from type 'type'
A parameter of the overloaded function cannot be converted to the required type. Possible resolutions:
Supply a conversion operator.
Use explicit conversion.
Example
The following sample generates C2665.
// C2665.cpp
void func(short, char*){}
void func(char*, char*){}
int main() {
func(0, 1); // C2665
func((short)0, (char*)1); // OK
}
Compiler Error C2666
10/31/2018 • 2 minutes to read • Edit Online
// C2666.cpp
struct complex {
complex(double);
};
void h(int,complex);
void h(double, double);
int main() {
h(3,4); // C2666
}
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003:
binary operators and user-defined conversions to pointer types
qualification conversion is not the same as identity conversion
For the binary operators <, >, <=, and >=, a passed parameter is now implicitly converted to the type of the
operand if the parameter's type defines a user-defined conversion operator to convert to the type of the operand.
There is now potential for ambiguity.
For code that is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, call the
class operator explicitly using function syntax.
Example
// C2666b.cpp
#include <string.h>
#include <stdio.h>
struct T
{
T( const T& copy )
{
m_str = copy.m_str;
}
char* m_str;
};
int main()
{
T str1( "ABCD" );
const char* str2 = "DEFG";
Example
The following sample generates C2666
// C2666c.cpp
// compile with: /c
enum E
{
E_A, E_B
};
class A
{
int h(const E e) const {return 0; }
int h(const int i) { return 1; }
// Uncomment the following line to resolve.
// int h(const E e) { return 0; }
void Test()
{
h(E_A); // C2666
h((const int) E_A);
h((int) E_A);
}
};
Compiler Error C2667
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2668:
// C2668.cpp
struct A {};
struct B : A {};
struct X {};
struct D : B, X {};
Example
Another way to resolve this error is with a using declaration:
// C2668b.cpp
// compile with: /EHsc /c
// C2668 expected
#include <iostream>
class TypeA {
public:
TypeA(int value) {}
};
class TypeB {
TypeB(int intValue);
TypeB(double dbValue);
};
class TestCase {
public:
void AssertEqual(long expected, long actual, std::string
conditionExpression = "");
};
Example
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003: ambiguous conversion on cast of constant 0.
Conversion on a cast using constant 0 is ambiguous since int requires a conversion both to long and to void*. To
resolve this error, cast 0 to the exact type of the function parameter it is being used for so that no conversions need
to take place (this code will be valid in the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual
C++).
// C2668c.cpp
#include "stdio.h"
void f(long) {
printf_s("in f(long)\n");
}
void f(void*) {
printf_s("in f(void*)\n");
}
int main() {
f((int)0); // C2668
// OK
f((long)0);
f((void*)0);
}
Example
This error can occur because the CRT now has float and double forms of all math functions.
// C2668d.cpp
#include <math.h>
int main() {
int i = 0;
float f;
f = cos(i); // C2668
f = cos((float)i); // OK
}
Example
This error can occur because the pow (int, int) was removed from math.h in the CRT.
// C2668e.cpp
#include <math.h>
int main() {
pow(9,9); // C2668
pow((double)9,9); // OK
}
Example
This code succeeds in Visual Studio 2015 but fails in Visual Studio 2017 and later with C2668. In Visual Studio
2015, the compiler erroneously treated copy-list-initialization in the same way as regular copy-initialization; it
considered only converting constructors for overload resolution.
struct A {
explicit A(int) {}
};
struct B {
B(int) {}
};
int main()
{
f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
}
Compiler Error C2669
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2669:
// C2669.cpp
struct X {
union {
int i;
void f() { // C2669, remove function
i = 0;
}
};
};
Compiler Error C2670
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : the function template cannot convert parameter number from type 'type'
A parameter could not be converted to the required type.
This error may be fixed if you create an explicit conversion.
Compiler Error C2671
10/31/2018 • 2 minutes to read • Edit Online
// C2671.cpp
struct S {
static S* const func() { return this; } // C2671
};
Compiler Error C2672
10/31/2018 • 2 minutes to read • Edit Online
The compiler could not find an overloaded function that matches the specified function. No function was found
that takes matching parameters, or no matching function has the required accessibility in context.
When used by certain standard library containers or algorithms, your types must provide accessible members or
friend functions that satisfy the requirements of the container or algorithm. For example, your iterator types should
derive from std::iterator<> . Comparison operations or use of other operators on container element types may
require the type be considered as both a left-hand and a right-hand operand. Use of the type as a right-hand
operand can require implementation of the operator as a non-member function of the type.
Example
Versions of the compiler before Visual Studio 2017 did not perform access checking on qualified names in some
template contexts. This can interfere with expected SFINAE behavior where the substitution is expected to fail due
to the inaccessibility of a name. This could have potentially caused a crash or unexpected behavior at runtime due
to the compiler incorrectly calling the wrong overload of the operator. In Visual Studio 2017, a compiler error is
raised.
This example compiles in Visual Studio 2015 but raises an error in Visual Studio 2017. To fix this issue, make the
template parameter member accessible where it is evaluated.
#include <type_traits>
int main()
{
f(10); // C2672: No matching overloaded function found.
}
Compiler Error C2673
10/31/2018 • 2 minutes to read • Edit Online
// C2673.cpp
int main() {
this = 0; // C2673
}
Compiler Error C2674
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2674.
// C2674.cpp
// compile with: /clr /c
void F(generic <class T> ref class R1); // C2674
generic <class T> ref class R2 {}; // OK
Compiler Error C2675
10/31/2018 • 2 minutes to read • Edit Online
unary 'operator' : 'type' does not define this operator or a conversion to a type acceptable to the predefined
operator
C2675 can also occur when using a unary operator, and the type does not define the operator or a conversion to a
type acceptable to the predefined operator. To use the operator, you must overload it for the specified type or
define a conversion to a type for which the operator is defined.
Example
The following sample generates C2675.
// C2675.cpp
struct C {
C(){}
} c;
struct D {
D(){}
void operator-(){}
} d;
int main() {
-c; // C2675
-d; // OK
}
Compiler Error C2676
10/31/2018 • 2 minutes to read • Edit Online
binary 'operator' : 'type' does not define this operator or a conversion to a type acceptable to the predefined
operator
To use the operator, you must overload it for the specified type or define a conversion to a type for which the
operator is defined.
Example
The following sample generates C2676.
// C2676.cpp
// C2676 expected
struct C {
C();
} c;
struct D {
D();
D operator >>( C& ){return * new D;}
D operator <<( C& ){return * new D;}
} d;
struct E {
// operator int();
};
int main() {
d >> c;
d << c;
E e1, e2;
e1 == e2; // uncomment operator int in class E, then
// it is OK even though neither E::operator==(E) nor
// operator==(E, E) defined. Uses the conversion to int
// and then the builtin-operator==(int, int)
}
Example
C2676 can also occur if you attempt to do pointer arithmetic on the this pointer of a reference type.
The this pointer is of type handle in a reference type. For more information, see Semantics of the this pointer.
The following sample generates C2676.
// C2676_a.cpp
// compile with: /clr
using namespace System;
ref struct A {
property Double default[Double] {
Double get(Double data) {
return data*data;
}
}
A() {
Console::WriteLine("{0}", this + 3.3); // C2676
Console::WriteLine("{0}", this[3.3]); // OK
}
};
int main() {
A ^ mya = gcnew A();
}
Compiler Error C2677
10/31/2018 • 2 minutes to read • Edit Online
binary 'operator' : no global operator found which takes type 'type' (or there is no acceptable conversion)
To use the operator, you must overload it for the specified type or define a conversion to a type for which the
operator is defined.
The following sample generates C2677:
// C2677.cpp
class C {
public:
C(){}
} c;
class D {
public:
D(){}
operator int(){return 0;}
} d;
int main() {
int i = 1 >> c; // C2677
int j = 1 >> d; // OK operator int() defined
}
Compiler Error C2678
10/31/2018 • 2 minutes to read • Edit Online
binary 'operator' : no operator defined which takes a left-hand operand of type 'type' (or there is no acceptable
conversion)
To use the operator, you must overload it for the specified type or define a conversion to a type for which the
operator is defined.
Example
C2678 can occur when the left-hand operand is const-qualified but the operator is defined to take a non-const
argument.
The following sample generates C2678 and shows how to fix it:
// C2678a.cpp
// Compile by using: cl /EHsc /W4 C2678a.cpp
struct Combo {
int number;
char letter;
};
int main() {
Combo const combo1{ 42, 'X' };
Combo combo2{ 13, 'Z' };
combo1 += 6; // C2678
combo2 += 9; // OK - operator+= matches non-const Combo
}
Example
C2678 can also occur if you do not pin a native member before calling a member function on it.
The following sample generates C2678 and shows how to fix it.
// C2678.cpp
// compile with: /clr /c
struct S { int _a; };
ref class C {
public:
void M( S param ) {
test = param; // C2678
// OK
pin_ptr<S> ptest = &test;
*ptest = param;
}
S test;
};
Compiler Error C2679
10/31/2018 • 2 minutes to read • Edit Online
binary 'operator' : no operator found which takes a right-hand operand of type 'type' (or there is no acceptable
conversion)
To use the operator, you must overload it for the specified type or define a conversion to a type for which the
operator is defined.
The following sample generates C2679:
// C2679.cpp
class C {
public:
C(); // no constructor with an int argument
} c;
class D {
public:
D(int) {}
D(){}
} d;
int main() {
c = 10; // C2679
d = 10; // OK
}
Compiler Error C2680
10/31/2018 • 2 minutes to read • Edit Online
// C2680.cpp
// compile with: /c
class A { virtual void f(); };
class B : public A {};
void g(B b) {
A a;
a = dynamic_cast<A>(b); // C2680 target not a reference type
a = dynamic_cast<A&>(b); // OK
}
// C2680b.cpp
// compile with: /clr /c
// C2680 expected
using namespace System::Collections;
// C2681.cpp
class A { virtual void f(); };
void g(int i) {
A* pa;
pa = dynamic_cast<A*>(i); // C2681
}
Compiler Error C2682
10/31/2018 • 2 minutes to read • Edit Online
// C2682.cpp
class A { virtual void f(); };
class B: public A {};
// C2682b.cpp
// compile with: /clr
ref struct R{};
ref struct RR : public R{};
ref struct H {
RR^ r ;
short s;
int i;
};
int main() {
H^ h = gcnew H();
interior_ptr<int>lr = &(h->i);
interior_ptr<short>ssr = safe_cast<interior_ptr<short> >(lr); // C2682
interior_ptr<short>ssr = reinterpret_cast<interior_ptr<short> >(lr); // OK
}
Compiler Error C2683
10/31/2018 • 2 minutes to read • Edit Online
// C2683.cpp
// compile with: /c
class B { };
class D : public B { };
// C2687.cpp
class C;
int main() {
try {}
catch (C) {} // C2687 error
}
Possible resolution:
// C2687b.cpp
// compile with: /EHsc
class C {};
int main() {
try {}
catch (C) {}
}
Compiler Error C2688
10/31/2018 • 2 minutes to read • Edit Online
'C2::fgrv' : covariant returns with multiple or virtual inheritance not supported for varargs functions
Covariant return types are not supported in Visual C++ when a function contains variable arguments.
To resolve this error, either define your functions so that they do not use variable arguments or make the return
values the same for all virtual functions.
The following sample generates C2688:
// C2688.cpp
struct G1 {};
struct G2 {};
struct G3 : G1, G2 {};
struct G4 {};
struct G5 {};
struct G6 : G4, G5 {};
struct G7 : G3, G6 {};
struct C1 {
virtual G4& fgrv(int,...);
};
struct C2 : C1 {
virtual G7& fgrv(int,...); // C2688, does not return G4&
};
Compiler Error C2689
10/31/2018 • 2 minutes to read • Edit Online
// C2689.cpp
// compile with: /c
void g() {
void f2();
class X {
friend void f2(){} // C2689
friend void f2(); // OK
};
}
Compiler Error C2690
10/31/2018 • 2 minutes to read • Edit Online
// C2691a.cpp
// compile with: /clr
class A {};
int main() {
array<A>^ a1 = gcnew array<A>(20); // C2691
array<int>^ a2 = gcnew array<int>(20); // value type OK
}
Compiler Error C2692
10/31/2018 • 2 minutes to read • Edit Online
'function_name' : fully prototyped functions required in C compiler with the '/clr' option
When compiling for .NET managed code, the C compiler requires ANSI function declarations. In addition, if a
function takes no parameters, it must explicitly declare void as the parameter type.
Compiler Error C2693
10/31/2018 • 2 minutes to read • Edit Online
'override': overriding virtual function has less restrictive exception specification than base class virtual member
function 'base'
A virtual function was overridden, but under /Za, the overriding function had a less restrictive exception
specification.
The following sample generates C2694:
// C2694.cpp
// compile with: /Za /c
class MyBase {
public:
virtual void f(void) throw(int) {
}
};
'function1': overriding virtual function differs from 'function2' only by calling convention
The signature of a function in a derived class cannot override a function in a base class and change the calling
convention.
The following sample generates C2695:
// C2695.cpp
class C {
virtual void __fastcall func();
};
class D : public C {
virtual void __clrcall func(); // C2695
};
Compiler Error C2696
10/31/2018 • 2 minutes to read • Edit Online
the using-declaration for 'declaration 1' cannot co-exist with the existing using-declaration for 'declaration 2'
Once you have a using declaration for a data member, any using declaration in the same scope that uses the same
name is not permitted, as only functions can be overloaded.
The following sample generates C2698:
// C2698.cpp
struct A {
int x;
};
struct B {
int x;
};
struct C : A, B {
using A::x;
using B::x; // C2698
}
Compiler Errors C2700 Through C2799
10/31/2018 • 7 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2700 'type': cannot be thrown (use /W4 for more info)
Compiler Error C2706 illegal __except without matching __try (missing '}' in __try
block?)
Compiler Error C2708 'identifier': actual parameters length in bytes differs from
previous call or reference
Compiler Error C2709 'identifier': formal parameters length in bytes differs from
previous declaration
Compiler Error C2712 Cannot use __try in functions that require object unwinding
Compiler Error C2713 Only one form of exception handling permitted per function
Compiler Error C2718 'type': actual parameter with requested alignment of number
won't be aligned
Compiler Error C2722 '::operator': illegal following operator command; use 'operator
operator'
Compiler Error C2724 'function': 'static' should not be used on member functions
defined at file scope
Compiler Error C2726 'gcnew' may only be used to create an object with
managed/WinRT type
Compiler Error C2728 'type': a native array cannot contain this type
Compiler Error C2734 'identifier': 'const' object must be initialized if not 'extern'
Compiler Error C2735 'keyword' keyword is not permitted in formal parameter type
specifier
Compiler Error C2743 'type': cannot catch a native type with __clrcall destructor or
copy constructor
Compiler Error C2748 managed/WinRT array creation must have array size or array
initializer
Compiler Error C2749 'type': can only throw or catch handle to a managed class with
/clr:safe
Compiler Error C2750 'type': cannot use 'new' on the reference type; use 'gcnew'
instead
Compiler Error C2752 'template': more than one partial specialization matches the
template argument list
Compiler Error C2753 'template': partial specialization cannot match argument list
for primary template
Compiler Error C2757 'identifier': a symbol with this name already exists and
therefore this name cannot be used as a namespace name
Compiler Error C2766 explicit specialization; 'specialization' has already been defined
ERROR MESSAGE
Compiler Error C2773 #import and #using available only in C++ compiler
Compiler Error C2774 'identifier': no 'put' method is associated with this property
Compiler Error C2775 'identifier': no 'get' method is associated with this property
Compiler Error C2776 only one 'get' method can be specified per property
Compiler Error C2777 only one 'put' method can be specified per property
Compiler Error C2779 'declaration': property methods can only be associated with
non-static data members
Compiler Error C2783 'declaration': could not deduce template/generic argument for
'identifier'
Compiler Error C2784 'declaration': could not deduce template/generic argument for
'type1' from 'type2'
Compiler Error C2785 'declaration1' and 'declaration2' have different return types
Compiler Error C2787 'identifier': no GUID has been associated with this object
Compiler Error C2788 'identifier': more than one GUID associated with this object
ERROR MESSAGE
Compiler Error C2790 'super': this keyword can only be used within the body of class
member function
Compiler Error C2791 illegal use of 'super': 'class' does not have any base classes
Compiler Error C2793 'token': unexpected token following '::', identifier or keyword
'operator' expected
Compiler Error C2794 'identifier': is not a member of any direct or indirect base class
of 'class'
Compiler Error C2796 'ref new' may only be used to create an instance of a WinRT
type
Compiler Error C2797 (Obsolete) 'identifier': list initialization inside member initializer
list or non-static data member initializer is not implemented
// C2701.cpp
// compile with: /c
template<typename T> // OK
void f1(const T &);
void MyFunction() {
class MyClass {
template<typename T> friend void f2(const T &); // C2701
};
}
Compiler Error C2702
10/31/2018 • 2 minutes to read • Edit Online
// C2702.cpp
// processor: x86 IPF
int Counter;
int main() {
__try {}
__finally {
__try {} // C2702
__except( Counter ) {} // C2702
}
}
Compiler Error C2703
10/31/2018 • 2 minutes to read • Edit Online
// C2703.cpp
int main() {
__leave; // C2703
__try {
// try the following line instead
__leave;
}
__finally {}
}
Compiler Error C2704
10/31/2018 • 2 minutes to read • Edit Online
// C2705.cpp
int main() {
goto trouble;
__try {
trouble: ; // C2705
}
__finally {}
// C2706.cpp
int main() {
__try {
void f();
// C2706 } missing here
__except(GetExceptionCode() == 0x0) {
}
}
Compiler Error C2707
10/31/2018 • 2 minutes to read • Edit Online
To resolve the error, be sure that the exception-handling intrinsics are placed in the appropriate context.
Example
The following sample generates C2707.
// C2707.cpp
#include <windows.h>
#include <stdio.h>
LONG func(void)
{
int x, y;
return(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? // C2707
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
__try
{
y = 0;
x = 4 / y;
return 0;
}
__except(MyFilter(GetExceptionCode()))
{
return(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? // ok
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
}
}
int main()
{
__try
{
func();
} __except(EXCEPTION_EXECUTE_HANDLER)
{
printf_s("Caught exception\n");
}
}
Compiler Error C2708
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : actual parameters length in bytes differs from previous call or reference
A __stdcall function must be preceded by a prototype. Otherwise, the compiler interprets the first call to the
function as a prototype and this error occurs when the compiler encounters a call that does not match.
To fix this error add a function prototype.
Compiler Error C2709
10/31/2018 • 2 minutes to read • Edit Online
// C2710.cpp
__declspec(restrict) void f(); // C2710
// try the following line instead
__declspec(restrict) int * g();
Compiler Error C2711
10/31/2018 • 2 minutes to read • Edit Online
'function' : this function cannot be compiled as managed, consider using #pragma unmanaged
Some instructions will prevent the compiler from generating MSIL for the enclosing function.
The following sample generates C2711:
// C2711.cpp
// compile with: /clr
// processor: x86
using namespace System;
value struct V {
static const t = 10;
};
void bar() {
V::t;
__asm int 3 // C2711 inline asm can't be compiled managed
}
Compiler Error C2712
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Error C2712 can occur if you use /EHsc, and a function with structured exception handling also has objects that
require unwinding (destruction).
Possible solutions:
Move code that requires SEH to another function
Rewrite functions that use SEH to avoid the use of local variables and parameters that have destructors. Do
not use SEH in constructors or destructors
Compile without /EHsc
Error C2712 can also occur if you call a method declared by using the __event keyword. Because the event might
be used in a multithreaded environment, the compiler generates code that prevents manipulation of the underlying
event object, and then encloses the generated code in an SEH try-finally statement. Consequently, error C2712 will
occur if you call the event method and pass by value an argument whose type has a destructor. One solution in this
case is to pass the argument as a constant reference.
C2712 can also occur if you compile with /clr:pure and declare a static array of pointers-to-functions in a __try
block. A static member requires the compiler to use dynamic initialization under /clr:pure, which implies C++
exception handling. However, C++ exception handling is not allowed in a __try block.
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
Example
The following sample generates C2712 and shows how to fix it.
// C2712.cpp
// compile with: /clr:pure /c
struct S1 {
static int smf();
void fnc();
};
void S1::fnc() {
__try {
static int (*array_1[])() = {smf,}; // C2712
// OK
static int (*array_2[2])();
array_2[0] = smf;
}
__except(0) {}
}
Compiler Error C2713
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2714.
// C2714.cpp
int main() {
return __alignof(void); // C2714
return __alignof(char); // OK
}
Compiler Error C2715
10/31/2018 • 2 minutes to read • Edit Online
// C2715a.cpp
// compile with: /clr
using namespace System;
value struct V {
int i;
};
void f1() {
V v;
v.i = 10;
throw v; // C2715
// try the following line instead
// throw ((V^)v);
}
int main() {
try {
f1();
}
// C2718.cpp
typedef struct __declspec(align(32)) AlignedStruct {
int i;
} AlignedStruct;
void f4() {
AlignedStruct as;
// C2719.cpp
void func(int __declspec(align(32)) i); // C2719
// try the following line instead
// void func(int i);
Compiler Error C2720
10/31/2018 • 2 minutes to read • Edit Online
The storage class cannot be used on class members outside the declaration. To fix this error, remove the unneeded
storage class specifier from the definition of the member outside the class declaration.
Example
The following sample generates C2720 and shows how to fix it:
// C2720.cpp
struct S {
static int i;
};
static S::i; // C2720 - remove the unneeded 'static' to fix it
Compiler Error C2721
10/31/2018 • 2 minutes to read • Edit Online
// C2723.cpp
struct X {
virtual void f();
virtual void g();
};
'identifier' : 'static' should not be used on member functions defined at file scope
Static member functions should be declared with external linkage.
The following sample generates C2724:
// C2724.cpp
class C {
static void func();
};
Example
The following sample generates C2725 and shows how to fix it.
// C2725.cpp
// compile with: /clr
ref class R {
public:
int i;
};
int main() {
R % r1 = *gcnew R;
throw r1; // C2725
R ^ r2 = gcnew R;
throw r2; // OK
}
Example
The following sample generates C2725 and shows how to fix it.
// C2725b.cpp
// compile with: /clr
using namespace System;
int main() {
try {}
catch( System::Exception%) {} // C2725
// try the following line instead
// catch( System::Exception ^e) {}
}
Compiler Error C2726
10/31/2018 • 2 minutes to read • Edit Online
'gcnew' may only be used to create an object with managed or WinRT type
You cannot create an instance of a native type on the garbage-collected heap.
The following sample generates C2726 and shows how to fix it:
// C2726.cpp
// compile with: /clr
using namespace System;
class U {};
ref class V {};
value class W {};
int main() {
U* pU = gcnew U; // C2726
U* pU2 = new U; // OK
V^ p2 = gcnew V; // OK
W p3; // OK
}
Compiler Error C2728
10/31/2018 • 2 minutes to read • Edit Online
// C2728.cpp
// compile with: /clr
int main() {
int^ arr[5]; // C2728
// C2731.cpp
extern "C" void WinMain(int, char *, char *);
void WinMain(int, short, char *, char*); // C2731
Compiler Error C2732
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2732:
// C2732.cpp
extern void func( void ); // implicit C++ linkage
extern "C" void func( void ); // C2732
Compiler Error C2733
10/31/2018 • 2 minutes to read • Edit Online
// C2733.cpp
extern "C" {
void F1(int);
}
extern "C" {
void F1(); // C2733
// try the following line instead
// void F2();
}
Compiler Error C2734
10/31/2018 • 2 minutes to read • Edit Online
// C2734.cpp
const int j; // C2734
extern const int i; // OK, declared as extern
Compiler Error C2735
10/31/2018 • 2 minutes to read • Edit Online
// C2735.cpp
void f(inline int){} // C2735
Compiler Error C2736
10/31/2018 • 2 minutes to read • Edit Online
// C2736.cpp
int main() {
return (virtual) 0; // C2736
// try the following line instead
// return 0;
}
Compiler Error C2738
10/31/2018 • 2 minutes to read • Edit Online
// C2738.cpp
struct A {
template <class T> operator T*();
// template <class T> operator T();
};
template <>
A::operator int() { // C2738
return 0;
}
Compiler Error C2739
10/31/2018 • 2 minutes to read • Edit Online
// C2739.cpp
// compile with: /clr
int main() {
array<int, -1>^a; // C2739
// try the following line instead
// array<int, 2>^a;
}
Compiler Error C2743
10/31/2018 • 2 minutes to read • Edit Online
'type' : cannot catch a native type with __clrcall destructor or copy constructor
A module compiled with /clr attempted to catch an exception of native type and where the type's destructor or
copy constructor uses __clrcall calling convention.
When compiled with /clr, exception handling expects the member functions in a native type to be __cdecl and not
__clrcall. Native types with member functions using __clrcall calling convention cannot be caught in a module
compiled with /clr.
For more information, see /clr (Common Language Runtime Compilation).
Example
The following sample generates C2743.
// C2743.cpp
// compile with: /clr
public struct S {
__clrcall ~S() {}
};
public struct T {
~T() {}
};
int main() {
try {}
catch(S) {} // C2743
// try the following line instead
// catch(T) {}
try {}
catch(S*) {} // OK
}
Compiler Error C2745
10/31/2018 • 2 minutes to read • Edit Online
// C2745.cpp
// compile with: /clr
int main() {
int __identifier([)); // C2745
}
Compiler Error C2748
10/31/2018 • 2 minutes to read • Edit Online
managed or WinRT array creation must have array size or array initializer
A managed or WinRT array was ill formed. For more information, see array.
The following sample generates C2748 and shows how to fix it:
// C2748.cpp
// compile with: /clr
int main() {
array<int> ^p1 = new array<int>(); // C2748
// try the following line instead
array<int> ^p2 = new array<int>(2);
}
Compiler Error C2749
10/31/2018 • 2 minutes to read • Edit Online
'type' : can only throw or catch handle to a managed class with /clr:safe
When using /clr:safe, you can only throw or catch a reference type.
For more information, see /clr (Common Language Runtime Compilation).
Example
The following sample generates C2749:
// C2749.cpp
// compile with: /clr:safe
ref struct MyStruct {
public:
int i;
};
int main() {
MyStruct ^x = gcnew MyStruct;
// OK
try {
throw (x);
}
catch(MyStruct ^){}
}
Compiler Error C2750
10/31/2018 • 2 minutes to read • Edit Online
'type' : cannot use 'new' on the reference type; use 'gcnew' instead
To create an instance of a CLR type, which causes the instance to be placed on the garbage-collected heap, you
must use gcnew.
The following sample generates C2750:
// C2750.cpp
// compile with: /clr
ref struct Y1 {};
int main() {
Y1 ^ x = new Y1; // C2750
// C2751.cpp
namespace std {
template<typename T>
class list {};
}
'template' : more than one partial specialization matches the template argument list
An instantiation was ambiguous.
The following sample generates C2752:
// C2752.cpp
template<class T, class U>
struct A {};
int main() {
A<char*,int*> a; // C2752 an instantiation
// OK
A<char*,int> a1;
A<char,int*> a2;
A<char,int> a3;
}
Compiler Error C2753
10/31/2018 • 2 minutes to read • Edit Online
'template' : partial specialization cannot match argument list for primary template
If the template argument list matches the parameter list, the compiler treats it as the same template. Defining the
same template twice is not allowed.
Example
The following sample generates C2753 and shows a way to fix it:
// C2753.cpp
// compile with: cl /c C2753.cpp
template<class T>
struct A {};
template<class T>
struct A<T> {}; // C2753
// try the following line instead
// struct A<int> {};
// C2754.cpp
// compile with: /c
template<class T, T t>
struct A {};
// C2755.cpp
template<int I, int J>
struct A {};
template<int I>
struct A<I,I*5> {}; // C2755
// try the following line instead
// struct A<I,5> {};
Compiler Error C2756
10/31/2018 • 2 minutes to read • Edit Online
// C2756.cpp
template <class T>
struct S {};
'symbol' : a symbol with this name already exists and therefore this name cannot be used as a namespace name
A symbol used in the current compilation as a namespace identifier is already being used in a referenced assembly.
The following sample generates C2757:
// C2757a.cpp
// compile with: /clr /LD
public ref class Nes {};
And then,
// C2757b.cpp
// compile with: /clr /c
#using <C2757a.dll>
// C2758.cpp
// Compile by using: cl /W3 /c C2758.cpp
struct A {
const int i;
A(int n) { }; // C2758
// try the following line instead
// A(int n) : i{n} {};
};
Compiler Error C2760
10/31/2018 • 2 minutes to read • Edit Online
// C2760.cpp
class B {};
class D : public B {};
Example
The following sample generates C2761.
// C2761.cpp
class a {
int t;
void test();
};
Example
Nonstatic members of a class or structure cannot be defined. The following sample generates C2761.
// C2761_b.cpp
// compile with: /c
struct C {
int s;
static int t;
};
// C2762.cpp
// compile with: /Za
template<typename T, T *pT>
class X2 {};
void f2() {
X2<int, 0> x21; // C2762
// try the following line instead
// X2<int, static_cast<int *>(0)> x22;
}
Compiler Error C2764
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2764:
// C2764.cpp
#include <stdio.h>
template <class T1, class T2>
struct S {
int m_i;
};
int main() {
S<int, char> s1;
S<void (*)(short), short *> s2;
s2.m_c = 10;
s1.m_i = s2.m_c;
printf_s("%d\n", s1.m_i);
}
Compiler Error C2765
10/31/2018 • 2 minutes to read • Edit Online
'function' : an explicit specialization of a function template cannot have any default arguments
Default arguments are not allowed on an explicit specialization of a function template. For more information, see
Explicit Specialization of Function Templates.
The following sample generates C2765:
// C2765.cpp
template<class T> void f(T t) {};
// C2766.cpp
// compile with: /c
template<class T>
struct A {};
template<>
struct A<int> {};
template<>
struct A<int> {}; // C2766
// try the following line instead
// struct A<char> {};
Compiler Error C2767
10/31/2018 • 2 minutes to read • Edit Online
// C2767.cpp
// compile with: /clr
int main() {
array<int> ^p1 = new array<int>(2,3); // C2767
array<int> ^p2 = new array<int>(2); // OK
}
Compiler Error C2768
10/31/2018 • 2 minutes to read • Edit Online
// C2768.cpp
template<typename T>
void f(T) {}
// an explicit specialization
template<>
void f<int>(int) {}
// C2770.cpp
#include <stdio.h>
template <class T>
int f(typename T::B*); // expects type with member B
int main() {
f<int>(0); // C2770 int has no B
// try the following line instead
f<OK>(0);
}
Compiler Error C2771
10/31/2018 • 2 minutes to read • Edit Online
// C2774.cpp
struct A {
__declspec(property(get=GetProp)) int prop;
int GetProp(void);
int main() {
A* pa = new A;
int val = 0;
pa->prop = val; // C2774
pa->prop++; // C2774
}
Compiler Error C2775
10/31/2018 • 2 minutes to read • Edit Online
// C2775.cpp
struct A {
__declspec(property(put=PutProp2, get=GetProp2)) int prop2;
int GetProp2(){return 0;}
void PutProp2(int){}
};
int main() {
A* pa = new A;
int x;
x = pa->prop; // C2775
x = pa->prop2;
}
Compiler Error C2776
10/31/2018 • 2 minutes to read • Edit Online
// C2776.cpp
struct A {
__declspec(property(get=GetProp,get=GetPropToo))
// try the following line instead
// __declspec(property(get=GetProp))
int prop; // C2776
int GetProp(void);
int GetPropToo(void);
};
Compiler Error C2777
10/31/2018 • 2 minutes to read • Edit Online
// C2777.cpp
struct A {
__declspec(property(put=PutProp,put=PutPropToo)) // C2777
// try the following line instead
// __declspec(property(put=PutProp))
int prop;
int PutProp(void);
int PutPropToo(void);
};
Compiler Error C2778
10/31/2018 • 2 minutes to read • Edit Online
// C2778a.cpp
// compile with: /c
struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) A {};
struct __declspec(uuid("{00000000-0000-0000-0000-000000000000}")) B{};
The uuid extended attribute accepts strings recognized by CLSIDFromString, with or without brace delimiters.
The following sample generates C2778:
// C2778b.cpp
struct __declspec(uuid(" 00000000-0000-0000-0000-000000000000 ")) C { }; // C2778
struct __declspec(uuid("00000000000000000000000000000000")) D { }; // C2778
Compiler Error C2779
10/31/2018 • 2 minutes to read • Edit Online
'declaration' : property methods can only be associated with non-static data members
The property extended attribute is incorrectly applied to a static data member.
The following sample generates C2779:
// C2779.cpp
struct A {
static __declspec(property(put=PutProp))
// try the following line instead
__declspec(property(put=PutProp))
int prop; // C2779
int PutProp(void);
};
Compiler Error C2780
10/31/2018 • 2 minutes to read • Edit Online
// C2780.cpp
template<typename T>
void f(T, T){}
int main() {
f(1); // C2780
// try the following line instead
// f(1,2);
}
Compiler Error C2781
10/31/2018 • 2 minutes to read • Edit Online
// C2781.cpp
template<typename T>
void f(T, T, ...){}
int main() {
f(1); // C2781
// C2782.cpp
template<typename T>
void f(T, T) {}
int main() {
f(1, 'c'); // C2782
// try the following line instead
// f<int>(1, 'c');
}
// C2782b.cpp
// compile with: /clr
generic<typename T> void gf(T, T) { }
int main() {
gf(1, 'c'); // C2782
// try the following line instead
// gf<int>(1, 'c');
}
Compiler Error C2783
10/31/2018 • 2 minutes to read • Edit Online
// C2783.cpp
template<typename T1, typename T2>
T1 f(T2) {
return 248;
}
int main() {
f(1); // C2783
// try the following line instead
int i = f<int>(1);
}
// C2783b.cpp
// compile with: /clr
using namespace System;
generic<typename T1, typename T2>
T1 gf(T2) {
T1 t1 = safe_cast<T1>( Activator::CreateInstance(T1::typeid));
return t1;
}
int main() {
int i;
i = gf(9); // C2783
// OK
i = gf<int>(9);
}
Compiler Error C2784
10/31/2018 • 2 minutes to read • Edit Online
'declaration' : could not deduce template argument for 'type' from 'type'
The compiler cannot determine a template argument from the supplied function arguments.
The following sample generates C2784 and shows how to fix it:
// C2784.cpp
template<class T> class X {};
template<class T> void f(X<T>) {}
int main() {
X<int> x;
f(1); // C2784
Example
The following sample generates C2785:
// C2785.cpp
// compile with: /c
template<class T> void f(T);
// C2786.cpp
struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) A {};
int main() {
__uuidof(int); // C2786
__uuidof(int *); // C2786
__uuidof(A **); // C2786
// no error
__uuidof(A);
__uuidof(A *);
__uuidof(A &);
__uuidof(A[]);
int i;
int *pi;
A **ppa;
__uuidof(i); // C2786
__uuidof(pi); // C2786
__uuidof(ppa); // C2786
}
Compiler Error C2787
10/31/2018 • 2 minutes to read • Edit Online
// C2787.cpp
#include <windows.h>
struct F {};
int main() {
__uuidof(F); // C2787
__uuidof(F2); // OK
}
Compiler Error C2788
10/31/2018 • 2 minutes to read • Edit Online
// C2788.cpp
#include <windows.h>
struct __declspec(uuid("00000001-0000-0000-0000-000000000000")) A {};
struct __declspec(uuid("{00000002-0000-0000-0000-000000000000}")) B {};
template <class T, class U> class MyClass {};
int main() {
__uuidof(MyBadClass); // C2788
// try the following line instead
__uuidof(MyGoodClass);
}
Compiler Error C2790
10/31/2018 • 2 minutes to read • Edit Online
'super' : this keyword can only be used within the body of class member function
This error message appears if the user ever tries to uses the keyword super outside of the context of a member
function.
The following sample generates C2790:
// C2790.cpp
void f() {
__super::g(); // C2790
}
Compiler Error C2791
10/31/2018 • 2 minutes to read • Edit Online
illegal use of 'super': 'class' does not have any base classes
The keyword super was used within the context of a member function of a class that does not have any base
classes.
The following sample generates C2791:
// C2791.cpp
struct D {
void mf() {
__super::mf(); // C2791
}
};
Compiler Error C2792
10/31/2018 • 2 minutes to read • Edit Online
// C2792.cpp
struct B {
void mf();
};
struct D : B {
void mf() {
__super.(); // C2792
// C2793.cpp
struct B {
void mf();
};
struct D : B {
void mf() {
__super::(); // C2793
}
};
Compiler Error C2794
10/31/2018 • 2 minutes to read • Edit Online
// C2794.cpp
struct B {
void mf();
};
struct D : B {
void mf() {
__super::f(); // C2794
}
};
Compiler Error C2795
10/31/2018 • 2 minutes to read • Edit Online
(Obsolete) List initialization inside member initializer list or non-static data member initializer is not implemented.
This warning is obsolete in Visual Studio 2015. In Visual Studio 2013 and earlier versions, the Visual C++
compiler does not implement list initialization inside either a member initializer list or a non-static data member
initializer. Before Visual Studio 2013 Update 3, this was silently converted to a function call, which could lead to
bad code generation. Visual Studio 2013 Update 3 reports this as an error.
This example generates C2797:
#include <vector>
struct S {
S() : v1{1} {} // C2797, VS2013 RTM incorrectly calls 'vector(size_type)'
std::vector<int> v1;
std::vector<int> v2{1, 2}; // C2797, VS2013 RTM incorrectly calls 'vector(size_type, const int &)'
};
struct S1 {
int i;
};
struct S2 {
S2() : s1{0} {} // C2797, VS2013 RTM interprets as S2() : s1(0) {} causing C2664
S1 s1;
S1 s2{0}; // C2797, VS2013 RTM interprets as S1 s2 = S1(0); causing C2664
};
To fix this issue, you can use explicit construction of inner lists. For example:
#include <vector>
typedef std::vector<int> Vector;
struct S {
S() : v1(Vector{1}) {}
Vector v1;
Vector v2 = Vector{1, 2};
};
struct S {
S() : s1("") {}
std::string s1;
std::string s2 = std::string("");
};
(The compiler in Visual Studio 2013 does this implicitly prior to Visual Studio 2013 Update 3.)
Compiler Error C2798
10/31/2018 • 2 minutes to read • Edit Online
'super::member' is ambiguous
Multiple inherited structures contain the member you referenced with super. You could fix the error by either:
Removing B1 or B2 from the inheritance list of D.
Changing the name of the data member in B1 or B2.
The following sample generates C2798:
// C2798.cpp
struct B1 {
int i;
};
struct B2 {
int i;
};
struct D : B1, B2 {
void g() {
__super::i = 4; // C2798
}
};
Compiler Errors C2800 Through C2899
11/8/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2802 static member 'operator operator' has no formal parameters
Compiler Error C2803 'operator operator' must have at least one formal parameter
of class type
Compiler Error C2804 binary 'operator operator' has too many parameters
Compiler Error C2805 binary 'operator operator' has too few parameters
Compiler Error C2806 'operator operator' has too many formal parameters
ERROR MESSAGE
Compiler Error C2807 the second formal parameter to postfix 'operator operator'
must be 'int'
Compiler Error C2808 unary 'operator operator' has too many formal parameters
Compiler Error C2810 'interface': an interface can only inherit from another interface
Compiler Error C2811 'type1': cannot inherit from 'type2', a ref class can only inherit
from a ref class or interface class
Compiler Error C2812 #import is not supported with /clr:pure and /clr:safe
Compiler Error C2815 'operator delete': first formal parameter must be 'void *', but
'type' was used
Compiler Error C2817 return type for 'operator delete' must be 'void'
Compiler Error C2819 type 'class' does not have an overloaded member 'operator -
>'
Compiler Error C2821 first formal parameter to 'operator new' must be 'size_t'
Compiler Error C2824 return type for 'operator new' must be 'void *'
Compiler Error C2825 'identifier': must be a class or namespace when followed by '::'
Compiler Error C2827 'operator operator' cannot be globally overridden with unary
form
Compiler Error C2828 'operator operator' cannot be globally overridden with binary
form
ERROR MESSAGE
Compiler Error C2829 'operator operator' cannot have a variable parameter list
Compiler Error C2830 only placement parameters to 'operator new' can have default
values
Compiler Error C2836 'identifier': only one non-static data member of a union may
have a default member initializer
Compiler Error C2837 'function': cannot use OpenMP directives and #pragma
loop(hint_parallel) in same function
Compiler Error C2839 invalid return type 'type' for overloaded 'operator ->'
Compiler Error C2842 'class': a managed/WinRT type may not define its own
'operator new' or 'operator delete'
Compiler Error C2843 'member': cannot take the address of a non-static data
member or method of a managed/WinRT type
Compiler Error C2845 'type': pointer arithmetic not allowed on this type
Compiler Error C2850 'construct': only allowed at file scope; may not be in a nested
construct
ERROR MESSAGE
Compiler Error C2851 'enum': A public WinRT enum can only use 'int' or 'unsigned
int' as a base type
Compiler Error C2852 'identifier': only data members can be initialized within a class
Compiler Error C2853 'identifier': a non-static data member cannot have a type that
contains 'auto'
Compiler Error C2857 '#include' statement specified with the /Ycfilename command-
line option was not found in the source file
Compiler Error C2859 filename is not the filetype file that was used when this
precompiled header was created, recreate the precompiled
header.
Compiler Error C2860 'void' cannot be an argument type, except for '(void)'
Compiler Error C2862 'interface': an interface can only have public members
Compiler Error C2864 'identifier': a static data member/template variable with an in-
class initializer must have non-volatile const integral type
Compiler Error C2870 'identifier': a namespace definition must appear either at file
scope or immediately within another namespace definition
Compiler Error C2871 'identifier': a namespace with this name does not exist
ERROR MESSAGE
Compiler Error C2878 'identifier': a namespace or class of this name does not exist
Compiler Error C2880 __swi or __hvc requires a valid constant as first argument (SWI
number)
Compiler Error C2887 __swi or __hvc cannot have more than five arguments (SWI
number, r0 - r3)
Compiler Error C2889 'class': a managed/WinRT class type cannot be a virtual base
class
Compiler Error C2890 'class': a ref class can only have one non-interface base class
Compiler Error C2891 'parameter': cannot take the address of a template parameter
Compiler Error C2892 local class shall not have member templates
ERROR MESSAGE
// C2800.cpp
// compile with: /c
class C {
operator:: (); // C2800
};
Compiler Error C2801
10/31/2018 • 2 minutes to read • Edit Online
Subscripting []
Function call ()
// C2801.cpp
// compile with: /c
operator[](); // C2801 not a member
class A {
static operator->(); // C2801 static
operator()(); // OK
};
Compiler Error C2802
10/31/2018 • 2 minutes to read • Edit Online
// C2802.cpp
// compile with: /clr /c
ref class A {
static operator+ (); // C2802
static operator+ (A^, A^); // OK
};
Compiler Error C2803
10/31/2018 • 2 minutes to read • Edit Online
'operator operator' must have at least one formal parameter of class type
The overloaded operator lacks a parameter of class type.
You need to pass at least one parameter by reference (not using pointers, but references) or by value to be able to
write "a < b" (a and b being of type class A).
If both parameters are pointers it will be a pure comparison of pointer addresses and will not use the user-defined
conversion.
The following sample generates C2803:
// C2803.cpp
// compile with: /c
class A{};
bool operator< (const A *left, const A *right); // C2803
// try the following line instead
// bool operator< (const A& left, const A& right);
Compiler Error C2804
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2804 and shows how to fix it.
// C2804.cpp
// compile by using: cl /c /W4 C2804.cpp
class X {
public:
X& operator+= (const X &left, const X &right); // C2804
X& operator+= (const X &right); // OK - left operand implicitly *this
};
int main() {
X x, y;
x += y; // equivalent to x.operator+=(y)
}
Example
The following sample generates C2804 and shows how to fix it.
// C2804_2.cpp
// compile with: /clr /c
ref struct Y {
Y^ operator +(Y^ hY, int i); // C2804
static Y^ operator +(Y^ hY, int i); // OK
Y^ operator +(int i); // OK
};
Compiler Error C2805
10/31/2018 • 2 minutes to read • Edit Online
// C2805.cpp
// compile with: /c
class X {
public:
X operator< ( void ); // C2805 must take one parameter
X operator< ( X ); // OK
};
Compiler Error C2806
10/31/2018 • 2 minutes to read • Edit Online
// C2806.cpp
// compile with: /c
class X {
public:
X operator++ ( int, int ); // C2806 more than 1 parameter
X operator++ ( int ); // OK
} ;
Compiler Error C2807
10/31/2018 • 2 minutes to read • Edit Online
// C2807.cpp
// compile with: /c
class X {
public:
X operator++ ( X ); // C2807 nonvoid parameter
X operator++ ( int ); // OK, int parameter
};
Compiler Error C2808
11/9/2018 • 2 minutes to read • Edit Online
// C2808.cpp
// compile with: /c
class X {
public:
X operator! ( X ); // C2808 nonvoid parameter list
X operator! ( void ); // OK
};
Compiler Error C2809
10/31/2018 • 2 minutes to read • Edit Online
// C2809.cpp
// compile with: /c
class A{};
int operator+ (); // C2809
int operator+ (A); // OK
Compiler Error C2810
10/31/2018 • 2 minutes to read • Edit Online
// C2810.cpp
#include <unknwn.h>
class CBase1 {
public:
HRESULT mf1();
int m_i;
};
[object, uuid="40719E20-EF37-11D1-978D-0000F805D73B"]
__interface IDerived : public CBase1 { // C2810
// try the following line instead
// __interface IDerived {
HRESULT mf2(void *a);
};
struct CBase2 {
HRESULT mf1(int a, char *b);
HRESULT mf2();
};
Compiler Error C2811
10/31/2018 • 2 minutes to read • Edit Online
'type1' : cannot inherit from 'type2', a ref class can only inherit from a ref class or interface class
You attempted to use an unmanaged class as a base class for a managed class.
The following sample generates C2811:
// C2811.cpp
// compile with: /clr /c
struct S{};
ref struct T {};
ref class C : public S {}; // C2811
ref class D : public T {}; // OK
Compiler Error C2812
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
#import Directive is not supported with /clr:pure and /clr:safe because #import requires the use of native
compiler support libraries.
Example
The following sample generates C2812.
// C2812.cpp
// compile with: /clr:pure /c
#import "importlib.tlb" // C2812
Compiler Error C2813
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2813. The command line in the "compile with:" comment indicates to the
compiler to use the /MP and /c compiler options to compile several files. At least one of the files contains the
#import directive. We use the same file twice for the sake of testing this example.
// C2813.cpp
// compile with: /MP /c C2813.cpp C2813.cpp
#import "C:\windows\system32\stdole2.tlb" // C2813
int main()
{
}
Compiler Error C2814
10/31/2018 • 2 minutes to read • Edit Online
'member' : a native type cannot be nested within a managed or WinRT type 'type'
Example
A native type cannot be nested in a CLR or WinRT type. The following sample generates C2814 and shows how to
fix it.
// C2814.cpp
// compile with: /clr /c
ref class A {
class B {}; // C2814
ref class C {}; // OK
};
Compiler Error C2815
10/31/2018 • 2 minutes to read • Edit Online
'operator delete' : first formal parameter must be 'void *', but 'param' was used
Any user-defined operator delete function must take a first formal parameter of type void * .
The following sample generates C2815:
// C2815.cpp
// compile with: /c
class CMyClass {
public:
void mf1(int *a);
void operator delete(CMyClass *); // C2815
void operator delete(void *);
};
Compiler Error C2817
10/31/2018 • 2 minutes to read • Edit Online
// C2819.cpp
// compile with: /c
class A {
public:
int i;
};
class B {};
void C(B j) {
j->i; // C2819
}
class D {
A* pA;
public:
A* operator->() {
return pA;
}
};
void F(D j) {
j->i;
}
C2819 can also occur when using C++ Stack Semantics for Reference Types. The following sample generates
C2819:
// C2819_b.cpp
// compile with: /clr
ref struct R {
void Test() {}
};
int main() {
R r;
r->Test(); // C2819
r.Test(); // OK
}
Compiler Error C2821
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2821:
// C2821.cpp
// compile with: /c
void * operator new( /* unsigned int,*/ void * ); // C2821
void * operator new( unsigned int, void * );
Compiler Error C2823
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2823, and shows one way to fix it:
// C2823.cpp
template<class T>
typedef struct x {
T i; // C2823 can't use T, specify data type and delete template
int i; // OK
} x1;
Compiler Error C2824
10/31/2018 • 2 minutes to read • Edit Online
// C2824.cpp
// compile with: /c
class A {
A* operator new(size_t i, char *m); // C2824
// try the following line instead
// void* operator new(size_t i, char *m);
};
Compiler Error C2825
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2825:
// C2825.cpp
typedef int i;
int main() {
int* p = new int;
p->i::i(); // C2825
// try the following line instead
// p->i::~i();
}
Compiler Error C2827
10/31/2018 • 2 minutes to read • Edit Online
new
Compiler Error C2830
10/31/2018 • 2 minutes to read • Edit Online
// C2831.cpp
// compile with: /c
#define BINOP <=
class A {
public:
int i;
int operator BINOP(int x = 1) { // C2831
// try the following line instead
// int operator BINOP(int x) {
return i+x;
}
};
Compiler Error C2833
10/31/2018 • 2 minutes to read • Edit Online
// C2833.cpp
// compile with: /c
class A {};
// C2835.cpp
class A {
public:
char v_char;
A() {
v_char = 'A';
};
operator char(char a) { // C2835
// try the following line instead
// operator char() {
return v_char + 1;
};
};
int main() {
A a;
}
Compiler Error C2838
10/31/2018 • 2 minutes to read • Edit Online
// C2838.cpp
// compile with: /c
class Bellini {
public:
void Norma();
};
class Bottesini {
Bellini::Norma(); // C2838
};
Compiler Error C2839
10/31/2018 • 2 minutes to read • Edit Online
'class' : a managed or WinRT type may not define its own 'operator new' or 'operator delete'
Remarks
You can define your own operator new or operator delete to manage memory allocation on the native heap.
However, reference classes cannot define these operators because they are only allocated on the managed heap.
For more information, see User-Defined Operators (C++/CLI).
Example
The following sample generates C2842.
// C2842.cpp
// compile with: /clr /c
ref class G {
void* operator new( size_t nSize ); // C2842
};
Compiler Error C2843
10/31/2018 • 2 minutes to read • Edit Online
'member' : cannot take the address of a non-static data member or method of a managed or WinRT type
An instance is needed to take the address of nonstatic data members of a managed or WinRT class or interface.
The following sample generates C2843 and shows how to fix it:
// C2843_2.cpp
// compile with: /clr
public ref class C {
public:
int m_i;
};
int main() {
MyStruct ^ps = gcnew MyStruct;
void (__clrcall MyStruct::*F1)() = & MyStruct::f; // C2843
void (__clrcall MyStruct::*F2)() = & ps->f; // C2843
void (__clrcall MyStruct::*F3)(); // C2843
// C2844a.cpp
// compile with: /clr /c
public interface class IFace {
int i; // C2844
// try the following line instead
// property int Size;
};
Compiler Error C2845
10/31/2018 • 2 minutes to read • Edit Online
// C2846.cpp
// compile with: /c
__interface C {
C(); // C2846 constructor not allowed in an interface
};
Compiler Error C2847
10/31/2018 • 2 minutes to read • Edit Online
// C2847.cpp
// compile with: /clr
ref class A {};
int main() {
A ^ xA = gcnew A;
sizeof(*xA); // C2847 cannot use sizeof on managed object
}
Compiler Error C2849
10/31/2018 • 2 minutes to read • Edit Online
// C2849.cpp
// compile with: /c
__interface C {
~C(); // C2849 destructor not allowed in an interface
};
Compiler Error C2850
10/31/2018 • 2 minutes to read • Edit Online
// C2850.cpp
// compile with: /c /Yc
// try the following line instead
// #pragma hdrstop
namespace X {
#pragma hdrstop // C2850
};
Compiler Error C2854
10/31/2018 • 2 minutes to read • Edit Online
// C2854.cpp
// compile with: /c
#pragma hdrstop( "\\source\\pchfiles\\myheader.pch" ] // C2854
// try the following line instead
// #pragma hdrstop( "\\source\\pchfiles\\myheader.pch" )
Compiler Error C2855
10/31/2018 • 2 minutes to read • Edit Online
'#include' statement specified with the /Ycfilename command-line option was not found in the source file
The /Yc option specifies the name of an include file that is not included in the source file being compiled.
Remarks
When you use the /Ycfilename option on a source file to create a precompiled header (PCH) file, that source file
must include the filename header file. Every file included by the source file, up to and including the specified
filename, is included in the PCH file. In other source files compiled by using the /Yufilename option to use the
PCH file, an include of filename must be the first non-comment line in the file. The compiler ignores anything in
the source file before this include.
This error can be caused by an #include "filename" statement in a conditional compilation block that is not
compiled in your PCH source file.
Example
In typical usage, one source file in your project is designated as the PCH source file, and one header file is used as
the PCH header file. A typical PCH header file has all of the library headers used in your project, but not local
headers that are still under development. In this sample, the PCH header file is named my_pch.h.
// my_pch.h
#pragma once
#include <stdio.h>
The PCH source file is compiled by using the /Ycmy_pch.h option. If the compiler does not find an include of this
PCH header file, it generates C2857:
// my_pch.cpp
// Compile by using: cl /EHsc /W4 /Yumy_pch.h /c my_pch.cpp
#if 0
#include "my_pch.h" // C2857; remove conditional directives to fix
#endif
To use this PCH file, source files must be compiled by using the /Yumy_pch.h option. The PCH header file must be
included first in source files that use the PCH:
// C2857.cpp
// Compile my_pch.cpp first, then
// compile by using: cl /EHsc /W4 /Yumy_pch.h my_project.cpp my_pch.obj
// Include the pch header before any other non-comment line
#include "my_pch.h"
int main()
{
puts("Using a precompiled header file.\n");
}
Compiler Error C2858
10/31/2018 • 2 minutes to read • Edit Online
command-line option '/Yc (/Fdfilename)' inconsistent with precompiled header, which used '/Fdfilename'
The program database specified by the Use Precompiled Header (/Yu) option is not the one specified by the
previous Create Precompiled Header (/Yc) option.
Compiler Error C2859
10/31/2018 • 2 minutes to read • Edit Online
filename is not the type file that was used when this precompiled header was created, recreate the precompiled
header.
The project database and precompiled header files must be created together to ensure consistent information.
Rebuild the project to recreate the precompiled header.
For information on precompiled headers, see /Y (Precompiled Headers).
Compiler Error C2860
10/31/2018 • 2 minutes to read • Edit Online
// C2860.cpp
// compile with: /c
void profunc1(void, int i); // C2860
void func10(void); // OK
Compiler Error C2861
11/9/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2861:
// C2861.cpp
// compile with: /c
#include <objbase.h> // required for IUnknown definition
[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface IMyInterface : IUnknown {
HRESULT mf(int a);
};
// C2862.cpp
// compile with: /c
#include <unknwn.h>
[object, uuid="60719E20-EF37-11D1-978D-0000F805D73B"]
__interface IMyInterface {
HRESULT mf1(void); // OK
protected:
HRESULT mf2(int *b); // C2862
private:
HRESULT mf3(int *c); // C2862
};
Compiler Error C2863
10/31/2018 • 2 minutes to read • Edit Online
// C2863.cpp
// compile with: /c
#include <unknwn.h>
class CMyClass {
void *f();
};
__interface IMyInterface {
void g();
'variable' : a static data member with an in-class initializer must have non-volatile const integral type
To initialize a static data member that is defined as volatile , non- const , or not an integral type, use a
member-definition statement. They cannot be initialized in a declaration.
This sample generates C2864:
// C2864.cpp
// compile with: /c
class B {
private:
int a = 3; // OK
static int b = 3; // C2864
volatile static int c = 3; // C2864
volatile static const int d = 3; // C2864
const static long long e = 3; // OK
static const double f = 3.33; // C2864
};
// C2864b.cpp
// compile with: /c
class C {
private:
int a = 3;
static int b; // = 3; C2864
volatile static int c; // = 3; C2864
volatile static const int d; // = 3; C2864
static const long long e = 3;
static const double f; // = 3.33; C2864
};
// C2867.cpp
// compile with: /c
namespace N {
class X {};
}
using namespace N::X; // C2867
Compiler Error C2868
10/31/2018 • 2 minutes to read • Edit Online
A using declaration requires a qualified name, a scope-operator ( :: ) separated sequence of namespace, class, or
enumeration names that ends with the identifier name. A single scope resolution operator may be used to
introduce a name from the global namespace.
Example
The following sample generates C2868 and also shows correct usage:
// C2868.cpp
class X {
public:
int i;
};
class Y : X {
public:
using X::i; // OK
};
int main() {
using X; // C2868
}
Compiler Error C2869
10/31/2018 • 2 minutes to read • Edit Online
// C2869.cpp
// compile with: /c
namespace A { int i; };
'name' : a namespace definition must appear either at file scope or immediately within another namespace
definition
You defined namespace name incorrectly. Namespaces must be defined at file scope (outside all blocks and
classes) or immediately within another namespace.
The following sample generates C2870:
// C2870.cpp
// compile with: /c
int main() {
namespace A { int i; }; // C2870
}
Compiler Error C2871
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2871:
// C2871.cpp
// compile with: /c
namespace a {
int fn(int i) { return i; }
}
namespace b {
using namespace d; // C2871 because d is not a namespace
using namespace a; // OK
}
Compiler Error C2872
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2872, because an ambiguous reference is made to a variable named i ; two
variables with the same name are in scope:
// C2872.cpp
// compile with: cl /EHsc C2872.cpp
namespace A {
int i;
}
using namespace A;
int i;
int main() {
::i++; // ok, uses i from global namespace
A::i++; // ok, uses i from namespace A
i++; // C2872 ambiguous: ::i or A::i?
// To fix this issue, use the fully qualified name
// for the intended variable.
}
Compiler Error C2873
10/31/2018 • 2 minutes to read • Edit Online
// C2874.cpp
namespace Z {
int i;
}
int main() {
int i;
using Z::i; // C2874, i already declared
}
Compiler Error C2875
10/31/2018 • 2 minutes to read • Edit Online
// C2875.cpp
struct A {
void f(int*);
};
struct B {
void f(double*);
};
struct AB : A, B {
using A::f;
using A::f; // C2875
using B::f;
};
Compiler Error C2876
10/31/2018 • 2 minutes to read • Edit Online
// C2876.cpp
// compile with: /c
class A {
public:
double a(double);
private:
int a(int);
};
class B : public A {
using A::a; // C2876 one overload is private in base class
};
Compiler Error C2877
10/31/2018 • 2 minutes to read • Edit Online
// C2877.cpp
// compile with: /c
class A {
private:
int a;
};
class B : public A {
using A::a; // C2877
};
Compiler Error C2878
10/31/2018 • 2 minutes to read • Edit Online
// C2878.cpp
// compile with: /c
namespace A {}
namespace B = C; // C2878 namespace C doesn't exist
namespace B = A;
Compiler Error C2879
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : only an existing namespace can be given an alternative name by a namespace alias definition
You cannot create a namespace alias to a symbol other than a namespace.
The following sample generates C2879:
// C2879.cpp
int main() {
int i;
namespace A = i; // C2879 i is not a namespace
}
Compiler Error C2881
10/31/2018 • 2 minutes to read • Edit Online
// C2881.cpp
// compile with: /c
namespace A {
int k;
}
namespace B {
int i;
}
namespace C = A;
namespace C = B; // C2881 C is already an alias for A
Compiler Error C2882
10/31/2018 • 2 minutes to read • Edit Online
// C2882.cpp
// compile with: /c
namespace A {
int k;
}
// C2883.cpp
namespace A {
void z(int);
}
int main() {
using A::z;
void z(int); // C2883 z is already defined
}
Compiler Error C2884
10/31/2018 • 2 minutes to read • Edit Online
// C2884.cpp
namespace A {
void z(int);
}
void f() {
void z(int);
using A::z; // C2884 z is already defined
}
Compiler Error C2885
10/31/2018 • 2 minutes to read • Edit Online
Example
This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: it is no
longer valid to have a using declaration to a nested type; you must explicitly qualify each reference you make to
the nested type, put the type in a namespace, or create a typedef.
The following sample generates C2885.
// C2885.cpp
namespace MyNamespace {
class X1 {};
}
struct MyStruct {
struct X1 {
int i;
};
};
int main () {
using MyStruct::X1; // C2885
// OK
using MyNamespace::X1;
X1 myX1;
MyStruct::X1 X12;
Example
If you use the using keyword with a class member, C++ requires you to define that member inside another class
(a derived class).
The following sample generates C2885.
// C2885_b.cpp
// compile with: /c
class A {
public:
int i;
};
void z() {
using A::i; // C2885 not in a class
}
class B : public A {
public:
using A::i;
};
Compiler Error C2886
10/31/2018 • 2 minutes to read • Edit Online
// C2886.cpp
// compile with: /c
namespace Z {
int i;
}
class B {
protected:
int i;
};
class D : public B {
// Error: Z is a namespace
using Z::i; // C2886
// C2888.cpp
// compile with: /c
namespace M {
namespace N {
void f1();
void f2();
}
namespace O {
void M::N::f2() {} // C2888 namespace O does not enclose M
}
Compiler Error C2890
10/31/2018 • 2 minutes to read • Edit Online
'class' : a ref class can only have one non-interface base class
A reference class can only have one base class.
The following sample generates C2890:
// C2890.cpp
// compile with: /clr /c
ref class A {};
ref class B {};
ref class C : public A, public B {}; // C2890
ref class D : public A {}; // OK
Compiler Error C2891
10/31/2018 • 2 minutes to read • Edit Online
Template parameters that are lvalues, such as reference types, can have their address taken.
To correct this error, do not take the address of a template parameter unless it is an lvalue.
Compiler Error C2892
10/31/2018 • 2 minutes to read • Edit Online
// C2892.cpp
int main() {
struct local {
template<class T> // C2892
void f() {}
};
}
Compiler Error C2893
10/31/2018 • 2 minutes to read • Edit Online
Example
C2893 occurs because f 's template parameter T is deduced to be std::map<int,int> , but std::map<int,int>
has no member data_type ( T::data_type can not be instantiated with T = std::map<int,int> .). The following
sample generates C2893.
// C2893.cpp
// compile with: /c /EHsc
#include<map>
using namespace std;
class MyClass {};
template<class T>
inline typename T::data_type
// try the following line instead
// inline typename T::mapped_type
f(T const& p1, MyClass const& p2);
template<class T>
void bar(T const& p1) {
MyClass r;
f(p1,r); // C2893
}
int main() {
map<int,int> m;
bar(m);
}
Compiler Error C2894
10/31/2018 • 2 minutes to read • Edit Online
// C2894.cpp
extern "C" {
template<class T> class stack {}; // C2894 fail
// C2894b.cpp
// compile with: /c
extern "C" template<class T> void f(const T &aT) {} // C2894
// C2896.cpp
template<class T1, class T2> void f1(void(*)(T1, T2));
template<class T1, class T2> void f2(T1, T2);
int main() {
f1(f2); // C2896
}
// C2896b.cpp
// compile with: /clr
generic<class T1> void gf1(T1){}
generic<class T1> void gf2(T1){}
int main() {
gf1(gf2); // C2896
gf1(1); // OK
}
Compiler Error C2897
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2897.
// C2897.cpp
// compile with: /c
class X {
public:
template<typename T> ~X() {} // C2897
};
Example
The following sample generates C2897.
// C2897_b.cpp
// compile with: /c /clr
ref struct R2 {
protected:
template<typename T> !R2(){} // C2897 error
};
Compiler Error C2898
10/31/2018 • 2 minutes to read • Edit Online
// C2898.cpp
// compile with: /c
class X {
public:
template<typename T> virtual void f(T t) {} // C2898
};
Compiler Errors C2900 Through C2999
10/31/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C2904 'identifier': name already used for a template in the current
scope
ERROR MESSAGE
Compiler Error C2907 register argument 'number' does not specify a valid register
number
Compiler Error C2908 explicit specialization; 'template' has already been instantiated
Compiler Error C2911 'member': cannot be declared or defined in the current scope
Compiler Error C2915 'identifier': 'type' cannot be directly used on the published
surface of a WinRT type. Use 'Platform::Object^' instead to
pass this type
Compiler Error C2919 'type': Operators cannot be used on the published surface of a
WinRT type
Compiler Error C2920 redefinition: 'type': class template/generic has already been
declared as 'declaration'
Compiler Error C2922 'interface': A WinRT interface cannot contain static members
Compiler Error C2926 'identifier': a default member initializer is not allowed for a
member of an anonymous struct within a union
Compiler Error C2927 'identifier': a function template must be called with at least
one argument
Compiler Error C2928 explicit instantiation; 'identifier' is not a function or static data
member of template-class 'class'
Compiler Error C2929 'declarator': explicit instantiation; cannot explicitly force and
suppress instantiation of template-class member
Compiler Error C2947 expecting '>' to terminate template arguments, found 'token'
Compiler Error C2948 explicit instantiation; storage class specifier 'specifier' not
permitted on specialization
Compiler Error C2953 'type': class template has already been defined
Compiler Error C2958 the left delimiter found at 'file(line_number)' was not matched
correctly
Compiler Error C2959 a generic class or function may not be a member of a template
Compiler Error C2967 'identifier': an overriding virtual function must have the same
__declspec(code_seg(...)) as an overridden virtual function
Compiler Error C2969 syntax error: 'token': expected member function definition to
end with '}'
Compiler Error C2972 'type': template parameter 'parameter': the type of non-type
argument is invalid
Compiler Error C2974 'type': invalid template/generic argument for 'parameter', type
expected
Compiler Error C2975 'type': invalid template argument for 'parameter', expected
compile-time constant expression
Compiler Error C2978 syntax error: expected 'keyword1' or 'keyword2'; found type
'type'; non-type parameters are not supported in generics
Compiler Error C2980 C++ exception handling is not supported with /kernel
Compiler Error C2981 the dynamic form of 'keyword' is not supported with /kernel
Compiler Error C2989 'class': class template/generic has already been declared as a
non-class template/generic
Compiler Error C2990 'class': non-class template/generic has already been declared
as a class template/generic
Compiler Error C2993 'type': illegal type for non-type template parameter 'identifier'
Compiler Error C2995 'declaration': function template has already been defined
Compiler Error C2997 'function': array bound cannot be deduced from a default
member initializer
Compiler Error C2999 UNKNOWN ERROR Please choose the Technical Support
command on the Visual C++ Help menu, or open the
Technical Support help file for more information
Compiler Error C2902
10/31/2018 • 2 minutes to read • Edit Online
// C2902.cpp
// compile with: /c
namespace N {
template<class T> class X {};
class Y {};
}
void g() {
N::template + 1; // C2902
}
void f() {
N::template X<int> x1; // OK
}
// C2902b.cpp
// compile with: /clr /c
namespace N {
generic<class T> ref class GC {};
}
void f() {
N::generic + 1; // C2902
N::generic GC<int>^ x;
}
Compiler Error C2903
10/31/2018 • 2 minutes to read • Edit Online
// C2903.cpp
// compile with: /c
namespace N {
template<class T> class X {};
class Y {};
}
void g() {
N::template Y y; // C2903
N::X<N::Y> y; // OK
}
// C2903b.cpp
// compile with: /clr /c
namespace N {
class Y {};
generic<class T> ref class Z {};
}
void f() {
N::generic Y y; // C2903
N:: generic Z<int>^ z; // OK
}
Compiler Error C2904
10/31/2018 • 2 minutes to read • Edit Online
// C2904.cpp
// compile with: /c
void X(); // X is declared as a function
template<class T> class X{}; // C2904
Compiler Error C2906
10/31/2018 • 2 minutes to read • Edit Online
// C2906.cpp
// compile with: /c
template<class T> class X{}; // primary template
class X<int> { } // C2906
template<> class X<int> { }; // new syntax
Compiler Error C2908
10/31/2018 • 2 minutes to read • Edit Online
// C2908.cpp
// compile with: /c
template<class T> class X {};
void f() {
X<int> x; //specialization and instantiation
//of X<int>
}
// C2909.cpp
// compile with: /c
template<class T> int f(T);
template f<int>(int); // C2909
template int f<int>(int); // OK
Compiler Error C2910
10/31/2018 • 2 minutes to read • Edit Online
// C2910.cpp
// compile with: /c
template <class T>
struct S;
C2910 can also be generated if you try to explicitly specialize a non-template member. That is, you can only
explicitly specialize a function template.
The following sample generates C2910:
// C2910b.cpp
// compile with: /c
template <class T> struct A {
A(T* p);
};
This error will also be generated as a result of compiler conformance work that was done in Visual Studio .NET
2003:.
For code will be valid in the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, remove
template <> .
// C2911.cpp
struct A;
namespace M {
struct D;
}
namespace N {
struct C;
namespace O {
struct B;
}
// in N
struct ::A {}; // C2911 A is member of global NS
struct O::B{}; // OK B is in O, O is inside of N
struct C {}; // OK C is member of N
struct M::D {}; // C2911 D is member of M, M not enclosed by N
}
Compiler Error C2912
10/31/2018 • 2 minutes to read • Edit Online
// C2912.cpp
// compile with: /c
void f(char);
template<> void f(char); // C2912
template<class T> void f(T); // OK
This error will also be generated as a result of compiler conformance work that was done in Visual Studio .NET
2003: for every explicit specialization, you must choose the parameters of the explicit specialization, such that, they
match the parameters of the primary template.
// C2912b.cpp
class CF {
public:
template <class A> CF(const A& a) {} // primary template
// C2913.cpp
// compile with: /c
class X{};
template <class T> class Y{};
// C2914.cpp
// compile with: /c
void f(int);
void f(double);
template<class T> void g(void (*) (T));
void h() { g(f); } // C2914
// try the following line instead
// void h() { g<int>(f); }
C2914 can also occur when using generics. The following sample generates C2914:
// C2914b.cpp
// compile with: /clr /c
void f(int);
void f(double);
template<class T>
void gf(void (*) (T));
Example
The following sample generates C2917.
// C2917.cpp
// compile with: /c
template<class T> class Vector {
void sort();
};
'name': Indexed properties cannot be used on the published surface of a WinRT type
Indexed properties are not supported on the published surface of a WinRT type.
Compiler Error C2919
10/31/2018 • 2 minutes to read • Edit Online
redefinition : 'class' : class template or generic has already been declared as 'type'
A generic or template class has multiple declarations, which are not equivalent. To fix this error, use different names
for different types, or remove the redefinition of the type name.
The following sample generates C2920 and shows how to fix it:
// C2920.cpp
// compile with: /c
typedef int TC1;
template <class T>
struct TC1 {}; // C2920
struct TC2 {}; // OK - fix by using a different name
// C2920b.cpp
// compile with: /clr /c
typedef int GC1;
generic <class T>
ref struct GC1 {}; // C2920
ref struct GC2 {}; // OK - fix by using a different name
Compiler Error C2921
10/31/2018 • 2 minutes to read • Edit Online
// C2921.cpp
// compile with: /c
template <class T> struct TC2 {};
typedef int TC2; // C2921
// try the following line instead
// typedef struct TC2<int> x; // OK - declare a template instance
// C2921b.cpp
// compile with: /clr /c
generic <class T> ref struct GC2 {};
typedef int GC2; // C2921
// try the following line instead
// typedef ref struct GC2<int> x;
Compiler Error C2923
10/31/2018 • 2 minutes to read • Edit Online
'type' : 'identifier' is not a valid template type argument for parameter 'param'
The argument list is missing a type needed to instantiate the template or generic. Check the template or generic
declaration.
The following sample generates C2923:
// C2923.cpp
template <class T> struct TC {};
int x;
int main() {
TC<x>* tc2; // C2923
TC<int>* tc2; // OK
}
// C2923b.cpp
// compile with: /clr /c
generic <class T> ref struct GC {};
int x;
int main() {
GC<x>^ gc2; // C2923
GC<int>^ gc2; // OK
}
Compiler Error C2927
10/31/2018 • 2 minutes to read • Edit Online
explicit instantiation; 'identifier' is not a function or static data member of template-class 'class'
You cannot explicitly instantiate a member of class that is not a function or static variable.
Compiler Error C2929
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member
You cannot explicitly instantiate an identifier while preventing it from being instantiated.
The following sample generates C2929:
// C2929.cpp
// compile with: /c
template<typename T>
class A {
public:
A() {}
};
template A<int>::A();
// C2930.cpp
// compile with: /c
template<class T>
class x{};
enum SomeEnum { x }; // C2930
class y{};
enum SomeEnum { y };
// C2930c.cpp
// compile with: /clr /c
generic<class T>
ref struct GC {};
enum SomeEnum { GC }; // C2930
// C2931.cpp
// compile with: /c
template<class T>
struct TC { };
struct MyStruct {
void TC<int>(); // C2931
};
struct TC2 { };
struct MyStruct2 {
void TC2();
};
// C2931b.cpp
// compile with: /clr /c
generic<class T> ref struct GC {};
struct MyStruct {
void GC<int>(); // C2931
void GC2(); // OK
};
Compiler Error C2932
10/31/2018 • 2 minutes to read • Edit Online
// C2932.cpp
// compile with: /c
template<class T>
struct TC {};
struct MyStruct {
int TC<int>; // C2932
int TC; // OK
};
// C2932b.cpp
// compile with: /clr /c
generic<class T>
ref struct GC {};
struct MyStruct {
int GC<int>; // C2932
int GC; // OK
};
Compiler Error C2933
10/31/2018 • 2 minutes to read • Edit Online
// C2933.cpp
// compile with: /c
template<class T> struct TC { };
struct MyStruct {
typedef int TC<int>; // C2933
};
struct TC2 { };
struct MyStruct2 {
typedef int TC2;
};
// C2933b.cpp
// compile with: /clr /c
generic<class T> ref struct GC { };
struct MyStruct {
typedef int GC<int>; // C2933
};
// C2935.cpp
// compile with: /c
template<class T>
struct TC {};
void TC<int>() {} // C2935
// OK
struct TC2 {};
void TC2() {}
// C2935b.cpp
// compile with: /clr /c
generic<class T>
ref struct GC { };
void GC<int>() {} // C2935
void GC() {} // OK
Compiler Error C2936
10/31/2018 • 2 minutes to read • Edit Online
// C2936.cpp
// compile with: /c
template<class T> struct TC { };
int TC<int>; // C2936
// OK
struct TC2 { };
int TC2;
// C2936b.cpp
// compile with: /clr /c
generic<class T>
ref struct GC {};
int GC<int>; // C2936
// OK
ref struct GC2 {};
int GC2;
Compiler Error C2937
10/31/2018 • 2 minutes to read • Edit Online
// C2937.cpp
// compile with: /c
template<class T>
struct TC { };
typedef int TC<int>; // C2937
typedef TC<int> c; // OK
// C2937b.cpp
// compile with: /clr
generic<class T>
ref struct GC { };
typedef int GC<int>; // C2937
typedef GC<int> xx; // OK
Compiler Error C2939
10/31/2018 • 2 minutes to read • Edit Online
// C2939.cpp
template<class T>
struct TC { };
int main() {
int TC<int>; // C2939
int TC; // OK
}
// C2939b.cpp
// compile with: /clr
generic<class T>
ref struct GC { };
int main() {
int GC<int>; // C2939
int GC; // OK
}
Compiler Error C2940
10/31/2018 • 2 minutes to read • Edit Online
// C2940.cpp
template<class T>
struct TC {};
int main() {
typedef int TC<int>; // C2940
typedef int TC; // OK
}
// C2940b.cpp
// compile with: /clr
generic<class T>
ref struct GC { };
int main() {
typedef int GC<int>; // C2940
typedef int GC;
}
Compiler Error C2941
10/31/2018 • 2 minutes to read • Edit Online
// C2942.cpp
// compile with: /c
template<class T>
struct TC {};
void f(int TC<int>) {} // C2942
// OK
struct TC2 {};
void f(TC2 i) {}
// C2942b.cpp
// compile with: /clr /c
generic<class T>
ref struct GC {};
void f(int GC<int>) {} // C2942
ref struct GC2 { };
void f(int GC2) {}
Compiler Error C2943
10/31/2018 • 2 minutes to read • Edit Online
// C2943.cpp
// compile with: /c
template<class T>
class List {};
// C2944.cpp
// compile with: /c
template<class T>
class TC { };
// C2944b.cpp
// compile with: /clr /c
generic<class T>
ref class GC {};
Example
The following sample generates C2946.
// C2946.cpp
class C {};
template C; // C2946
int main() {}
Compiler Error C2947
10/31/2018 • 2 minutes to read • Edit Online
// C2947.cpp
// compile with: /c
template <typename T>= // C2947
// try the following line instead
// template <typename T>
struct A {};
Compiler Error C2948
10/31/2018 • 2 minutes to read • Edit Online
// C2951.cpp
template <class T>
class A {};
int main() {
template <class T> // C2951
class B {};
}
// C2951b.cpp
// compile with: /clr /c
// OK
generic <class T>
ref class GC { };
int main() {
generic <class T> ref class GC2 {}; // C2951
}
Compiler Error C2952
10/31/2018 • 2 minutes to read • Edit Online
// C2952.cpp
// compile with: /c
template <class T>
struct S {
template <class T1>
struct S1 {
void f();
};
};
// OK
template <class T>
template <class T1>
void S<T>::S1<T1>::f() {}
// C2952b.cpp
// compile with: /clr /c
generic <class T>
ref struct GC {
generic <class T1>
ref struct GC1 {
void f();
};
};
// OK
generic <class T>
generic <class T1>
void GC<T>::GC1<T1>::f() {}
Compiler Error C2953
10/31/2018 • 2 minutes to read • Edit Online
// C2953.cpp
// compile with: /c
template <class T> class A {};
template <class T> class A {}; // C2953
template <class T> class B {}; // OK
Compiler Error C2955
11/9/2018 • 2 minutes to read • Edit Online
'identifier' : use of class template or alias generic requires template or generic argument list
You cannot use a class template or class generic as an identifier without a template or generic argument list.
For more information, see Class Templates.
The following sample generates C2955 and shows how to fix it:
// C2955.cpp
// compile with: /c
template<class T>
class X {};
X x1; // C2955
X<int> x2; // OK - this is how to fix it.
C2955 can also occur when attempting an out-of-line definition for a function declared in a class template:
// C2955_b.cpp
// compile with: /c
template <class T>
class CT {
public:
void CTFunc();
void CTFunc2();
};
// C2955_c.cpp
// compile with: /clr
generic <class T>
ref struct GC {
T t;
};
int main() {
GC^ g; // C2955
GC <int>^ g;
}
Example
Visual Studio 2017 and later: The compiler correctly diagnoses missing template argument lists when the
template appears in a template parameter list (for example as part of a default template argument or a non-type
template parameter). The following code compiles in Visual Studio 2015 but produces an error in Visual Studio
2017.
// C2957.cpp
// compile with: /clr /LD
generic << class T> // C2957
// try the following line instead
// generic < class T>
gc class C {};
Compiler Error C2958
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2959.
// C2959.cpp
// compile with: /clr /c
template <class T> ref struct S {
generic <class U> ref struct GR1; // C2959
};
Compiler Error C2962
10/31/2018 • 2 minutes to read • Edit Online
syntax error : 'token' : expected template-class member function definition to end with '}'
The token caused a syntax error in a template declaration.
This error can be caused by mismatched delimiters
Compiler Error C2969
10/31/2018 • 2 minutes to read • Edit Online
syntax error : 'symbol' : expected member function definition to end with '}'
A template member function definition has an unmatched closing brace.
The following sample generates C2969:
// C2969.cpp
// compile with: /c
class A {
int i;
public:
A(int i) {}
};
A anA(1);
class B {
A a;
B() : a(anA); // C2969
// try the following line instead
// B() : a(anA) {}
};
Compiler Error C2970
10/31/2018 • 2 minutes to read • Edit Online
'class' : template parameter 'param' : 'arg' : an expression involving objects with internal linkage cannot be used as
a non-type argument
You cannot use the name or address of a static variable as a template argument. The template class expects a const
value that can be evaluated at compile time.
The following sample generates C2970:
// C2970.cpp
// compile with: /c
static int si;
// could declare nonstatic to resolve all errors
// int si;
'class' : template parameter 'param' : 'arg' : a local variable cannot be used as a non-type argument
You cannot use the name or address of a local variable as a template argument.
The following sample generates C2971:
// C2971.cpp
template <int *pi>
class Y {};
int global_var = 0;
int main() {
int local_var = 0;
Y<&local_var> aY; // C2971
// try the following line instead
// Y<&global_var> aY;
}
Compiler Error C2973
10/31/2018 • 2 minutes to read • Edit Online
// C2974.cpp
// C2974 expected
template <class T>
struct TC {};
int main() {
// Delete the following 2 lines to resolve
TC<1>* tc;
tf<"abc">("abc");
TC<int>* tc;
tf<const char *>("abc");
}
// C2974b.cpp
// compile with: /clr
// C2974 expected
using namespace System;
generic <class T>
ref struct GCtype {};
int main() {
// Delete the following 2 lines to resolve
GCtype<"a">^ gc;
gf<"a">("abc");
// OK
GCtype<int>^ gc;
gf<String ^>("abc");
}
Compiler Error C2975
10/31/2018 • 2 minutes to read • Edit Online
'argument' : invalid template argument for 'type', expected compile-time constant expression
The template argument does not match the template declaration; a constant expression should appear within the
angle brackets. Variables are not allowed as template actual arguments. Check the template definition to find the
correct types.
Example
The following sample generates C2975 and also shows correct usage:
// C2975.cpp
template<int I>
class X {};
int main() {
int i = 4, j = 2;
X<i + j> x1; // C2975
X<6> x2; // OK
}
C2975 also occurs when you use __LINE__ as a compile-time constant with /ZI. One solution would be to compile
with /Zi instead of /ZI.
// C2975b.cpp
// compile with: /ZI
// processor: x86
template<long line>
void test(void) {}
int main() {
test<__LINE__>(); // C2975
}
Compiler Error C2976
10/31/2018 • 2 minutes to read • Edit Online
// C2976.cpp
template <class T>
struct TC {
T t;
};
int main() {
TC<>* t; // C2976
TC<int>* t2; // OK
}
// C2976b.cpp
// compile with: /clr
generic <class T>
ref struct GC {
T t;
};
int main() {
GC<>^ g; // C2976
GC<int>^ g2; // OK
}
Compiler Error C2977
10/31/2018 • 2 minutes to read • Edit Online
// C2977.cpp
// compile with: /c
template<class T, int i>
class MyClass {};
// C2977b.cpp
// compile with: /clr
// C2977 expected
generic <class T, class U>
void f(){}
int main() {
// Delete the following 2 lines to resolve.
GC1<int, char> ^ pgc1;
f<int,int,int>();
// OK
GC1<int> ^ pgc1;
f<int, int>();
}
Compiler Error C2978
10/31/2018 • 2 minutes to read • Edit Online
syntax error : expected 'keyword1' or 'keyword2'; found type 'keyword3'; non-type parameters are not supported
in generics
A generic class was declared incorrectly. See Genericsfor more information.
Example
The following sample generates C2978.
// C2978.cpp
// compile with: /clr /c
generic <ref class T> // C2978
// try the following line instead
// generic <typename T> // OK
ref class Utils {
static void sort(T elems, size_t size);
};
generic <int>
// try the following line instead
// generic <class T>
ref class Utils2 {
static void sort(T elems, size_t size);
};
Compiler Error C2979
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2979.
// C2979.cpp
// compile with: /clr /c
generic <>
ref class Utils {}; // C2979 error
// C2989.cpp
// compile with: /c
class C{};
// C2989b.cpp
// compile with: /clr /c
ref class GC1;
// C2990.cpp
// compile with: /c
template <class T>
class C{};
class C{}; // C2990
// C2990b.cpp
// compile with: /clr /c
generic <class T>
ref struct GC;
C2990 can also occur due to a breaking change in the Visual C++ compiler for Visual C++ 2005; the compiler
now requires that multiple declarations for the same type be identical with respect to template specification.
The following sample generates C2990:
// C2990c.cpp
// compile with: /c
template<class T>
class A;
template<class T>
struct A2 {
friend class A; // C2990
};
// OK
template<class T>
struct B {
template<class T>
friend class A;
};
Compiler Error C2991
10/31/2018 • 2 minutes to read • Edit Online
// C2991.cpp
// compile with: /c
template<class T, class T> struct TC {}; // C2991
// try the following line instead
// template<class T, class T2> struct TC {};
// C2991b.cpp
// compile with: /clr /c
generic<class T,class T> ref struct GC {}; // C2991
// try the following line instead
// generic<class T,class T2> ref struct GC {};
Compiler Error C2992
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C2992:
// C2992.cpp
// compile with: /c
template <class T>
struct TC1 {
template <class U>
struct TC2;
};
// OK
template <class T>
template <class U>
struct TC1<T>::TC2 {};
// C2992 can also occur when using generics:
// C2992c.cpp
// compile with: /clr /c
generic <class T>
ref struct GC1 {
generic <class U>
ref struct GC2;
};
// OK
generic <class T>
generic <class U>
ref struct GC1<T>::GC2 {};
Compiler Error C2993
10/31/2018 • 2 minutes to read • Edit Online
// C2993.cpp
// compile with: /c
// C2993 expected
struct MyStruct {
int a;char b;
};
This error will also be generated as a result of compiler conformance work that was done in Visual Studio .NET
2003: floating point non-type template parameters no longer allowed. The C++ standard does not allow floating
point non-type template parameters.
If it is a function template, use a function argument to pass in the floating point non-type template parameter (this
code will be valid in the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++). If it is a class
template, there is no easy workaround.
// C2993b.cpp
// compile with: /c
template<class T, float f> void func(T) {} // C2993
// OK
template<class T> void func2(T, float) {}
Compiler Error C2994
10/31/2018 • 2 minutes to read • Edit Online
// C2995.cpp
// compile with: /c
template <class T>
void Test(T x){}
// C2998.cpp
// compile with: /c
template <class T> int x = 1018; // C2998
Compiler Errors C3000 Through C3099
10/31/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3003 'directive': OpenMP directive name not allowed after directive
clauses
Compiler Error C3004 'clause': clause not valid on OpenMP 'directive' directive
Compiler Error C3007 'clause': clause on OpenMP 'directive' directive does not take
an argument
Compiler Error C3009 'label': jump into OpenMP structured block not allowed
Compiler Error C3010 'label': jump out of OpenMP structured block not allowed
Compiler Error C3011 inline assembly not allowed directly within a parallel region
Compiler Error C3012 'function': intrinsic function not allowed directly within a
parallel region
Compiler Error C3013 'clause': clause may only appear once on OpenMP 'directive'
directive
Compiler Error C3014 expected a for loop following OpenMP 'directive' directive
Compiler Error C3015 initialization in OpenMP 'for' statement has improper form
Compiler Error C3016 'identifier': index variable in OpenMP 'for' statement must
have signed integral type
Compiler Error C3017 termination test in OpenMP 'for' statement has improper form
Compiler Error C3018 'identifier': OpenMP 'for' test or increment must use index
variable 'variable'
Compiler Error C3019 increment in OpenMP 'for' statement has improper form
Compiler Error C3020 'variable': index variable of OpenMP 'for' loop cannot be
modified in loop body
Compiler Error C3028 'member': only a variable or static data member can be used in
a data-sharing clause
Compiler Error C3029 'symbol': can only appear once in data-sharing clauses in an
OpenMP directive
Compiler Error C3031 'identifier': variable in 'reduction' clause must have scalar
arithmetic type
Compiler Error C3032 'identifier': variable in 'clause' clause cannot have incomplete
type 'type'
Compiler Error C3033 'identifier': variable in 'clause' clause cannot have const-
qualified type
Compiler Error C3034 OpenMP 'directive' directive cannot be directly nested within
'directive' directive
Compiler Error C3035 OpenMP 'ordered' directive must bind directly to a 'for' or
'parallel for' directive with the 'ordered' clause
Compiler Error C3036 'clause': invalid operator token in OpenMP 'reduction' clause
Compiler Error C3039 'identifier': index variable in OpenMP 'for' statement cannot
be a reduction variable
Compiler Error C3042 'copyprivate' and 'nowait' clauses cannot appear together on
OpenMP 'directive' directive
Compiler Error C3044 'section': only allowed directly nested under an OpenMP
'sections' directive
ERROR MESSAGE
Compiler Error C3048 Expression following '#pragma omp atomic' has improper form
Compiler Error C3050 'class': a ref class cannot inherit from 'identifier'
Compiler Error C3053 'identifier': 'threadprivate' is only valid for global or static data
items
Compiler Error C3054 '#pragma omp parallel' is currently not supported in a generic
class or function
Compiler Error C3056 'identifier': symbol is not in the same scope with
'threadprivate' directive
Compiler Error C3060 'identifier': a friend function may not be defined inside a class
using a qualified name (it may only be declared)
Compiler Error C3061 operator 'operator': not allowed on enumeration 'type' with
underlying type 'type'
Compiler Error C3062 'identifier': enumerator requires value since the underlying
type is 'type'
Compiler Error C3063 operator 'operator': all operands must have the same
enumeration type
ERROR MESSAGE
Compiler Error C3066 there are multiple ways that an object of this type can be
called with these arguments
Compiler Error C3067 an initializer list cannot be used with the built-in operator[]
Compiler Error C3068 'identifier': a 'naked' function cannot contain objects that
would require unwinding if a C++ exception occurred
Compiler Error C3069 operator 'operator': not allowed for enumeration type
Compiler Error C3070 'identifier': property does not have a 'set' method
Compiler Error C3071 operator 'operator' can only be applied to an instance of a ref
class or a value-type
Compiler Error C3073 'identifier': ref class does not have a user-defined copy
constructor
Compiler Error C3075 'identifier': you cannot embed an instance of a reference type,
'type', in a value-type
Compiler Error C3076 'identifier': you cannot embed an instance of a reference type,
'type', in a native type
Compiler Error C3079 an initializer list cannot be used as the right operand of this
assignment operator
Compiler Error C3083 'identifier': the symbol to the left of a '::' must be a type
Compiler Error C3087 'identifier': call of 'declaration' already initializes this member
Compiler Error C3088 'class': attribute constructor must have named formal
arguments
Compiler Error C3089 'identifier': parameter name does not match any data
member's name
Compiler Error C3091 'class': attribute class cannot have base classes
Compiler Error C3092 'class': attribute class member cannot be a bit field, 'static' or
'const'
Compiler Error C3093 'type': type not allowed for attribute class member 'member'
// C3001.c
// compile with: /openmp
int main()
{
#pragma omp // C3001 missing token
}
Compiler Error C3002
10/31/2018 • 2 minutes to read • Edit Online
// C3002.c
// compile with: /openmp
int main()
{
#pragma omp parallel single // C3002
}
Compiler Error C3003
10/31/2018 • 2 minutes to read • Edit Online
// C3003.c
// compile with: /openmp
int main()
{
int x, y, z;
#pragma omp parallel shared(x, y, z) for // C3003
}
Compiler Error C3004
10/31/2018 • 2 minutes to read • Edit Online
// C3004.c
// compile with: /openmp
int main()
{
int x, y, z;
x = y;
}
Compiler Error C3005
10/31/2018 • 2 minutes to read • Edit Online
// C3005.c
// compile with: /openmp
int main()
{
#pragma omp parallel + for // C3005
}
C3005 can also occur if you put an open brace on the same line as the pragma.
// C3005b.c
// compile with: /openmp
int main() {
#pragma omp parallel { // C3005 put open brace on next line
lbl2:;
}
goto lbl2;
}
Compiler Error C3006
10/31/2018 • 2 minutes to read • Edit Online
// C3006.c
// compile with: /openmp
int main()
{
#pragma omp parallel shared // C3006
// Try the following line instead:
// #pragma omp parallel shared(x) {}
}
Compiler Error C3007
10/31/2018 • 2 minutes to read • Edit Online
// C3007.c
// compile with: /openmp
int main()
{
#pragma omp parallel for ordered(2) // C3007
}
Compiler Error C3008
10/31/2018 • 2 minutes to read • Edit Online
// C3008.c
// compile with: /openmp
int main()
{
int x, y, z;
#pragma omp parallel shared(x // C3008
// Try the following line instead:
#pragma omp parallel shared(x)
{
}
}
Compiler Error C3009
10/31/2018 • 2 minutes to read • Edit Online
// C3009.c
// compile with: /openmp
int main() {
#pragma omp parallel
{
lbl2:;
}
goto lbl2; // C3009
}
Compiler Error C3010
10/31/2018 • 2 minutes to read • Edit Online
// C3010.c
// compile with: /openmp
int main() {
#pragma omp parallel
{
#pragma omp parallel
{
goto lbl3;
}
}
lbl3:; // C3010
}
Compiler Error C3011
10/31/2018 • 2 minutes to read • Edit Online
// C3011.cpp
// compile with: /openmp
// processor: /x86
int main() {
int n = 0;
A compiler intrinsic function is not allowed in an omp parallel region. To fix this issue, move intrinsics out of the
region, or replace them with non-intrinsic equivalents.
Example
The following sample generates C3012, and shows one way to fix it:
// C3012.cpp
// compile with: /openmp
#ifdef __cplusplus
extern "C" {
#endif
void* _ReturnAddress();
#ifdef __cplusplus
}
#endif
int main()
{
#pragma omp parallel
{
_ReturnAddress(); // C3012
}
_ReturnAddress(); // OK
}
Compiler Error C3013
10/31/2018 • 2 minutes to read • Edit Online
// C3013.cpp
// compile with: /openmp
int main() {
int a, b, c, x, y, z;
// C3014.cpp
// compile with: /openmp
int main()
{
int i = 0;
// C3015.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 10;
'var' : index variable in OpenMP 'for' statement must have signed integral type
The index variable in an OpenMP for statement must be a signed integral type.
The following sample generates C3016:
// C3016.cpp
// compile with: /openmp
int main()
{
#pragma omp parallel
{
unsigned int i = 0;
// Try the following line instead:
// int i = 0;
// C3017.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 10;
'var1' : OpenMP 'for' test or increment must use index variable 'var2'
A for loop in an OpenMP statement must use the same variable for its test and increment as it uses for its index.
The following sample generates C3018:
// C3018.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 5;
// C3019.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 1, n = 3;
'var' : index variable of OpenMP 'for' loop cannot be modified in loop body
An OpenMP for loop may not modify the index (loop counter) in the body of the for loop.
The following sample generates C3020:
// C3020.cpp
// compile with: /openmp
int main() {
int i = 0, n = 3;
A variable declared with lastprivate cannot be used as the index inside a parallelized loop.
The following sample will give C3020 for the second lastprivate because that lastprivate will trigger a write to idx_a
within the outermost for loop. The first lastprivate doesn't give an error because that lastprivate triggers a write to
idx_a outside the outermost for loop (technically, at the very end of the last iteration). The following sample
generates C3020.
// C3020b.cpp
// compile with: /openmp /c
float a[100][100];
int idx_a, idx_b;
void test(int first, int last)
{
#pragma omp parallel for lastprivate(idx_a)
for (idx_a = first; idx_a <= last; ++idx_a) {
#pragma omp parallel for lastprivate(idx_a) // C3020
for (idx_b = first; idx_b <= last; ++idx_b) {
a[idx_a][idx_b] += 1.0f;
}
}
}
Example
The following sample generates C3021:
// C3021.cpp
// compile with: /openmp
#include <stdio.h>
#include "omp.h"
int g = 0;
int main()
{
int x, y, i;
//
// The following shows correct syntax examples.
//
#pragma omp parallel reduction(+ : x, y)
;
// C3022.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
int main() {
int i;
// OK
#pragma omp parallel for schedule(runtime)
for (i = 0; i < 10; ++i)
;
}
Compiler Error C3023
10/31/2018 • 2 minutes to read • Edit Online
// C3023.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
int main() {
int i;
// OK
#pragma omp parallel for schedule(dynamic, 10)
for (i = 0; i < 10; ++i)
;
}
Compiler Error C3024
10/31/2018 • 2 minutes to read • Edit Online
// C3024.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
int main() {
int i;
Example
The following sample generates C3025.
// C3025.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
float f = 2.0F;
int main()
{
int i = 0;
// OK
puts("Test with int");
#pragma omp parallel for num_threads(i)
for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);
Example
The following sample generates C3026:
// C3026.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
int main()
{
int i;
const int i1 = 0;
Example
The following sample generates C3027:
// C3027.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
struct MyStruct
{
int x;
} m_MyStruct;
int main()
{
int i;
'member' : only a variable or static data member can be used in a data-sharing clause
A symbol other than a variable or static data member was passed to the reduction clause.
The following sample generates C3028:
// C3028.cpp
// compile with: /openmp /link vcomps.lib
int g_i;
class MyClass {
public:
MyClass();
MyClass(int x);
static int x_public;
int mbr;
private:
static int x_private;
};
int MyClass::x_public;
int MyClass::x_private;
namespace XyzNS {
struct xyz { int x; };
xyz xyz;
}
namespace NS {
int a1;
struct Bar {
static MyClass MyClass;
};
struct Baz : public Bar {
using NS::Bar::MyClass;
};
}
MyClass NS::Bar::MyClass;
CTempl<int,5> tx;
struct Incomplete;
extern Incomplete inc;
MyClass::MyClass(int x) {
#pragma omp parallel reduction(+: x, g_i, x_public, x_private)
// OK
;
int main() {
// C3029.cpp
// compile with: /openmp /link vcomps.lib
#include "omp.h"
int g_i;
int main() {
int i, x;
// C3030.cpp
// compile with: /openmp /link vcomps.lib
#include "omp.h"
void test2(int r) {
#pragma omp parallel reduction(+ : r) // OK
;
}
// C3031.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"
typedef struct {
int n;
} Incomplete;
int main() {
#pragma omp parallel reduction(+: inc) // C3031
;
// C3032.cpp
// compile with: /openmp /link vcomps.lib
#include "omp.h"
struct Incomplete;
extern struct Incomplete inc;
int main() {
int i = 9;
#pragma omp parallel private(inc) // C3032
;
}
Compiler Error C3033
10/31/2018 • 2 minutes to read • Edit Online
// C3033.cpp
// compile with: /openmp /link vcomps.lib
int main() {
const int val = 1;
int val2 = 1;
// C3034.cpp
// compile with: /openmp /link vcomps.lib
int main() {
OpenMP 'ordered' directive must bind directly to a 'for' or 'parallel for' directive with the 'ordered' clause
An ordered clause was ill formed.
The following sample generates C3035:
// C3035.cpp
// compile with: /openmp /link vcomps.lib
int main() {
int n = 0, x, i;
// C3036.cpp
// compile with: /openmp
static float a[1000], b[1000], c[1000];
void test1(int first, int last) {
static float dp = 0.0f;
#pragma omp for nowait reduction(.:dp) // C3036
// try the following line instead
// #pragma omp for nowait reduction(+: dp)
for (int i = first ; i <= last ; ++i)
dp += a[i] * b[i];
}
Compiler Error C3037
10/31/2018 • 2 minutes to read • Edit Online
// C3037.cpp
// compile with: /openmp /c
int g_i;
int main() {
int i;
// C3038.cpp
// compile with: /openmp /c
int g_i, g_i2;
int main() {
int i;
Example
The following sample generates C3039:
// C3039.cpp
// compile with: /openmp /c
int g_i;
int main() {
int i;
'var' : type of variable in 'reduction' clause is incompatible with reduction operator 'operator'
A variable in a reduction clause cannot be used with the reduction operator.
The following sample generates C3040:
// C3040.cpp
// compile with: /openmp /c
#include "omp.h"
double d;
int main() {
#pragma omp parallel reduction(&:d) // C3040
;
// C3041.cpp
// compile with: /openmp /c
#include "omp.h"
double d;
int main() {
#pragma omp parallel shared(d)
// try the following line instead
// #pragma omp parallel private(d)
{
// or don't make d copyprivate
#pragma omp single copyprivate(d) // C3041
{
}
}
}
Compiler Error C3042
10/31/2018 • 2 minutes to read • Edit Online
'copyprivate' and 'nowait' clauses cannot appear together on OpenMP 'directive' directive
The copyprivate and nowait clauses are mutually exclusive on the specified directive. To fix this error, remove one
or both of the copyprivate or nowait clauses.
The following sample generates C3042:
// C3042.cpp
// compile with: /openmp /c
#include <stdio.h>
#include "omp.h"
double d;
int main() {
#pragma omp parallel private(d)
{
#pragma omp single copyprivate(d) nowait // C3042
{
}
}
}
Compiler Error C3043
10/31/2018 • 2 minutes to read • Edit Online
OpenMP 'critical' directive cannot be nested in 'critical' directive with same name
A critical directive cannot be nested in a critical directive that uses the same name.
The following sample generates C3043:
// C3043.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n1 = 1, n2 = 2, n3 = 3;
// C3044.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n2 = 2, n3 = 3;
// C3045.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n2 = 2, n3 = 3;
// C3046.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n2 = 2, n3 = 3;
Structured block in an OpenMP 'sections' region must be preceded by '#pragma omp section'
Any code in a code block introduced by a sections directive must be in a code block introduced by a section
directive.
The following sample generates C3047:
// C3047.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n2 = 2, n3 = 3;
// C3048.cpp
// compile with: /openmp vcomps.lib
#include "omp.h"
#include <stdio.h>
int main() {
int a[10];
omp_set_num_threads(4);
#pragma omp parallel
{
#pragma omp atomic
a[0] = 1; // C3048
// try the following line instead
// a[0] += 1;
}
}
Compiler Error C3049
10/31/2018 • 2 minutes to read • Edit Online
// C3049.cpp
// compile with: /openmp /c
int main() {
int n1 = 1;
// C3050.cpp
// compile with: /clr /LD
ref struct X : System::ValueType {}; // C3050
ref struct Y {}; // OK
Compiler Error C3052
10/31/2018 • 2 minutes to read • Edit Online
// C3052.cpp
// compile with: /openmp /c
int main() {
int n1 = 1;
// C3053.cpp
// compile with: /openmp
void Test() {
int x, y;
#pragma omp threadprivate(x, y) // C3053
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Possible resolution:
// C3053b.cpp
// compile with: /openmp /LD
int x, y;
#pragma omp threadprivate(x, y)
void Test() {
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Compiler Error C3054
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3054.
// C3054.cpp
// compile with: /openmp /clr /c
#include <omp.h>
// OK
void Test2() {
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
}
}
};
Compiler Error C3055
10/31/2018 • 2 minutes to read • Edit Online
// C3055.cpp
// compile with: /openmp
int x, y;
int z = x;
#pragma omp threadprivate(x, y) // C3055
void test() {
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Possible resolution:
// C3055b.cpp
// compile with: /openmp /LD
int x, y, z;
#pragma omp threadprivate(x, y)
void test() {
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Compiler Error C3056
10/31/2018 • 2 minutes to read • Edit Online
// C3056.cpp
// compile with: /openmp
int x, y;
void test() {
#pragma omp threadprivate(x, y) // C3056
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Possible resolution:
// C3056b.cpp
// compile with: /openmp /LD
int x, y;
#pragma omp threadprivate(x, y)
void test() {
#pragma omp parallel copyin(x, y)
{
x = y;
}
}
Compiler Error C3057
10/31/2018 • 2 minutes to read • Edit Online
// C3057.cpp
// compile with: /openmp /c
extern int f();
int x, y = f();
int a, b;
#pragma omp threadprivate(x, y) // C3057
int main() {
// Delete the following 4 lines to resolve.
#pragma omp parallel copyin(x, y)
{
x = y;
}
// C3057b.cpp
// compile with: /openmp /c
extern int Initialize();
int main() {
#pragma omp parallel
{
static int var = Initialize();
#pragma omp threadprivate(var) // C3057
}
// OK
#pragma omp parallel
{
static int var2;
static bool initialized2;
#pragma omp threadprivate(var2, initialized2)
if (!initialized2) {
var2 = Initialize();
initialized2 = true;
}
}
}
Compiler Error C3058
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : symbol not declared as 'threadprivate' before it is used in the 'copyin' clause
A symbol must first be declared threadprivate before it can be used in a copyin clause.
The following sample generates C3058:
// C3058.cpp
// compile with: /openmp
int x, y, z;
#pragma omp threadprivate(x, z)
void test() {
#pragma omp parallel copyin(x, y) // C3058
{
}
}
Possible resolution:
// C3058b.cpp
// compile with: /openmp /LD
int x, y, z;
#pragma omp threadprivate(x, y)
void test() {
#pragma omp parallel copyin(x, y)
{
}
}
Compiler Error C3059
10/31/2018 • 2 minutes to read • Edit Online
// C3059.cpp
// compile with: /openmp
#include "omp.h"
int x, y;
#pragma omp threadprivate(x, y)
int main() {
#pragma omp parallel private(x, y) // C3059
{
x = y;
}
}
Possible resolution:
// C3059b.cpp
// compile with: /openmp
#include "omp.h"
int x = 0, y = 0;
int main() {
#pragma omp parallel firstprivate(y) private(x)
{
x = y;
}
}
Compiler Error C3060
10/31/2018 • 2 minutes to read • Edit Online
'member' : a friend function may not be defined inside a class using a qualified name (it may only be declared)
A friend function was defined using a qualified name, which is not allowed.
The following sample generates C3060:
// C3060.cpp
class A {
public:
void func();
};
class C {
public:
friend void A::func() { } // C3060
// Try the following line and the out of class definition:
// friend void A::func();
};
// void A::func(){}
Compiler Error C3062
10/31/2018 • 2 minutes to read • Edit Online
// C3062.cpp
// compile with: /clr
operator 'operator': all operands must have the same enumeration type
When using operators on enumerators, both operands must be of the enumeration type. For more information,
see How to: Define and consume enums in C++/CLI.
Example
The following sample generates C3063 and shows how to fix it:
// C3063.cpp
// compile with: /clr
enum class E { a, b } e, mask;
int main() {
if ( ( e & mask ) != 0 ) ; // C3063 no operator!= (E, int)
// C3065.cpp
// compile with: /c
__declspec(property(get=get_i)) int i; // C3065
class x {
public:
__declspec(property(get=get_i)) int i; // OK
};
Compiler Error C3066
10/31/2018 • 2 minutes to read • Edit Online
there are multiple ways that an object of this type can be called with these arguments
The compiler detected an ambiguous function call involving surrogates.
The following sample generates C3066:
// C3066.cpp
template <class T, class U> void func(T*, U*){}
struct A {
operator PF() const {
return func;
}
operator PF1() {
return func;
}
};
int main() {
A a;
int i;
char c;
Copy-list-initialization
In Visual Studio 2015, the compiler erroneously treated copy-list-initialization in the same way as regular copy-
initialization; it considered only converting constructors for overload resolution. In the following example, Visual
Studio 2015 chooses MyInt(23) but Visual Studio 2017 correctly raises the error.
// From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1228
struct MyList {
explicit MyStore(int initialCapacity);
};
struct MyInt {
MyInt(int i);
};
struct Printer {
void operator()(MyStore const& s);
void operator()(MyInt const& i);
};
void f() {
Printer p;
p({ 23 }); // C3066: there are multiple ways that an object of this type can be called with these
arguments
}
Compiler Error C3068
10/31/2018 • 2 minutes to read • Edit Online
'function' : a 'naked' function cannot contain objects that would require unwinding if a C++ exception occurred
The compiler was unable to perform stack unwinding on a naked function that threw an exception because a
temporary object was created in the function and C++ exception handling (/EHsc) was specified.
To resolve this error, do at least one of the following:
Do not compile with /EHsc.
Do not mark the function as naked .
Do not create a temporary object in the function.
If a function creates a temporary object on the stack, if the function throws an exception, and if C++ exception
handling is enabled, the compiler will clean up the stack if an exception is thrown.
When an exception is thrown, compiler generated code, called the prolog and epilog and which are not present in a
naked function, is executed for a function.
Example
The following sample generates C3068:
// C3068.cpp
// compile with: /EHsc
// processor: x86
class A {
public:
A(){}
~A(){}
};
void b(A){}
Example
The following sample generates C3069:
// C3069.cpp
// compile with: /clr
enum struct E { e1 };
enum F { f1 };
int main() {
E e = E::e1;
bool tf;
tf = !e; // C3069
// C3070.cpp
// compile with: /clr
ref class R {
public:
R(int size) {
m_data = gcnew array<int>(size);
}
private:
array<int>^ m_data;
};
int main() {
R^ r = gcnew R(10);
r->MyProp[4] = 4; // C3070
int value = 4;
r->MyProp2[4] = value; // OK
r->MyProp3[4] = 4; // OK
}
Compiler Error C3071
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3071.
// C3071.cpp
// compile with: /clr
class N {};
ref struct R {};
int main() {
N n;
%n; // C3071
R r;
R ^ r2 = %r; // OK
}
Compiler Error C3072
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3072.
// C3072.cpp
// compile with: /clr
ref class R {};
int main() {
R r1;
R^ r2 = &r1; // C3072
R^ r3 = %r1; // OK
}
Compiler Error C3073
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3073.
// C3073.cpp
// compile with: /clr
ref class R {
public:
R(int) {}
};
ref class S {
public:
S(int) {}
S(const S %rhs) {} // copy constructor
};
void f(R) {}
void f2(S) {}
void f3(R%){}
int main() {
R r(1);
f(r); // C3073
f3(r); // OK
S s(1);
f2(s); // OK
}
Compiler Error C3075
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3075.
// C3075.cpp
// compile with: /clr /c
ref struct U {};
value struct X {
U y; // C3075
};
ref struct Y {
U y; // OK
};
Compiler Error C3076
10/31/2018 • 2 minutes to read • Edit Online
'instance' : you cannot embed an instance of a reference type, 'type', in a native type
A native type cannot contain an instance of a CLR type.
For more information, see C++ Stack Semantics for Reference Types.
Example
The following sample generates C3076.
// C3076.cpp
// compile with: /clr /c
ref struct U {};
struct V {
U y; // C3076
};
ref struct W {
U y; // OK
};
Compiler Error C3077
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3077.
// C3077.cpp
// compile with: /clr /c
value struct vs {
!vs(){} // C3077
};
ref struct rs {
protected:
!rs(){} // OK
};
Compiler Error C3080
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3080.
// C3080.cpp
// compile with: /clr /c
ref struct rs {
protected:
static !rs(){} // C3080
!rs(){} // OK
};
Compiler Error C3083
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3083.
// C3083.cpp
// compile with: /c
struct N {
~N();
};
struct N1 {
~N1();
};
N::N::~N() {} // C3083
N1::~N1() {} // OK
Compiler Error C3084
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3084.
// C3084.cpp
// compile with: /clr /c
ref struct R {
protected:
!R() sealed; // C3084
!R() abstract; // C3084
!R();
};
Compiler Error C3085
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3085.
// C3085.cpp
// compile with: /c /clr
ref struct S {
S() abstract; // C3085
S(S%) abstract; // C3085
};
ref struct T {
T() sealed {} // C3085
T(T%) sealed {} // C3085
};
Compiler Error C3087
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3087.
// C3087.cpp
// compile with: /c
[idl_quote("quote1", text="quote2")]; // C3087
[idl_quote(text="quote3")]; // OK
[idl_quote("quote4")]; // OK
Compiler Error C3094
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3094.
// C3094.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::Class)]
public ref class AAttribute : Attribute {};
[A]; // C3094
// OK
[A]
ref class x{};
Compiler Error C3095
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3095.
// C3095.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::All, AllowMultiple=false)]
public ref class Attr : public Attribute {
public:
Attr(int t) : m_t(t) {}
const int m_t;
};
[AttributeUsage(AttributeTargets::All, AllowMultiple=true)]
public ref class Attr2 : public Attribute {
public:
Attr2(int t) : m_t(t) {}
const int m_t;
};
[Attr(10)] // C3095
[Attr(11)]
ref class A {};
[Attr2(10)] // OK
[Attr2(11)]
ref class B {};
Compiler Error C3096
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3097.
// C3097.cpp
// compile with: /clr /c
using namespace System;
[Attr(10)]; // C3097
[assembly:Attr(10)]; // OK
[Attr(10)] // OK
public ref class MyClass {};
Compiler Error C3099
3/5/2019 • 2 minutes to read • Edit Online
For more information about /CLR attributes, see User-Defined Attributes. For supported attributes in Windows
Runtime, see Windows.Foundation.Metadata namespace
Example
The following sample generates C3099 and shows how to fix it.
// C3099.cpp
// compile with: /clr /c
using namespace System;
[usage(10)] // C3099
// try the following line instead
// [AttributeUsageAttribute(AttributeTargets::All)]
ref class A : Attribute {};
Compiler Errors C3100 Through C3199
10/31/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3101 illegal expression for named attribute argument 'identifier'
Compiler Error C3108 cannot deduce a type as an initializer list is not an expression
Compiler Error C3109 'identifier': interface methods must use either the '__stdcall' or
'__cdecl' calling convention
Compiler Error C3110 'function': you cannot overload a COM interface method
Compiler Error C3111 An initializer list cannot be used as the default argument for a
template parameter
Compiler Error C3116 'specifier': invalid storage class for interface method
Compiler Error C3117 'interface': an interface can only have one base class
Compiler Error C3120 'identifier': interface methods cannot take a variable argument
list
Compiler Error C3122 'interface': a WinRT generic interface cannot have GUID
Compiler Error C3124 'signed char' is not a valid WinRT data type. Use 'unsigned
char', 'wchar_t' or 'signed short' instead.
Compiler Error C3125 'type': type cannot directly or indirectly derive from
'Platform::Exception'
Compiler Error C3126 cannot define a union 'union' inside of managed/WinRT type
'type'
Compiler Error C3127 'type': 'trait' trait can only be used on a WinRT ref class
Compiler Error C3128 'type' does not have a vtable that was introduced by 'type'
ERROR MESSAGE
Compiler Error C3130 Internal Compiler Error: failed to write injected code block to
PDB
Compiler Error C3131 project must have a 'module' attribute with a 'name' property
Compiler Error C3132 'parameter': parameter arrays can only be applied to a formal
argument of type 'single-dimensional managed/WinRT array'
Compiler Error C3134 'value': value of attribute argument 'argument' does not have
valid type 'type'
Compiler Error C3135 'identifier': a property cannot have a 'const' or 'volatile' type
Compiler Error C3136 'interface': a COM interface can only inherit from another
COM interface, 'interface' is not a COM interface
Compiler Error C3138 'identifier': a 'attribute' interface must inherit from IDispatch,
or from an interface that inherits from IDispatch
Compiler Error C3140 cannot have multiple 'module' attributes in the same
compilation unit
Compiler Error C3142 'property': you cannot take the address of a property
Compiler Error C3143 'argument': attribute argument cannot have multiple values
Compiler Error C3145 'identifier': global or static variable may not have
managed/WinRT type 'type'
Compiler Error C3149 'type': cannot use this type here without a top-level 'token'
ERROR MESSAGE
Compiler Error C3150 'construct': 'attribute' can only be applied to a class, struct,
interface, array or pointer
Compiler Error C3152 'function': 'keyword' can only be applied to a class, struct, or
virtual member function
Compiler Error C3154 Expected ',' before ellipsis. Non-comma separated ellipsis not
supported on parameter array functions.
Compiler Error C3156 'class': you cannot have a local definition of a managed/WinRT
type
Compiler Error C3157 ParamArray attribute can only be applied to the last
parameter
Compiler Error C3158 'function': 'keyword' can only be applied to a virtual member
function
Compiler Error C3159 'identifier': array of pointers to value type cannot be declared
Compiler Error C3160 'type': a data member of a managed/WinRT class cannot have
this type
Compiler Error C3162 'type': a reference type which has a destructor cannot be used
as the type of static data member 'member'
Compiler Error C3165 'value': cannot convert to an integral or floating point value
Compiler Error C3167 Unable to initialize .NET Framework: make sure it is installed
Compiler Error C3169 'type': cannot deduce type for 'auto' from 'type'
Compiler Error C3175 'function': cannot call a method of a managed type from
unmanaged function 'function'
Compiler Error C3177 you cannot have a conversion function to a type that contains
'type'
Compiler Error C3178 'type': cannot use ParamArray in a function with default
arguments
Compiler Error C3180 'type': name exceeds meta-data limit of 'number' characters
Compiler Error C3183 cannot define unnamed class, struct or union inside of
managed/WinRT type 'class'
Compiler Error C3185 'typeid': used on managed/WinRT type 'type', use 'operator'
instead
Compiler Error C3187 'identifier': is only available within the body of a function
Compiler Error C3190 'declarator' with the provided template arguments is not the
explicit instantiation of any member function of 'type'
Compiler Error C3192 syntax error: '^' is not a prefix operator (did you mean '*'?)
Compiler Error C3193 'construct': requires '/clr' or '/ZW' command line option
Compiler Error C3199 invalid use of floating-point pragmas: exceptions are not
supported in non-precise mode
Compiler Error C3100
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3100.
// C3100.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::All)]
public ref class Attr : public Attribute {
public:
Attr(int t) : m_t(t) {}
int m_t;
};
[invalid_target:Attr(10)]; // C3100
[assembly:Attr(10)]; // OK
Compiler Error C3101
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3101.
// C3101.cpp
// compile with: /clr /c
ref class AAttribute : System::Attribute {
public:
int Field;
};
extern int i;
Example
The following sample generates C3103.
// C3103.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::All)]
public ref class Attr : public Attribute {
public:
int m_t;
};
Example
The following sample generates C3104.
// C3104a.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::Class)]
public ref struct ABC : public Attribute {
ABC(array<int>^){}
array<double> ^ param;
};
Example
The following sample generates C3104.
// C3104b.cpp
// compile with: /clr /c
// C3104 expected
using namespace System;
int func() {
return 0;
}
[attribute(All)]
ref class A {
public:
A(int) {}
};
// OK
[A(0)]
ref class B {};
Compiler Error C3106
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3106.
// C3106.cpp
// compile with: /c
[module(name="MyLib", dll)]; // C3106
[module(dll, name="MyLib")]; // OK
Compiler Error C3110
10/31/2018 • 2 minutes to read • Edit Online
// C3110.cpp
#include <unknwn.h>
[ object, uuid= "4F98A180-EF37-11D1-978D-0000F805D73B" ]
__interface ITestInterface
{
HRESULT mf1(void);
HRESULT mf1(BSTR); // C3110
};
int main()
{
}
Compiler Error C3113
10/31/2018 • 2 minutes to read • Edit Online
// C3113.cpp
// compile with: /c
template <class T>
enum E {}; // C3113
// try the following line instead
// class MyClass{};
Compiler Error C3114
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3114.
// C3114.cpp
// compile with: /clr /c
public ref class A : System::Attribute {
public:
static property int StaticProp {
int get();
}
[A(StaticProp=123)] // C3114
public ref class R {};
[A(Prop2=123)] // OK
public ref class S {};
Compiler Error C3115
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3115.
// C3115.cpp
// compile with: /c
#include <unknwn.h>
[module(name="xx")];
// C3116.cpp
__interface ImyInterface
{
static void myFunc(); // C3116
};
Compiler Error C3117
10/31/2018 • 2 minutes to read • Edit Online
// C3117.cpp
#include <windows.h>
[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface I1
{
};
[ object, uuid("00000000-0000-0000-0000-000000000002") ]
__interface I2
{
};
[ object, uuid("00000000-0000-0000-0000-000000000003") ]
__interface I3 : I1, I2
{ // C3117
};
Compiler Error C3118
10/31/2018 • 2 minutes to read • Edit Online
// C3118.cpp
__interface I1 {
};
// C3120.cpp
__interface A {
int X(int i, ...); // C3120
};
// C3121.cpp
[emitidl];
[module(name="MyLibrary")];
[coclass, uuid="00000000-0000-0000-0000-111111111111"]
class __declspec(uuid("00000000-0000-0000-0000-111111111112")) A // C3121
{
};
int main()
{
}
Compiler Error C3126
10/31/2018 • 2 minutes to read • Edit Online
// C3126_2.cpp
// compile with: /clr /c
ref class Test
{
union x
{ // C3126
int a;
int b;
};
};
Compiler Error C3130
10/31/2018 • 2 minutes to read • Edit Online
// C3131.cpp
[emitidl];
[module]; // C3131
// try the following line instead
// [module (name="MyLib")];
[public]
typedef long int LongInt;
Compiler Error C3132
3/5/2019 • 2 minutes to read • Edit Online
'function-parameter' : parameter arrays can only be applied to a formal argument of type 'single-dimensional
managed array'
The ParamArrayAttribute attribute was applied to a parameter that was not a single-dimension array.
The following sample generates C3132:
// C3132.cpp
// compile with: /clr /c
using namespace System;
void f( [ParamArray] Int32[,] ); // C3132
void g( [ParamArray] Int32[] ); // C3132
Example
The following sample generates C3133.
// C3133.cpp
// compile with: /clr /c
ref struct MyAttr: System::Attribute {};
void Func([MyAttr]...); // C3133
void Func2([MyAttr] int i); // OK
Compiler Error C3134
10/31/2018 • 2 minutes to read • Edit Online
'value' : value of attribute argument 'attribute' does not have valid type 'type'
A syntax error was detected when a value was assigned to an attribute.
See Also
Attributes by Usage
Compiler Error C3135
10/31/2018 • 2 minutes to read • Edit Online
'interface' : a COM interface can only inherit from another COM interface, 'interface' is not a COM interface
An interface to which you applied an interface attribute inherits from an interface that is not a COM interface. A
COM interface ultimately inherits from IUnknown . Any interface preceded by an interface attribute is a COM
interface.
The following example generates C3136:
// C3136.cpp
#include "unknwn.h"
__interface A // C3136
// try the following line instead
// _interface A : IUnknown
{
int a();
};
[object]
__interface B : A
{
int aa();
};
Compiler Error C3137
10/31/2018 • 2 minutes to read • Edit Online
// C3137.cpp
// compile with: /clr /c
ref class CMyClass {
public:
property int Size {
int get() {
return 0;
}
void set( int i ) {}
}
'interface' : a 'attribute' interface must inherit from IDispatch, or from an interface that inherits from IDispatch
An interface with the dual or dispinterface attributes does not have IDispatch as a direct or indirect base interface.
The following example generates C3138:
// C3138.cpp
#include <unknwn.h>
[ object, uuid("77ac9240-6e9a-11d2-97de-0000f805d73b") ]
__interface IMyCustomInterface
{
HRESULT mf1(void);
};
[ dispinterface, uuid("3536f8a0-6e9a-11d2-97de-0000f805d73b") ]
__interface IMyDispInterface : IUnknown
{
[id(1)] HRESULT mf2(void);
};
// C3139.cpp
#include "unknwn.h"
[emitidl];
[module(name=xx)];
// C3140.cpp
// compile with: /c
[emitidl];
[module(name = "MyLibrary")];
[module(name = "MyLibrary2")]; // C3140
Compiler Error C3141
10/31/2018 • 2 minutes to read • Edit Online
// C3141.cpp
__interface IBase {};
__interface IDerived1 : protected IBase {}; // C3141
__interface IDerived2 : private IBase {}; // C3141
Compiler Error C3142
10/31/2018 • 2 minutes to read • Edit Online
// C3142_2.cpp
// compile with: /clr
using namespace System;
ref class CSize {
private:
property int Size {
int get();
}
};
int main() {
&CSize::Size; // C3142
}
Compiler Error C3145
10/31/2018 • 2 minutes to read • Edit Online
'object' : global or static variable may not have managed or WinRT type 'type'
You can only define CLR or WinRT objects within function scope.
The following sample generates C3145 and shows how to fix it:
// C3145.cpp
// compile with: /clr
using namespace System;
ref class G {};
G ^ ptr; // C3145
G ^ ptr2 = gcnew G; // C3145
int main() {
G ^ ptr; // OK
G ^ ptr2 = gcnew G; // OK
}
// C3145b.cpp
// compile with: /clr
ref class MyClass {
public:
static int data;
};
void Test(interior_ptr<int> x) {}
int main() {
MyClass ^ h_MyClass = gcnew MyClass;
interior_ptr<int> p = &(h_MyClass->data);
}
Compiler Error C3149
10/31/2018 • 2 minutes to read • Edit Online
// C3149.cpp
// compile with: /clr
using namespace System;
int main() {
// declare an array of value types
array< Int32 ^> IntArray; // C3149
array< Int32>^ IntArray2; // OK
}
// C3149b.cpp
// compile with: /clr /c
delegate int MyDelegate(const int, int);
void Test1(MyDelegate m) {} // C3149
void Test2(MyDelegate ^ m) {} // OK
Compiler Error C3150
10/31/2018 • 2 minutes to read • Edit Online
'construct' : 'keyword' can only be applied to a class, struct, or virtual member function
Certain keywords can only be applied to a C++ class.
The following sample generates C3152 and shows how to fix it:
// C3152.cpp
// compile with: /clr /c
ref class C {
int (*pfn)() sealed; // C3152
virtual int g() sealed; // OK
};
Compiler Error C3153
10/31/2018 • 2 minutes to read • Edit Online
// C3153.cpp
// compile with: /clr
interface class A {
};
int main() {
A^ a = gcnew A; // C3153
}
Compiler Error C3154
10/31/2018 • 2 minutes to read • Edit Online
Expected ',' before ellipsis. Non-comma separated ellipsis not supported on parameter array functions.
A variable argument function was not declared correctly.
For more information, see Variable Argument Lists (...) (C++/CLI).
Example
The following sample generates C3154.
// C3154.cpp
// compile with: /clr
ref struct R {
void Func(int ... array<int> ^); // C3154
void Func2(int i, ... array<int> ^){} // OK
void Func3(array<int> ^){} // OK
void Func4(... array<int> ^){} // OK
};
int main() {
R ^ r = gcnew R;
r->Func4(1,2,3);
}
Compiler Error C3155
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3155.
// C3155.cpp
// compile with: /clr /c
using namespace System;
ref struct R {
property int F[[ParamArray] int] { // C3155
// try the following line instead
// property int F[ int] { // OK
int get(int i) {
return 0;
}
}
};
Compiler Error C3156
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3156.
// C3156.cpp
// compile with: /clr /c
void f() {
ref class X {}; // C3156
ref class Y; // C3156
}
Compiler Error C3157
3/5/2019 • 2 minutes to read • Edit Online
'pointer' : a data member of a managed or WinRT class cannot have this type
Interior garbage collection pointers may point to the interior of a managed or WinRT class. Because they are
slower than whole-object pointers and require special handling by the garbage collector, you cannot declare
interior managed pointers as members of a class.
The following sample generates C3160:
// C3160.cpp
// compile with: /clr
ref struct A {
// cannot create interior pointers inside a class
interior_ptr<int> pg; // C3160
int g; // OK
int* pg2; // OK
};
int main() {
interior_ptr<int> pg2; // OK
}
Compiler Error C3161
10/31/2018 • 2 minutes to read • Edit Online
'interface' : nesting class, struct, union or interface in an interface is illegal; nesting interface in a class, struct or
union is illegal
An __interface can only appear at global scope or within a namespace. A class, struct, or union cannot appear in an
interface.
Example
The following sample generates C3161.
// C3161.cpp
// compile with: /c
__interface X {
__interface Y {}; // C3161 A nested interface
};
Compiler Error C3162
10/31/2018 • 2 minutes to read • Edit Online
'type' : a reference type which has a destructor cannot be used as the type of static data member 'member'
The common language runtime cannot know when to run a user-defined destructor when the class also contains
static member function.
A destructor will never be run unless the object is deleted explicitly.
For more information, see,
/clr (Common Language Runtime Compilation)
Common Visual C++ 64-bit Migration Issues
Example
The following sample generates C3162.
// C3162.cpp
// compile with: /clr /c
ref struct A {
~A() { System::Console::WriteLine("in destructor"); }
static A i; // C3162
static A^ a = gcnew A; // OK
};
int main() {
A ^ a = gcnew A;
delete a;
}
Compiler Error C3163
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3163.
// C3163.cpp
// compile with: /clr /c
using namespace System;
See Also
SAL Annotations
Compiler Error C3166
10/31/2018 • 2 minutes to read • Edit Online
// C3168.cpp
// compile with: /clr /c
ref class G{};
// C3170.cpp
[ module(name="MyModule", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f") ];
int main() {}
And then,
// C3170b.cpp
// compile with: C3170.cpp
// C3170 expected
[ module(name="MyModule1", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f") ];
Identical module attributes can be specified in more than one source code file.
For example, if the following module attributes were found:
// C3171.cpp
[ module(name="MyModule", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f", version="1.0") ];
int main() {}
And then,
// C3171b.cpp
// compile with: C3171.cpp
// C3171 expected
[ module(name="MyModule", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f", version="1.1") ];
the compiler would generate C3171 (note the different version values).
Compiler Error C3172
10/31/2018 • 2 minutes to read • Edit Online
// C3172.cpp
[module(name="MyMod")];
[ idl_module(name="x", dllname="file.dll", version="1.1") ];
int main() {}
And then,
// C3172b.cpp
// compile with: C3172.cpp
// C3172 expected
[ idl_module(name="x", dllname="file.dll", version="1.0") ];
the compiler would generate C3172 (note the different version values).
Compiler Error C3173
10/31/2018 • 2 minutes to read • Edit Online
// C3174.cpp
// C3174 expected
// uncomment the following line to resolve this C3174
// [module(name="x")];
[export]
struct S
{
int i;
};
int main()
{
}
Compiler Error C3175
10/31/2018 • 2 minutes to read • Edit Online
'function1' : cannot call a method of a managed type from unmanaged function 'function2'
Unmanaged functions cannot call member functions of managed classes.
The following sample generates C3175:
// C3175_2.cpp
// compile with: /clr
ref struct A {
static void func() {
}
};
void func2() {
A::func(); // C3175
}
#pragma managed
int main() {
A ^a = gcnew A;
func2();
}
Compiler Error C3176
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3176.
// C3176.cpp
// compile with: /clr
int main () {
enum class C {}; // C3176
}
Compiler Error C3179
10/31/2018 • 2 minutes to read • Edit Online
// C3179a.cpp
// compile with: /clr /c
typedef value struct { // C3179
// try the following line instead
// typedef value struct MyStruct {
int i;
} V;
Compiler Error C3180
10/31/2018 • 2 minutes to read • Edit Online
// C3181a.cpp
// compile with: /clr
using namespace System;
int main() {
Type ^pType1 = interior_ptr<int>::typeid; // C3181
Type ^pType2 = int::typeid; // OK
}
Compiler Error C3182
10/31/2018 • 2 minutes to read • Edit Online
// C3182a.cpp
// compile with: /clr /c
ref struct B {
void mf(int) {
}
};
ref struct D : B {
using B::mf; // C3182, delete to resolve
void mf(char) {
}
};
Compiler Error C3183
10/31/2018 • 2 minutes to read • Edit Online
cannot define unnamed class, struct or union inside of managed or WinRT type 'type'
A type that is embedded in a managed or WinRT type must be named.
The following sample generates C3183:
// C3183a.cpp
// compile with: /clr /c
ref class Test
{
ref class
{ // C3183, delete class or name it
int a;
int b;
};
};
Compiler Error C3185
10/31/2018 • 2 minutes to read • Edit Online
// C3185a.cpp
// compile with: /clr
ref class Base {};
ref class Derived : public Base {};
int main() {
Derived ^ pd = gcnew Derived;
Base ^pb = pd;
const type_info & t1 = typeid(pb); // C3185
System::Type ^ MyType = Base::typeid; // OK
};
Compiler Error C3187
10/31/2018 • 2 minutes to read • Edit Online
'typeid<type abstract declarator>': this syntax is no longer supported, use ::typeid instead
An obsolete form of typeid was used, use the new form.
The following sample generates C3189:
// C3189.cpp
// compile with: /clr
int main() {
System::Type^ t = typeid<System::Object>; // C3189
System::Type^ t2 = System::Object::typeid; // OK
}
Compiler Error C3190
10/31/2018 • 2 minutes to read • Edit Online
'instantiation' with the provided template arguments is not the explicit instantiation of any member function of
'type'
The compiler detected an attempt to make an explicit function instantiation; however, the provided type arguments
do not match any of the possible functions.
The following sample generates C3190:
// C3190.cpp
// compile with: /LD
template<class T>
struct A {
A(int x = 0) {
}
A(int x, int y) {
}
};
struct Y {
template<class T> void f(T);
};
syntax error : '^' is not a prefix operator (did you mean '*'?)
A handle cannot be used as a dereference operator.
The following sample generates C3192:
// C3192.cpp
// compile with: /clr
using namespace System;
int main() {
MyClass ^ s = gcnew MyClass;
MyClass b = ^s; // C3192
// OK
MyClass b2 = *s;
}
Compiler Error C3194
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3194.
// C3194.cpp
// compile with: /clr /c
value struct MyStruct {
MyStruct& operator= (const MyStruct& i) { return *this; } // C3194
};
'operator' : is reserved and cannot be used as a member of a ref class or value type. CLR or WinRT operators must
be defined using the 'operator' keyword
The compiler detected an operator definition using the Managed Extensions for C++ syntax. You must use the
C++ syntax for operators.
The following sample generates C3195 and shows how to fix it:
// C3195.cpp
// compile with: /clr /LD
#using <mscorlib.dll>
value struct V {
static V op_Addition(V v, int i); // C3195
static V operator +(V v, char c); // OK for new C++ syntax
};
Compiler Error C3196
10/31/2018 • 2 minutes to read • Edit Online
// C3196.cpp
// compile with: /clr
ref struct R abstract abstract {}; // C3196
ref struct S abstract {}; // OK
Compiler Error C3197
10/31/2018 • 2 minutes to read • Edit Online
// C3197.cpp
// compile with: /clr /c
ref struct R abstract; // C3197
ref struct R abstract {}; // OK
invalid use of floating-point pragmas: fenv_access pragma operates only in precise mode
fenv_access pragma was used under an /fp setting other than /fp:precise.
The following sample generates C3198:
// C3198.cpp
// compile with: /fp:fast
#pragma fenv_access(on) // C3198
Compiler Error C3199
10/31/2018 • 2 minutes to read • Edit Online
invalid use of floating-point pragmas: exceptions are not supported in non-precise mode
The float_control pragma was used to specify floating-point exception model under an /fp setting other than
/fp:precise.
The following sample generates C3199:
// C3199.cpp
// compile with: /fp:fast
#pragma float_control(except, on) // C3199
Compiler Errors C3200 Through C3299
10/31/2018 • 9 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3200 'type': invalid template argument for template parameter
'parameter', expected a class template
Compiler Error C3201 the template parameter list for class template 'template' does
not match the template parameter list for template parameter
'parameter'
Compiler Error C3202 'identifier': invalid default argument, expected a class template
Compiler Error C3204 'function' cannot be called from within a catch block
ERROR MESSAGE
Compiler Error C3205 argument list for template template parameter 'identifier' is
missing
Compiler Error C3207 'function': invalid template argument for 'parameter', class
template expected
Compiler Error C3208 'function': template parameter list for class template 'template'
does not match template parameter list for template template
parameter 'parameter'
Compiler Error C3210 'identifier': access declaration can only be applied to a base
class member
Compiler Error C3213 base class 'class' is less accessible than 'derived_class'
Compiler Error C3214 'argument': invalid type argument for generic parameter
'parameter' of generic 'type', does not meet constraint
'constraint'
Compiler Error C3221 'member': multiple 'default' and 'case' attributes not allowed
on a member
Compiler Error C3222 'function': cannot declare default arguments for member
functions of a managed/WinRT type or generic functions
Compiler Error C3224 'type': no overloaded generic class takes 'number' generic type
arguments
Compiler Error C3225 generic type argument for 'argument' cannot be 'type', it must
be a value type or a handle to a reference type
Compiler Error C3227 'type': cannot use 'operator' to allocate a generic type
Compiler Error C3228 'function': generic type argument for 'argument' cannot be
'type', it must be a value type or handle type
Compiler Error C3229 'type': indirections on a generic type parameter are not
allowed
Compiler Error C3230 'function': template type argument for 'argument' cannot
contain a generic type parameter: 'type'
Compiler Error C3231 'type': template type argument cannot use a generic type
parameter
Compiler Error C3234 a generic class may not derive from a generic type parameter
Compiler Error C3238 'type': a type with this name has already been forwarded to
assembly 'assembly'
Compiler Error C3241 'member': this method was not introduced by 'interface'
Compiler Error C3242 'function': you can only explicitly override virtual functions
Compiler Error C3243 none of the overload functions were introduced by 'interface'
ERROR MESSAGE
Compiler Error C3244 'member': this method was introduced by 'interface1' not by
'interface2'
Compiler Error C3246 'class': cannot inherit from 'base_class' as it has been declared
as 'inheritance'
Compiler Error C3247 'coclass': a coclass cannot inherit from another coclass
'base_class'
Compiler Error C3251 cannot invoke base class method on a value type instance
Compiler Error C3254 'function': class contains explicit override 'function' but does
not derive from an interface that contains the function
declaration
Compiler Error C3255 'type': cannot dynamically allocate this value type object on
native heap
Compiler Error C3256 'function': variable use does not produce a constant
expression
Compiler Error C3259 'constexpr' functions can only have one return statement
Compiler Error C3260 'token': skipping unexpected token(s) before lambda body
Compiler Error C3261 a function returning a managed/WinRT array must have array
brackets at the end of the declaration: 'identifier(...) []'
Compiler Error C3262 invalid array indexing: number dimension(s) specified for
number-dimensional 'type'
Compiler Error C3266 'function': a class-constructor must have a 'void' parameter list
Compiler Error C3270 'field': the FieldOffset attribute can only be used in the context
of StructLayout(LayoutKind::Explicit)
Compiler Error C3271 'field': invalid value 'number' for the FieldOffset attribute
Compiler Error C3275 'identifier': cannot use this symbol without qualifier
Compiler Error C3276 'keyword': jump out of finally/__finally block has undefined
behavior during termination handling
Compiler Error C3278 direct call of interface or pure method 'function' will fail at
runtime
Compiler Error C3281 'function': global operator cannot have managed/WinRT type
'type' in signature
Compiler Error C3282 generic parameter lists can only appear on managed/WinRT
classes, structs, or functions
Compiler Error C3284 the constraints for generic parameter 'parameter' of function
'declarator' must match the constraints for generic parameter
'parameter' of function 'declarator'
Compiler Error C3285 for each statement cannot operate on variables of type 'type'
Compiler Error C3286 'specifier': an iteration variable cannot have any storage-class
specifiers
Compiler Error C3287 the type 'type' (return type of GetEnumerator) must have a
suitable public MoveNext member function and public Current
property
Compiler Error C3290 'type': a trivial property cannot have reference type
Compiler Error C3293 'identifier': use 'default' to access the default property
(indexer) for class 'class'
Compiler Error C3295 '#pragma specifier' can only be used at global or namespace
scope
Compiler Error C3296 'identifier': a property with this name already exists
Compiler Error C3297 ' constraint2': cannot use ' constraint1' as a constraint
because ' constraint1' has the value constraint
Compiler Error C3298 ' constraint1': cannot use ' constraint2' as a constraint
because ' constraint2' has the ref constraint and ' constraint1'
has the value constraint
Compiler Error C3299 ' function': cannot specify constraints, they are inherited from
the base method
Compiler Error C3200
10/31/2018 • 2 minutes to read • Edit Online
'template' : invalid template argument for template parameter 'parameter', expected a class template
You passed an invalid argument to a class template. The class template expects template as a parameter. In the
following example, calling Y<int, int> aY will generate C3200. The first parameter needs to be a template, such
as Y<X, int> aY .
// C3200.cpp
template<typename T>
class X
{
};
int main()
{
Y<int, int> y; // C3200
}
Compiler Error C3201
10/31/2018 • 2 minutes to read • Edit Online
the template parameter list for class template 'template' does not match the template parameter list for template
parameter 'template'
You passed a class template in the argument to a class template that does not take a template parameter, or you
passed a mismatched number of template arguments for the default template argument.
// C3201.cpp
template<typename T1, typename T2>
class X1
{
};
'arg name' : invalid default argument for template parameter 'parameter', expected a class template
You passed an invalid default argument for a template parameter.
The following sample generates C3202:
// C3202.cpp
template<typename T>
class X
{
};
class Z
{
};
'type' : unspecialized class template or generic can't be used as a template or generic argument for template or
generic parameter 'param', expected a real type
You passed an invalid argument to a class template or generic. The class template or generic expects a type as a
parameter.
This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: an
unspecialized class template can't be used as a template argument in a base class list. To resolve C3203, explicitly
add the template type parameter(s) to the template class name when using it as a template parameter in a base
class list.
// C3203.cpp
template< typename T >
struct X {
void f(X) {}
};
int main() {
Y<int> y;
}
The following sample generates C3203 and shows how to fix it:
// C3203_b.cpp
// compile with: /c
template <class T>
struct S1 {};
// OK
template <template <class> class T>
class C2 {};
Example
The following sample generates C3204:
// C3204.cpp
// compile with: /EHsc
#include <malloc.h>
void ShowError(void)
{
try
{
}
catch(...)
{
_alloca(1); // C3204
}
}
Compiler Error C3205
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3205:
// C3205.cpp
template<template<class> class T> struct A {
typedef T unparameterized_type; // C3205
// try the following line instead
// typedef T<int> unparameterized_type;
};
int main() {
A<B> x;
}
Compiler Error C3206
10/31/2018 • 2 minutes to read • Edit Online
'function' : invalid type argument for 'param', missing type argument list on class type 'typename'
A template function is defined as taking a template type argument. However, a template template argument was
passed.
The following sample generates C3206:
// C3206.cpp
template <class T>
void f() {}
void f1() {
f<S>(); // C3206
// try the following line instead
// f<S<int> >();
}
Possible resolution:
// C3206b.cpp
// compile with: /c
template <class T>
void f() {}
void f1() {
f<S<int> >();
}
// C3206c.cpp
// compile with: /clr
generic <class GT1>
void gf() {}
int main() {
gf<GS>(); // C3206
}
Possible resolution:
// C3206d.cpp
// compile with: /clr
generic <class GT1>
void gf() {}
int main() {
gf<GS<int> >();
}
A class template is not allowed as a template type argument. The following sample raises C3206:
// C3206e.cpp
template <class T>
struct S {};
int main() {
func<S>(); // C3206 S is not a type.
}
Possible resolution:
// C3206f.cpp
template <class T>
struct S {};
int main() {
func<S<int> >();
}
If a template template parameter is necessary, then you have to wrap the function in a template class that takes a
template template parameter:
// C3206g.cpp
template <class T>
struct S {};
int main() {
X<S>::func();
}
Compiler Error C3207
10/31/2018 • 2 minutes to read • Edit Online
// C3207.cpp
template <template <class T> class TT>
void f(){}
void f1()
{
f<S<int> >(); // C3207
// try the following line instead
// f<S>();
}
Compiler Error C3208
10/31/2018 • 2 minutes to read • Edit Online
'function' : template parameter list for class template 'class' does not match template parameter list for template
template parameter 'parameter'
A template template parameter does not have the same number of template parameters as the provided class
template.
The following sample generates C3208:
// C3208.cpp
template <template <class T> class TT >
int f();
// C3209.cpp
// compile with: /clr
generic <class T>
class C {}; // C3209
Example
The following sample generates C3210.
// C3210.cpp
// compile with: /c
struct A {
protected:
int i;
};
struct B {
using A::i; // C3210
};
struct C : public A {
using A::i; // OK
};
Compiler Error C3211
10/31/2018 • 2 minutes to read • Edit Online
'explicit specialization' : explicit specialization is using partial specialization syntax, use template <> instead
An explicit specialization was ill formed.
The following sample generates C3211:
// C3211.cpp
// compile with: /LD
template<class T>
struct s;
template<class T>
// use the following line instead
// template<>
struct s<int>{}; // C3211
Compiler Error C3212
10/31/2018 • 2 minutes to read • Edit Online
// C3212.cpp
// compile with: /LD
template <class T>
struct S {
template <class T1>
struct S1;
};
/*
// try the following instead
template <>
template <>
struct S<int>::S1<int> {};
*/
/*
// or, the following
template <>
struct S<int> {
template <class T1>
struct S1;
};
template <>
struct S<int>::S1<int> {
};
*/
Compiler Error C3213
10/31/2018 • 2 minutes to read • Edit Online
// C3213.cpp
// compile with: /clr
private ref struct privateG {
public:
int i;
};
'type' : invalid type argument for generic parameter 'param' of generic 'generic_type', does not meet constraint
'constraint'
The type was specified for an instantiation of a generic class that does not meet the generic class's constraint.
The following sample generates C3214:
// C3214.cpp
// compile with: /clr
interface struct A {};
int main() {
C<int>^ c = new C<int>; // C3214
C<X ^> ^ c2 = new C<X^>; // OK
}
Compiler Error C3215
10/31/2018 • 2 minutes to read • Edit Online
// C3215.cpp
// compile with: /clr
interface struct A {};
Possible resolution:
// C3215b.cpp
// compile with: /clr /c
interface struct A {};
// C3216.cpp
// compile with: /clr
interface struct A {};
// C3216b.cpp
// compile with: /clr /c
interface struct A {};
// C3217.cpp
// compile with: /clr
interface struct A {};
// C3217b.cpp
// compile with: /clr /c
interface struct A {};
Example
The following sample generates C3218.
// C3218.cpp
// compile with: /clr /c
class A {};
ref class B {};
// OK
generic <class T>
where T : B
ref class D {};
Compiler Error C3219
10/31/2018 • 2 minutes to read • Edit Online
// C3219.cpp
// compile with: /clr
ref class A {};
ref class B {};
// C3219b.cpp
// compile with: /clr /c
ref class A {};
'parameter' : cannot declare default arguments for member functions of a managed or WinRT type or generic
functions
It is not permitted to declare a method parameter with a default argument. An overloaded form of the method is
one way to work around this issue. That is, define a method with the same name with no parameters and then
initialize the variable in the method body.
The following sample generates C3222:
// C3222_2.cpp
// compile with: /clr
public ref class G {
void f( int n = 0 ); // C3222
};
Compiler Error C3223
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3223.
// C3223.cpp
// compile with: /clr
ref class R {
public:
property int myprop;
};
int main() {
System::Type^ type2 = R::myprop::typeid; // C3223
}
Compiler Error C3224
10/31/2018 • 2 minutes to read • Edit Online
// C3224.cs
// compile with: /target:library
public class C<T> {}
public class C<T,U> {}
And then,
// C3224b.cpp
// compile with: /clr
#using "C3224.dll"
int main() {
C<int,int,int>^ c = gcnew C<int,int,int>(); // C3224
C<int,int>^ c2 = gcnew C<int,int>(); // OK
}
Compiler Error C3225
10/31/2018 • 2 minutes to read • Edit Online
generic type argument for 'arg' cannot be 'type', it must be a value type or handle type
The generic type argument was not of the correct type.
For more information, see Generics.
Example
You cannot instantiate a generic type with a native type. The following sample generates C3225.
// C3225.cpp
// compile with: /clr
class A {};
int main() {
C<A>^ c = gcnew C<A>; // C3225
C<B^>^ c2 = gcnew C<B^>; // OK
}
Example
The following sample creates a component using C#. Notice that the constraint specifies that the generic type can
only be instantiated with a value type.
// C3225_b.cs
// compile with: /target:library
// a C# program
public class MyList<T> where T: struct {}
Example
This sample consumes the C#-authored component, and violates the constraint that MyList can only be
instantiated with a value type other than Nullable. The following sample generates C3225.
// C3225_c.cpp
// compile with: /clr
#using "C3225_b.dll"
ref class A {};
value class B {};
int main() {
MyList<A> x; // C3225
MyList<B> y; // OK
}
Compiler Error C3226
10/31/2018 • 2 minutes to read • Edit Online
// C3226.cpp
// compile with: /clr
generic <class T>
ref class C {
template <class T1> // C3226
ref struct S1 {};
};
// C3226b.cpp
// compile with: /clr /c
generic <class T>
ref class C {
generic <class T1>
ref struct S1 {};
};
Compiler Error C3227
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3227.
// C3227.cpp
// compile with: /clr /c
generic<class T> interface class ICreate {
static T Create();
};
// OK
T t2 = ICreate<T>::Create();
T t3 = safe_cast<T>( System::Activator::CreateInstance(T::typeid) );
}
};
Compiler Error C3228
10/31/2018 • 2 minutes to read • Edit Online
'function' : generic type argument for 'param' cannot be 'type', it must be a valuetype or handle type
An incorrect type was passed as a generic type argument.
The following sample generates C3228:
// C3228.cpp
// compile with: /clr
class A {};
ref class C {
public:
generic <class T>
static void f() {}
};
int main() {
C::f<A>(); // C3228
C::f<B>(); // OK
Test<C>(); // C3228
Test<C ^>(); // OK
}
Compiler Error C3229
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3229.
// C3229.cpp
// compile with: /clr /c
generic <class T>
ref class C {
T^ t; // C3229
};
// OK
generic <class T>
ref class D {
T u;
};
Example
The following sample generates C3229.
// C3229_b.cpp
// compile with: /clr /c
generic <class T> // OK
ref class Utils {
static void sort(T elems[], size_t size); // C3229
static void sort2(T elems, size_t size); // OK
};
Compiler Error C3230
10/31/2018 • 2 minutes to read • Edit Online
'function' : template type argument for 'template' cannot contain a generic type parameter: 'param'
Templates are instantiated at compile time, but generics are instantiated at run time. Therefore, it is not possible to
generate generic code that can call the template because the template cannot be instantiated at run time when the
generic type is finally known.
The following sample generates C3230:
// C3230.cpp
// compile with: /clr /LD
template <class S>
void f(S t);
// C3231.cpp
// compile with: /clr /LD
template <class T> class A;
// C3232.cpp
// compile with: /clr
generic <class T>
ref class C {
typename T::TYPE t; // C3232
};
Compiler Error C3233
10/31/2018 • 2 minutes to read • Edit Online
// C3233.cpp
// compile with: /clr /LD
Example
The following sample generates C3234.
// C3234.cpp
// compile with: /clr /c
generic <class T>
public ref class C : T {}; // C3234
// try the following line instead
// public ref class C {};
Compiler Error C3235
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3235.
// C3235.cpp
// compile with: /clr
generic<class T>
public ref class C {};
generic<>
public ref class C<int> {}; // C3235 Remove this specialization to resolve this error.
Compiler Error C3236
10/31/2018 • 2 minutes to read • Edit Online
// C3236.cpp
// compile with: /clr
generic<class T>
public ref class X {};
// C3236b.cpp
// compile with: /clr /c
generic<class T>
public ref class X {};
Compiler Error C3237
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3237.
// C3237.cpp
// compile with: /clr /c
// C3237 expected
using namespace System;
'type' : a type with this name has already been forwarded to assembly 'assembly'
A type was defined in a client application that is also defined, via type forwarding syntax, in a referenced assembly.
Both types cannot be defined in the scope of the application.
See Type Forwarding (C++/CLI) for more information.
Example
The following sample creates an assembly that contains a type that was forwarded from another assembly.
// C3238.cpp
// compile with: /clr /LD
public ref class R {};
Example
The following sample creates an assembly that used to contain the type definition, but not only contains type
forwarding syntax.
// C3238_b.cpp
// compile with: /clr /LD
#using "C3238.dll"
[ assembly:TypeForwardedTo(R::typeid) ];
Example
The following sample generates C3238.
// C3238_c.cpp
// compile with: /clr /c
// C3238 expected
// Delete the following line to resolve.
#using "C3238_b.dll"
public ref class R {};
Compiler Error C3239
10/31/2018 • 2 minutes to read • Edit Online
// C3239.cpp
// compile with: /clr
int main() {
interior_ptr<int>* pip0; // C3239
// OK
int * pip1;
interior_ptr<int> pip2;
int ** pip;
}
Compiler Error C3240
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3240.
// C3240.cpp
// compile with: /c
__interface I {
void f();
};
struct A1 : I {
void f() {}
};
struct A2 : I {
void f() = 0;
};
A3<A1> x; // C3240
A3<I> x2;
A4<A2> x3;
Compiler Error C3241
10/31/2018 • 2 minutes to read • Edit Online
// C3241.cpp
#pragma warning(disable:4199)
__interface IX12A {
void mf();
};
__interface IX12B {
void mf(int);
};
// C3243.cpp
#pragma warning(disable:4199)
__interface IX14A {
void g();
};
__interface IX14B {
void f();
void f(int);
};
// C3244.cpp
#pragma warning(disable:4199)
__interface IX15A {
void f();
};
__interface IX15B {
void g();
};
// C3246_2.cpp
// compile with: /clr /LD
ref class X sealed {};
// C3247.cpp
[module(name="MyLib")];
[coclass]
class a {
};
[coclass]
class b : public a { // C3247
};
int main() {
}
Compiler Error C3248
10/31/2018 • 2 minutes to read • Edit Online
// C3252.cpp
// compile with: /clr /c
ref class A {
public:
virtual void f1() {}
};
// C3253.cpp
// compile with: /clr
public interface struct I {
void a();
void b();
void c();
};
'explicit override' : class contains explicit override 'override' but does not derive from an interface that contains the
function declaration
When you explicitly override a method, the class that contains the override must derive, directly or indirectly, from
the type that contains the function you are overriding.
The following sample generates C3254:
// C3254.cpp
__interface I
{
void f();
};
__interface I1 : I
{
};
struct A /* : I1 */
{
void I1::f()
{ // C3254, uncomment : I1 to resolve this C3254
}
};
int main()
{
}
Compiler Error C3255
10/31/2018 • 2 minutes to read • Edit Online
'value type' : cannot dynamically allocate this value type object on native heap
Instances of a value type (see Classes and Structs) that contain managed members can be created on the stack but
not on the heap.
The following sample generates C3255:
// C3255.cpp
// compile with: /clr
using namespace System;
value struct V {
Object^ o;
};
value struct V2 {
int i;
};
int main() {
V* pv = new V; // C3255
V2* pv2 = new V2;
V v2;
}
Compiler Error C3262
10/31/2018 • 2 minutes to read • Edit Online
invalid array indexing: '#' dimension(s) specified for '#'-dimensional 'array type'
An array was improperly subscripted. The number of indices may not match the number of dimensions in the
array.
The following sample generates C3262:
// C3262.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;
#define ARRAY_SIZE 2
return local;
}
int main() {
int i, j;
// C3264_2.cpp
// compile with: /clr
ref class X {
public:
static int X() { // C3264
}
// C3265_2.cpp
// compile with: /clr /LD
#include <vcclr.h>
ref class A { };
class B
// try the following line instead
// ref class B
{
A ^a; // C3265
// or embed the managed handle using gcroot
// try the following line instead
// gcroot<A^> a;
};
Compiler Error C3266
10/31/2018 • 2 minutes to read • Edit Online
// C3266.cpp
// compile with: /clr
ref class X {
static X(int i) { // C3266
// try the following line instead
// static X() {
}
};
int main() {
}
Compiler Error C3268
10/31/2018 • 2 minutes to read • Edit Online
'function' : a generic function or a member-function of a generic class cannot have a variable parameter list
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
See Generics for more information.
Example
The following sample generates C3268.
// C3268.cpp
// compile with: /clr:pure /c
generic <class ItemType>
void Test(ItemType item, ...) {} // C3268
// try the following line instead
// void Test(ItemType item) {}
// C3269_2.cpp
// compile with: /clr
ref struct A
{
void func(int i, ...) // C3269
// try the following line instead
// void func(int i )
{
}
};
int main()
{
}
Compiler Error C3270
10/31/2018 • 2 minutes to read • Edit Online
'field': the FieldOffset attribute can only be used in the context of StructLayout(Explicit), in which case it is required
A field was marked with FieldOffset, which is only allowed when StructLayout(Explicit) is in effect.
The following sample generates C3270:
// C3270_2.cpp
// compile with: /clr /c
using namespace System::Runtime::InteropServices;
[ StructLayout(LayoutKind::Sequential) ]
// try the following line instead
// [ StructLayout(LayoutKind::Explicit) ]
public value struct MYUNION
{
[FieldOffset(0)] int a; // C3270
// ...
};
Compiler Error C3271
10/31/2018 • 2 minutes to read • Edit Online
// C3271.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Runtime::InteropServices;
[StructLayout(LayoutKind::Explicit)]
value class MyStruct1 {
public: [FieldOffset(0)] int a;
public: [FieldOffset(-1)] long b; // C3271
};
Compiler Error C3272
10/31/2018 • 2 minutes to read • Edit Online
// C3272_2.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Runtime::InteropServices;
[StructLayout(LayoutKind::Explicit)]
ref struct X
{
int data_; // C3272
// try the following line instead
// [FieldOffset(0)] int data_;
};
Compiler Error C3273
10/31/2018 • 2 minutes to read • Edit Online
// C3273.cpp
// compile with: /GX
int main()
{
try
{
}
catch (int)
{
}
__finally // C3273, remove __finally clause
{
}
}
Compiler Error C3274
10/31/2018 • 2 minutes to read • Edit Online
// C3274.cpp
// compile with: /clr
// C3274 expected
using namespace System;
int main() {
try {
try {
throw gcnew ApplicationException();
}
catch(...) {
Console::Error->WriteLine(L"Caught an exception");
}
finally {
Console::WriteLine(L"In finally");
}
} finally {
Console::WriteLine(L"In finally");
}
finally {
Console::WriteLine(L"In finally");
}
Console::WriteLine(L"**FAIL**");
}
Compiler Error C3275
10/31/2018 • 2 minutes to read • Edit Online
'keyword' : jump out of __finally/finally block has undefined behavior during termination handling
This error is the same as the C4532 warning. However, when you are using /clr, this condition cannot be disabled
with the warning pragma.
Compiler Error C3277
10/31/2018 • 2 minutes to read • Edit Online
// C3277a.cpp
// compile with: /clr
ref class A
{
enum E {e1,e2}; // C3277
// try the following line instead
// enum class E {e1,e2};
};
int main()
{
}
Compiler Error C3278
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A call was made to an interface method or a pure method, which is not allowed.
Example
The following sample generates C3278:
// C3278_2.cpp
// compile with: /clr
using namespace System;
interface class I
{
void vmf();
};
};
int main()
{
C^ pC = gcnew C;
pC->vmf();
}
Compiler Error C3279
10/31/2018 • 2 minutes to read • Edit Online
partial and explicit specializations as well as explicit instantiations of class templates declared in the cli namespace
are disallowed
The cli namespace is defined by Microsoft and contains pseudo-templates. The Visual C++ compiler does not
allow user-defined, partial and explicit specializations, and explicit instantiations of class templates in this
namespace.
The following sample generates C3279:
// C3279.cpp
// compile with: /clr
namespace cli {
template <> ref class array<int> {}; // C3279
template <typename T> ref class array<T, 2> {}; // C3279
}
Compiler Error C3280
10/31/2018 • 2 minutes to read • Edit Online
// C3280_2.cpp
// compile with: /clr
ref struct A {
void func();
};
#pragma managed(push,off)
#pragma managed(pop)
Compiler Error C3282
10/31/2018 • 2 minutes to read • Edit Online
generic parameter lists can only appear on managed or WinRTclasses, structs, or functions
A generic parameter list was used incorrectly. For more information, see Generics.
Example
The following sample generates C3282 and shows how to fix it.
// C3282.cpp
// compile with: /clr /c
generic <typename T> int x; // C3282
// OK
generic <typename T>
ref class M {};
Compiler Error C3283
10/31/2018 • 2 minutes to read • Edit Online
// C3283.cpp
// compile with: /clr
interface class I {
I(); // C3283
};
Possible resolution:
// C3283b.cpp
// compile with: /clr /c
interface class I {
static I(){}
};
Compiler Error C3284
3/12/2019 • 2 minutes to read • Edit Online
the constraints for generic parameter 'parameter' of function 'function' must match the constraints for generic
parameter 'parameter' of function 'function'
A virtual generic function must use the same constraints as a virtual function with the same name and set of
arguments in the base class.
The following sample generates C3284:
// C3284.cpp
// compile with: /clr /c
// C3284 expected
public interface class IGettable {
int Get();
};
Example
The following sample generates C3285.
// C3285.cpp
// compile with: /clr
int main() {
for each (int i in 0) {} // C3285
array<int> ^p = { 1, 2, 3 };
for each (int j in p) {} // OK
}
Compiler Error C3286
10/31/2018 • 2 minutes to read • Edit Online
A storage class can't be specified on an iteration variable. For more information, see Storage classes (C++) and for
each, in.
Example
The following sample generates C3286, and also shows correct usage.
// C3286.cpp
// compile with: /clr
int main() {
array<int> ^p = { 1, 2, 3 };
for each (static int i in p) {} // C3286
for each (int j in p) {} // OK
}
Compiler Error C3287
10/31/2018 • 2 minutes to read • Edit Online
the type 'type' (return type of GetEnumerator) must have a suitable public MoveNext member function and public
Current property
User-defined collection classes must contain definitions for MoveNext and Current .
See How to: Iterate Over a User-Defined Collection with for each for more information.
Example
The following sample generates C3287.
// C3287.cpp
// compile with: /clr
using namespace System;
ref struct R {
bool MoveNext() {
return true;
}
property Object^ Current {
Object^ get() {
Object ^ o = gcnew Object;
return o;
}
}
};
ref struct R2 {
R ^GetEnumerator() {
R^ r = gcnew R;
return r;
}
};
ref struct T2 {
T ^GetEnumerator() {
T^ t = gcnew T;
return t;
}
};
int main() {
for each (int i in gcnew T2) {} // C3287
for each (int i in gcnew R2) {} // OK
}
Compiler Error C3288
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3288.
// C3288.cpp
// compile with: /clr
ref class R {};
int main() {
*(System::Object^) nullptr; // C3288
// OK
(System::Object^) nullptr; // OK
R^ r;
R% pr = *r;
}
Compiler Error C3289
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3289.
// C3289.cpp
// compile with: /clr
public ref struct C {
// user-defined simple indexer
property int indexer1[int]; // C3289
// user-defined indexer
property int indexer2[int] {
int get(int i) { return 0; }
void set(int i, int j) {}
}
};
int main() {
C ^ MyC = gcnew C();
MyC->indexer2[0] = 1;
}
Compiler Error C3290
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3290.
// C3290.cpp
// compile with: /clr /c
ref struct R {};
ref struct X {
R^ mr;
property R % y; // C3290
property R ^ x; // OK
// OK
property R% prop {
R% get() {
return *mr;
}
void set(R%) {}
}
};
int main() {
X x;
R% xp = x.prop;
}
Compiler Error C3291
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3291.
// C3291.cpp
// compile with: /clr /c
ref struct C {
property System::String ^ default; // C3291
property System::String ^ Default; // OK
};
Compiler Error C3292
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3292.
// C3292.cpp
// compile with: /clr /c
namespace cli {}; // C3292
Compiler Error C3293
10/31/2018 • 2 minutes to read • Edit Online
'accessor': use 'default' to access the default property (indexer) for class 'type'
An indexed property was accessed incorrectly. See How to: Use Properties in C++/CLI for more information.
Visual Studio 2017 and later: In Visual Studio 2015 and earlier, the compiler in some cases misidentified a
default property as a default indexer. It was possible to work around the issue by using the identifier "default" to
access the property. The workaround itself became problematic after default was introduced as a keyword in
C++11. Therefore, in Visual Studio 2017 the bugs that required the workaround were fixed, and the compiler now
raises an error when "default" is used to access the default property for a class.
Example
The following sample generates C3293 in Visual Studio 2015 and earlier.
// C3293.cpp
// compile with: /clr /c
using namespace System;
ref class IndexerClass {
public:
// default indexer
property int default[int] {
int get(int index) { return 0; }
void set(int index, int value) {}
}
};
int main() {
IndexerClass ^ ic = gcnew IndexerClass;
ic->Item[0] = 21; // C3293 in VS2015 OK in VS2017
ic->default[0] = 21; // OK in VS2015 and earlier
String ^s = "Hello";
wchar_t wc = s->Chars[0]; // C3293 in VS2015 OK in VS2017
wchar_t wc2 = s->default[0]; // OK in VS2015 and earlier
Console::WriteLine(wc2);
}
Compiler Error C3295
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3295.
// C3295.cpp
int main() {
#pragma managed // C3295
}
Compiler Error C3296
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3296.
// C3296.cpp
// compile with: /clr /c
using namespace System;
ref class R {
public:
property int MyProp[int] { int get(int); }
'constraint_2' : cannot use 'constraint_1' as a constraint because 'constraint_1' has the value constraint
Value classes are sealed. If a constraint is a value class, another constraint can never derive from it.
For more information, see Constraints on Generic Type Parameters (C++/CLI).
Example
The following sample generates C3297.
// C3297.cpp
// compile with: /clr /c
generic<class T, class U>
where T : value class
where U : T // C3297
public ref struct R {};
Compiler Error C3298
10/31/2018 • 2 minutes to read • Edit Online
'constraint_1' : cannot use 'constraint_2' as a constraint because 'constraint_2' has the ref constraint and
'constraint_1' has the value constraint
You cannot specify mutually exclusive characteristics for a constraint. For example, a generic type parameter cannot
be constrained to both a value type and a reference type.
For more information, see Constraints on Generic Type Parameters (C++/CLI).
Example
The following sample generates C3298.
// C3298.cpp
// compile with: /clr /c
generic<class T, class U>
where T : ref class
where U : T, value class // C3298
public ref struct R {};
Compiler Error C3299
10/31/2018 • 2 minutes to read • Edit Online
'member_function' : cannot specify constraints, they are inherited from the base method
When overriding a generic member function, you cannot specify constraint clauses (repeating the constraints
implies that the constraints are not inherited).
The constraint clauses on the generic function you are overriding will be inherited.
For more information, see Constraints on Generic Type Parameters (C++/CLI).
Example
The following sample generates C3299.
// C3299.cpp
// compile with: /clr /c
public ref struct R {
generic<class T>
where T : R
virtual void f();
};
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3302 'identifier': identifier has more than number characters
Compiler Error C3308 ' function': direct call through imported class is not supported
Compiler Error C3312 no callable 'identifier' function found for type 'type'
Compiler Error C3313 'identifier': variable cannot have the type 'type'
Compiler Error C3316 'type': an array of unknown size cannot be used in a range-
based for statement
Compiler Error C3318 'type': an array cannot have an element type that contains
'auto'
Compiler Error C3320 'type': type cannot have the same name as the module 'name'
property
Compiler Error C3322 'property': is not a valid property for attribute 'attribute'
Compiler Error C3323 'alignas' and '__declspec(align)' are not allowed on function
declarations
Compiler Error C3324 'property': property occurs more than once in attribute
'attribute'
Compiler Error C3326 'value': is not a valid value for property 'property' of attribute
'attribute'
Compiler Error C3327 'property': must specify value for property of attribute
'attribute'
Compiler Error C3328 'attribute': attribute does not have enough arguments
ERROR MESSAGE
Compiler Error C3330 ' function': a function cannot return an array 'type'
Compiler Error C3331 'identifier': attributes on parameters are only allowed on COM
interfaces and coclasses
Compiler Error C3335 'identifier': There can be at most one default interface for a
coclass 'class'
Compiler Error C3337 'identifier': defaultvtable must be an event source for a coclass
'class'
Compiler Error C3338 'identifier': There can be at most one default interface that is
also an event source for a coclass 'class'
Compiler Error C3340 'identifier': interface cannot be both 'restricted' and 'default' in
coclass 'class'
Compiler Error C3343 'class::name': attribute identifier has too many characters
Compiler Error C3344 you cannot define an explicit specialization nor a partial
specialization of 'symbol'
Compiler Error C3348 exported templates are not part of the current C++ standards
Compiler Error C3351 ' function': if you pass a NULL object instance to a delegate
constructor you must also pass the address of a static
member function
Compiler Error C3352 'function': the specified function does not match the delegate
type 'type'
Compiler Error C3353 'identifier': a delegate can only be created from a global
function or a member function of a managed/WinRT type
Compiler Error C3354 'identifier': the function used to create a delegate cannot have
return type 'type'
Compiler Error C3356 'identifier': cannot call a multicast attribute with a fully
qualified name
Compiler Error C3357 'attribute': attribute is ambiguous, must use fully qualified
name
Compiler Error C3362 'class::member': multicast attribute has not been implemented
Compiler Error C3364 ' function': invalid argument for delegate constructor; delegate
target needs to be a pointer to a member function
Compiler Error C3365 operator 'operator': differing operands of type 'type' and 'type'
Compiler Error C3366 'member': static data members of managed/WinRT types must
be defined within the class definition
Compiler Error C3367 ' function': cannot use static function to create an unbound
delegate
Compiler Error C3371 'idl_module': only the 'name' property is allowed here
Compiler Error C3372 must specify at least 1 interface for attribute 'attribute' on a
coclass
Compiler Error C3374 can't take address of ' function' unless creating delegate
instance
Compiler Error C3376 'template': only static data member templates are allowed
Compiler Error C3378 a declaration can be exported only from a module interface
unit
Compiler Error C3379 'class': a nested class cannot have an assembly access specifier
as part of its declaration
Compiler Error C3380 'specifier': invalid assembly access specifier - only 'public' or
'private' are allowed
Compiler Error C3381 'specifier': assembly access specifiers are only available in code
compiled with a /clr option
Compiler Error C3384 'type': the value constraint and the ref constraint are mutually
exclusive
Compiler Error C3385 ' function': a function that has a DllImport custom attribute
cannot return an instance of a class
Compiler Error C3390 'type': invalid type argument for generic parameter
'parameter' of generic 'generic_type', must be a reference type
Compiler Error C3391 'type': invalid type argument for generic parameter
'parameter' of generic 'generic_type', must be a non-nullable
value type
Compiler Error C3392 'type': invalid type argument for generic parameter
'parameter' of generic 'generic_type', must have a public
parameterless constructor
Compiler Error C3393 syntax error in constraint clause: 'identifier' is not a type
Compiler Error C3394 syntax error in constraint clause: found 'symbol' expected a
type
Compiler Error C3398 'operator': cannot convert from 'type' to 'type'. Source
expression must be a function symbol
Compiler Error C3399 'type': cannot provide arguments when creating an instance of
a generic parameter
Compiler Error C3303
10/31/2018 • 2 minutes to read • Edit Online
// C3309.cpp
#define NAME MyModule
[module(name="NAME")]; // C3309
// Try the following line instead
// [module(name="MyModule")];
[coclass]
class MyClass {
public:
void MyFunc();
};
int main() {
}
Compiler Error C3320
10/31/2018 • 2 minutes to read • Edit Online
'type': type cannot have the same name as the module 'name' property
An exported user-defined type (UDT), which could be a struct, class, enum, or union, cannot have the same name
as the parameter passed to the module attribute's name property.
Example
The following sample generates C3320:
// C3320.cpp
#include "unknwn.h"
[module(name="xx")];
// C3340.cpp
#include <windows.h>
[module(name="MyModule")];
[ object, uuid(373a1a4c-469b-11d3-a6b0-00c04f79ae8f) ]
__interface IMyIface
{
HRESULT f1();
};
[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f),
default(IMyIface),
source(IMyIface),restricted(IMyIface) ]
class CmyClass // C3340
{
};
int main()
{
}
Compiler Error C3342
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3342.
// C3342.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Reflection;
[AttributeUsage(AttributeTargets::All)]
public ref class XAttribute : public Attribute {};
[AttributeUsage(AttributeTargets::All)]
public ref class X : public Attribute {};
Example
The following code example causes error message C3345 because the name parameter of the module attribute
contains a blank.
// cpp_attr_name_module.cpp
// compile with: /LD /link /OPT:NOREF
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <atlplus.h>
// C3345 expected
[module(dll, name="My Library", version="1.2", helpfile="MyHelpFile")]
// Try the following line instead
//[module(dll, name="MyLibrary", version="1.2", helpfile="MyHelpFile")]
// Module attribute now applies to this class
class CMyClass {
public:
BOOL WINAPI DllMain(DWORD dwReason, LPVOID lpReserved) {
// add your own code here
return __super::DllMain(dwReason, lpReserved);
}
};
See Also
__iscsym
Character Classification
module
Compiler Error C3347
10/31/2018 • 2 minutes to read • Edit Online
// C3347.cpp
// compile with: /c
[module(name="xx")];
[idl_module(dllname="x")]; // C3347
// try the following line instead
// [idl_module(name="test", dllname="x")];
Compiler Error C3350
10/31/2018 • 2 minutes to read • Edit Online
// C3350.cpp
// compile with: /clr
delegate void SumDelegate();
int main() {
X ^ MyX = gcnew X();
SumDelegate ^ pSD = gcnew SumDelegate(); // C3350
SumDelegate ^ pSD1 = gcnew SumDelegate(MyX, &X::F);
SumDelegate ^ pSD2 = gcnew SumDelegate(&X::F2);
}
Compiler Error C3351
10/31/2018 • 2 minutes to read • Edit Online
'object' : delegate constructor: second argument must be address of a static member function or global function
The compiler expected the address of a function declared static .
The following sample generates C3351:
// C3351a.cpp
// compile with: /clr
delegate int D(int, int);
ref class C {
public:
int mf(int, int) {
return 1;
}
int main() {
System::Delegate ^pD = gcnew D(nullptr, &C::mf); // C3351
System::Delegate ^pD2 = gcnew D(&C::mf2);
}
Compiler Error C3352
10/31/2018 • 2 minutes to read • Edit Online
'function' : the specified function does not match the delegate type 'type'
The parameter lists for function and the delegate do not match.
For more information, see delegate (C++ Component Extensions).
The following sample generates C3352:
// C3352.cpp
// compile with: /clr
delegate int D( int, int );
ref class C {
public:
int mf( int ) {
return 1;
}
int main() {
C^ pC = gcnew C;
System::Delegate^ pD = gcnew D( pC, &C::mf ); // C3352
}
Compiler Error C3353
10/31/2018 • 2 minutes to read • Edit Online
'delegate' : a delegate can only be created from a global function or a member function of a managed or WinRT
type
Delegates, declared with the delegate keyword, can only be declared at global scope.
The following sample generates C3353:
// C3353.cpp
// compile with: /clr
delegate int f; // C3353
Compiler Error C3354
10/31/2018 • 2 minutes to read • Edit Online
'function' : the function used to create a delegate cannot have return type 'type'
The following types are invalid as return types for a delegate :
Pointer to function
Pointer to member
Pointer to member function
Reference to function
Reference to member function
The following sample generates C3354:
// C3354_2.cpp
// compile with: /clr /c
using namespace System;
typedef void ( *VoidPfn )();
// C3358.cpp
#define __ATLEVENT_H__ 1 // remove this line to resolve the error
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[event_receiver(com)]
struct A // C3358
{
void func();
};
int main()
{
}
Compiler Error C3360
10/31/2018 • 2 minutes to read • Edit Online
// C3360.cpp
[ uuid("1") ]
// try this line instead
// [ uuid("12341234-1234-1234-1234-123412341234") ]
struct A // C3360
{
};
int main()
{
}
Compiler Error C3363
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3363.
// C3363.cpp
// compile with: /clr
int main() {
System::typeid; // C3363
}
Compiler Error C3364
10/31/2018 • 2 minutes to read • Edit Online
'delegate': delegate constructor: argument must be pointer to member function of managed class or global
function
The second parameter of the delegate's constructor takes either the address of a member function or the address
of a static member function of any class. Both are treated as simple addresses.
The following sample generates C3364:
// C3364_2.cpp
// compile with: /clr
ref class C {
public:
int mf( int, int ) {
return 1;
}
};
int main() {
C^ pC = gcnew C;
System::Delegate^ pD = gcnew D( pC,pC->mf( 1, 2 ) ); // C3364
Example
The following sample generates C3365:
// C3365.cpp
// compile with: /clr
delegate void D1();
delegate void D2(int);
ref class R {
public:
void f(){}
void g(int){}
};
int main() {
D1^ d1 = gcnew D1(gcnew R, &R::f);
D2^ d2 = gcnew D2(gcnew R, &R::g);
D1^ d3 = gcnew D1(gcnew R, &R::f);
d1 += d2; // C3365
d1 += d3; // OK
d1();
}
Compiler Error C3366
10/31/2018 • 2 minutes to read • Edit Online
'variable' : static data members of managed or WinRTtypes must be defined within the class definition
You attempted to reference a static member of a WinRT or .NET class or interface outside the definition of that
class or interface.
The compiler needs to know the full definition of the class (to emit the meta-data after one pass) and requires static
data members to be initialized within the class.
For example, the following example generates C3366 and shows how to fix it:
// C3366.cpp
// compile with: /clr /c
ref class X {
public:
static int i; // initialize i here to avoid C3366
};
Example
The following sample generates C3367.
// C3367.cpp
// compile with: /clr
ref struct R {
void b() {}
static void f() {}
};
int main() {
Del ^ a = gcnew Del(&R::b); // OK
Del ^ b = gcnew Del(&R::f); // C3367
}
Compiler Error C3368
10/31/2018 • 2 minutes to read • Edit Online
// C3368.cpp
// processor: x86
[idl_module(name="Name", dllname="Some.dll")];
[idl_module(name="Name")]
int __fastcall f1(); // C3368
Compiler Error C3369
10/31/2018 • 2 minutes to read • Edit Online
// C3369.cpp
// compile with: /c
[idl_module(name="name1", dllname="x.dll")]; // C3369
[idl_module(name="name1", dllname="x.dll")];
Compiler Error C3370
10/31/2018 • 2 minutes to read • Edit Online
// C3370.cpp
[module(name=MyLibrary)];
// uncomment the following line to resolve the error
// [idl_module(name="name1", dllname=x.dll)];
[idl_module(name="name1"), entry(100)] // C3370
int f1();
int main()
{
}
Compiler Error C3371
10/31/2018 • 2 minutes to read • Edit Online
// C3371.cpp
[idl_module(name="Name", dllname="Some.dll")];
[idl_module(name="Name", helpstring="Some help")] // C3371
int f1();
// try
// [idl_module(name="Name")]
// int f1();
int main()
{
}
Compiler Error C3372
10/31/2018 • 2 minutes to read • Edit Online
// C3372.cpp
#include <windows.h>
[module(name="MyModule")];
[ object, uuid(373a1a4c-469b-11d3-a6b0-00c04f79ae8f) ]
__interface IMyIface {
HRESULT f1();
};
// to resolve, pass an interface name to the source attribute
// for example, source(IMyIface)
[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f), source,
default(IMyIface) ] // C3372
class CMyClass {
};
int main() {
}
Compiler Error C3373
10/31/2018 • 2 minutes to read • Edit Online
// C3373.cpp
#include <windows.h>
[module(name="MyModule")];
[ object, uuid(373a1a4c-469b-11d3-a6b0-00c04f79ae8f) ]
__interface IMyIface
{
// arguments to source and restricted are not allowed when
// these attributes are applied to an interface
[source(IMyIface)] HRESULT f1();
[restricted(IMyIface)] HRESULT f2(); // C3373
};
[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f) ]
class CMyClass : public IMyIface {
};
int main() {
}
Compiler Error C3374
10/31/2018 • 2 minutes to read • Edit Online
// C3374.cpp
// compile with: /clr
public delegate void MyDel(int i);
ref class A {
public:
void func1(int i) {
System::Console::WriteLine("in func1 {0}", i);
}
};
int main() {
&A::func1; // C3374
// OK
A ^ a = gcnew A;
MyDel ^ StaticDelInst = gcnew MyDel(a, &A::func1);
}
See Also
How to: Define and Use Delegates (C++/CLI)
Compiler Error C3375
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3375.
// C3375.cpp
// compile with: /clr
ref struct R {
static void f(R^) {}
void f() {}
};
int main() {
Del ^ a = gcnew Del(&R::f); // C3375
}
Compiler Error C3379
10/31/2018 • 2 minutes to read • Edit Online
'class' : a nested class cannot have an assembly access specifier as part of its declaration
When applied to a managed type, such as class or struct, the public and private keywords indicate whether the
class will be exposed through assembly metadata. public or private cannot be applied to a nested class, which
will inherit the assembly access of the enclosing class.
When used with /clr, the ref and value keywords indicate that a class is managed (see Classes and Structs).
The following sample generates C3379:
// C3379a.cpp
// compile with: /clr
using namespace System;
int main() {
A^ myA = gcnew A;
Console::WriteLine(myA->i);
'class' : invalid assembly access specifier - only 'public' or 'private' are allowed
When applied to a managed class or struct, the public and private keywords indicate whether the class will be
exposed through assembly metadata. Only public or private can be applied to a class in a program compiled
with /clr.
The ref and value keywords, when used with /clr, indicate that a class is managed (see Classes and Structs).
The following sample generates C3380:
// C3380_2.cpp
// compile with: /clr
protected ref class A { // C3380
// try the following line instead
// ref class A {
public:
static int i = 9;
};
int main() {
A^ myA = gcnew A;
System::Console::WriteLine(myA->i);
}
Compiler Error C3381
10/31/2018 • 2 minutes to read • Edit Online
'assembly' : assembly access specifiers are only available in code compiled with a /clr option
Native types can be visible outside the assembly, but you can only specify assembly access for native types in a /clr
compilation.
For more information, see Type visibility and /clr (Common Language Runtime Compilation).
Example
The following sample generates C3381.
// C3381.cpp
// compile with: /c
public class A {}; // C3381
Compiler Error C3382
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3382.
// C3382.cpp
// compile with: /clr:safe
int main() {
sizeof( char ); // C3382
}
Compiler Error C3383
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3383.
// C3383.cpp
// compile with: /clr:safe
int main() {
char* pCharArray = new char[256]; // C3383
}
Compiler Error C3384
10/31/2018 • 2 minutes to read • Edit Online
'type_parameter' : the value constraint and the ref constraint are mutually exclusive
You cannot constrain a generic type to both value class and ref class .
See Constraints on Generic Type Parameters (C++/CLI) for more information.
Example
The following sample generates C3384.
// C3384.cpp
// compile with: /c /clr
generic <typename T>
where T : ref class
where T : value class // C3384
ref class List {};
Compiler Error C3385
10/31/2018 • 2 minutes to read • Edit Online
'class::function' : a function that has a DllImport Custom attribute cannot return an instance of a class
A function defined as being in a .dll file specified with the DllImport attribute cannot return an instance of a class.
The following sample generates C3385:
// C3385.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Runtime::InteropServices;
// C3386.cpp
// compile with: /clr /c
ref class __declspec(dllimport) X1 { // C3386
// try the following line instead
// ref class X1 {
};
Compiler Error C3387
10/31/2018 • 2 minutes to read • Edit Online
// C3387a.cpp
// compile with: /clr /c
ref class X2 {
void __declspec(dllexport) mf() { // C3387
// try the following line instead
// void mf() {
}
};
Compiler Error C3388
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3388.
// C3388.cpp
// compile with: /clr /c
interface class AA {};
// OK
generic <class T>
where T : AA
ref class D {};
Compiler Error C3389
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
A __declspec modifier used implies a per process state. /clr:pure implies a per appdomain state. So, declaring a
variable with the keyword __declspec modifier and compiling with /clr:pure is not allowed.
Example
The following sample generates C3389:
// C3389.cpp
// compile with: /clr:pure /c
__declspec(dllexport) int g2 = 0; // C3389
Compiler Error C3390
10/31/2018 • 2 minutes to read • Edit Online
'type_arg' : invalid type argument for generic parameter 'param' of generic 'generic_type', must be a reference type
A generic type was instantiated incorrectly. Check the type definition. For more information, see Generics.
Example
The first sample uses C# to create a component that contains a generic type that has certain constraints that are
not supported when authoring generic types in C++/CLR. For more information, see Constraints on Type
Parameters.
// C3390.cs
// Compile by using: csc /target:library C3390.cs
// a C# program
public class GR<C, V, N>
where C : class
where V : struct
where N : new() {}
When the C3390.dll component is available, the following sample generates C3390.
// C3390_b.cpp
// Compile by using: cl /clr C3390_b.cpp
#using <C3390.dll>
ref class R { R(int) {} };
value class V {};
ref struct N { N() {} };
int main () {
GR<V, V, N^>^ gr2; // C3390 first type must be a ref type
GR<R^, V, N^>^ gr2b; // OK
}
Compiler Error C3391
10/31/2018 • 2 minutes to read • Edit Online
'type_arg' : invalid type argument for generic parameter 'param' of generic 'generic_type', must be a non-nullable
value type
A generic type was instantiated incorrectly. Check the type definition. For more information, see Nullable and
Generics.
Example
The following sample uses C# to create a component that contains a generic type that has certain constraints that
are not supported when authoring generic types in C++/CLI. For more information, see Constraints on Type
Parameters.
// C3391.cs
// Compile by using: csc /target:library C3391.cs
// a C# program
public class GR<N>
where N : struct {}
When the C3391.dll component is available, the following sample generates C3391.
// C3391_b.cpp
// Compile by using: cl /clr C3391_b.cpp
#using <C3391.dll>
using namespace System;
value class VClass {};
int main() {
GR< Nullable<VClass> >^ a =
gcnew GR< Nullable<VClass> >(); // C3391 can't be Nullable
GR<VClass>^ aa = gcnew GR<VClass>(); // OK
}
Compiler Error C3392
10/31/2018 • 2 minutes to read • Edit Online
'type_arg' : invalid type argument for generic parameter 'param' of generic 'generic_type', must have a public
parameterless constructor
A generic type was instantiated incorrectly. Check the type definition. For more information, see Generics.
Example
The following sample uses C# to create a component that contains a generic type that has certain constraints that
are not supported when authoring generic types in C++/CLI. For more information, see Constraints on Type
Parameters.
// C3392.cs
// Compile by using: csc /target:library C3392.cs
// a C# program
public class GR<C, V, N>
where C : class
where V : struct
where N : new() {}
When the C3392.dll component is available, the following sample generates C3392.
// C3392_b.cpp
// Compile by using: cl /clr C3392_b.cpp
#using <C3392.dll>
int main () {
GR<R^, V, N^>^ gr1; // C3392
GR<R^, V, N2^>^ gr1a; // OK
Example
The following sample generates C3393:
// C3393.cpp
// compile with: /clr /c
void MyInterface() {}
interface class MyInterface2 {};
generic<typename T>
where T : MyInterface // C3393
// try the following line instead
// where T : MyInterface2
ref class R {};
Compiler Error C3394
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3394:
// C3394.cpp
// compile with: /clr /c
ref class MyClass {};
ref class R {
generic<typename T>
where T : static // C3394
// try the following line instead
// where T : MyClass
void f() {}
};
Compiler Error C3395
10/31/2018 • 2 minutes to read • Edit Online
'function' : __declspec(dllexport) cannot be applied to a function with the __clrcall calling convention
__declspec(dllexport) and __clrcall are not compatible. For more information, see dllexport, dllimport.
The following sample generates C3395:
// C3395.cpp
// compile with: /clr /c
Example
The following sample generates C3397.
// C3397.cpp
// compile with: /clr
// /clr /c
void Func(array<int> ^p = gcnew array<int> { 1, 2, 3 }); // C3397
void Func2(array<int> ^p = gcnew array<int> (3)); // OK
int main() {
array<int> ^p = gcnew array<int> { 1, 2, 3}; // OK
}
Compiler Error C3398
10/31/2018 • 2 minutes to read • Edit Online
'operator' : cannot convert from 'function_signature' to 'function_pointer'. Source expression must be a function
symbol
When the __clrcall calling convention is not specified when compiling with /clr, the compiler generates two entry
points (addresses) for each function, a native entry point and a managed entry point.
By default the compiler returns the native entry point, but there are some cases where the managed entry point is
desired (for instance when assigning the address to a __clrcall function pointer). In order for the compiler to
reliably choose the managed entry point in an assignment, the right hand side must be a function symbol.
Compiler Error C3399
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3399.
// C3399.cpp
// compile with: /clr /c
generic <class T>
where T : gcnew()
void f() {
T t = gcnew T(1); // C3399
T t2 = gcnew T(); // OK
}
Compiler Errors C3400 Through C3499
10/31/2018 • 8 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3401 'specifier': invalid assembly access specifier - only 'private' is
allowed on class templates
Compiler Error C3402 'function': cannot resolve overload except in the current scope
Compiler Error C3410 'identifier': the type of the explicit instantiation 'type' does not
match the type of the variable template 'type'
Compiler Error C3411 'type' is not valid as the size of an array as it is not an integer
type
Compiler Error C3415 multiple 'section' sections found with different attributes
('0xvalue')
Compiler Error C3417 'declarator': value types cannot contain user-defined special
member functions
Compiler Error C3421 'function': you cannot call the finalizer for this class as it is
either inaccessible or it does not exist
Compiler Error C3424 'type': a function-style cast to an array type is not allowed
Compiler Error C3425 cannot throw pointer to object of incomplete type 'type'
Compiler Error C3428 'context': 'keyword' can only be applied to class declarations or
definitions
Compiler Error C3433 'identifier': all declarations of an enumeration must have the
same underlying type, was 'type1' now 'type2'
Compiler Error C3441 'declaration': 'keyword' cannot be applied after the class has
been defined
Compiler Error C3443 The default member initializer for 'class' is recursive
Compiler Error C3444 Empty aggregate class 'class' must be initialized with '{}'
Compiler Error C3446 'class': a default member initializer is not allowed for a member
of a value class
Compiler Error C3453 'attribute': attribute not applied because qualifier 'qualifier'
did not match
Compiler Error C3455 'attribute': none of the attribute constructors matched the
arguments
Compiler Error C3457 'attribute': attribute does not support unnamed arguments
Compiler Error C3459 '[attribute]': attribute allowed only on class indexer (default
indexed property)
Compiler Error C3465 to use type 'type' you must reference the assembly 'assembly'
Compiler Error C3467 'type': this type has already been forwarded
Compiler Error C3468 'type': you can only forward a type to an assembly: 'identifier'
is not an assembly
Compiler Error C3470 'class': a class cannot have both an indexer (default indexed
property) and an operator[]
Compiler Error C3471 new module name name (set on command line) conflicts with
previous name name
Compiler Error C3472 new output file name filename (set on command line) conflicts
with previous file name filename
Compiler Error C3476 could not open file 'filename' for input
Compiler Error C3482 'this' can only be used as a lambda capture within a non-static
member function
Compiler Error C3483 'identifier' is already part of the lambda capture list
Compiler Error C3484 syntax error: expected '->' before the return type
Compiler Error C3487 'type': all return expressions must deduce to the same type:
previously it was 'type'
Compiler Error C3488 '&identifier' is not allowed when the default capture mode is
by-reference
Compiler Error C3489 '&identifier' is required when the default capture mode is by
copy
Compiler Error C3498 'identifier': you cannot capture a variable that has a
managed/WinRT type
Compiler Error C3499 a lambda that has been specified to have a void return type
cannot return a value
Compiler Error C3400
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3400.
// C3400.cpp
// compile with: /clr /c
generic<class T, class U>
where T : U
where U : T // C3400
public ref struct R {};
Compiler Error C3408
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3408.
// C3408.cpp
// compile with: /c
template <class T> struct PTS {
enum {
IsPointer = 0,
IsPointerToDataMember = 0
};
};
template
<class T, class U>
struct PTS<T U::*> {
enum {
IsPointer = 1,
IsPointerToDataMember = 1
};
};
struct S{};
int main() {
S s, *pS;
int S::*ptm;
Remarks
The square brackets were interpreted by the compiler as an attribute block, but no attributes were found.
The compiler may generate this error when you use square brackets as part of the definition of a lambda
expression. This error occurs when the compiler cannot determine whether the square brackets are part of the
definition of a lambda expression or of an attribute block. For more information about lambda expressions, see
Lambda Expressions.
To correct this error
1. If the square brackets are part of an attribute block:
a. Provide one or more attributes in the attribute block.
b. Remove the attribute block.
2. If the square brackets are part of a lambda expression, make sure that the lambda expression follows valid
syntax rules.
For more information about lambda expression syntax, see Lambda Expression Syntax.
Example
The following example generates C3409.
// C3409.cpp
// compile with: /c
#include <windows.h>
[] // C3409
class a {};
// OK
[object, uuid("00000000-0000-0000-0000-000000000000")]
__interface x {};
[coclass, uuid("00000000-0000-0000-0000-000000000001")]
class b : public x {};
Example
The following example generates C3409 because a lambda expression uses the mutable specification, but does
not provide a parameter list. The compiler cannot determine whether the square brackets are part of the definition
of a lambda expression or of an attribute block.
// C3409b.cpp
int main()
{
[] mutable {}();
}
See Also
attribute
Lambda Expressions
Lambda Expression Syntax
Compiler Error C3412
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3412.
// C3412.cpp
template <class T>
struct S {
template <>
struct S<int> {}; // C3412 in a class
};
Example
The following sample shows a possible resolution.
// C3412b.cpp
// compile with: /c
template <class T>
struct S {};
template <>
struct S<int> {};
Compiler Error C3413
10/31/2018 • 2 minutes to read • Edit Online
// C3413.cpp
template
class MyClass {}; // C3413
Possible resolution:
// C3413b.cpp
// compile with: /c
template <class T>
class MyClass {};
template <>
class MyClass<int> {};
Compiler Error C3414
10/31/2018 • 2 minutes to read • Edit Online
// C3414a2.cpp
// compile with: /clr /LD
public ref class MyClass {
public:
void Test(){}
};
and then:
// C3414b2.cpp
// compile with: /clr
#using <C3414a2.dll>
System::Object::Object() { // C3414
}
Compiler Error C3415
10/31/2018 • 2 minutes to read • Edit Online
// C3415.cpp
#pragma section("mysec1",write)
#pragma section("mysec1",read) // C3415
Compiler Error C3417
10/31/2018 • 2 minutes to read • Edit Online
// C3417.cpp
// compile with: /clr /c
value class VC {
VC(){} // C3417
// OK
static VC(){}
VC(int i){}
};
Compiler Error C3418
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3418.
// C3418.cpp
// compile with: /clr /c
ref struct m {
internal public: // C3418
void test(){}
};
ref struct n {
internal: // OK
void test(){}
};
Compiler Error C3420
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3420.
// C3420.cpp
// compile with: /clr /c
ref class R {
virtual !R() {} // C3420
};
Compiler Error C3421
10/31/2018 • 2 minutes to read • Edit Online
'type' : you cannot call the finalizer for this class as it is either inaccessible or it does not exist
A finalizer is implicitly private, so it cannot be called from outside its enclosing type.
For more information, see Destructors and finalizers in How to: Define and consume classes and structs
(C++/CLI).
Example
The following sample generates C3421.
// C3421.cpp
// compile with: /clr
ref class A {};
ref class B {
!B() {}
public:
~B() {}
};
int main() {
A a;
a.!A(); // C3421
B b;
b.!B(); // C3421
}
Compiler Error C3445
10/31/2018 • 2 minutes to read • Edit Online
According to the ISO C++17 standard, the compiler is required to consider an explicit constructor for overload
resolution in copy-list-initialization, but must raise an error if that overload is actually chosen.
Starting in Visual Studio 2017, the compiler finds errors related to object creation by using an initializer list that
were not found by Visual Studio 2015. These errors could lead to crashes or undefined behavior at runtime.
Example
The following sample generates C3445.
// C3445.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
A a1 = { 1 }; // error C3445: copy-list-initialization of
// 'A' cannot use an explicit constructor
}
// C3445b.cpp
struct A
{
explicit A(int) {}
A(double) {}
};
int main()
{
A a1{ 1 };
}
Compiler Error C3446
10/31/2018 • 2 minutes to read • Edit Online
'class': a default member initializer is not allowed for a member of a value class
In Visual Studio 2015 and earlier, the compiler permitted (but ignored) a default member initializer for a member
of a value class. Default initialization of a value class always zero-initializes the members; a default constructor is
not permitted. In Visual Studio 2017, default member initializers raise a compiler error, as shown in this example:
Example
The following sample generates C3446 in Visual Studio 2017 and later:
// C3446.cpp
value struct V
{
int i = 0; // error C3446: 'V::i': a default member initializer
// is not allowed for a member of a value class
int j {0}; // C3446
};
// C3446b.cpp
value struct V
{
int i;
int j;
};
Compiler Error C3450
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3450 and shows how to fix it.
// C3450.cpp
// compile with: /clr
// C3450 expected
using namespace System;
using namespace System::Security;
using namespace System::Security::Permissions;
[attribute(AttributeTargets::All)]
ref struct AtClass {
AtClass(Type ^) {}
};
[attribute(AttributeTargets::All)]
ref struct AtClass2 {
AtClass2() {}
};
Example
The following sample generates C3451.
// C3451.cpp
// compile with: /clr /c
using namespace System;
[ attribute(AttributeTargets::All) ]
public ref struct MyAttr {};
Example
The following sample generates C3452.
// C3452.cpp
// compile with: /c
int i;
[module( name="mod", type=dll, custom={i} ) ]; // C3452
// try the following line instead
// [module( name="mod", type=dll, custom={"a"} ) ];
Compiler Error C3453
10/31/2018 • 2 minutes to read • Edit Online
'attribute': attribute not applied because qualifier 'assembly' did not match
Assembly or module level attributes can only be specified as stand-alone instructions.
Example
The following sample generates C3453.
// C3453.cpp
// compile with: /clr /c
[assembly:System::CLSCompliant(true)] // C3453
// try the following line instead
// [assembly:System::CLSCompliant(true)];
ref class X {};
Compiler Error C3454
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3454.
// C3454.cpp
// compile with: /clr /c
using namespace System;
[attribute] // C3454
ref class Attr1;
[attribute] // OK
ref class Attr2 {};
Compiler Error C3455
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3455.
// C3455.cpp
// compile with: /clr /c
using namespace System;
[attribute("MyAt")] // C3455
// try the following line instead
// [attribute(All)]
ref struct MyAttr {
MyAttr() {}
};
Compiler Error C3456
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3457.
#include "SourceAnnotations.h"
[vc_attributes::Post( 1 )] int f(); // C3457
[vc_attributes::Post( Valid=vc_attributes::Yes )] int f2(); // OK
Compiler Error C3458
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3458
// C3458.cpp
// compile with: /clr /c
[System::Reflection::DefaultMember("Chars")]
public ref class MyString {
public:
[System::Runtime::CompilerServices::IndexerName("Chars")] // C3458
property char default[int] {
char get(int index);
void set(int index, char c);
}
};
Compiler Error C3459
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3459.
// C3459.cpp
// compile with: /clr /c
public ref class MyString {
public:
[System::Runtime::CompilerServices::IndexerName("Chars")] // C3459
property int Prop;
};
// OK
public ref class MyString2 {
array<int>^ MyArr;
public:
MyString2() {
MyArr = gcnew array<int>(5);
}
[System::Runtime::CompilerServices::IndexerName("Chars")] // OK
property int default[int] {
int get(int index) {
return MyArr[index];
}
void set(int index, int value) {
MyArr[index] = value;
}
}
};
Compiler Error C3460
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3460.cpp
// compile with: /LD /clr
public ref class R {};
Example
The following sample generates C3460.
// C3460_b.cpp
// compile with: /clr /c
#using "C3460.dll"
[assembly:TypeForwardedTo(int::typeid)]; // C3460
[assembly:TypeForwardedTo(R::typeid)];
Compiler Error C3461
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3461.cpp
// compile with: /clr /LD
public ref class R {};
Example
The following sample generates C3461.
// C3461b.cpp
// compile with: /clr /c
#using "C3461.dll"
class N {};
[assembly:TypeForwardedTo(N::typeid)]; // C3461
[assembly:TypeForwardedTo(R::typeid)]; // OK
Compiler Error C3462
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3462.cpp
// compile with: /clr /LD
public ref class R {};
Example
The following sample generates C3462.
// C3462b.cpp
// compile with: /clr /c
#using "C3462.dll"
ref class N {};
[assembly:TypeForwardedTo(N::typeid)]; // C3462
[assembly:TypeForwardedTo(R::typeid)];
Compiler Error C3463
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3463.
// C3463.cpp
// compile with: /c
#include <windows.h>
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface X {};
typedef X* PX;
Example
The following sample creates a component.
// C3464.cpp
// compile with: /LD /clr
public ref class R {
public:
ref class N {};
};
Example
The following sample generates C3464.
// C3464_b.cpp
// compile with: /clr /c
#using "C3464.dll"
[assembly:TypeForwardedTo(R::N::typeid)]; // C3464
[assembly:TypeForwardedTo(R::typeid)]; // OK
Compiler Error C3465
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample builds an assembly that contains the new location of a type.
// C3465.cpp
// compile with: /clr /LD
public ref class R {
public:
ref class N {};
};
Example
The following sample builds an assembly that used to contain the definition of the type, but now contains
forwarding syntax for the type.
// C3465_b.cpp
// compile with: /clr /LD
#using "C3465.dll"
[ assembly:TypeForwardedTo(R::typeid) ];
Example
The following sample generates C3465.
// C3465_c.cpp
// compile with: /clr
// C3465 expected
#using "C3465_b.dll"
// Uncomment the following line to resolve.
// #using "C3465.dll"
int main() {
R^ r = gcnew R();
}
Compiler Error C3466
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3466.cpp
// compile with: /clr /LD
generic<typename T>
public ref class GR {};
Example
The following sample generates C3466.
// C3466_b.cpp
// compile with: /clr /c
#using "C3466.dll"
[assembly:TypeForwardedTo(GR<int>::typeid)]; // C3466
[assembly:TypeForwardedTo(GR2::typeid)]; // OK
Compiler Error C3467
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3467.cpp
// compile with: /LD /clr
public ref class R {};
Example
The following sample generates C3467.
// C3467_b.cpp
// compile with: /clr /c
#using "C3467.dll"
[ assembly:TypeForwardedTo(R::typeid) ];
[ assembly:TypeForwardedTo(R::typeid) ]; // C3467
Compiler Error C3468
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a module.
// C3468.cpp
// compile with: /LN /clr
public ref class R {};
Example
The following sample generates C3468.
// C3468_b.cpp
// compile with: /clr /c
#using "C3468.netmodule"
[ assembly:TypeForwardedTo(R::typeid) ]; // C3468
Compiler Error C3469
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample creates a component.
// C3469.cpp
// compile with: /clr /LD
generic<typename T>
public ref class GR {};
Example
The following sample generates C3466.
// C3469_b.cpp
// compile with: /clr /c
#using "C3469.dll"
[assembly:TypeForwardedTo(GR::typeid)]; // C3469
[assembly:TypeForwardedTo(GR2::typeid)]; // OK
Compiler Error C3470
10/31/2018 • 2 minutes to read • Edit Online
'type' : a class cannot have both an indexer (default indexed property) and an operator[]
A type cannot define both a default indexer and an operator[].
Example
The following sample generates C3470
// C3470.cpp
// compile with: /clr
using namespace System;
ref class R {
public:
property int default[int] {
int get(int i) {
return i+1;
}
}
int main() {
R ^ r = gcnew R;
// return r[9] + r["32"] - 42;
}
Compiler Error C3480
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3480 because the variable global is not from an enclosing function scope:
// C3480a.cpp
int global = 0;
int main()
{
[&global] { global = 5; }(); // C3480
}
Example
The following example resolves C3480 by removing the variable global from the capture list of the lambda
expression:
// C3480b.cpp
int global = 0;
int main()
{
[] { global = 5; }();
}
See Also
Lambda Expressions
Compiler Error C3481
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3481 because the variable n is not defined:
// C3481.cpp
int main()
{
[n] {}(); // C3481
}
See Also
Lambda Expressions
Compiler Error C3482
10/31/2018 • 2 minutes to read • Edit Online
'this' can only be used as a lambda capture within a non-static member function
You cannot pass this to the capture list of a lambda expression that is declared in a static method or a global
function.
To correct this error
Convert the enclosing function to a non-static method, or
Remove the this pointer from the capture list of the lambda expression.
Example
The following example generates C3482:
// C3482.cpp
// compile with: /c
class C
{
public:
static void staticMethod()
{
[this] {}(); // C3482
}
};
See Also
Lambda Expressions
Compiler Error C3483
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3483 because the variable n appears more than one time in the capture list of
the lambda expression:
// C3483.cpp
int main()
{
int m = 6, n = 5;
[m,n,n] { return n + m; }(); // C3483
}
See Also
Lambda Expressions
Compiler Error C3484
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3484:
// C3484a.cpp
int main()
{
return []() . int { return 42; }(); // C3484
}
Example
The following example resolves C3484 by providing -> before the return type of the lambda expression:
// C3484b.cpp
int main()
{
return []() -> int { return 42; }();
}
See Also
Lambda Expressions
Compiler Error C3485
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3485 because it uses the const qualifier as part of the definition of a lambda
expression:
// C3485.cpp
int main()
{
auto x = []() const mutable {}; // C3485
}
See Also
Lambda Expressions
Compiler Error C3487
10/31/2018 • 2 minutes to read • Edit Online
'return type': all return expressions must deduce to the same type: previously it was 'return type'
A lambda must specify its return type unless it contains a single return statement. If a lambda contains multiple
return statements, they must all have the same type.
To correct this error
Specify a trailing return type for the lambda. Verify that all returns from the lambda are the same type or can be
implicitly converted to the return type.
Example
The following example generates C3487 because the return types of the lambda do not match:
// C3487.cpp
// Compile by using: cl /c /W4 C3487.cpp
See Also
Lambda Expressions
Compiler Error C3488
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3488 because a reference to the variable n appears in the capture clause of a
lambda expression whose default mode is by-reference:
// C3488a.cpp
int main()
{
int n = 5;
[&, &n]() { return n; } (); // C3488
}
Example
The following example shows four possible resolutions to C3488:
// C3488b.cpp
int main()
{
int n = 5;
// Possible resolution 1:
// Do not explicitly pass &n to the capture clause.
[&]() { return n; } ();
// Possible resolution 2:
// Do not specify by-reference as the default capture mode.
[&n]() { return n; } ();
// Possible resolution 3:
// Specify by-value as the default capture mode.
[=, &n]() { return n; } ();
// Possible resolution 4:
// Pass n by value to the capture clause.
[n]() { return n; } ();
}
See Also
Lambda Expressions
Compiler Error C3489
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3489 variable n appears by value in the capture clause of a lambda expression
whose default mode is by-value:
// C3489a.cpp
int main()
{
int n = 5;
[=, n]() { return n; } (); // C3489
}
Example
The following example shows four possible resolutions to C3489:
// C3489b.cpp
int main()
{
int n = 5;
// Possible resolution 1:
// Do not explicitly pass n to the capture clause.
[=]() { return n; } ();
// Possible resolution 2:
// Do not specify by-value as the default capture mode.
[n]() { return n; } ();
// Possible resolution 3:
// Specify by-reference as the default capture mode.
[&, n]() { return n; } ();
// Possible resolution 4:
// Pass n by reference to the capture clause.
[&n]() { return n; } ();
}
See Also
Lambda Expressions
Compiler Error C3490
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3490 because it modifies the member variable _i in a const method:
// C3490a.cpp
// compile with: /c
class C
{
void f() const
{
auto x = [=]() { _i = 20; }; // C3490
}
int _i;
};
Example
The following example resolves C3490 by removing the const modifier from the method declaration:
// C3490b.cpp
// compile with: /c
class C
{
void f()
{
auto x = [=]() { _i = 20; };
}
int _i;
};
See Also
Lambda Expressions
Compiler Error C3491
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3491 because the body of a non-mutable lambda expression modifies the
capture variable m :
// C3491a.cpp
int main()
{
int m = 55;
[m](int n) { m = n; }(99); // C3491
}
Example
The following example resolves C3491 by declaring the lambda expression with the mutable keyword:
// C3491b.cpp
int main()
{
int m = 55;
[m](int n) mutable { m = n; }(99);
}
See Also
Lambda Expressions
Compiler Error C3492
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3492 because it captures a member of an anonymous union:
// C3492a.cpp
int main()
{
union
{
char ch;
int x;
};
ch = 'y';
[&x](char ch) { x = ch; }(ch); // C3492
}
Example
The following example resolves C3492 by giving the union a name and by passing the complete union structure to
the capture list of the lambda expression:
// C3492b.cpp
int main()
{
union
{
char ch;
int x;
} u;
u.ch = 'y';
[&u](char ch) { u.x = ch; }(u.ch);
}
See Also
Lambda Expressions
Compiler Error C3493
10/31/2018 • 2 minutes to read • Edit Online
'var' cannot be implicitly captured because no default capture mode has been specified
The empty lambda expression capture, [] , specifies that the lambda expression does not explicitly or implicitly
capture any variables.
To correct this error
Provide a default capture mode, or
Explicitly capture one or more variables.
Example
The following example generates C3493 because it modifies an external variable but specifies the empty capture
clause:
// C3493a.cpp
int main()
{
int m = 55;
[](int n) { m = n; }(99); // C3493
}
Example
The following example resolves C3493 by specifying by-reference as the default capture mode.
// C3493b.cpp
int main()
{
int m = 55;
[&](int n) { m = n; }(99);
}
See Also
Lambda Expressions
Compiler Error C3495
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3495 because the static variable n appears in the capture list of a lambda
expression:
// C3495.cpp
int main()
{
static int n = 66;
[&n]() { return n; }(); // C3495
}
See Also
Lambda Expressions
Compiler Error C3496
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3496 because a reference to the this pointer appears in the capture list of a
lambda expression:
// C3496.cpp
// compile with: /c
class C
{
void f()
{
[&this] {}(); // C3496
}
};
See Also
Lambda Expressions
Compiler Error C3498
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example generates C3498 because a variable that has a managed type appears in the capture list of
a lambda expression:
// C3498a.cpp
// compile with: /clr
using namespace System;
int main()
{
String ^ s = "Hello";
[&s](String ^ r)
{ return String::Concat(s, r); } (", World!"); // C3498
}
Example
The following example resolves C3498 by passing the managed variable s to the parameter list of the lambda
expression:
// C3498b.cpp
// compile with: /clr
using namespace System;
int main()
{
String ^ s = "Hello";
[](String ^ s, String ^ r)
{ return String::Concat(s, r); } (s, ", World!");
}
See Also
Lambda Expressions
Compiler Error C3499
10/31/2018 • 2 minutes to read • Edit Online
a lambda that has been specified to have a void return type cannot return a value
The compiler generates this error when a lambda expression that specifies void as the return type returns a value;
or when a lambda expression contains more than one statement and returns a value, but does not specify its return
type.
To correct this error
Do not return a value from the lambda expression, or
Provide the return type of the lambda expression, or
Combine the statements that make up the body of the lambda expression into a single statement.
Example
The following example generates C3499 because the body of a lambda expression contains multiple statements
and returns a value, but the lambda expression does not specify the return type:
// C3499a.cpp
int main()
{
[](int x) { int n = x * 2; return n; } (5); // C3499
}
Example
The following example shows two possible resolutions to C3499. The first resolution provides the return type of
the lambda expression. The second resolution combines the statements that make up the body of the lambda
expression into a single statement.
// C3499b.cpp
int main()
{
// Possible resolution 1:
// Provide the return type of the lambda expression.
[](int x) -> int { int n = x * 2; return n; } (5);
// Possible resolution 2:
// Combine the statements that make up the body of
// the lambda expression into a single statement.
[](int x) { return x * 2; } (5);
}
See Also
Lambda Expressions
Compiler Errors C3500 through C3999
10/31/2018 • 34 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the error messages that are generated by the
compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Error messages
ERROR MESSAGE
Compiler Error C3503 character '0xvalue' is not allowed in a raw string literal
Compiler Error C3507 a ProgID can have no more than 39 characters 'progid'; nor
contain any punctuation apart from '.'; nor start with a digit
Compiler Error C3509 'type': invalid Automation return type; when a parameter is
marked 'retval', the return type must be 'void', 'HRESULT' or
'SCODE'
Compiler Error C3511 'identifier': a call to a delegating constructor shall be the only
member-initializer
Compiler Error C3512 the delimiting character sequence for a raw string literal shall
have no more than 16 characters
Compiler Error C3513 'string': unsupported raw string literal delimiter character
Compiler Error C3514 'character' (value): unsupported raw string literal delimiter
character
Compiler Error C3516 unexpected end-of-file found while processing the raw string
literal; delimiter sequence 'string' was not matched
Compiler Error C3520 'identifier': parameter pack must be expanded in this context
Compiler Error C3522 'type': parameter pack cannot be expanded in this context
Compiler Error C3524 'identifier': 'sizeof' cannot be applied to a parameter pack. Did
you mean to use 'sizeof...'?
Compiler Error C3525 'parameter': if a class template has a template parameter pack
it must appear at the end of the template parameter list
Compiler Error C3527 'identifier' is not a valid operand for 'sizeof...'. Did you mean to
use 'sizeof'?
Compiler Error C3528 'identifier1': the number of elements in this pack expansion
does not match the number of elements in 'identifier2'
Compiler Error C3529 'parameter': a template parameter pack cannot have a default
argument
Compiler Error C3530 'type' cannot be combined with any other type-specifier
Compiler Error C3531 'identifier': a symbol whose type contains 'type' must have an
initializer
Compiler Error C3532 the element type of an array cannot be a type that contains
'type'
Compiler Error C3533 a parameter cannot have a type that contains 'type'
Compiler Error C3535 cannot deduce type for 'type1' from 'type2'
Compiler Error C3537 you cannot cast to a type that contains 'type'
Compiler Error C3538 in a declarator-list 'type' must always deduce to the same type
Compiler Error C3540 sizeof cannot be applied to a type that contains 'type'
Compiler Error C3541 typeid cannot be applied to a type that contains 'type'
Compiler Error C3542 'identifier': a virtual member function shall not have a return
type that contains 'type'
Compiler Error C3546 '...': there are no parameter packs available to expand
Compiler Error C3548 'identifier': parameter pack cannot be used in this context
Compiler Error C3549 'value': a function parameter pack cannot have a default
argument
Compiler Error C3551 if a trailing return type is used then the leading return type
shall be the single type-specifier 'auto' (not 'type')
Compiler Error C3554 'type' cannot be combined with any other type-specifier
Compiler Error C3560 'function': IL is not available when compiling the call graph for
the concurrency::parallel_for_each at: 'function'
Compiler Error C3561 tile barrier operation found in control flow that is not tile-
uniform when compiling the call graph for the
concurrency::parallel_for_each at: 'function'
Compiler Error C3562 intrinsic function 'function' is limited to have no more than
number parameters
Compiler Error C3563 Infinite loop detected when compiling the call graph for the
concurrency::parallel_for_each at: 'function'
Compiler Error C3564 reading uninitialized value when compiling the call graph for
the concurrency::parallel_for_each at: 'function'
Compiler Error C3565 The total amount of tile_static memory ( number bytes)
exceeds the limit of number bytes when compiling the call
graph for the concurrency::parallel_for_each
Compiler Error C3566 blocks with side effects nested too deeply when compiling the
call graph for the concurrency::parallel_for_each at: 'function'
Compiler Error C3567 divide or mod by zero detected when compiling the call graph
for the concurrency::parallel_for_each at: 'function'
ERROR MESSAGE
Compiler Error C3568 sum of registers exceeds the limit of number when compiling
the call graph for the concurrency::parallel_for_each. Please
simplify your program
Compiler Error C3569 race condition detected when compiling the call graph for the
concurrency::parallel_for_each at: 'function'
Compiler Error C3570 illegal use of amp restricted scope when compiling with /clr
Compiler Error C3571 'type': illegal compute domain argument; not a class type
Compiler Error C3572 'type': illegal compute domain argument; missing public
member: 'static const int rank' or rank value is non-positive
Compiler Error C3574 'type': illegal tile extents: must be positive and (1) Z <=
number; (2) ZYX <= number
Compiler Error C3575 'type': illegal compute domain argument; missing public
member: 'concurrency::index<number> _map_index(const
concurrency::index<number>&) restrict(amp)'
Compiler Error C3583 'identifier': the size of the variable (number bytes) is larger
than the maximum size (number bytes) supported in amp
restricted code
Compiler Error C3585 'identifier' has unsupported storage class in amp restricted
code
Compiler Error C3589 'string': unsupported usage of string literals in amp restricted
code
Compiler Error C3594 exception handling (try, catch, throw etc.) is unsupported in
amp restricted code
Compiler Error C3595 constant value is out of supported range in amp restricted
code
Compiler Error C3600 'function': use of tile_static memory detected when compiling
the call graph for the non-tiling concurrency::parallel_for_each
at: 'function'
Compiler Error C3601 'type': is invalid argument type for amp diagnostic function
'function'
Compiler Error C3602 Unsupported control flow detected when compiling the call
graph for the concurrency::parallel_for_each at: 'function'
Compiler Error C3604 'identifier': can only create a managed object on the gc heap
Compiler Error C3605 The total number of samplers (number captured and number
predefined) exceed number when compiling the call graph for
the concurrency::parallel_for_each at: 'function'
Compiler Error C3610 'identifier': value type must be 'boxed' before method
'method' can be called
Compiler Error C3612 'identifier': a sealed class cannot have any pure virtual
methods
Compiler Error C3613 missing return type after '->' ('int' assumed)
Compiler Error C3614 Differing values for pack size within the same class; previous
was 'value', new value is 'value'
Compiler Error C3620 'type': setting the alignment is not allowed on WinRT types
Compiler Error C3621 'type': only the default packing value (number) is allowed for
WinRT types
Compiler Error C3623 'identifier': bit fields are not supported in managed/WinRT
types
Compiler Error C3625 'class': a native type cannot derive from a managed/WinRT
type 'type'
Compiler Error C3626 'identifier': 'keyword' keyword can only be used on COM
interfaces, member functions and data members that are
pointers to delegates
Compiler Error C3628 'class': managed/WinRT classes only support public inheritance
Compiler Error C3629 'token': a capture default can only appear at the beginning of
a lambda capture list
Compiler Error C3638 'operator': the standard boxing and unboxing conversion
operators cannot be redefined
Compiler Error C3641 'function': invalid calling convention 'convention' for function
compiled with /clr:pure or /clr:safe
Compiler Error C3642 'function': cannot call a function with __clrcall calling
convention from native code
Compiler Error C3644 'function': cannot compile the function to generate managed
code
ERROR MESSAGE
Compiler Error C3648 this explicit override syntax is not supported for managed
types
Compiler Error C3649 this explicit override syntax is not allowed with /ZW
Compiler Error C3652 'member': a function that explicitly overrides must be virtual
Compiler Error C3661 explicit override list did not find any methods to override
Compiler Error C3664 'member': cannot be used as an explicit override, must have
'public' or 'protected' accessibility
Compiler Error C3667 'attribute': attribute does not support pack expansion
Compiler Error C3668 'member': method with override specifier 'override' did not
override any base class methods
Compiler Error C3669 'member': override specifier 'override' not allowed on static
member functions or constructors
Compiler Error C3670 'member': cannot override inaccessible base class method
'member'
Compiler Error C3674 could not find standard library module 'module'
Compiler Error C3676 'class': ref class and base class have incompatible attributes
'[attribute]'
Compiler Error C3677 string literal after 'operator' cannot have an encoding prefix
Compiler Error C3678 string literal after 'operator' must be the empty string '""""'
Compiler Error C3679 expected a literal suffix identifier after 'operator """"'
Compiler Error C3681 'fallthrough': attribute may only appear in an enclosing switch
statement
Compiler Error C3683 cannot define both raw literal operator and literal operator
template with the same literal suffix identifier
Compiler Error C3685 'operator identifier': literal operator template cannot have
function parameters
ERROR MESSAGE
Compiler Error C3686 'operator identifier': literal operator template must have
exactly one template parameter that is a parameter pack
Compiler Error C3687 'operator identifier': literal operator template must have non-
type template parameter of type 'char'
Compiler Error C3688 invalid literal suffix 'suffix'; literal operator or literal operator
template 'operator identifier' not found
Compiler Error C3690 expected a string literal, but found a user-defined string literal
instead
Compiler Error C3698 'type': cannot use this type as argument of 'operator'
Compiler Error C3699 'operator': cannot use this indirection on type 'type'
Compiler Error C3703 'event_handler': an event handler method must have the
same storage class as the source 'event'
Compiler Error C3706 'function': must be a COM interface to fire COM events
Compiler Error C3710 'function': improper syntax for specifying event handler in
__hook/__unhook
Compiler Error C3711 'event': a non-managed event source method must return
void or an integral type
Compiler Error C3712 'event_handler': an event handler method must return the
same type as the source 'event'
Compiler Error C3713 'event_handler': an event handler method must have the
same function parameters as the source 'event'
Compiler Error C3714 'event_handler': an event handler method must have the
same calling convention as the source 'event'
Compiler Error C3717 'member': a method that fires events cannot be defined
Compiler Error C3718 can only call '__keyword' in the context of a member function
of the receiving class
Compiler Error C3719 'member': an interface based event source can only be used
for COM events
Compiler Error C3720 'type': can only implement IDispatch on a dual or dispinterface
Compiler Error C3728 'event': event does not have a raise method
ERROR MESSAGE
Compiler Error C3731 incompatible event 'event' and handler 'event_handler'; event
source and event handler must have the same event type
Compiler Error C3732 'interface': a custom interface that fires COM events cannot
inherit from IDispatch
Compiler Error C3733 'event': improper syntax for specifying a COM event; did you
forget '__interface'?
Compiler Error C3736 'member': must be a method or, in the case of managed
events, optionally a data member
Compiler Error C3737 'identifier': a delegate may not have an explicit calling
convention
Compiler Error C3738 'convention': the calling convention of the explicit instantiation
must match that of the template being instantiated
Compiler Error C3739 'class': syntax is only supported when the 'layout_dependent'
parameter of event_receiver is true
Compiler Error C3743 can only hook/unhook an entire interface when the
'layout_dependent' parameter of event_receiver is true
Compiler Error C3744 __unhook must have at least 3 arguments for managed events
Compiler Error C3746 standard attribute 'identifier' may appear at most once in an
attribute list
Compiler Error C3748 'interface': unmanaged interfaces may not fire events
ERROR MESSAGE
Compiler Error C3749 'attribute': a custom attribute may not be used inside a
function
Compiler Error C3752 'attribute': cannot classify attribute; 'keyword' should not be
used in this context
Compiler Error C3757 'type': type not allowed for 'constexpr' function
Compiler Error C3761 'function': 'retval' can only appear on the last argument of a
function
Compiler Error C3763 'type': 'retval' and 'out' can only appear on a data-pointer type
Compiler Error C3764 'member': cannot override base class method 'member'
Compiler Error C3765 'event': cannot define an event in a class/struct 'type' marked
as an event_receiver
Compiler Error C3766 'type' must provide an implementation for the interface
method 'function'
Compiler Error C3768 cannot take the address of a virtual vararg function in pure
managed code
Compiler Error C3769 'identifier': a nested class cannot have the same name as the
immediately enclosing class
ERROR MESSAGE
Compiler Error C3771 'identifier': friend declaration cannot be found in the nearest
namespace scope
Compiler Error C3773 please use /await compiler switch to enable coroutines
Compiler Error C3774 cannot find 'scope::identifier': Please include header header
Compiler Error C3776 cannot return an expresssion of type void in a coroutine with
non-void eventual return type
Compiler Error C3777 'function': a coroutine cannot take a variable argument list
Compiler Error C3779 'function': a function that returns 'type' cannot be used before
it is defined
Compiler Error C3780 'function': a conversion function that returns 'type' cannot be
used before it is defined
Compiler Error C3782 type: a coroutine's promise cannot contain both keyword and
keyword
Compiler Error C3787 cannot deduce the return type of this coroutine
Compiler Error C3797 'keyword': event declaration cannot have override specifier
(should be placed on event add/remove/raise methods
instead)
Compiler Error C3798 'keyword': property declaration cannot have override specifier
(should be placed on property get/set methods instead)
Compiler Error C3799 indexed property cannot have an empty parameter list
Compiler Error C3801 'attribute': attribute may not have an argument clause
Compiler Error C3803 'property': property has a type which is incompatible with one
of its accessors 'accessor'
Compiler Error C3804 'member': the accessor methods for a property must either be
all static or all non-static
Compiler Error C3805 'token': unexpected token, expected either '}' or a ','
Compiler Error C3806 'token': unexpected token, expected either a '{' or a member-
initializer
Compiler Error C3807 'type': a class with the ComImport attribute cannot derive
from 'type', only interface implementation is allowed
Compiler Error C3808 'type': a class with the ComImport attribute cannot define
member 'member', only abstract or dllimport functions are
allowed
Compiler Error C3809 'type': a managed/WinRT type cannot have any friend
functions/classes/interfaces
Compiler Error C3812 '__property' must be the first token in a property declaration
Compiler Error C3813 a property declaration can only appear within the definition of
a managed/WinRT type
Compiler Error C3815 return type of method 'member' must match type of the last
parameter of a setter
Compiler Error C3816 'class/struct member' was previously declared or defined with
a different managed/WinRT modifier
Compiler Error C3818 array property declaration 'property' shall not overload an
index property 'property'
Compiler Error C3824 'type': this type cannot appear in this context (function
parameter, return type, or a static member)
Compiler Error C3827 standard attribute 'deprecated' may have either no arguments
or one string literal describing the reason
Compiler Error C3829 standard attribute 'noreturn' may only be applied to functions
Compiler Error C3830 'type1': cannot inherit from 'type2', value types can only
inherit from interface classes
Compiler Error C3831 'identifier': 'type' cannot have a pinned data member or a
member function returning a pinning pointer
ERROR MESSAGE
Compiler Error C3832 'typelib': type library looks as if it was built for 32-bit pointers;
please change the 'ptrsize' qualifier
Compiler Error C3834 illegal explicit cast to a pinning pointer; use a pinned local
variable instead
Compiler Error C3836 a static constructor is not allowed to have a member initializer
list
Compiler Error C3842 'identifier': 'const' and 'volatile' qualifiers on member functions
of managed/WinRT types are not supported
Compiler Error C3844 'identifier': cannot import symbol from 'source': as 'identifier'
already exists in the current scope
Compiler Error C3846 'identifier': cannot import symbol from 'source': as 'identifier'
has already been imported from another assembly 'assembly'
Compiler Error C3848 expression having type 'type' would lose some const-volatile
qualifiers in order to call 'identifier'
Compiler Error C3849 function-style call on an expression of type 'type' would lose
const and/or volatile qualifiers for all number available
operator overloads
Compiler Error C3852 'member' having type 'type': aggregate initialization could not
initialize this member
Compiler Error C3854 expression to left of '=' evaluates to a function. Cannot assign
to a function (a function is not an l-value)
Compiler Error C3857 'template': multiple template/generic parameter lists are not
allowed
Compiler Error C3859 virtual memory range for PCH exceeded; please recompile
with a command line option of '-Zmnumber' or greater
Compiler Error C3865 'keyword': can only be used on native member functions
Compiler Error C3867 'function': non-standard syntax; use '&' to create a pointer to
member
Compiler Error C3869 gcnew constraint is missing empty parameter list '()'
Compiler Error C3873 '0xvalue': this character is not allowed as a first character of an
identifier
Compiler Error C3874 return type of 'identifier' should be 'type1' instead of 'type2'
Compiler Error C3875 call of non-static member function missing argument list
Compiler Error C3881 can only inherit constructor from direct base
Compiler Error C3882 'class': constructor has already been inherited from 'class'
Compiler Error C3883 'member': an initonly static data member must be initialized
Compiler Error C3885 'type': An array of unknown size cannot be initialized with an
empty initializer list
Compiler Error C3887 'member': the initializer for a literal data member must be a
constant expression
Compiler Error C3888 'member': the const expression associated with this literal data
member is not supported by C++/CLI
Compiler Error C3890 'member': you cannot take the address of a literal data
member
Compiler Error C3891 'member': a literal data member cannot be used as a l-value
Compiler Error C3892 'variable': you cannot assign to a variable that is const
Compiler Error C3893 'member': l-value use of initonly data member is only allowed
in an instance constructor of class 'class'
ERROR MESSAGE
Compiler Error C3894 'member': l-value use of initonly static data member is only
allowed in the class constructor of class 'class'
Compiler Error C3896 'member': improper initializer: this literal data member can
only be initialized with 'nullptr'
Compiler Error C3898 'member': type data members can only be members of
managed types
Compiler Error C3899 'member': l-value use of initonly data member is not allowed
directly within a parallel region in class 'class'
Compiler Error C3903 'property': does not have set or get method
Compiler Error C3905 unaligned accesses are not supported for intrinsic type 'type'
Compiler Error C3906 intrinsic type 'type' is not a supported return or argument
type for vararg or unprototyped functions
Compiler Error C3908 access level less restrictive than that of 'identifier'
Compiler Error C3915 'identifier' has no default indexed property (class indexer)
Compiler Error C3917 'token': obsolete construct declaration style (did you mean to
use '[' ']' instead?)
Compiler Error C3919 'function': function must have type 'return_type (type)'
Compiler Error C3923 'member': local class, struct or union definitions are not
allowed in a member function of a managed/WinRT class
Compiler Error C3925 expected a loop (for, while, or do) following 'directive' directive
Compiler Error C3927 '->': trailing return type is not allowed after a non-function
declarator
Compiler Error C3928 '->': trailing return type is not allowed after a parenthesized
declarator
Compiler Error C3931 'type': cannot call a function that has restriction specifiers that
are incompatible with the ambient context
Compiler Error C3933 'class': destructor's restriction specifiers must cover the union
of restrictions on all constructors
Compiler Error C3934 a function that is in any form of 'main' cannot have restriction
specifiers other than restrict(cpu)
Compiler Error C3938 'identifier': multiple restriction specifiers are not supported on
extern \042C\042 functions
Compiler Error C3940 'identifier': identifier not found - possible mismatch between
compiler and library versions. Please ensure vccorlib.h/.lib,
vccorlib120.dll and c1xx.dll match
Compiler Error C3945 'type': unable to throw or catch a winrt object which doesn't
derive from Platform::Exception
Compiler Error C3948 'keyword': a pack expansion cannot appear in this context
Compiler Error C3952 'type': WinRT does not support 'in/out' arrays. Use 'const
Array^' for 'in' and 'WriteOnlyArray' or 'Array^*' for 'out' on
public APIs
Compiler Error C3953 Cannot use managed class 'type' in WinRT module.
Compiler Error C3954 'type': An array returned from a published method on a WinRT
type must use the form 'Array^'
Compiler Error C3955 'type': A public constructor cannot contain an 'out' parameter
or 'WriteOnlyArray'
Compiler Error C3956 'type': Type is marked as Exclusive To 'type' and cannot be
used as a base of 'derived_type'
ERROR MESSAGE
Compiler Error C3957 'type': cannot use 'new' on a WinRT type; use 'ref new' instead
Compiler Error C3958 'type': cannot use 'gcnew' on a WinRT type; use 'ref new'
instead
Compiler Error C3959 'ref new' may only be used to create an object with WinRT
type
Compiler Error C3968 the token 'token' is not valid as module name separator; use
period ('.') instead
Compiler Error C3970 'identifier': 'keyword' can only be applied to 'ref class' or 'ref
struct' at global scope or namespace scope
Compiler Error C3971 'type': partial definition cannot appear after full definition
Compiler Error C3972 'type': 'partial' can only be applied to class declarations or
definitions
Compiler Error C3975 'class/struct identifier' was previously declared or defined with
a different modifier
Compiler Error C3981 'type': a value type cannot have any static data members
'identifier'
Compiler Error C3982 'type': a value type cannot have any non-public data members
'identifier'
Compiler Error C3983 'type': a value type cannot have any public non-data members
'identifier'
Compiler Error C3984 'type': a non-value type cannot have any public data members
'identifier'
Compiler Error C3985 'identifier': signature of public member contains private type
'member'
Compiler Error C3986 'identifier': signature of public member contains native type
'member'
Compiler Error C3987 'identifier': signature of public member contains native type
'type'
Compiler Error C3992 'identifier': signature of public member contains invalid type
'type'
Compiler Error C3993 'type': a value type must contain at least one public field
Compiler Error C3994 'type': a value type cannot implement interfaces or have
virtual functions
Compiler Error C3995 'type': a value type cannot have any event members
'identifier'
Compiler Error C3999 UNKNOWN ERROR Please choose the Technical Support
command on the Visual C++ Help menu, or open the
Technical Support help file for more information
Compiler Error C3500
10/31/2018 • 2 minutes to read • Edit Online
C3505 can be caused if you are running the 32-bit, x86-hosted cross-compiler for 64-bit, x64 targets on a 64-bit
machine, because the compiler is running under WOW64 and can only read from the 32-bit registry hive.
You can resolve this error by building both 32-bit and 64-bit versions of the type library you are trying to import,
and then register them both. Or you can use the native 64-bit compiler, which requires you to change your VC++
Directories property in the IDE to point to the 64-bit compiler.
For more information, see,
How to: Enable a 64-Bit Visual C++ Toolset on the Command Line
How to: Configure Visual C++ Projects to Target 64-Bit, x64 Platforms
Compiler Error C3506
10/31/2018 • 2 minutes to read • Edit Online
a ProgID can have no more than 39 characters 'id'; nor contain any punctuation apart from '.'; nor start with a digit
The progid attribute has restrictions on the values that it can take.
The following sample generates C3507:
// C3507.cpp
[module(name="x")];
[
coclass,
progid("0123456789012345678901234567890123456789"),
uuid("00000000-0000-0000-0000-000000000001") // C3507 expected
]
struct CMyStruct {
};
int main() {
}
Compiler Error C3508
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3508:
// C3508.cpp
#define _ATL_DEBUG_QI
#define WIN32_LEAN_AND_MEAN
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <atlctl.h>
#include <atlstr.h>
[module(name=oso)];
union U
// try the following two lines instead
// [export]
// struct U
{
int i, j;
};
[dispinterface]
__interface I
{
[id(1)] HRESULT func(U* u);
};
[coclass]
struct C : I
{
HRESULT func(U*) // C3508
{
return E_FAIL;
}
};
int main()
{
}
Compiler Error C3509
10/31/2018 • 2 minutes to read • Edit Online
'type': invalid Automation return type; when a parameter is marked 'retval', the return type must be 'void',
'HRESULT' or 'SCODE'
A method in a COM interface must return either void or an HRESULT.
The following sample generates C3509:
// C3509.cpp
#define _ATL_DEBUG_QI
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <atlctl.h>
#include <atlstr.h>
[module(name=oso)];
[dispinterface, uuid(00000000-0000-0000-0000-000000000001)]
__interface I {
[id(1)] int f([out, retval] int*); // C3509
// try the following line instead
// [id(1)] void f([out, retval] int*);
};
[coclass, uuid(00000000-0000-0000-0000-000000000002)]
struct C : I {
int f(int*) {
// try the following line instead, and delete return statement
// void f(int*) {
return 0;
}
};
int main() {
}
Compiler Error C3510
10/31/2018 • 2 minutes to read • Edit Online
// C3510a.idl
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12b")]
library C3510aLib
{
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12c")]
enum E_C3510
{
one, two, three
};
};
And then the source code for the second type library:
// C3510b.idl
// post-build command: del /f C3510a.tlb
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12e")]
library C3510bLib
{
importlib ("C3510a.tlb");
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12d")]
struct S_C3510 {
enum E_C3510 e;
};
};
// C3510.cpp
#import "c3510b.tlb" no_registry auto_search // C3510
int main() {
C3510aLib::S_C4336 ccc;
}
Compiler Error C3519
10/31/2018 • 2 minutes to read • Edit Online
// C3519.cpp
// compile with: /LD
[module(name="MyLib2")];
#import "C:\testdir\bin\importlib.tlb" embedded_idl("no_emitidcl")
// C3519
#import "C:\testdir\bin\importlib.tlb" embedded_idl("no_emitidl")
// OK
Compiler Error C3530
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3530 because variable x is declared with both the auto keyword and type int ,
and because the example is compiled with /Zc:auto.
// C3530.cpp
// Compile with /Zc:auto
int main()
{
auto int x; // C3530
return 0;
}
See Also
auto Keyword
Compiler Error C3531
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3531 because variables x1 , y1, y2, y3 , and z2 are not initialized.
// C3531.cpp
// Compile with /Zc:auto
int main()
{
auto x1; // C3531
auto y1, y2, y3; // C3531
auto z1 = 1, z2, z3 = -1; // C3531
return 0;
}
See Also
auto Keyword
Compiler Error C3532
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3532 because the auto keyword cannot declare a method return type.
// C3532a.cpp
// Compile with /Zc:auto
auto f(){} // C3532
Example
The following example yields C3532 because the auto keyword cannot declare an array.
// C3532b.cpp
// Compile with /Zc:auto
int main()
{
int x[5];
auto a[5]; // C3532
auto b[1][2]; // C3532
auto y[5] = x; // C3532
auto z[] = {1, 2, 3}; // C3532
auto w[] = x; // C3532
return 0;
}
See Also
auto Keyword
Compiler Error C3533
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3533 because it declares a function parameter with the auto keyword and it is
compiled with /Zc:auto.
// C3533a.cpp
// Compile with /Zc:auto
void f(auto j) {} // C3533
Example
The following example yields C3533 in C++14 mode because it declares a template parameter with the auto
keyword and it is compiled with /Zc:auto. (In C++17, this is a valid definition of a class template with a single
non-type template parameter whose type is deduced.)
// C3533b.cpp
// Compile with /Zc:auto
template<auto T> class C {}; // C3533
See Also
auto Keyword
/Zc:auto (Deduce Variable Type)
Compiler Error C3535
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3535 because the initialization expression evaluates to void .
// C3535a.cpp
// Compile with /Zc:auto
void f(){}
int main()
{
auto x = f(); //C3535
return 0;
}
Example
The following example yields C3535 because the statement declares variable x as a pointer to a deduced type,
but the type of the initializer expression is double. Consequently, the compiler cannot deduce the type of the
variable.
// C3535b.cpp
// Compile with /Zc:auto
int main()
{
auto* x = 123.0; // C3535
return 0;
}
Example
The following example yields C3535 because variable p declares a pointer to a deduced type, but the initialization
expression is not a pointer type.
// C3535c.cpp
// Compile with /Zc:auto
class A { };
A x;
auto *p = x; // C3535
See Also
auto Keyword
Fundamental Types
Compiler Error C3536
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3536 because each variable is initialized with itself.
// C3536.cpp
// Compile with /Zc:auto
int main()
{
auto a = a; //C3536
auto b = &b; //C3536
auto c = c + 1; //C3536
auto* d = &d; //C3536
auto& e = e; //C3536
return 0;
};
See Also
auto Keyword
Compiler Error C3537
10/31/2018 • 2 minutes to read • Edit Online
Example
The following code yields C3537 because the variables are cast to a type that contains the auto keyword.
// C3537.cpp
// Compile with /Zc:auto
int main()
{
int value = 123;
auto(value); // C3537
(auto)value; // C3537
auto x1 = auto(value); // C3537
auto x2 = (auto)value; // C3537
auto x3 = static_cast<auto>(value); // C3537
return 0;
}
See Also
auto Keyword
Compiler Error C3538
10/31/2018 • 2 minutes to read • Edit Online
Example
The following statements yield C3538. Each statement declares multiple variables, but each use of the auto
keyword does not deduce to the same type.
// C3538.cpp
// Compile with /Zc:auto
// C3538 expected
int main()
{
// Variable x1 is a pointer to char, but y1 is a double.
auto * x1 = "a", y1 = 3.14;
// Variable c is a char and c1 is char*, but c2, and c3 are pointers to pointers.
auto c = 'a', *c1 = &c, * c2 = &c1, * c3 = &c2;
// Variable x2 is an int, but y2 is a double and z is a char.
auto x2(1), y2(0.0), z = 'a';
// Variable a is a pointer to int, but b is a pointer to double.
auto *a = new auto(1), *b = new auto(2.0);
return 0;
}
See Also
auto Keyword
Compiler Error C3539
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3539.
// C3539.cpp
// Compile with /Zc:auto
template<class T> class C{};
int main()
{
C<auto> c; // C3539
return 0;
}
See Also
auto Keyword
Compiler Error C3540
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3540.
// C3540.cpp
// Compile with /Zc:auto
int main() {
auto x = 123;
sizeof(x); // OK
sizeof(auto); // C3540
return 0;
}
See Also
auto Keyword
/Zc:auto (Deduce Variable Type)
sizeof Operator
Compiler Error C3541
10/31/2018 • 2 minutes to read • Edit Online
Example
The following example yields C3541.
// C3541.cpp
// Compile with /Zc:auto
#include <typeinfo>
int main() {
auto x = 123;
typeid(x); // OK
typeid(auto); // C3541
return 0;
}
See Also
auto Keyword
/Zc:auto (Deduce Variable Type)
typeid
Compiler Error C3550
10/31/2018 • 2 minutes to read • Edit Online
See Also
auto
Compiler Error C3551
10/31/2018 • 2 minutes to read • Edit Online
auto myFunction()->int(*)[4];
See Also
auto
Compiler Error C3552
10/31/2018 • 2 minutes to read • Edit Online
The decltype() keyword requires an expression as an argument, not the name of a type. For example, the last
statement in the following code fragment yields error C3553.
int x = 0;
decltype(x+1);
decltype(int); // C3553
Compiler Error C3554
10/31/2018 • 2 minutes to read • Edit Online
int x;
unsigned decltype(x); // C3554
Compiler Error C3555
10/31/2018 • 2 minutes to read • Edit Online
The argument to the decltype( expression ) type specifier is not a valid expression.
NOTE
C3555 is not likely to occur. If the compiler emits C3555, it is probably because an internal compiler error has occurred.
See Also
Compiler Error C3556
Fatal Error C1001
Compiler Error C3556
10/31/2018 • 2 minutes to read • Edit Online
The compiler cannot deduce the type of the expression that is the argument to the decltype( expression ) type
specifier.
Example
In the following code example, the compiler cannot deduce the type of the myFunction argument because
myFunction is overloaded. To fix this issue, you could use static_cast to create an instance of a pointer to the
particular overloaded function to specify in the decltype expression.
// C3556.cpp
// compile with: cl /W4 /EHsc C3556.cpp
#include <iostream>
void myFunction(int);
void myFunction(float, float);
void myFunction(int i) {
std::cout << "called myFunction(" << i << ")" << std::endl;
}
int main() {
callsMyFunction(myFunction, 42);
callsMyFunction(myFunction, 0.1f, 2.3f);
}
Compiler Error C3603
10/31/2018 • 2 minutes to read • Edit Online
// C3609.cpp
// compile with: /clr /c
ref class C {
int f() sealed; // C3609
virtual int f2() sealed; // OK
};
Compiler Error C3610
10/31/2018 • 2 minutes to read • Edit Online
'valuetype': value type must be 'boxed' before method 'method' can be called
By default, a value type is not on the managed heap. Before you can call methods from .NET runtime classes, such
as Object , you need to move the value type to the managed heap.
C3610 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3611
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3611.
// C3611.cpp
// compile with: /clr /c
ref struct V {
virtual void Test() sealed = 0; // C3611
virtual void Test2() sealed; // OK
virtual void Test3() = 0; // OK
};
Compiler Error C3612
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3612:
// C3612.cpp
// compile with: /clr /c
value struct V: public System::ICloneable {}; // C3612
// OK
value struct V2: public System::ICloneable {
Object^ Clone();
};
Compiler Error C3615
10/31/2018 • 2 minutes to read • Edit Online
The function function could not be evaluated as constexpr at compile time. To be constexpr , a function can only
call other constexpr functions.
Example
Visual Studio 2017 correctly raises an error when the left-hand operand of a conditionally evaluating operation is
not valid in a constexpr context. The following code compiles in Visual Studio 2015 but not in Visual Studio 2017.
// C3615.cpp
// Compile with: /c
template<int N>
struct myarray
{
int size() const { return N; }
};
To fix this issue, either declare the array::size() function as constexpr or remove the constexpr qualifier from
f .
Compiler Error C3618
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3618.
// C3618.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Runtime::InteropServices;
Example
The following sample generates C3622.
// C3622.cpp
// compile with: /clr
ref class a abstract {};
int main() {
a aa; // C3622
}
Compiler Error C3623
10/31/2018 • 2 minutes to read • Edit Online
// C3623.cpp
// compile with: /clr
using namespace System;
ref class CMyClass {
public:
int i : 1; // C3623
};
int main() {
CMyClass^ pMyClass = gcnew CMyClass();
pMyClass->i = 3;
Console::Out->WriteLine(pMyClass->i);
}
Compiler Error C3624
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3624:
// C3624.cpp
// compile with: /clr /c
#using <System.Windows.Forms.dll>
'native_type': a native type cannot derive from a managed or WinRT type 'type'
A native class cannot inherit from a managed or WinRT class. For more information, see Classes and Structs.
Example
The following sample generates C3625:
// C3625.cpp
// compile with: /clr /c
ref class B {};
class D : public B {}; // C3625 cannot inherit from a managed class
Compiler Error C3626
10/31/2018 • 2 minutes to read • Edit Online
'keyword': '__event' keyword can only be used on COM interfaces, member functions and data members that are
pointers to delegates
A keyword was used incorrectly.
The following sample generates C3626:
// C3626.cpp
// compile with: /c
struct A {
__event int i; // C3626
// try the following line instead
// __event int i();
};
Compiler Error C3627
10/31/2018 • 2 minutes to read • Edit Online
// C3628a.cpp
// compile with: /clr
ref class B {
};
int main() {
}
Compiler Error C3630
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3633.
// C3633.cpp
// compile with: /clr /c
#pragma warning( disable : 4368 )
class A1 {
public:
A1() { II = 0; }
int II;
};
ref class B {
public:
A1 a1; // C3633
A1 * a2; // OK
B() : a2( new A1 ) {}
~B() { delete a2; }
};
Compiler Error C3634
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3634:
// C3634.cpp
// compile with: /clr
ref class C {
virtual void f() = 0;
};
void C::f() { // C3634 - don't define managed class' pure virtual method
}
Compiler Error C3637
10/31/2018 • 2 minutes to read • Edit Online
// C3637.cpp
template <class T>
void f();
struct S {
friend void f<int>() {} // C3637
};
Possible resolution:
// C3637b.cpp
// compile with: /c
template <class T>
void f();
struct S {
friend void f() {}
};
// C3637c.cpp
// compile with: /clr
struct S {
friend void gf<int>() {} // C3637
};
Possible resolution:
// C3637d.cpp
// compile with: /clr /c
generic <class T>
void gf();
struct S {
friend void gf() {}
};
Compiler Error C3638
10/31/2018 • 2 minutes to read • Edit Online
'operator' : the standard boxing and unboxing conversion operators cannot be redefined
The compiler defines a conversion operator for each managed class to support implicit boxing. This operator
cannot be redefined.
For more information, see Implicit Boxing.
The following sample generates C3638:
// C3638.cpp
// compile with: /clr
value struct V {
V(){}
static operator V^(V); // C3638
};
int main() {
V myV;
V ^ pmyV = myV; // operator supports implicit boxing
}
Compiler Error C3640
10/31/2018 • 2 minutes to read • Edit Online
// C3640.cpp
void f()
{
struct S
{
virtual void f1(); // C3640
// Try the following line instead:
// virtual void f1(){}
};
}
Compiler Error C3641
10/31/2018 • 2 minutes to read • Edit Online
'function' : invalid calling convention 'calling_convention' for function compiled with /clr:pure or /clr:safe
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
Only __clrcall calling convention is allowed with /clr:pure.
Example
The following sample generates C3641:
// C3641.cpp
// compile with: /clr:pure /c
void __cdecl f() {} // C3641
Compiler Error C3642
10/31/2018 • 2 minutes to read • Edit Online
'return_type/args' : cannot call a function with __clrcall calling convention from native code
A function that is marked with the __clrcall calling convention cannot be called from native (unmanaged) code.
return_type/args is either the name of the function or the type of the __clrcall function you are trying to call. A
type is used when you're calling through a function-pointer.
To call a managed function from a native context, you can add a "wrapper" function that will call the __clrcall
function. Or, you can use the CLR marshalling mechanism; see How to: Marshal Function Pointers Using PInvoke
for more information.
The following sample generates C3642:
// C3642.cpp
// compile with: /clr
using namespace System;
struct S {
void Test(String ^ s) { // CLR type in signature, implicitly __clrcall
Console::WriteLine(s);
}
void Test2(char * s) {
Test(gcnew String(s));
}
};
#pragma unmanaged
int main() {
S s;
s.Test("abc"); // C3642
s.Test2("abc"); // OK
}
Compiler Error C3644
10/31/2018 • 2 minutes to read • Edit Online
// C3644.cpp
// compile with: /clr
// processor: x86
Example
The following sample generates C3645.
// C3645.cpp
// compile with: /clr /c
#pragma unmanaged
int __clrcall dog() {} // C3645
Compiler Error C3646
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The compiler found a token in the position where it expected to find an override specifier, but the token was not
recognized by the compiler.
For example, if the unrecognized specifier is _NOEXCEPT, replace it with the keyword noexcept.
For more information, see Override Specifiers.
Example
The following sample generates C3646 and shows a way to fix it:
// C3646.cpp
// compile with: /clr /c
ref class C {
void f() unknown; // C3646
// try the following line instead
// virtual void f() abstract;
};
Compiler Error C3648
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3648:
// C3648.cpp
// compile with: /clr
public interface struct I {
void f();
};
'interface_method' : cannot be used as an explicit override, must be a virtual member function of a base class
An attempt was made to perform an explicit override on a member that was not virtual.
For more information, see Explicit Overrides.
The following sample generates C3650:
// C3650.cpp
// compile with: /clr
public interface struct I {
void a();
};
// C3651.cpp
// compile with: /clr /c
ref class C {
public:
virtual void func2();
};
// C3652.cpp
// compile with: /clr /c
public interface class I {
void f();
};
'function' : cannot be used as a named override: a function being overridden not found; did you forget to name the
function explicitly, using a :: operator?
An explicit override specified a function that was not found in any interface. For more information, see Explicit
Overrides.
The following sample generates C3653:
// C3653.cpp
// compile with: /clr
public interface struct I {
void h();
};
// C3654.cpp
// compile with: /clr /c
public ref struct B {
virtual void f() = 0;
virtual void g() = 0;
virtual void h() = 0;
};
// C3655.cpp
// compile with: /clr /c
public ref struct B {
virtual void f();
virtual void g();
};
// C3656.cpp
// compile with: /clr /c
public interface struct O {
int f();
};
Example
The following sample generates C3657.
// C3657.cpp
// compile with: /clr
public ref struct I {
virtual ~I() { }
virtual void a();
};
'member' : override specifier 'specifier' only allowed on member functions of managed or WinRT classes
An override specifier was used on a member of native type, which is not allowed.
For more information, see Explicit Overrides.
Example
The following sample generates C3662.
// C3662.cpp
// compile with: /clr /c
struct S {
virtual void f();
};
struct S1 : S {
virtual void f() new; // C3662
};
ref struct T {
virtual void f();
};
ref struct T1 : T {
virtual void f() new; // OK
};
Compiler Error C3665
10/31/2018 • 2 minutes to read • Edit Online
// C3665.cpp
// compile with: /clr
public ref struct R {
virtual ~R() { }
virtual void a() { }
};
Example
The following sample generates C3666.
// C3666.cpp
// compile with: /clr /c
ref struct R {
R() new {} // C3666
R(int i) {} // OK
};
Compiler Error C3668
10/31/2018 • 2 minutes to read • Edit Online
'method' : method with override specifier 'override' did not override any base class methods
A function attempted to override a non-existent function.
For more information, see Explicit Overrides.
Example
The following sample generates C3668.
// C3668.cpp
// compile with: /c
__interface I {
void f(int); // virtual by default
};
class J {
public:
void g(int);
virtual void h(int);
};
struct R : I,J {
virtual void f() override {} // C3668
virtual void f(int) override {} // OK
'member' : override specifier 'override' not allowed on static member functions or constructors
An override was specified incorrectly. For more information, see Explicit Overrides.
Example
The following sample generates C3669.
// C3669.cpp
// compile with: /clr
public ref struct R {
R() override {} // C3669
};
Compiler Error C3670
10/31/2018 • 2 minutes to read • Edit Online
// C3670.cpp
// compile with: /clr /c
public ref class C {
// Uncomment the following line to resolve.
// public:
virtual void g() { }
};
Example
The following sample generates C3671.
// C3671.cpp
// compile with: /clr /c
ref struct S {
virtual void f();
};
ref struct S1 : S {
virtual void f(int) new sealed = S::f; // C3671
virtual void f() new sealed = S::f;
};
Compiler Error C3672
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3672.
// C3672.cpp
template<typename T>
void f(T* pT) {
&pT->T::~T; // C3672
pT->T::~T(); // OK
};
int main() {
int i;
f(&i);
}
Compiler Error C3673
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3673.
// C3673.cpp
// compile with: /clr
public ref struct R {
public:
R() {}
// Uncomment the following line to resolve.
// R(R% p) {}
};
int main() {
R r;
R s = r; // C3673
}
Example
The following sample generates C3673.
// C3673_b.cpp
// compile with: /clr /c
// C3673 expected
using namespace System;
[AttributeUsage(AttributeTargets::Class)]
ref class MyAttr : public Attribute {
public:
MyAttr() {}
// Uncomment the following line to resolve.
// MyAttr(int i) {}
property int Priority;
property int Version;
};
[MyAttr]
ref class ClassA {}; // OK, no arguments
[MyAttr(Priority = 1)]
ref class ClassB {}; // OK, named argument
[MyAttr(123)]
ref class ClassC {}; // Positional argument
Example
The following sample generates C3675.
// C3675.cpp
// compile with: /clr /c
ref struct C {
public:
property int Size;
int get_Size() { return 0; } // C3675
};
Compiler Error C3697
10/31/2018 • 2 minutes to read • Edit Online
// C3697.cpp
// compile with: /clr
using namespace System;
int main() {
String ^__restrict s; // C3697
String ^ s2; // OK
}
Compiler Error C3698
10/31/2018 • 2 minutes to read • Edit Online
// C3698.cpp
// compile with: /clr
int main() {
array<int>^a = new array<int>^(20); // C3698
array<int>^a2 = gcnew array<int>(20); // OK
}
Compiler Error C3699
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3699.
// C3699.cpp
// compile with: /clr /c
using namespace System;
int main() {
String * s; // C3699
// try the following line instead
// String ^ s2;
}
Example
A trivial property cannot have reference type. See property for more information. The following sample generates
C3699.
// C3699_b.cpp
// compile with: /clr /c
ref struct C {
property System::String % x; // C3699
property System::String ^ y; // OK
};
Example
The equivalent of a "pointer to a pointer" syntax is a handle to a tracking reference. The following sample generates
C3699.
// C3699_c.cpp
// compile with: /clr /c
using namespace System;
void Test(String ^^ i); // C3699
void Test2(String ^% i);
Compiler Error C3701
10/31/2018 • 2 minutes to read • Edit Online
// C3701.cpp
[ event_source(native) ]
class CEventSrc {
public:
// uncomment the following line to resolve this C3701
// __event void fireEvent(int i);
}; // C3701
int main() {
}
Compiler Error C3702
10/31/2018 • 2 minutes to read • Edit Online
// C3702.cpp
// uncomment the following line to resolve
// #define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
[object]
__interface IEvents : IUnknown
{
HRESULT event1([in] int i);
};
[dual]
__interface IBase
{
HRESULT fireEvents();
};
[coclass, event_source(com)]
class CEventSrc : public IBase
{
public:
__event __interface IEvents;
HRESULT fireEvents()
{
HRESULT hr = IEvents_event1(123);
return hr;
}
}; // C3702
int main() {
}
Compiler Error C3703
10/31/2018 • 2 minutes to read • Edit Online
'event handler': an event handler method must have the same storage class as the source 'event'
An event has a different storage class than the event handler to which it is hooked. For example, this error occurs if
the event handler is a static member function and the event is not static. To fix this error, give the event and the
event handler the same storage class.
The following sample generates C3703:
// C3703.cpp
// C3703 expected
#include <stdio.h>
[event_source(type=native)]
class CEventSrc {
public:
__event static void MyEvent();
};
[event_receiver(type=native)]
class CEventHandler {
public:
// delete the following line to resolve
void MyHandler() {}
int main() {
CEventSrc src;
CEventHandler hnd;
hnd.HookIt(&src);
__raise src.MyEvent();
hnd.UnhookIt(&src);
}
Compiler Error C3704
10/31/2018 • 2 minutes to read • Edit Online
// C3704.cpp
[ event_source(native) ]
class CEventSrc {
public:
__event void fireEvent(int i, ...); // C3704
// try the following line instead:
// __event void fireEvent(int i);
};
int main() {
}
Compiler Error C3705
10/31/2018 • 2 minutes to read • Edit Online
// C3705.cpp
// compile with: /c
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
[dual, uuid("00000000-0000-0000-0000-000000000001")]
__interface IBase {
HRESULT fireEvents();
};
// C3706.cpp
// compile with: /c
// C3706 expected
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
[dual, uuid="12341234-1234-1234-1234-123412341235"]
__interface IBase {
HRESULT fireEvents();
};
HRESULT fireEvents() {
HRESULT hr = IEvents_event1(123);
return hr;
}
};
Compiler Error C3707
10/31/2018 • 2 minutes to read • Edit Online
// C3707.cpp
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
[module(name="xx")];
[dispinterface]
__interface IEvents : IDispatch
{
HRESULT event1([in] int i); // C3707
// try the following line instead
// [id(1)] HRESULT event1([in] int i);
};
int main() {
}
Compiler Error C3708
10/31/2018 • 2 minutes to read • Edit Online
// C3708.cpp
// compile with: /c
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[ module(name="MyLibrary")];
[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface I {
HRESULT func();
};
[ object, uuid("00000000-0000-0000-0000-000000000002") ]
__interface II {
HRESULT func();
};
// C3709.cpp
// compile with: /LD
[event_source(native)]
class CEventSrc
{
public:
__event void event1();
};
[event_receiver(native)]
class CEventRec
{
public:
void handler1()
{
}
Example
The following sample generates C3710
// C3710.cpp
// compile with: /link /opt:noref
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <stdio.h>
[event_source(native)]
class CEventSrc
{
public:
__event void event1();
};
[event_receiver(native)]
class CEventRec
{
public:
void handler1()
{
printf_s("Executing handler1().\n");
}
int main()
{
CEventSrc eventSrc;
CEventRec eventRec;
eventRec.HookEvents(&eventSrc);
eventSrc.event1();
eventRec.UnhookEvents(&eventSrc);
}
Compiler Error C3711
10/31/2018 • 2 minutes to read • Edit Online
'method': an non-managed event source method must return void or an integral type
You defined a method in the event source that did not return void or an integral type. To fix this error, make the
event and event handler have a return type of void or an integral type such as int or long .
The following sample generates C3711:
// C3711.cpp
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
[event_source(native)]
class CEventSrc {
public:
__event float event1(); // C3711
// try the following line instead
// __event int event1();
// also change the handler, below
};
[event_receiver(native)]
class CEventRec {
public:
float handler1() { // change float to int
return 0.0; // change 0.0 to 0
}
void HookEvents(CEventSrc* pSrc) {
__hook(CEventSrc::event1, pSrc, CEventRec::handler1);
}
void UnhookEvents(CEventSrc* pSrc) {
__unhook(CEventSrc::event1, pSrc, CEventRec::handler1);
}
};
int main() {
}
Compiler Error C3712
10/31/2018 • 2 minutes to read • Edit Online
'method': an event handler method must return the same type as the source 'method'
You defined an event handler method that did not return the same type as the source event method. To fix this
error, give the event handler method the same return type as that of the source event method.
The following sample generates C3712:
// C3712.cpp
// compile with: /c
[event_source(native)]
class CEventSrc {
public:
__event void event1();
};
[event_receiver(native)]
class CEventRec {
public:
int handler1() { return 0; }
// try the following line instead
// void handler1() {}
'method': an event handler method must have the same function parameters as the source 'method'
You defined an event handler method that did not use the same parameters as the source event method. To fix this
error, give the event handler method the same parameters as those of the source event method.
The following sample generates C3713:
// C3713.cpp
// compile with: /c
[event_source(native)]
class CEventSrc {
public:
__event void event1(int nValue);
// try the following line instead
// __event void event1();
};
[event_receiver(native)]
class CEventRec {
public:
void handler1() {}
'method': an event handler method must have the same calling convention as the source 'method'
You defined an event handler method that did not use the same calling convention as the source event method. To
fix this error, give the event handler method the same calling conventions as those of the source event method. For
example, in the code below, make the calling conventions of handler1 and event1 match (__cdecl or __stdcall or
others). Removing calling convention keywords from both declarations will also solve the problem, and cause
event1 and handler1 to default to the thiscall calling convention. See Calling Conventions for more information.
// C3714.cpp
// compile with: /c
// processor: x86
[event_source(native)]
class CEventSrc {
public:
__event void __cdecl event1();
// try the following line instead
// __event void __stdcall event1();
};
[event_receiver(native)]
class CEventRec {
public:
void __stdcall handler1() {}
// C3717.cpp
[event_source(native)]
class CEventSrc {
public:
__event void event1() { // C3717
}
[event_receiver(native)]
class CEventRec {
public:
void handler1() {
}
int main() {
}
Compiler Error C3718
10/31/2018 • 2 minutes to read • Edit Online
can only call 'event' in the context of a member function of the receiving class
The event can only be called from the receiving class.
Example
The following sample generates C3718:
// C3718.cpp
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[module(name="test")];
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface I
{
HRESULT f();
};
[event_receiver(com)]
struct R
{
void b()
{
printf_s("B::bar()\n");
}
int main()
{
CComObject<E>* pE;
CComObject<E>::CreateInstance(&pE);
'interface': an interface based event source can only be used for COM events
You declared an interface in a non-COM context.
The following sample generates C3719:
// C3719a.cpp
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[object]
__interface I {
HRESULT func1();
};
[event_source(native), coclass]
struct A {
__event __interface I; // C3719
int main() {
}
To fix this error, apply the object, coclass, event_source, and event_receiver attributes appropriately to make the
classes in which you are using the interface COM classes. For example:
// C3719b.cpp
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="xx")];
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface I {
HRESULT f();
};
[event_receiver(com)]
struct MyStruct2 {
void f() {
}
MyStruct2(I* pB) {
__hook(&I::f, pB, &MyStruct2::f);
}
};
int main()
{
}
Compiler Error C3721
10/31/2018 • 2 minutes to read • Edit Online
// C3722.cpp
// compile with: /clr
generic <typename T>
public delegate void MyEventHandler(System::Object^ sender, System::EventArgs^ e, T optional);
// C3723.cpp
struct A {
// To resolve, comment void f(int); and uncomment the __event function
void f(int);
// __event void f(int);
void f(float);
};
struct B {
void g(int);
B(A* a) {
__hook(&A::f, a, &B::g); // C3723
}
};
int main() {
}
__hook and __unhook are not compatible with /clr programming. Use the += and -= operators instead.
The following sample generates C3723:
// C3723b.cpp
// compile with: /clr
using namespace System;
int main() {
}
Compiler Error C3724
10/31/2018 • 2 minutes to read • Edit Online
// C3724.cpp
// uncomment the following line to resolve
// #include <windows.h>
[event_source(native), threading(apartment)]
class CEventSrc {
public:
__event void event1(); // C3724
};
[event_receiver(native)]
class CEventRec {
public:
void handler1() {
}
int main() {
}
Compiler Error C3727
10/31/2018 • 2 minutes to read • Edit Online
'event': a managed event must be a member function or a data member that is a pointer to a delegate
.NET events must be a pointer to a delegate type.
Compiler Error C3728
10/31/2018 • 2 minutes to read • Edit Online
incompatible event 'function1' and handler 'function2'; event source and event handler must be the same type
The event source and event receiver must have the same type (for example native vs. com types). To fix this error,
make the types of the event source and the event handler match.
The following sample generates C3731:
// C3731.cpp
// compile with: /clr
#using <mscorlib.dll>
[event_source(native)]
struct A {
__event void MyEvent();
};
[event_receiver(managed)]
// try the following line instead
// [event_receiver(native)]
struct B {
void func();
B(A a) {
__hook(&A::MyEvent, &a, &B::func); // C3731
}
};
int main() {
}
Compiler Error C3732
10/31/2018 • 2 minutes to read • Edit Online
'interface': a custom interface that fires COM events cannot inherit from IDispatch
An interface that supports COM events cannot inherit from IDispatch . For more information, see Event Handling
in COM.
The following error generates C3732:
// C3732.cpp
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[module(name="test")];
[ event_source(com), coclass ]
struct A
{
__event __interface I; // C3732
};
int main()
{
}
Compiler Error C3733
10/31/2018 • 2 minutes to read • Edit Online
'event': improper syntax for specifying a COM event; did you forget '__interface'?
The wrong syntax was used for a COM event. To fix this error, change the event type or correct the syntax to
comply with the COM event rules.
The following sample generates C3733:
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
int main()
{
}
Compiler Error C3734
10/31/2018 • 2 minutes to read • Edit Online
// C3734.cpp
// compile with: /clr /c
[module(name="x")];
[coclass]
ref class CMyClass { // C3734 remove the ref keyword to resolve
};
Compiler Error C3736
10/31/2018 • 2 minutes to read • Edit Online
'event': must be a method or, in the case of managed events, optionally a data member
Native and COM events must be methods. .NET events can also be data members.
The following sample generates C3736:
// C3736.cpp
struct A {
__event int e();
};
struct B {
int f; // C3736
// The following line resolves the error.
// int f();
B(A* a) {
__hook(&A::e, a, &B::f);
}
};
int main() {
}
Compiler Error C3737
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3737:
// C3737a.cpp
// compile with: /clr
delegate void __stdcall MyFunc(); // C3737
// Try the following line instead.
// delegate void MyFunc();
int main() {
}
Compiler Error C3738
10/31/2018 • 2 minutes to read • Edit Online
'calling_convention': the calling convention of the explicit instantiation must match that of the template being
instantiated
It is recommended that you do not specify a calling convention on an explicit instantiation. If you must, though, the
calling conventions must match.
Example
The following sample generates C3738.
// C3738.cpp
// compile with: /clr
// processor: x86
#include <stdio.h>
template< class T >
void f ( T arg ) { // by default calling convention is __cdecl
printf ( "f: %s\n", __FUNCSIG__ );
}
template
void __stdcall f< int > ( int arg ); // C3738
// try the following line instead
// void f< int > ( int arg );
int main () {
f(1);
f< int > ( 1 );
}
Compiler Error C3739
10/31/2018 • 2 minutes to read • Edit Online
'class': syntax is only supported when the 'layout_dependent' parameter of event_receiver is true
You tried to hook an entire interface of events but layout_dependent on event_receiver attribute is not true; you
must hook a single event at a time.
The following sample generates C3739:
// C3739.cpp
struct A
{
__event void e();
};
// event_receiver is implied
// [ event_receiver(layout_dependent=false)]
int main()
{
}
Compiler Error C3740
10/31/2018 • 2 minutes to read • Edit Online
// C3740.cpp
template <typename T> // Delete the template specification
struct E {
__event void f(); // C3740
};
int main() {
}
Compiler Error C3741
10/31/2018 • 2 minutes to read • Edit Online
// C3741.cpp
// compile with: /c
// C3741 expected
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="xx")];
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface I{ HRESULT f(); };
can only hook/unhook an entire interface when the 'layout_dependent' parameter of event_receiver is true
The __unhook function varies in the number of parameters that it takes based on the value passed to the
layout_dependent parameter in the event_receiver class.
// C3743.cpp
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="xx")];
[object] __interface I { HRESULT f(); };
R(I* a) {
__hook(I, a, &R::f); // C3743
// The following line resolves the error.
// __hook(I, a);
}
};
Compiler Error C3744
10/31/2018 • 2 minutes to read • Edit Online
// C3745.cpp
struct E {
__event void func();
void func(int) {
}
void func2() {
}
void bar() {
__raise func();
__raise func(1); // C3745
__raise func2(); // C3745
}
};
int main() {
E e;
__raise e.func();
__raise e.func(1); // C3745
__raise e.func2(); // C3745
}
Compiler Error C3747
10/31/2018 • 2 minutes to read • Edit Online
// C3747.cpp
template <class T1 = int, class T2> // C3747
struct MyStruct {};
Possible resolution:
// C3747b.cpp
// compile with: /c
template <class T1, class T2 = int>
struct MyStruct {};
Compiler Error C3748
10/31/2018 • 2 minutes to read • Edit Online
// C3748.cpp
__interface I {
// try the following line instead
// struct I {
__event void f(); // C3748
};
int main() {
}
Compiler Error C3749
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3749:
// C3749a.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::All)]
public ref struct ABC : public Attribute {
ABC() {}
};
'attribute class': cannot classify attribute; 'keyword' should not be used in this context
A user-defined attribute was applied incorrectly.
Compiler Error C3753
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3753.
// C3753.cpp
// compile with: /clr /c
ref struct A {
generic <typename T>
property int i; // C3753 error
};
Compiler Error C3754
10/31/2018 • 2 minutes to read • Edit Online
delegate constructor: member function 'function' cannot be called on an instance of type 'type'
A call was made to a function through a pointer to a type that does not contain the function.
Example
The following sample generates C3754:
// C3754a.cpp
// compile with: /clr
using namespace System;
int main() {
MyInterface^ p = gcnew MyClass;
MyDel^ q = gcnew MyDel(p, &MyClass::f); // C3754
// try the following line instead
// MyDel^ q = gcnew MyDel(safe_cast<MyClass^>(p), &MyClass::f);
}
Compiler Error C3755
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3755.
// C3755.cpp
// compile with: /clr /c
delegate void MyDel() {}; // C3755
Example
C3755 can also occur if you attempt to create a delegate template. The following sample generates C3755.
// C3755_b.cpp
// compile with: /clr /c
ref struct R {
template<class T>
delegate void D(int) {} // C3755
};
Compiler Error C3761
10/31/2018 • 2 minutes to read • Edit Online
// C3761.cpp
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[ module(name=test) ];
[dispinterface]
__interface I
{
[id(1)] HRESULT func([out, retval] int* i, [in] int j);
// try the following line instead
// [id(1)] HRESULT func([in] int i, [out, retval] int* j);
};
[coclass]
struct C : I { // C3761
HRESULT func(int* i, int j)
// try the following line instead
// HRESULT func(int j, int* i)
{
return S_OK;
}
};
int main()
{
}
Compiler Error C3762
10/31/2018 • 2 minutes to read • Edit Online
// C3763.cpp
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlplus.h>
#include <atlcom.h>
[ module(name=test) ];
[ dispinterface, uuid("00000000-0000-0000-0000-000000000001") ]
__interface IF84 : IDispatch
{
[id(0x00000002)]HRESULT m2([out]unsigned char);
};
[ coclass, uuid("00000000-0000-0000-0000-000000000002") ]
class CF84 : public IF84
{ // C3763
public:
HRESULT __stdcall m2(unsigned char i)
{
return S_OK;
}
};
int main()
{
}
Compiler Error C3764
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3764.
// C3764.cpp
// compile with: /clr /c
public ref struct A {
void g(int);
virtual void h(int);
};
Example
C3764 can also occur when a base class method is both explicitly and named overridden. The following sample
generates C3764.
// C3764_b.cpp
// compile with: /clr /c
ref struct A {
virtual void Test() {}
};
// C3765.cpp
[event_receiver(native)]
struct ER2 {
__event void f(); // C3765
__event void b(int); // C3765
};
Compiler Error C3766
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3766.
// C3766.cpp
// compile with: /clr /c
// OK
ref struct Class2 : public IFace {
virtual event MyDel ^ E {
void add(MyDel ^) {}
void remove(MyDel ^) {}
}
};
Compiler Error C3767
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3767:
// C3767a.cpp
// compile with: /clr
using namespace System;
public delegate void TestDel();
int main() {
MyClass^ x = gcnew MyClass;
x->MyClass_Event(); // C3767
// OK
MyClass2^ y = gcnew MyClass2();
y->Test();
};
cannot take the address of a virtual vararg function in pure managed code
Remarks
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
When compiling with /clr:pure, you cannot take the address of a virtual vararg function.
Example
The following sample generates C3768:
// C3768.cpp
// compile with: /clr:pure
struct A
{
virtual void f(...);
};
int main()
{
&(A::f); // C3768
}
Compiler Error C3769
10/31/2018 • 2 minutes to read • Edit Online
'type' : a nested class cannot have the same name as the immediately enclosing class
A nested class cannot have the same name as the immediately enclosing class.
Example
The following sample generates C3769.
// C3769.cpp
// compile with: /c
class x {
class x {}; // C3769
class y {
class x{}; // OK
};
};
Compiler Error C3771
10/31/2018 • 2 minutes to read • Edit Online
Example
The following code example declares a class template and function in namespace NA , but attempts to declare a
friend function template in namespace NB .
// C3771.cpp
// compile with: /c
namespace NA {
template<class T> class A {
void aFunction(T t) {};
};
}
// using namespace NA;
namespace NB {
class X {
template<class T> friend void A<T>::aFunction(T); // C3771
// try the following line instead
// template<class T> friend void NA::A<T>::aFunction(T);
// or try "using namespace NA;" instead.
};
}
See Also
Templates
Compiler Error C3772
10/31/2018 • 2 minutes to read • Edit Online
Example
The following code example fails because it declares a friend of a partial specialization of a class template.
// c3772.cpp
// compile with: /c
// A class template.
template<class T> class A {};
// An explicit specialization.
template<> class A<char>;
class X {
// Invalid declaration of a friend of a partial specialization.
template<class T> friend class A<T*>; // C3772
See Also
Templates
Template Specialization
Compiler Error C3797
10/31/2018 • 2 minutes to read • Edit Online
'override': event declaration cannot have override specifier (should be placed on event add/remove/raise methods
instead)
You cannot override a trivial event (an event without explicitly defined accessor methods) with another trivial event.
The overriding event must define its behavior with accessor functions.
For more information, see event.
Example
The following sample generates C3797.
// C3797.cpp
// compile with: /clr /c
delegate void MyDel();
// OK
ref class Class3 : public Class1 {
public:
virtual event MyDel ^ E {
void add(MyDel ^ d) override {}
void remove(MyDel ^ d) override {}
}
};
Compiler Error C3798
10/31/2018 • 2 minutes to read • Edit Online
'specifier': property declaration cannot have override specifier (should be placed on property get/set methods
instead)
A property was declared incorrectly. For more information, see
property
abstract
sealed
Example
The following sample generates C3798
// C3798.cpp
// compile with: /clr /c
ref struct A {
property int Prop_1 abstract; // C3798
property int Prop_2 sealed; // C3798
// OK
property int Prop_3 {
virtual int get() abstract;
virtual void set(int i) abstract;
}
Example
The following sample generates C3799 and shows how to fix it.
// C3799.cpp
// compile with: /clr /c
ref struct C {
property int default[] { // C3799
// try the following line instead
// property int default[int] {
int get(int index) { return 0; }
void set(int index, int value) {}
}
};
Compiler Error C3800
10/31/2018 • 2 minutes to read • Edit Online
'property': property has a type that is incompatible with one of its accessors 'accessor'
The type of a property defined with property does not match the return type for one of its accessor functions.
The following sample generates C3803:
// C3803.cpp
struct A
{
__declspec(property(get=GetIt)) int i;
char GetIt()
{
return 0;
}
/*
// try the following definition instead
int GetIt()
{
return 0;
}
*/
}; // C3803
int main()
{
}
Compiler Error C3804
10/31/2018 • 2 minutes to read • Edit Online
'property_accessor': the accessor methods for a property must either be all static or all non-static
When defining a non-trivial property, the accessor functions can be either static or instance, but not both.
See property for more information.
Example
The following sample generates C3804.
// C3804.cpp
// compile with: /c /clr
ref struct A {
property int i {
static int get() {}
void set(int i) {}
} // C3804 error
// OK
property int j {
int get() { return 0; }
void set(int i) {}
}
property int k {
static int get() { return 0; }
static void set(int i) {}
}
};
Compiler Error C3805
10/31/2018 • 2 minutes to read • Edit Online
'type' : a class with the ComImport attribute cannot derive from 'type2', only interface implementation is allowed
A type that derived from ComImportAttribute can only implement an interface.
Example
The following sample generates C3807.
// C3807.cpp
// compile with: /clr /c
ref struct S {};
interface struct I {};
[System::Runtime::InteropServices::ComImportAttribute()]
ref struct S1 : S {}; // C3807
ref struct S2 : I {};
Compiler Error C3808
10/31/2018 • 2 minutes to read • Edit Online
'type' : a class with the ComImport attribute cannot define member 'member', only abstract or dllimport
functions are allowed
Remarks
A type that derived from ComImportAttribute cannot define member.
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
Example
The following sample generates C3808.
// C3808.cpp
// compile with: /c /clr:pure user32.lib
using namespace System::Runtime::InteropServices;
[System::Runtime::InteropServices::ComImportAttribute()]
ref struct S1 {
int f() {} // C3808
virtual int g() abstract; // OK
[DllImport("msvcrt.dll")]
int printf(System::String ^, int i); // OK
};
Compiler Error C3809
10/31/2018 • 2 minutes to read • Edit Online
// C3809a.cpp
// compile with: /clr
ref class A {};
ref class B
{
public:
friend ref class A; // C3809
};
int main()
{
}
Compiler Error C3812
10/31/2018 • 2 minutes to read • Edit Online
a property declaration can only appear within the definition of a managed or WinRT type
A property can only be declared within a managed or Windows Runtime type. Native types do not support the
property keyword.
Example
The following sample generates C3813 and shows how to fix it:
// C3813.cpp
// compile by using: cl /c /clr C3813.cpp
class A
{
property int Int; // C3813
};
ref class B
{
property int Int; // OK - declared within managed type
};
Compiler Error C3815
10/31/2018 • 2 minutes to read • Edit Online
return type of method 'get_accessor' must match type of the last parameter of a setter
When declaring properties, the return value of the get_accessor method must match the last parameter in the
declaration of the set accessor method.
C3815 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3816
10/31/2018 • 2 minutes to read • Edit Online
// C3816a.cpp
// compile with: /clr /c
class C1;
// try the following line instead
// ref class C1;
ref class C1{ // C3816, forward declaration does not use ref
};
Compiler Error C3817
10/31/2018 • 2 minutes to read • Edit Online
array property declaration 'property1' shall not overload an index property 'property2'
An overload is not possible for properties when one is an indexer and the other is an array property.
C3818 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3820
10/31/2018 • 2 minutes to read • Edit Online
See Also
Initializers
Additional Startup Considerations
Compiler Error C3821
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3821.
// C3821a.cpp
// compile with: /clr /c
public ref struct R {};
void test1(...) {
R r; // C3821
}
Example
The following sample generates C3821.
// C3821b.cpp
// compile with: /clr
// processor: /x86
ref class A {
public:
int i;
};
int main() {
// cannot use managed classes in this function
A ^a;
__asm {
nop
}
} // C3821
Compiler Error C3824
10/31/2018 • 2 minutes to read • Edit Online
'member': this type cannot appear in this context (function parameter, return type, or a static member)
Pinning pointers cannot be function parameters, return types, or declared static .
Example
The following sample generates C3824:
// C3824a.cpp
// compile with: /clr /c
void func() {
static pin_ptr<int> a; // C3824
pin_ptr<int> b; // OK
}
Compiler Error C3825
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3825 and shows how to fix it:
// C3825a.cpp
// compile with: /clr
public delegate void del1();
void FireEvents() {
event1();
}
};
int main()
{
CEventSrc^ pEventSrc = gcnew CEventSrc;
CEventRec^ pEventRec = gcnew CEventRec;
pEventRec->HookEvents(pEventSrc);
pEventSrc->FireEvents();
pEventRec->UnhookEvents(pEventSrc);
}
Compiler Error C3828
10/31/2018 • 2 minutes to read • Edit Online
'object type': placement arguments not allowed while creating instances of managed or WinRTclasses
When creating an object of a managed type or Windows Runtime type, you cannot use the placement form of
operator ref new, gcnew or new.
The following sample generates C3828 and shows how to fix it:
// C3828a.cpp
// compile with: /clr
ref struct M {
};
ref struct N {
static array<char>^ bytes = gcnew array<char>(256);
};
int main() {
M ^m1 = new (&N::bytes) M(); // C3828
// The following line fixes the error.
// M ^m1 = gcnew M();
}
Compiler Error C3830
10/31/2018 • 2 minutes to read • Edit Online
'type1': cannot inherit from 'type2', value types can only inherit from interface classes
A value type cannot inherit a base class. For more information, see Classes and Structs.
Example
The following sample generates C3830:
// C3830a.cpp
// compile with: /clr /c
public value struct MyStruct4 {
int i;
};
// OK
public interface struct MyInterface4 {
void i();
};
'member': 'class' cannot have a pinned data member or a member function returning a pinning pointer
pin_ptr (C++/CLI) was used incorrectly.
Example
The following sample generates C3831:
// C3831a.cpp
// compile with: /clr
ref class Y
{
public:
int i;
};
ref class X
{
pin_ptr<int> mbr_Y; // C3831
int^ mbr_Y2; // OK
};
int main() {
Y y;
pin_ptr<int> p = &y.i;
}
Compiler Error C3832
10/31/2018 • 2 minutes to read • Edit Online
'type library': type library looks as if it was built for 32-bit pointers; please change the 'ptrsize' qualifier
Explicit information supplied with the ptrsize attribute of the #import directive did not agree with what the
compiler found in the type library.
Compiler Error C3833
10/31/2018 • 2 minutes to read • Edit Online
// C3833.cpp
// compile with: /clr
int main() {
interior_ptr<MyClass> p; // C3833
// OK
MyClass ^ h_MyClass = gcnew MyClass;
interior_ptr<int> i = &(h_MyClass->data);
System::Console::WriteLine(*i);
}
// C3833b.cpp
// compile with: /clr /c
ref class G {
public:
int i;
};
int main() {
G ^ pG = gcnew G;
pin_ptr<G> ppG = &pG; // C3833 can't pin a whole object
// OK
pin_ptr<int> ppG2 = &pG->i;
*ppG2 = 54;
int * pi = ppG2;
System::Console::WriteLine(*pi);
System::Console::WriteLine(*ppG2);
*pi = 55;
System::Console::WriteLine(*pi);
System::Console::WriteLine(*ppG2);
*ppG2 = 56;
System::Console::WriteLine(*pi);
System::Console::WriteLine(*ppG2);
}
Compiler Error C3834
10/31/2018 • 2 minutes to read • Edit Online
illegal explicit cast to a pinning pointer; use a pinned local variable instead
Explicit casts to a pinned pointer are not allowed.
Example
The following sample generates C3834.
// C3834.cpp
// compile with: /clr
int main() {
int x = 33;
Example
The following sample generates C3836:
// C3836a.cpp
// compile with: /clr
ref class M
{
static int s_i;
public:
static M() : s_i(1234) // C3836, delete initializer to resolve
{
}
};
int main()
{
}
Compiler Error C3838
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3838:
// C3838a.cpp
// compile with: /clr /c
public ref class B : public System::Enum {}; // C3838
Compiler Error C3839
10/31/2018 • 2 minutes to read • Edit Online
// C3839a.cpp
// compile with: /clr
ref class C
{
public:
__declspec(align(32)) int m_j; // C3839
};
int main()
{
}
Compiler Error C3842
10/31/2018 • 2 minutes to read • Edit Online
'function': 'const' and 'volatile' qualifiers on member functions of WinRT or managed types are not supported
const and volatile are not supported on member functions of Windows Runtime or managed types.
The following sample generates C3842:
// C3842a.cpp
// compile with: /clr /c
public ref struct A {
void f() const {} // C3842
void f() volatile {} // C3842
void f() {}
};
Compiler Error C3846
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : cannot import symbol from 'assembly2': as 'symbol' has already been imported from another assembly
'assembly1'
A symbol could not be imported from a referenced assembly because it was previously imported from a
referenced assembly.
Example
The following sample generates C3846:
// C3846a.cpp
// compile with: /LD /clr
public ref struct G
{
};
// C3846b.cpp
// compile with: /clr
#using "c3846a.dll"
#using "c3846a.obj" // C3846
int main()
{
}
Compiler Error C3848
10/31/2018 • 2 minutes to read • Edit Online
expression having type 'type' would lose some const-volatile qualifiers in order to call 'function'
A variable with a specified const-volatile type can only call member functions defined with same or greater const-
volatile qualifications.
The following samples generate C3848:
// C3848.cpp
void glbFunc1()
{
}
struct S3
{
operator pFunc1() // const
{
return &glbFunc1;
}
};
int main()
{
const S3 s3;
s3(); // C3848, uncomment const qualifier
}
Compiler Error C3849
10/31/2018 • 2 minutes to read • Edit Online
function-style call on an expression of type 'type' would lose const and/or volatile qualifiers for all number
available operator overloads
A variable with a specified const-volatile type can only call member functions defined with same or greater const-
volatile qualifications.
To fix this error, provide an appropriate member function. You cannot execute a conversion on a const or volatile
qualified object when the conversion causes loss of qualification. You can gain qualifiers but you cannot lose
qualifiers in a conversion.
The following samples generate C3849:
// C3849.cpp
void glbFunc3(int i, char c)
{
i;
}
typedef void (* pFunc3)(int, char);
void glbFunc2(int i)
{
i;
}
void glbFunc1()
{
}
typedef void (* pFunc1)();
struct S4
{
operator ()(int i)
{
i;
}
operator pFunc3()
{
return &glbFunc3;
}
int main()
{
// Cannot call any of the 4 overloads of "operator ()(.....)" and
// "operator pFunc()" because none is declared as "const volatile"
const volatile S4 s4; // can only call cv member functions of S4
s4(); // C3849 to resolve, uncomment member function
}
Compiler Error C3850
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Characters represented as universal character names must represent valid Unicode code points in the range 0-
10FFFF. A universal character name cannot contain a value in the Unicode surrogate range, D800-DFFF, or an
encoded surrogate pair. The compiler generates the surrogate pair from a valid code point automatically.
In code compiled as C, a universal character name may not represent a character in the range 0000-009F,
inclusive, with the exceptions of 0024 ('$'), 0040 ('@') and 0060 ('`').
In code compiled as C++, a universal character name may use any valid Unicode code point in a string or character
literal. Outside of a literal, a universal character name may not represent a control character in the ranges 0000-
001F or 007F -009F, both inclusive, or a member of the basic source character set. For more information, see
Character Sets.
Example
The following sample generates C3850, and shows how to fix it:
// C3850.cpp
int main() {
int \u0019 = 0; // C3850, not in allowed range for an identifier
const wchar_t * wstr_bad = L"\UD840DC8A"; // C3850, UCN is surrogate pair
const wchar_t * wstr_good = L"\U0002008A"; // Okay, UCN is valid code point
}
Compiler Error C3851
10/31/2018 • 2 minutes to read • Edit Online
Remarks
In code compiled as C++, you cannot use a universal character name that represents a character in the basic
source character set outside of a string or character literal. For more information, see Character Sets. In code
compiled as C, you cannot use a universal character name for characters in the range 0x20-0x7f, inclusive, except
for 0x24 ('$'), 0x40 ('@'), or 0x60 ('`').
Example
The following samples generate C3851, and show how to fix it:
// C3851.cpp
int main()
{
int test1_\u0041 = 0; // C3851, \u0041 = 'A' in basic character set
int test2_A = 0; // OK
}
Compiler Error C3852
10/31/2018 • 2 minutes to read • Edit Online
'member' having type 'type': aggregate initialization could not initialize this member
An attempt was made to assign a default initialization as part of an aggregate initialization to a data member that
cannot receive a default initialization in an aggregate initialization.
The following samples generate C3852:
// C3852.cpp
struct S
{
short s;
};
struct S1
{
int i;
const S s;
};
struct S2
{
int i;
char & rc;
};
int main()
{
S1 s1 = { 1 }; // C3852 const member
// try the following line instead
// S1 s1 = { 1, 2 };
// C3853.cpp
// compile with: /EHsc
#include <iostream>
int afunc(int i)
{
return i;
}
int main()
{
rFunc_t rf = afunc; // OK binding a reference to function
rf = afunc; // C3853, can't reassign to a ref that's an lvalue
int i = 99;
int & ri = i;
std::cout << i << std::endl;
ri = 0; // OK, i = 88;
std::cout << i << std::endl;
}
Compiler Error C3854
10/31/2018 • 2 minutes to read • Edit Online
expression to left of '=' evaluates to a function. Cannot assign to a function (a function is not an l-value)
A reference cannot be reinitialized. Dereferencing a reference to a function yields a function, which is an rvalue, to
which you cannot assign. Therefore, you cannot assign through a reference to a function.
The following sample generates C3854:
// C3854.cpp
int afunc(int i)
{
return i;
}
int main()
{
rFunc_t rf = afunc; // OK binding a reference to function
pFunc_t pf = &afunc; // OK initializing a pointer to function
// C3855.cpp
template <int N>
struct C {
void f();
};
Possible resolution:
// C3855b.cpp
// compile with: /c
template <int N>
struct C {
void f();
};
// C3855c.cpp
// compile with: /clr
generic <class T>
ref struct GC1 {
generic <class U>
ref struct GC2;
};
Possible resolution:
// C3855d.cpp
// compile with: /clr /c
generic <class T>
ref struct GC1 {
generic <class U>
ref struct GC2;
};
// C3856.cpp
template <class T>
struct S {
template <class T1>
struct S1;
void f();
};
Possible resolution:
// C3856b.cpp
// compile with: /c
template <class T>
struct S {
template <class T1>
struct S1;
void f();
};
// C3856c.cpp
// compile with: /clr
generic <class T>
ref struct GS {
generic <class U>
ref struct GS2;
};
Possible resolution:
// C3856d.cpp
// compile with: /clr /c
generic <class T>
ref struct GS {
generic <class U>
ref struct GS2;
};
// C3857.cpp
template <class T, class TT>
template <class T2> // C3857
struct B {};
Possible resolution:
// C3857b.cpp
// compile with: /c
template <class T, class TT, class T2>
struct B {};
// C3857c.cpp
// compile with: /clr
generic <typename T>
generic <typename U>
ref class GC; // C3857
Possible resolution:
// C3857d.cpp
// compile with: /clr /c
generic <typename U>
ref class GC;
Compiler Error C3858
10/31/2018 • 2 minutes to read • Edit Online
// C3858.cpp
// compile with: /LD
template <class T>
struct Outer
{
struct Inner;
};
virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm value' or
greater
The virtual memory allocated for your precompiled header is too small for the amount of data the compiler is
trying to put in it. Starting in Visual Studio 2015, the /Zm recommendation is only significant when using the
#pragma hdrstop directive. In other cases, it's a spurious error that indicates Windows virtual memory pressure
issues.
If your precompiled header uses a #pragma hdrstop directive, use the /Zm compiler flag to specify a larger value
for the precompiled header file. Otherwise, consider reducing the number of parallel compilation processes in
your build. For more information, see /Zm (Specify Precompiled Header Memory Allocation Limit).
Compiler Error C3860
10/31/2018 • 2 minutes to read • Edit Online
type argument list following class type name must list parameters in the order used in type parameter list
A generic or template argument list was ill formed.
The following sample generates C3860:
// C3860.cpp
// compile with: /LD
template <class T1, class T2>
struct A {
void f();
};
Possible resolution:
// C3860b.cpp
// compile with: /c
template <class T1, class T2>
struct A {
void f();
};
// C3860c.cpp
// compile with: /clr
generic<class T,class U>
ref struct GC {
void f();
};
Possible resolution:
// C3860d.cpp
// compile with: /clr /c
generic<class T,class U>
ref struct GC {
void f();
};
The compiler was not able to resolve a reference to an identifier, even using argument-dependent lookup.
Remarks
To fix this error, compare use of identifier to the identifier declaration for case and spelling. Verify that scope
resolution operators and namespace using directives are used correctly. If the identifier is declared in a header file,
verify that the header is included before the identifier is referenced. If the identifier is meant to be externally visible,
make sure that it is declared in any source file that uses it. Also check that the identifier declaration or definition is
not excluded by conditional compilation directives.
Changes to remove obsolete functions from the C Runtime Library in Visual Studio 2015 can cause C3861. To
resolve this error, remove references to these functions or replace them with their secure alternatives, if any. For
more information, see Obsolete Functions.
If error C3861 appears after project migration from older versions of the compiler, you may have issues related to
supported Windows versions. Visual C++ no longer supports targeting Windows 95, Windows 98, Windows ME,
Windows NT or Windows 2000. If your WINVER or _WIN32_WINNT macros are assigned to one of these
versions of Windows, you must modify the macros. For more information, see Modifying WINVER and
_WIN32_WINNT.
Examples
Undefined identifier
The following sample generates C3861 because the identifier is not defined.
// C3861.cpp
void f2(){}
int main() {
f(); // C3861
f2(); // OK
}
// C3861_a1.cpp
// Compile with: cl /EHsc /W4 C3861_a1.cpp C3861_a2.cpp
#include <iostream>
// Uncomment the following line to fix:
// int f(); // declaration makes external function visible
int main() {
std::cout << f() << std::endl; // C3861
}
// C3861_a2.cpp
int f() { // declared and defined here
return 42;
}
// C3861_b.cpp
// compile with: /EHsc
#include <iostream>
int main() {
try {
throw exception("Exception"); // C3861
// try the following line instead
// throw std::exception("Exception");
}
catch (...) {
std::cout << "caught an exception" << std::endl;
}
}
// C3861_c.cpp
#include <stdio.h>
int main() {
char line[21]; // room for 20 chars + '\0'
gets( line ); // C3861
// Use gets_s instead.
printf( "The line entered was: %s\n", line );
}
namespace N {
class C {
friend void FriendFunc() {}
friend void AnotherFriendFunc(C* c) {}
};
}
int main() {
using namespace N;
FriendFunc(); // C3861 error
C* pC = new C();
AnotherFriendFunc(pC); // found via argument-dependent lookup
}
To fix the error, declare the friend in class scope and define it in namespace scope:
class MyClass {
int m_private;
friend void func();
};
void func() {
MyClass s;
s.m_private = 0;
}
int main() {
func();
}
Compiler Error C3862
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual
Studio 2017.
A compilation with /clr:pure or /clr:safe will produce an MSIL only image, an image with no native (unmanaged)
code. Therefore, you cannot use the unmanaged pragma in a /clr:pure or /clr:safe compilation.
For more information, see /clr (Common Language Runtime Compilation) and managed, unmanaged.
Example
The following sample generates C3862:
// C3862.cpp
// compile with: /clr:pure /c
#pragma unmanaged
void f() {} // C3862
Compiler Error C3865
10/31/2018 • 2 minutes to read • Edit Online
// C3865.cpp
// compile with: /clr
// processor: x86
void __thiscall Func(){} // C3865
// OK
struct MyType {
void __thiscall Func(){}
};
Compiler Error C3866
10/31/2018 • 2 minutes to read • Edit Online
// C3866.cpp
// compile with: /c
class C {
~C();
void f() {
this->~C; // C3866
this->~C(); // OK
}
};
Compiler Error C3867
10/31/2018 • 2 minutes to read • Edit Online
'func': function call missing argument list; use '&func' to create a pointer to member
You tried to take the address of a member function without qualifying the member function with its class name and
the address-of operator.
This error can also be generated as a result of compiler conformance work that was done for Visual C++ 2005:
enhanced pointer-to-member conformance. Code that compiled prior to Visual C++ 2005 will now generate
C3867.
Example
C3867 can be issued from the compiler with a misleading suggested resolution. Whenever possible, use the most
derived class.
The following sample generates C3867 and shows how to fix it.
// C3867_1.cpp
// compile with: /c
struct Base {
protected:
void Test() {}
};
void Derived::Bar() {
void (Base::*p1)() = Test; // C3867
&Derived::Test; // OK
}
Example
The following sample generates C3867 and shows how to fix it.
// C3867_2.cpp
#include<stdio.h>
struct S {
char *func() {
return "message";
}
};
class X {
public:
void f() {}
};
int main() {
X::f; // C3867
// OK
X * myX = new X;
myX->f();
S s;
printf_s("test %s", s.func); // C3867
printf_s("test %s", s.func()); // OK
}
Example
The following sample generates C3867 and shows how to fix it.
// C3867_3.cpp
class X {
public:
void mf(){}
};
int main() {
void (X::*pmf)() = X::mf; // C3867
Example
The following sample generates C3867.
// C3867_4.cpp
// compile with: /c
class A {
public:
void f(int) {}
struct B {
TAmtd p;
};
void g() {
B b1;
b1.p = f; // C3867
}
};
Example
The following sample generates C3867.
// C3867_5.cpp
// compile with: /EHsc
#include <iostream>
class Testpm {
public:
void m_func1() {
std::cout << m_num << "\tm_func1\n";
}
int m_num;
typedef void (Testpm::*pmfn1)();
void func(Testpm* p);
};
void Testpm::func(Testpm* p) {
pmfn1 s = m_func1; // C3867
pmfn1 s2 = &Testpm::m_func1; // OK
(p->*s2)();
}
int main() {
Testpm *pTestpm = new Testpm;
pTestpm->m_num = 10;
pTestpm->func(pTestpm);
}
Compiler Error C3868
10/31/2018 • 2 minutes to read • Edit Online
'type': constraints on generic parameter 'parameter' differ from those on the declaration
Multiple declarations must have the same generic constraints. For more information, see Generics.
Example
The following sample generates C3868.
// C3868.cpp
// compile with: /clr /c
interface struct I1;
// OK
generic <typename T> ref struct MyStruct2;
generic <typename U> ref struct MyStruct2;
Example
The following sample generates C3869.
// C3869.cpp
// compile with: /c /clr
using namespace System;
generic <typename T>
where T : gcnew // C3869
// try the following line instead
// where T : gcnew()
ref class List {};
Compiler Error C3872
10/31/2018 • 2 minutes to read • Edit Online
// C3872.cpp
int main() {
int abc_\u0040; // C3872, U+0040 is in base char set
int abc_\u3001; // C3872, U+3001 is not in allowed range
int \u30A2_abc_\u3042; // OK, UCNs in allowed range
}
Compiler Error C3873
10/31/2018 • 2 minutes to read • Edit Online
// C3873.cpp
int main() {
int \u036F_abc; // C3873, not in allowed range for initial character
int abc_\u036F; // OK, in allowed range for non-initial character
}
Compiler Error C3874
10/31/2018 • 2 minutes to read • Edit Online
// C3874b.cpp
double main()
{ // C3874
}
Compiler Error C3880
10/31/2018 • 2 minutes to read • Edit Online
// C3880.cpp
// compile with: /clr /c
ref struct Y1 {
literal System::Decimal staticConst1 = 10; // C3880
literal int staticConst2 = 10; // OK
};
Compiler Error C3883
10/31/2018 • 2 minutes to read • Edit Online
// C3883.cpp
// compile with: /clr
ref struct Y1 {
initonly
static int staticConst1; // C3883
};
// C3883b.cpp
// compile with: /clr /c
ref struct Y1 {
initonly
static int staticConst2 = 0;
};
// C3883c.cpp
// compile with: /clr /LD
ref struct Y1 {
initonly
static int staticConst1;
static Y1() {
staticConst1 = 0;
}
};
Compiler Error C3886
10/31/2018 • 2 minutes to read • Edit Online
// C3886.cpp
// compile with: /clr /c
ref struct Y1 {
literal int staticConst; // C3886
literal int staticConst2 = 0; // OK
};
Compiler Error C3887
10/31/2018 • 2 minutes to read • Edit Online
'var' : the initializer for a literal data member must be a constant expression
A literal data member can only be initialized with a constant expresion.
The following sample generates C3887:
// C3887.cpp
// compile with: /clr
ref struct Y1 {
static int i = 9;
literal
int staticConst = i; // C3887
};
Possible resolution:
// C3887b.cpp
// compile with: /clr /c
ref struct Y1 {
literal
int staticConst = 9;
};
Compiler Error C3888
10/31/2018 • 2 minutes to read • Edit Online
'name' : the const expression associated with this literal data member is not supported by C++/CLI
The name data member that is declared with the literal keyword is initialized with a value the compiler does not
support. The compiler supports only constant integral, enum, or string types. The likely cause for the C3888 error
is that the data member is initialized with a byte array.
To correct this error
1. Check that the declared literal data member is a supported type.
See Also
literal
Compiler Error C3890
10/31/2018 • 2 minutes to read • Edit Online
// C3890.cpp
// compile with: /clr
ref struct Y1 {
literal int staticConst = 9;
};
int main() {
int p = &Y1::staticConst; // C3890
int p2 = Y1::staticConst; // OK
}
Compiler Error C3891
10/31/2018 • 2 minutes to read • Edit Online
// C3891.cpp
// compile with: /clr
ref struct Y1 {
literal int staticConst = 9;
};
int main() {
Y1::staticConst = 0; // C3891
}
Compiler Error C3892
10/31/2018 • 2 minutes to read • Edit Online
// C3892.cpp
// compile with: /clr
ref struct Y1 {
static const int staticConst = 9;
};
int main() {
Y1::staticConst = 0; // C3892
}
Compiler Error C3893
10/31/2018 • 2 minutes to read • Edit Online
'var' : l-value use of initonly data member is only allowed in an instance constructor of class 'type_name'
Static initonly data members can only have their address taken in a static constructor.
Instance (non-static) initonly data members can only have their address taken in instance (non-static) constructors.
The following sample generates C3893:
// C3893.cpp
// compile with: /clr
ref struct Y1 {
Y1() : data_var(0) {
int% i = data_var; // OK
}
initonly int data_var;
};
int main(){
Y1^ y= gcnew Y1;
int% i = y->data_var; // C3893
}
Compiler Error C3894
10/31/2018 • 2 minutes to read • Edit Online
'var' : l-value use of initonly static data member is only allowed in the class constructor of class 'class'
Static initonly data members can only be used as l-values at their point of declaration, or in a static constructor.
Instance (non-static) initonly data members can only be used as l-values at their point of declaration, or in instance
(non-static) constructors.
The following sample generates C3894:
// C3894.cpp
// compile with: /clr
ref struct Y1 {
initonly static int data_var = 0;
public:
// class constructor
static Y1() {
data_var = 99; // OK
System::Console::WriteLine("in static constructor");
}
};
int main() {
Y1::data_var = 88; // C3894
int i = Y1::data_var;
Y1 ^ MyY1 = gcnew Y1(99);
Y1::Test();
}
Compiler Error C3895
10/31/2018 • 2 minutes to read • Edit Online
// C3895.cpp
// compile with: /clr
ref struct Y1 {
initonly
volatile int data_var2; // C3895
};
Compiler Error C3896
10/31/2018 • 2 minutes to read • Edit Online
'member' : improper initializer: this literal data member can only be initialized with 'nullptr'
A literal data member was initialized incorrectly. See nullptr for more information.
The following sample generates C3896:
// C3896.cpp
// compile with: /clr /c
ref class R{};
value class V {
literal R ^ r = "test"; // C3896
literal R ^ r2 = nullptr; // OK
};
Compiler Error C3898
10/31/2018 • 2 minutes to read • Edit Online
// C3898.cpp
// compile with: /clr
struct Y1 {
initonly
static int data_var = 9; // C3898
};
Possible resolution:
// C3898b.cpp
// compile with: /clr /c
ref struct Y1 {
initonly
static int data_var = 9;
};
Compiler Error C3899
10/31/2018 • 2 minutes to read • Edit Online
'var' : l-value use of initonly data member is not allowed directly within a parallel region in class 'class'
An initonly (C++/CLI) data member cannot be initialized inside that part of a constructor that is in a parallel
region. This is because the compiler does an internal relocation of that code, such that, it is effectively no longer
part of the constructor.
To resolve, initialize the initonly data member in the constructor, but outside the parallel region.
Example
The following sample generates C3899.
// C3899.cpp
// compile with: /clr /openmp
#include <omp.h>
int main() {
R^ r = gcnew R;
System::Console::WriteLine(r->x);
}
Compiler Error C3900
10/31/2018 • 2 minutes to read • Edit Online
// C3900.cpp
// compile with: /clr
ref class X {
property int P {
void set(int); // OK
int i; // C3900 variable declaration
};
};
// C3900b.cpp
// compile with: /clr
using namespace System;
delegate void H();
ref class X {
event H^ E {
int m; // C3900
// OK
void Test() {}
void add( H^ h ) {}
void remove( H^ h ) {}
void raise( ) {}
}
};
Compiler Error C3901
10/31/2018 • 2 minutes to read • Edit Online
// C3901.cpp
// compile with: /clr /c
using namespace System;
ref class X {
property String^ Name {
void get(); // C3901
// try the following line instead
// String^ get();
};
};
ref class Y {
property double values[int, int] {
int get(int, int); // C3901
// try the following line instead
// double get(int, int);
};
};
Compiler Error C3902
10/31/2018 • 2 minutes to read • Edit Online
// C3902.cpp
// compile with: /clr /c
using namespace System;
ref class X {
property String ^Name {
void set(int); // C3902
// try the following line instead
// void set(String^){}
}
// C3903.cpp
// compile with: /clr
ref class X {
property int P {
void f(int){}
// Add one or both of the following lines.
// void set(int){}
// int get(){return 0;}
}; // C3903
Example
The following sample generates C3904.
// C3904.cpp
// compile with: /clr /c
ref class X {
property int P {
// set
void set(); // C3904
// try the following line instead
// void set(int);
// get
int get(int, int); // C3904
// try the following line instead
// int get();
};
};
Example
The following sample generates C3904.
// C3904b.cpp
// compile with: /clr /c
ref struct X {
property int Q[double, double, float, float, void*, int] {
// set
void set(double, void*); // C3904
// try the following line instead
// void set(double, double, float, float, void*, int, int);
// get
int get(); // C3904
// try the following line instead
// int get(double, double, float, float, void*, int);
}
};
Compiler Error C3908
10/31/2018 • 2 minutes to read • Edit Online
// C3908.cpp
// compile with: /clr
ref class X {
protected:
property int i {
public: // C3908 property i is protected
int get();
private:
void set(int); // OK more restrictive
};
};
Compiler Error C3909
10/31/2018 • 2 minutes to read • Edit Online
// C3909.cpp
// compile with: /clr /c
delegate void H();
class X {
event H^ E; // C3909 - use ref class X instead
};
ref class Y {
static event H^ E {
void add(H^) {}
void remove( H^ h ) {}
void raise( ) {}
}
};
Compiler Error C3910
10/31/2018 • 2 minutes to read • Edit Online
// C3910.cpp
// compile with: /clr /c
delegate void H();
ref class X {
event H^ E {
// uncomment the following lines
// void add(H^) {}
// void remove( H^ h ) {}
// void raise( ) {}
}; // C3910
// C3911.cpp
// compile with: /clr
using namespace System;
delegate void H(String^, int);
ref class X {
event H^ E1 {
void add() {} // C3911
// try the following line instead
// void add(H ^ h) {}
void remove(){}
// try the following line instead
// void remove(H ^ h) {}
void raise(){}
// try the following line instead
// void raise(String ^ s, int i) {}
};
};
Compiler Error C3912
10/31/2018 • 2 minutes to read • Edit Online
// C3912.cpp
// compile with: /clr
delegate void H();
ref class X {
event int Ev; // C3912
event H^ Ev2; // OK
};
Compiler Error C3913
10/31/2018 • 2 minutes to read • Edit Online
// C3913.cpp
// compile with: /clr /c
ref struct X {
property int default { // C3913
// try the following line instead
// property int default[int] {
int get(int) { return 0; }
void set(int, int) {}
}
};
Compiler Error C3914
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3914 and shows how to fix it.
// C3914.cpp
// compile with: /clr /c
ref struct X {
static property int default[int] { // C3914
// try the following line instead
// property int default[int] {
int get(int) { return 0; }
void set(int, int) {}
}
};
Compiler Error C3915
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3915.
// C3915.cpp
// compile with: /clr
ref class X {
public:
// uncomment property to resolve this C3915
// property int default[]
// {
// int get(int i)
// {
// return 863;
// }
// }
};
int main() {
X^ x = new X;
System::Console::WriteLine(x[1]); // C3915
}
Example
C3915 can also occur if you attempt to consume a default indexer in the same compiland where it was defined
with DefaultMemberAttribute.
The following sample generates C3915.
// C3915_b.cpp
// compile with: /clr
using namespace System;
[Reflection::DefaultMember("XXX")]
ref struct A {
property Double XXX[Double] {
Double get(Double data) {
return data*data;
}
}
};
ref struct B {
property Double default[Double] {
Double get(Double data) {
return data*data;
}
}
};
int main() {
A ^ mya = gcnew A();
Console::WriteLine("{0}", mya[3]); // C3915
Example
// C3917.cpp
// compile with: /clr /c
public ref class C {
private:
int m_length;
public:
C() {
m_length = 0;
}
Example
C3918 can occur because a class member is required in the current context. The following sample generates
C3918.
// C3918.cpp
// compile with: /clr /c
public ref class C {
public:
System::Object ^ o;
delegate void Del();
Example
C3918 is also caused if you try to check a trivial event for null (the event name will no longer provide direct access
to the backing store delegate for the event).
The following sample generates C3918.
// C3918_2.cpp
// compile with: /clr /c
using namespace System;
public delegate int MyDel(int);
Example
C3918 can also occur if you incorrectly subscribe to an event. The following sample generates C3918.
// C3918_3.cpp
// compile with: /clr /c
using namespace System;
void raise() {
d();
}
}
del^ d;
void f() {}
A() {
e = gcnew del(this, &A::f); // C3918
// try the following line instead
// e += gcnew del(this, &A::f);
e();
}
};
int main() {
A a;
}
Compiler Error C3919
10/31/2018 • 2 minutes to read • Edit Online
// C3919.cpp
// compile with: /clr /c
using namespace System;
delegate void D(String^);
ref class R {
event D^ e {
int add(int); // C3919
int remove(int); // C3919
void add(D^); // OK
void remove(D^); // OK
}
};
Compiler Error C3920
11/9/2018 • 2 minutes to read • Edit Online
'operator'' : cannot define a postfix increment/decrement WinRT or CLR operator Calling the postfix WinRT or
CLR operator will call the corresponding prefix WinRT or CLR operator (op_Increment/op_Decrement), but with
postfix semantics
The Windows Runtime and CLR do not support the postfix operator and user-defined postfix operators are not
allowed. You can define a prefix operator and the prefix operator will be used for both pre- and post-increment
operations.
The following sample generates C3920 and shows how to fix it:
// C3920.cpp
// compile with: /clr /LD
public value struct V {
static V operator ++(V me, int)
// try the following line instead
// static V operator ++(V me)
{ // C3920
me.m_i++;
return me;
}
int m_i;
};
Compiler Error C3923
10/31/2018 • 2 minutes to read • Edit Online
'member' : local class, struct, or union definitions are not allowed in a member function of a WinRT or managed
class
Example
The following sample generates C3923.
// C3923.cpp
// compile with: /clr /c
ref struct x {
void Test() {
struct a {}; // C3923
class b {}; // C3923
union c {}; // C3923
}
};
Compiler Warnings by compiler version
10/31/2018 • 34 minutes to read • Edit Online
The compiler can suppress warnings that were introduced after a version you specify by using the /Wv compiler
option. This is useful for managing your build process when you introduce a new toolset version, and want to
temporarily suppress new warnings. This option does not suppress new error messages. We do not recommend
you suppress all new warnings permanently! We recommend you always compile at the highest regular warning
level, /W4, and remove the /Wv option in your build as soon as possible.
These versions of the compiler introduced new warnings:
You can specify only the major number, the major and minor numbers, or the major, minor, and build numbers to
the /Wv option. The compiler reports all warnings which match versions that begin with the specified number,
and suppresses all warnings for versions greater than the specified number. For example, /Wv:17 reports all
warnings introduced in or before any version of Visual Studio 2012, and suppresses all warnings introduced by
any compiler from Visual Studio 2013 (version 18) or later. To suppress warnings introduced in Visual Studio
2015 update 2 and later, you can use /Wv:19.00.23506. Use /Wv:19.11 to report all warnings introduced in any
version of Visual Studio before Visual Studio 2017 version 15.5, but suppresses warnings introduced in Visual
Studio 2017 version 15.5 and later.
The following sections list the warnings introduced by each version of Visual C++ that you can suppress by using
the /Wv compiler option. The /Wv option can't suppress warnings that are not listed, which predate the specified
versions of the compiler.
C4642 'issue': could not import the constraints for generic parameter
'parameter'
C4455 'operator name': literal suffix identifiers that do not start with
an underscore are reserved
C4462 'type' : cannot determine the GUID of the type. Program may
fail at runtime.
C4463 overflow; assigning value to bit-field that can only hold values
from value to value
C4609 'type' derives from default interface 'type' on type 'type'. Use
a different default interface for 'type', or break the
base/derived relationship.
C4419 'name' has no effect when applied to private ref class 'type'.
C4435 'type': Object layout under /vd2 will change due to virtual
base 'type'
C4446 'type': cannot map member 'name' into this type, due to
conflict with the type name. The method was renamed to
'name'
C4451 'type': Usage of ref class 'type' inside this context can lead to
invalid marshaling of object across contexts
C4492 'type': matches base ref class method 'type', but is not marked
'override'
C4881 the constructor and/or the destructor will not be invoked for
tile_static variable 'type'
C4573 the usage of 'type' requires the compiler to capture 'this' but
the current default capture mode does not allow it
C4574 'name' is defined to be '0': did you mean to use '#if name'?
C4751 /arch AVX flag does not apply to Intel(R) Streaming SIMD
Extensions that are within inline ASM
C4398 'type': per-process global object might not work correctly with
multiple appdomains; consider using __declspec(appdomain)
C4430 missing type specifier - int assumed. Note: C++ does not
support default-int
C4461 'type': this class has a finalizer '!type' but no destructor '~type'
C4484 'type': matches base ref class method 'type', but is not marked
'virtual', 'new' or 'override'; 'new' (and not 'virtual') is assumed
C4485 'type': matches base ref class method 'type', but is not marked
'new' or 'override'; 'new' (and 'virtual') is assumed
C4727 PCH named name with same timestamp found in name and
name. Using first PCH.
C4734 More than 64k line numbers in a COFF debug info section;
stop emitting COFF debug line numbers for module 'module'
C4738 storing 32-bit float result in memory, possible loss of
performance
C4747 Calling managed 'type': Managed code may not be run under
loader lock, including the DLL entrypoint and calls reached
from the DLL entrypoint
C4835 'type': the initializer for exported data will not be run until
managed code is first executed in the host assembly
C4822 'type': local class member function does not have a body
C4823 'type': uses pinning pointers but unwind semantics are not
enabled. Consider using /EHa
C4913 user defined binary operator ',' exists but no overload could
convert all operands, default built-in binary operator ',' used
C4951 'description' has been edited since profile data was collected,
function profile data not used
C4953 Inlinee 'description' has been edited since profile data was
collected, profile data not used
C4199 description
C4256 'declaration': constructor for class with virtual bases has '...';
calls may not be compatible with older versions of Visual C++
C4258 'name': definition from the for loop is ignored; the definition
from the enclosing scope is used
C4265 'type': class has virtual functions, but destructor is not virtual
instances of this class may not be destructed correctly
C4562 fully prototyped functions are required with the '/clr' option:
converting '()' to '(void)'
C4685 expecting '> >' found '>>' when parsing template parameters
C4931 we are assuming the type library was built for number-bit
pointers
C4932 __identifier(description) and __identifier(description) are
indistinguishable
See also
/Wv compiler option
Compiler Warnings that are off by default
warning
Compiler Warnings C4000 Through C4199
3/14/2019 • 10 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the warning messages that are generated by
the compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Warning messages
WARNING MESSAGE
Help menu, or open the Technical Support help file for more
information
Compiler Warning (level 4) C4001 nonstandard extension 'single line comment' was used
Compiler warning (level 1) C4002 too many actual parameters for macro 'identifier'
Compiler Warning (level 1) C4003 not enough actual parameters for macro 'identifier'
Compiler Warning (level 3) C4013 'function' undefined; assuming extern returning int
Compiler Warning (level 1) C4015 'identifer': type of bit field must be integral
Compiler Warning (level 1) C4022 'function': pointer mismatch for actual parameter 'parameter
number'
Compiler warning (level 1) C4023 'function': based pointer passed to unprototyped function:
parameter 'parameter_number'
Compiler Warning (level 1) C4024 'function': different types for formal and actual parameter
'parameter_number'
Compiler warning (level 1) C4025 'function': based pointer passed to function with variable
arguments: parameter 'parameter_number'
Compiler warning (level 1) C4026 function declared with formal parameter list
Compiler warning (level 1) C4027 function declared without formal parameter list
Compiler Warning (level 1) C4029 declared formal parameter list different from definition
Compiler warning (level 1) C4030 first formal parameter list longer than the second list
Compiler Warning (level 1) C4031 second formal parameter list longer than the first list
Compiler Warning (level 4) C4032 formal parameter 'parameter_number' has different type when
promoted
Compiler Warning (level 1) C4047 'operator': 'identifier1' differs in levels of indirection from
'identifier2'
Compiler Warning (level 1) C4048 different array subscripts: 'identifier1' and 'identifier2'
Compiler Warning (level 1) C4049 compiler limit: terminating line number emission
Compiler warning (level 4) C4052 function declarations different; one contains variable
arguments
Compiler warning (level 1) C4055 'conversion' : from data pointer 'type1' to function pointer
'type2'
Compiler warning (level 4) C4057 'operator': 'identifier1' differs in indirection to slightly different
base types from 'identifier2'
Compiler Warning (level 4) C4061 enumerator 'identifier' in switch of enum 'enumeration' is not
explicitly handled by a case label
Compiler Warning (level 4) C4062 enumerator 'identifier' in switch of enum 'enumeration' is not
handled
Compiler warning C4063 case 'identifier' is not a valid value for switch of enum
'enumeration'
Compiler warning C4065 switch statement contains 'default' but no 'case' labels
Compiler warning (level 3) C4066 characters beyond first in wide-character constant ignored
Compiler Warning (level 1) C4067 unexpected tokens following preprocessor directive - expected
a newline
WARNING MESSAGE
Compiler Warning (level 1) C4074 initializers put in compiler reserved initialization area
Compiler warning (level 1) C4076 'type_modifier': can not be used with type 'typename'
Compiler warning (level 1) C4080 expected identifier for segment name; found 'symbol'
Compiler warning (level 1) C4086 expected pragma parameter to be '1', '2', '4', '8', or '16'
Compiler warning (level 1) C4087 'function': declared with 'void' parameter list
Compiler Warning (level 1) C4091 keyword': ignored on left of 'type' when no variable is declared
Compiler Warning (level 1) C4096 'identifier': interface is not a COM interface; will not be emitted
to IDL
Compiler Warning (level 2) C4099 'identifier': type name first seen using 'object_type1' now seen
using 'object_type2'
WARNING MESSAGE
Compiler Warning (level 1) C4103 'filename': alignment changed after including header, may be
due to missing #pragma pack(pop)
Compiler warning (level 1) C4112 #line requires an integer between 1 and 'line_count'
Compiler Warning (level 1) C4113 'identifier1' differs in parameter lists from 'identifier2'
Compiler Warning (level 1) C4114 same type qualifier used more than once
Compiler warning (level 1 and level 4) C4115 'type': named type definition in parentheses
Compiler warning (level 1) C4117 macro name 'name' is reserved, 'command' ignored
Compiler warning (level 1) C4119 different bases 'base1' and 'base2' specified
Compiler Warning (level 4) C4121 'symbol': alignment of a member was sensitive to packing
Compiler warning (level 1) C4122 'function': alloc_text applicable only to functions with C linkage
Compiler warning (level 4) C4125 decimal digit terminates octal escape sequence
Compiler warning (level 4) C4130 'operator': logical operation on address of string constant
Compiler Warning (level 3) C4133 'expression': incompatible types - from 'type1' to 'type2'
Compiler warning (level 1) C4143 pragma 'same_seg' not supported; use __based allocation
Compiler Warning (level 2) C4146 unary minus operator applied to unsigned type, result still
unsigned
Compiler Warning (level 2) C4150 deletion of pointer to incomplete type 'type'; no destructor
called
Compiler Warning (level 1) C4154 deletion of an array expression; conversion to pointer supplied
Compiler warning (level 1) C4155 deletion of an array expression without using the array form of
'delete'
Compiler Warning (level 2) C4156 deletion of an array expression without using the array form of
'delete'; array form substituted
Compiler Warning (level 3) C4159 #pragma 'pragma'(pop,...): has popped previously pushed
identifier 'identifier'
Compiler warning (level 1) C4160 #pragma 'pragma'(pop,...): did not find previously pushed
identifier 'identifier'
Compiler warning (level 3) C4161 #pragma 'pragma'(pop...): more pops than pushes
Compiler warning (level 1) C4165 'HRESULT' is being converted to 'bool'; are you sure this is
what you want?
Compiler warning (level 1) C4168 compiler limit: out of debugger types, delete program
database 'database' and rebuild
Compiler warning (level 1) C4175 #pragma component(browser, on): browser info must initially
be specified on the command line
Compiler warning (level 1) C4177 #pragma 'pragma' should only be used at global scope or
namespace scope
Compiler warning (level 1) C4178 case constant 'constant' too big for the type of the switch
expression
Compiler warning (level 4) C4179 '//*': parsed as '/' and '/*': confusion with standard '//'
comments
Compiler warning (level 1) C4180 qualifier applied to function type has no meaning; ignored
Compiler warning (level 1) C4182 #include nesting level is 'nest_count' deep; possible infinite
recursion
Compiler Warning (level 1) C4183 'identifier': missing return type; assumed to be a member
function returning 'int'
Compiler warning (level 1) C4187 #import attributes 'attribute1' and 'attribute2' are
incompatible; both ignored
Compiler warning (level 4) C4189 'identifier': local variable is initialized but not referenced
WARNING MESSAGE
Compiler Warning (level 1) C4190 'identifier1' has C-linkage specified, but returns UDT
'identifier2' which is incompatible with C
Compiler Warning (level 3) C4192 automatically excluding 'identifier' while importing type library
'library'
Compiler warning (level 1) C4195 #pragma stop_map_region used without matching #pragma
start_map_region; ignored
NOTE
This warning is removed in Visual Studio 2017 version 15.5 because single-line comments are standard in C99.
Single-line comments are standard in C++ and standard in C starting with C99. Under strict ANSI compatibility
(/Za), C files that contain single-line comments, generate C4001 due to the usage of a nonstandard extension.
Since single-line comments are standard in C++, C files containing single-line comments do not produce C4001
when compiling with Microsoft extensions (/Ze).
Example
To disable warning, uncomment #pragma warning(disable:4001).
// C4001.cpp
// compile with: /W4 /Za /TC
// #pragma warning(disable:4001)
int main()
{
// single-line comment in main
// C4001
}
Compiler Warning (level 1) C4002
10/31/2018 • 2 minutes to read • Edit Online
// C4002.cpp
// compile with: /W1
#define test(a) (a)
int main() {
int a = 1;
int b = 2;
a = test(a,b); // C4002
// try..
a = test(a);
}
This error can also be generated as a result of compiler conformance work that was done for Visual Studio .NET
2003: extra commas in macro no longer accepted.
The compiler will no longer accept extra commas in a macro. For code to be valid in both the Visual Studio .NET
2003 and Visual Studio .NET versions of Visual C++, remove the extra commas.
// C4002b.cpp
// compile with: /W1
#define F(x,y)
int main()
{
F(2,,,,,,3,,,,,,) // C4002
// Try the following line instead:
// F(2,3)
}
Compiler Warning (level 1) C4003
10/31/2018 • 2 minutes to read • Edit Online
// C4003.cpp
// compile with: /WX
#define test(a,b) (a+b)
int main()
{
int a = 1;
int b = 2;
a = test(b); // C4003
// try..
a = test(a,b);
}
Compiler Warning (level 1) C4005
10/31/2018 • 2 minutes to read • Edit Online
// C4005.cpp
// compile with: /W1 /EHsc
#include <iostream>
using namespace std;
int main() {
cout << TEST << endl;
}
Compiler Warning (level 1) C4006
10/31/2018 • 2 minutes to read • Edit Online
// C4006.cpp
// compile with: /W1
#undef // C4006
// try..
// #undef TEST
int main() {
}
Compiler Warning (level 2) C4007
10/31/2018 • 2 minutes to read • Edit Online
// C4010.cpp
// compile with: /WX
int main() {
// the next line is also a comment because of the backslash \
int a = 3; // C4010
a++;
}
Compiler Warning (level 3) C4013
10/31/2018 • 2 minutes to read • Edit Online
// C4018.cpp
// compile with: /W3
int main() {
unsigned int uc = 0;
int c = 0;
unsigned int c2 = 0;
// OK
if (uc == c2) uc = 0;
}
Compiler Warning (level 4) C4019
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4019.c
// compile with: /Za /W4
#define declint( varname ) int varname;
declint( a ); // C4019, int a;;
declint( b ) // OK, int b;
int main()
{
}
Compiler Warning (level 1) C4020
10/31/2018 • 2 minutes to read • Edit Online
// C4020.c
// compile with: /W1 /c
void f(int);
int main() {
f(1,2); // C4020
}
Possible resolution:
// C4020b.c
// compile with: /c
void f(int);
int main() {
f(1);
}
Compiler Warning (level 1) C4022
10/31/2018 • 2 minutes to read • Edit Online
'number' : based pointer passed to function with variable arguments: parameter number
Passing a based pointer to a function with variable arguments causes the pointer to be normalized, with
unpredictable results. Do not pass based pointers to functions with variable arguments.
Compiler Warning (level 1) C4026
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4028.
// C4028.c
// compile with: /W1 /Za
void f(int , ...);
void f(int i, int j) {} // C4028
int main() {}
Compiler Warning (level 1) C4029
3/12/2019 • 2 minutes to read • Edit Online
Example
// C4032.c
// compile with: /W4
void func();
void func(char); // C4032, char promotes to int
int main()
{
}
Compiler Warning (level 1) C4033
10/31/2018 • 2 minutes to read • Edit Online
// C4033.c
// compile with: /W1 /LD
int test_1(int x) // C4033 expected
{
if (x)
{
return; // C4033
}
}
Compiler Warning (level 1) C4034
10/31/2018 • 2 minutes to read • Edit Online
sizeof returns 0
The sizeof operator is applied to an operand of size zero (an empty structure, union, class, or enumerated type, or
type void ).
Compiler Warning (level 1) C4036
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4036.
// C4036.c
// compile with: /Zg /W1
// D9035 expected
typedef struct { int i; } T;
void f(T* t) {} // C4036
// OK
typedef struct MyStruct { int i; } T2;
void f2(T2 * t) {}
Compiler Warning (level 1) C4038
10/31/2018 • 2 minutes to read • Edit Online
// C4042.cpp
// compile with: /W1 /LD
int func2( __declspec( thread ) int tls_i ) // C4042
// try the following line instead
// int func2( int tls_i )
{
return tls_i;
}
Compiler Warning (level 1) C4045
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4047:
// C4047.c
// compile with: /W1
int main() {
char **p = 0; // two levels of indirection
char *q = 0; // one level of indirection
p = q; // C4047
p2 = q2;
}
Example
The following sample generates C4047:
// C4047b.c
// compile with: /W1
#include <stdio.h>
int main() {
int i;
FILE *myFile = NULL;
errno_t err = 0;
char file_name[256];
char *cs = 0;
// C4052.c
// compile with: /W4 /c
int f();
int f(int i, ...); // C4052
Compiler Warning (level 4) C4053
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Obsolete: This warning is not generated by Visual Studio 2017 and later versions.
A data pointer is cast (possibly incorrectly) to a function pointer. This is a level 1 warning under /Za and a level 4
warning under /Ze.
Example
The following sample generates C4055:
// C4055.c
// compile with: /Za /W1 /c
typedef int (*PFUNC)();
int *pi;
PFUNC f() {
return (PFUNC)pi; // C4055
}
// C4055b.c
// compile with: /W4 /c
typedef int (*PFUNC)();
int *pi;
PFUNC f() {
return (PFUNC)pi; // C4055
}
Compiler Warning (level 2) C4056
10/31/2018 • 2 minutes to read • Edit Online
// C4056.cpp
// compile with: /W2 /LD
#pragma warning (default : 4056)
float fp_val = 1.0e300 * 1.0e300; // C4056
Compiler Warning (level 4) C4057
10/31/2018 • 2 minutes to read • Edit Online
enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label
Example
The following sample generates C4061; add a case for the missing enumerator to fix:
// C4061.cpp
// compile with: /W4
#pragma warning(default : 4061)
enum E { a, b, c };
void func ( E e )
{
switch(e)
{
case a:
case b:
default:
break;
} // C4061 c' not handled
}
int main()
{
}
Compiler Warning (level 4) C4062
10/31/2018 • 2 minutes to read • Edit Online
// C4062.cpp
// compile with: /W4
#pragma warning(default : 4062)
enum E { a, b, c };
void func ( E e ) {
switch(e) {
case a:
case b:
break; // no default label
} // C4062, enumerate 'c' not handled
}
int main() {
}
Compiler Warning (level 3) C4066
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The compiler found and ignored extra characters following a preprocessor directive. This can be caused by any
unexpected characters, though a common cause is a stray semicolon after the directive. Comments do not cause
this warning. The /Za compiler option enables this warning for more preprocessor directives than the default
setting.
Example
// C4067a.cpp
// compile with: cl /EHsc /DX /W1 /Za C4067a.cpp
#include <iostream>
#include <string> s // C4067
#if defined(X); // C4067
std::string s{"X is defined"};
#else
std::string s{"X is not defined"};
#endif; // C4067 only under /Za
int main()
{
std::cout << s << std::endl;
}
To resolve this warning, delete the stray characters, or move them into a comment block. Certain C4067 warnings
may be disabled by removing the /Za compiler option.
// C4067b.cpp
// compile with: cl /EHsc /DX /W1 C4067b.cpp
#include <iostream>
#include <string>
#if defined(X)
std::string s{"X is defined"};
#else
std::string s{"X is not defined"};
#endif
int main()
{
std::cout << s << std::endl;
}
Compiler Warning (level 1) C4068
10/31/2018 • 2 minutes to read • Edit Online
unknown pragma
The compiler ignored an unrecognized pragma. Be sure the pragma is allowed by the compiler you are using. The
following sample generates C4068:
// C4068.cpp
// compile with: /W1
#pragma NotAValidPragmaName // C4068, use valid name to resolve
int main()
{
}
Compiler Warning (level 3) C4073
10/31/2018 • 2 minutes to read • Edit Online
// C4073.cpp
// compile with: /W3
#pragma init_seg(lib) // C4073
int main() {
}
Compiler Warning (level 1) C4074
10/31/2018 • 2 minutes to read • Edit Online
// C4074.cpp
// compile with: /W1
#pragma init_seg( compiler ) // C4074
int main() {
}
Compiler Warning (level 1) C4075
10/31/2018 • 2 minutes to read • Edit Online
// C4075.cpp
// compile with: /W1
#pragma init_seg("mysegg") // C4075
// try..
// #pragma init_seg(user)
int main() {
}
Compiler Warning (level 1) C4076
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A type modifier, whether it is signed or unsigned, cannot be used with a non-integer type. type modifier is
ignored.
Example
The following sample generates C4076; to fix it, remove the unsigned type modifier:
// C4076.cpp
// compile with: /W1 /LD
unsigned double x; // C4076
Compiler Warning (level 1) C4077
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4077.cpp
// compile with: /W1 /LD
#pragma check_stack yes // C4077
#pragma check_stack + // Correct old form
#pragma check_stack (on) // Correct new form
Compiler Warning (level 1) C4079
10/31/2018 • 2 minutes to read • Edit Online
// C4079.cpp
// compile with: /W1
#pragma warning(disable : 4081)
#pragma pack(c,16) // C4079
int main() {
}
Compiler Warning (level 1) C4080
10/31/2018 • 2 minutes to read • Edit Online
// C4080.cpp
// compile with: /W1
extern "C" void func(void);
int main() {
}
void func(void) {
}
Compiler Warning (level 1) C4081
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4081.cpp
// compile with: /W1 /LD
#pragma optimize) "l", on ) // C4081
Compiler Warning (level 1) C4083
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4083.cpp
// compile with: /W1 /LD
#pragma warning disable:4083 // C4083
#pragma warning(disable:4083) //correct
// C4085.cpp
// compile with: /W1 /LD
#pragma optimize( "t", maybe ) // C4085
Compiler Warning (level 1) C4086
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4086.cpp
// compile with: /W1 /LD
#pragma pack( 3 ) // C4086
Compiler Warning (level 1) C4087
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4087.c
// compile with: /W1
int f1( void ) {
}
int main() {
f1( 10 ); // C4087
}
Compiler Warning (level 1) C4088
10/31/2018 • 2 minutes to read • Edit Online
// C4090.c
// compile with: /W1
int *volatile *p;
int *const *q;
int **r;
int main() {
p = q; // C4090
p = r;
q = p; // C4090
q = r;
r = p; // C4090
r = q; // C4090
}
Compiler Warning (level 1) C4091
10/31/2018 • 2 minutes to read • Edit Online
Example
A __declspec attribute at the beginning of a user-defined type declaration applies to the variable of that type.
C4091 indicates no variable is declared. The following sample generates C4091.
// C4091.cpp
// compile with: /W1 /c
__declspec(dllimport) class X {}; // C4091
Example
If an identifier is a typedef, it cannot also be a variable name. The following sample generates C4091.
// C4091_b.cpp
// compile with: /c /W1 /WX
#define LIST 4
typedef struct _LIST {} LIST; // C4091
Compiler Warning (level 4) C4092
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4094.cpp
// compile with: /W2
struct
{
}; // C4094
int main()
{
}
// C4096.cpp
// compile with: /W1 /LD
#include "windows.h"
[module(name="xx")];
// [object, uuid("00000000-0000-0000-0000-000000000001")]
__interface a
{
};
[coclass, uuid("00000000-0000-0000-0000-000000000002")]
struct b : a
{
}; // C4096, remove coclass or uncomment object
Compiler Warning (level 1) C4097
10/31/2018 • 2 minutes to read • Edit Online
// C4097.cpp
// compile with: /W1
#pragma runtime_checks("",test) // C4097
// try the following line instead
// #pragma runtime_checks("",off)
int main() {
}
Compiler Warning (level 1) C4098
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : type name first seen using 'objecttype1' now seen using 'objecttype2'
An object declared as a structure is defined as a class, or an object declared as a class is defined as a structure. The
compiler uses the type given in the definition.
Example
The following sample generates C4099.
// C4099.cpp
// compile with: /W2 /c
struct A;
class A {}; // C4099, use different identifer or use same object type
Compiler Warning (level 4) C4100
10/31/2018 • 2 minutes to read • Edit Online
// C4100.cpp
// compile with: /W4
void func(int i) { // C4100, delete the unreferenced parameter to
//resolve the warning
// i; // or, add a reference like this
}
int main()
{
func(1);
}
Compiler Warning (level 3) C4101
10/31/2018 • 2 minutes to read • Edit Online
// C4101a.cpp
// compile with: /W3
int main() {
int i; // C4101
}
However, this warning will also occur when calling a static member function through an instance of the class:
// C4101b.cpp
// compile with: /W3
struct S {
static int func()
{
return 1;
}
};
int main() {
S si; // C4101, si is never used
int y = si.func();
return y;
}
In this situation, the compiler uses information about si to access the static function, but the instance of the class
is not needed to call the static function; hence the warning. To resolve this warning, you could:
Add a constructor, in which the compiler would use the instance of si in the call to func .
Remove the static keyword from the definition of func .
Call the static function explicitly: int y = S::func(); .
Compiler Warning (level 3) C4102
10/31/2018 • 2 minutes to read • Edit Online
// C4102.cpp
// compile with: /W3
int main() {
int a;
a = 1;
}
Compiler Warning (level 1) C4103
10/31/2018 • 2 minutes to read • Edit Online
'filename' : alignment changed after including header, may be due to missing #pragma pack(pop)
Packing affects the layout of classes, and commonly, if packing changes across header files, there can be problems.
Use #pragma pack(pop) before exiting the header file to resolve this warning.
The following sample generates C4103:
// C4103.h
#pragma pack(push, 4)
And then,
// C4103.cpp
// compile with: /LD /W1
#include "c4103.h" // C4103
Compiler Warning (level 1) C4109
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4109.cpp
// compile with: /W1 /LD
#pragma init_seg( abc ) // C4109
Compiler Warning (levels 1 and 4) C4112
10/31/2018 • 2 minutes to read • Edit Online
// C4112.cpp
// compile with: /W4
#line 0 // C4112, value must be between 1 and number
int main() {
}
Compiler Warning (level 1) C4113
10/31/2018 • 2 minutes to read • Edit Online
// C4114.cpp
// compile with: /W1 /c
volatile volatile int i; // C4114
// C4114_b.cpp
// compile with: /W1 /c
static const int const * ii; // C4114
static const int * const iii; // OK
Compiler Warning (levels 1 and 4) C4115
10/31/2018 • 2 minutes to read • Edit Online
// C4117.cpp
// compile with: /W1
#define __FILE__ test // C4117. __FILE__ is a predefined macro
#define ValidMacroName test // ok
int main() {
}
Compiler Warning (level 1) C4119
10/31/2018 • 2 minutes to read • Edit Online
based/unbased mismatch
The compiler cannot convert between the two pointers because one is based and the other is not.
Compiler Warning (level 4) C4121
10/31/2018 • 2 minutes to read • Edit Online
// C4121.cpp
// compile with: /W4 /c
#pragma pack(2)
struct s
{
char a;
int b; // C4121
long long c;
};
This warning only happens when the compiler adds padding before data members. It does not happen when
packing has placed data at a memory location that is not aligned for the data type, but no padding was placed
before the data member. When data is not aligned on boundaries that are multiples of the data's size, performance
can degrade. Reads and writes of unaligned data cause processor faults on some architectures and the faults may
take two or three orders of magnitude more time to resolve. Unaligned data accesses cannot be ported to some
RISC architectures.
You can use #pragma pack or /Zp to specify the structure alignment. (The compiler does not generate this warning
when /Zp1 is specified.)
Compiler Warning (level 1) C4122
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4125a.cpp
// compile with: /W4
char array1[] = "\709"; // C4125
int main()
{
}
// C4125b.cpp
// compile with: /W4
char array[] = "\0709"; // C4125 String containing "89"
int main()
{
}
Compiler Warning (level 4) C4127
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The controlling expression of an if statement or while loop evaluates to a constant. Because of their common
idiomatic usage, beginning in Visual Studio 2015 update 3, trivial constants such as 1 or true do not trigger the
warning, unless they are the result of an operation in an expression.
If the controlling expression of a while loop is a constant because the loop exits in the middle, consider replacing
the while loop with a for loop. You can omit the initialization, termination test and loop increment of a for loop,
which causes the loop to be infinite, just like while(1) , and you can exit the loop from the body of the for
statement.
Example
The following sample shows two ways C4127 is generated, and shows how to use a for loop to avoid the warning:
// C4127.cpp
// compile with: /W4
#include <stdio.h>
int main() {
if (true) {} // OK in VS2015 update 3 and later
if (1 == 1) {} // C4127
while (42) { break; } // C4127
// OK
for ( ; ; ) {
printf("test\n");
break;
}
}
Compiler Warning (level 1) C4129
10/31/2018 • 2 minutes to read • Edit Online
// C4129.cpp
// compile with: /W1
int main() {
char array1[] = "\/709"; // C4129
char array2[] = "\n709"; // OK
}
Compiler Warning (level 4) C4130
10/31/2018 • 2 minutes to read • Edit Online
// C4130.cpp
// compile with: /W4
int main()
{
char *pc;
pc = "Hello";
if (pc == "Hello") // C4130
{
}
}
The if statement compares the value stored in the pointer pc to the address of the string "Hello", which is
allocated separately each time the string occurs in code. The if statement does not compare the string pointed to by
pc with the string "Hello".
// C4131.c
// compile with: /W4 /c
void addrec( name, id ) // C4131 expected
char *name;
int id;
{ }
Example
// C4138a.cpp
// compile with: /W1
int */*comment*/ptr; // C4138 Ambiguous first delimiter causes warning
int main()
{
}
// C4138b.cpp
// compile with: /W1
#if 0
int my_variable; /* Declaration currently not needed */
#endif
int main()
{
}
Compiler Warning (level 1) C4141
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4141.cpp
// compile with: /W1 /LD
inline inline void func (); // C4141
Compiler Warning (level 1) C4142
10/31/2018 • 2 minutes to read • Edit Online
// C4142.c
// compile with: /W1
float X2;
X2 = 2.0 + 1.0; // C4142
int main() {
float X2;
X2 = 2.0 + 1.0; // OK
}
Compiler Warning (level 1) C4143
10/31/2018 • 2 minutes to read • Edit Online
// C4144.cpp
// compile with: /W1
int main()
{
int i = 0;
switch(!i) { // C4144, remove the ! to resolve
case 1:
break;
default:
break;
}
}
Compiler Warning (level 1) C4145
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4145:
// C4145.cpp
// compile with: /W1
int main() {
int i = 0;
switch(i == 1) { // C4145, use i instead of i == 1 to resolve
case 1:
break;
default:
break;
}
}
Compiler Warning (level 2) C4146
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4146:
// C4146.cpp
// compile with: /W2
#include <stdio.h>
void check(int i)
{
if (i > -2147483648) // C4146
printf_s("%d is greater than the most negative int\n", i);
}
int main()
{
check(-100);
check(1);
}
Compiler Warning (level 2) C4150
10/31/2018 • 2 minutes to read • Edit Online
// C4150.cpp
// compile with: /W2
class IncClass;
int main()
{
}
Compiler Warning (level 4) C4152
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4154.cpp
// compile with: /c /W1
int main() {
int array[ 10 ];
delete array; // C4154 can't delete stack object
Example
The following sample generates C4155:
// C4155.cpp
// compile with: /Za /W1
#include <stdio.h>
int main(void)
{
int (*array)[ 10 ] = new int[ 5 ] [ 10 ];
array[0][0] = 8;
printf_s("%d\n", array[0][0]);
deletion of an array expression without using the array form of 'delete'; array form substituted
The non-array form of delete cannot delete an array. The compiler translated delete to the array form.
This warning occurs only under Microsoft extensions (/Ze).
Example
// C4156.cpp
// compile with: /W2
int main()
{
int (*array)[ 10 ] = new int[ 5 ][ 10 ];
delete array; // C4156, changed by compiler to "delete [] array;"
}
Compiler Warning (level 1) C4157
10/31/2018 • 2 minutes to read • Edit Online
A #pragma pointers_to_members( single | multiple | virtual ) was issued without an accompanying #pragma
pointers_to_members(full_generality).
Compiler Warning (level 3) C4159
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Your source code contains a push instruction with an identifier for a pragma followed by a pop instruction without
an identifier. As a result, identifier is popped, and subsequent uses of identifier may cause unexpected behavior.
Example
To avoid this warning, give an identifier in the pop instruction. For example:
// C4159.cpp
// compile with: /W3
#pragma pack(push, f)
#pragma pack(pop) // C4159
int main()
{
}
Compiler Warning (level 1) C4160
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A pragma statement in your source code tries to pop an identifier that has not been pushed. To avoid this warning,
be sure that the identifier being popped has been properly pushed.
Example
The following example generates C4160 and shows how to fix it:
// C4160.cpp
// compile with: /W1
#pragma pack(push)
int main() {
}
Compiler Warning (level 3) C4161
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Because your source code contains one more pop than pushes for pragma pragma, the stack may not behave as
you expect. To avoid the warning, be sure that the number of pops does not exceed the number of pushes.
Example
The following example generates C4161:
// C4161.cpp
// compile with: /W3 /LD
#pragma pack(push, id)
#pragma pack(pop, id)
#pragma pack(pop, id) // C4161, an extra pop
#pragma bss_seg(".my_data1")
int j;
// C4162.cpp
// compile with: /c /W1
unsigned char _bittest(long* a, long b);
#pragma intrinsic (_bittest) // C4162
int main() {
bool bit;
long num = 78002;
bit = _bittest(&num, 5);
}
Possible resolution:
// C4162b.cpp
// compile with: /c
extern "C"
unsigned char _bittest(long* a, long b);
#pragma intrinsic (_bittest)
int main() {
bool bit;
long num = 78002;
bit = _bittest(&num, 5);
}
Compiler Warning (level 1) C4163
10/31/2018 • 2 minutes to read • Edit Online
// C4163.cpp
// compile with: /W1 /LD
#include <math.h>
#pragma intrinsic(mysin) // C4163
// try the following line instead
// #pragma intrinsic(sin)
Compiler Warning (level 1) C4164
10/31/2018 • 2 minutes to read • Edit Online
'HRESULT' is being converted to 'bool'; are you sure this is what you want?
When using an HRESULT in an if statement, the HRESULT will be converted to a bool unless you explicitly test for
the variable as an HRESULT. This warning is off by default.
Example
The following sample generates C4165
// C4165.cpp
// compile with: /W1
#include <windows.h>
#pragma warning(1:4165)
Example
// C4167.cpp
// compile with: /W1
#include <malloc.h>
#pragma function(_alloca ) // C4167: _alloca() is intrinsic only
int main(){}
Compiler Warning (level 1) C4168
10/31/2018 • 2 minutes to read • Edit Online
compiler limit : out of debugger types, delete program database 'database' and rebuild
The program database file must be rebuilt to accommodate all types in the program.
Compiler Warning (level 1) C4172
10/31/2018 • 2 minutes to read • Edit Online
// C4172.cpp
// compile with: /W1 /LD
float f = 10;
Example
// C4174.cpp
// compile with: /W1
#pragma component(info) // C4174; unknown
#pragma component(browser, off) // turn off browse info
int main()
{
}
Compiler Warning (level 1) C4175
10/31/2018 • 2 minutes to read • Edit Online
#pragma component(browser, on) : browser info must initially be specified on the command line
To use component pragma, you must generate browse information during compilation (/FR ).
Compiler Warning (level 1) C4176
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4176.cpp
// compile with: /W1 /LD
#pragma component(browser, off, i) // C4176
#pragma component(browser, off, references, i) // ok
Compiler Warning (level 1) C4177
10/31/2018 • 2 minutes to read • Edit Online
// C4177.cpp
// compile with: /W1
// #pragma bss_seg("global") // OK
int main() {
#pragma bss_seg("local") // C4177
}
Compiler Warning (level 1) C4178
10/31/2018 • 2 minutes to read • Edit Online
case constant 'constant' too big for the type of the switch expression
A case constant in a switch expression does not fit in the type to which it is assigned.
Example
// C4178.cpp
// compile with: /W1
int main()
{
int i; // maximum size of unsigned long int is 4294967295
switch( i )
{
case 4294967295: // OK
break;
case 4294967296: // C4178
break;
}
}
Compiler Warning (level 1) C4179
10/31/2018 • 2 minutes to read • Edit Online
'//*' : parsed as '/' and '/*': confusion with standard '//' comments
Example
// C4180.cpp
// compile with: /W1 /c
typedef int FuncType(void);
// C4183.cpp
// compile with: /W1 /c
#pragma warning(disable : 4430)
class MyClass1;
class MyClass2 {
MyClass1() {}; // C4183
};
Compiler Warning (level 1) C4185
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4185.cpp
// compile with: /W1 /c
#import "stdole2.tlb" no_such_attribute // C4185
Compiler Warning (level 1) C4186
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4186.cpp
// compile with: /W1 /c
#import "stdole2.tlb" no_namespace("abc") rename("a","b","c") // C4186
The no_namespace attribute takes no arguments. The rename attribute takes only two arguments.
Compiler Warning (level 1) C4187
10/31/2018 • 2 minutes to read • Edit Online
// C4189.cpp
// compile with: /W4
int main() {
int a = 1; // C4189, remove declaration to resolve
}
Compiler Warning (level 1) C4190
10/31/2018 • 2 minutes to read • Edit Online
'identifier1' has C -linkage specified, but returns UDT 'identifier2' which is incompatible with C
A function or pointer to function has a UDT (user-defined type, which is a class, structure, enum, or union) as
return type and extern "C" linkage. This is legal if:
All calls to this function occur from C++.
The definition of the function is in C++.
Example
// C4190.cpp
// compile with: /W1 /LD
struct X
{
int i;
X ();
virtual ~X ();
};
// C4191.cpp
// compile with: /W3 /clr
#pragma warning(default: 4191)
int main() {
fnptr1 fp1 = static_cast<fnptr1>(&f1);
fnptr2 fp2 = (fnptr2) &f2;
// C4197.cpp
// compile with: /W3
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sigproc(int);
struct S
{
int i;
} s;
int main()
{
signal(SIGINT, sigproc);
s.i = 1;
S *pS = &s;
for ( ; (volatile int)pS->i ; ) // C4197
break;
// for ( ; *(volatile int *)&pS->i ; ) // OK
// break;
}
The articles in this section of the documentation explain a subset of the warning messages that are generated by
the compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Warning messages
WARNING MESSAGE
Compiler Warning (levels 2 and 4) C4200 nonstandard extension used: zero-sized array in struct/union
Compiler Warning (level 4) C4202 nonstandard extension used: '...': prototype parameter in name
list illegal
Compiler warning C4203 nonstandard extension used: union with static member
variable
Compiler Warning (level 4) C4205 nonstandard extension used: static function declaration in
function scope
Compiler Warning (level 4) C4206 nonstandard extension used: translation unit is empty
Compiler Warning (level 4) C4207 nonstandard extension used: extended initializer form
Compiler Warning (level 4) C4208 nonstandard extension used: delete [exp] - exp evaluated but
ignored
Compiler Warning (level 4) C4210 nonstandard extension used: function given file scope
Compiler Warning (level 4) C4211 nonstandard extension used: redefined extern to static
Compiler Warning (level 4) C4212 nonstandard extension used: function declaration used ellipsis
Compiler Warning (level 4) C4214 nonstandard extension used: bit field types other than int
Compiler Warning (level 1) C4218 nonstandard extension used: must specify at least a storage
class or a type
Compiler Warning (level 4) C4221 nonstandard extension used: 'identifier': cannot be initialized
using address of automatic variable 'variable'
Compiler Warning (levels 1 and 4) C4223 nonstandard extension used: non-lvalue array converted to
pointer
Compiler Warning (level 1) C4224 nonstandard extension used: formal parameter 'identifier' was
previously defined as a type
Compiler Warning (level 1, Error) C4226 nonstandard extension used: 'keyword' is an obsolete keyword
Compiler Warning (level 1) C4227 anachronism used: qualifiers on reference are ignored
Compiler Warning (level 1) C4228 nonstandard extension used: qualifiers after comma in
declarator list are ignored
Compiler Warning (level 1) C4229 anachronism used: modifiers on data are ignored
Compiler Warning (level 4) C4232 nonstandard extension used: 'identifier': address of dllimport
'dllimport' is not static, identity not guaranteed
WARNING MESSAGE
Compiler Warning (level 4, Error) C4233 nonstandard extension used: 'keyword' keyword only
supported in C++, not C
Compiler Warning (level 4, Error) C4234 nonstandard extension used: 'keyword' keyword reserved for
future use
Compiler Warning (level 4, Error) C4235 nonstandard extension used: 'keyword' keyword not
supported on this architecture
Compiler Warning (level 1) C4237 'keyword' keyword is not yet supported, but reserved for
future use
Compiler Warning (level 4) C4238 nonstandard extension used: class rvalue used as lvalue
Compiler Warning (level 4) C4239 nonstandard extension used: 'token': conversion from 'type1'
to 'type2'
Compiler Warning (level 3) C4240 nonstandard extension used: access to 'classname' now
defined to be 'access_specifier1', previously it was defined to
be 'access_specifier2'
Compiler Warning (level 4) C4242 'identifier': conversion from 'type1' to 'type2', possible loss of
data
Compiler Warning (level 3) C4243 'conversion_type' conversion from 'type1' to 'type2' exists, but
is inaccessible
Compiler Warning (level 2) C4244 'conversion_type': conversion from 'type1' to 'type2', possible
loss of data
Compiler Warning (levels 3 and 4) C4244 'conversion_type': conversion from 'type1' to 'type2', possible
loss of data
Compiler Warning (level 1) C4251 'identifier': 'object_type1' 'identifier1' needs to have dll-
interface to be used by clients of 'object_type' 'identfier2'
Compiler Warning (level 4) C4255 'function': no function prototype given: converting '()' to
'(void)'
Compiler Warning (level 4) C4256 'function': constructor for class with virtual bases has '...'; calls
may not be compatible with older versions of Visual C++
Compiler Warning (level 1) C4258 'variable': definition from the for loop is ignored; the definition
from the enclosing scope is used
WARNING MESSAGE
Compiler Warning (level 4) C4263 'function': member function does not override any base class
virtual member function
Compiler Warning (level 1) C4264 'virtual_function': no override available for virtual member
function from base 'classname'; function is hidden
Compiler Warning (level 3) C4265 'classname': class has virtual functions, but destructor is not
virtual\n instances of this class may not be destructed
correctly
Compiler Warning (level 4) C4266 'virtual_function': no override available for virtual member
function from base 'classname'; function is hidden
Compiler Warning (level 3) C4267 'variable': conversion from 'size_t' to 'type', possible loss of
data
Compiler Warning (level 4) C4268 'identifier': 'const' static/global data initialized with compiler
generated default constructor fills the object with zeros
Compiler Warning (level 1) C4269 'identifier': 'const' automatic data initialized with compiler
generated default constructor produces unreliable results
Compiler Warning (level 1) C4272 'function': is marked __declspec(dllimport); must specify native
calling convention when importing a function.
Compiler warning (level 1) C4274 #ident ignored; see documentation for #pragma
comment(exestr, 'string')
Compiler Warning (level 2) C4275 non dll-interface 'classkey' 'identifier1' used as base for dll-
interface 'classkey' 'identifier2'
Compiler warning (level 1) C4277 imported item 'classname::member' exists as both data
member and function member; data member ignored
Compiler Warning (level 3) C4278 'identifier': identifier in type library 'library' is already a macro;
use the 'rename' qualifier
Compiler warning (level 3 and level 4) C4279 'identifier': identifier in type library 'library' is a keyword; use
the 'rename' qualifier
Compiler Warning (level 3) C4280 'operator ->' was self recursive through type 'type'
Compiler Warning (level 3) C4281 'operator ->' recursion occurred through type 'type1'
Compiler Warning (level 2) C4285 return type for 'identifier::operator ->' is recursive if applied
using infix notation
Compiler Warning (level 1) C4286 'derived_type': is caught by base class ('base_type') on line
'line_number'
Compiler Warning (level 1) C4288 nonstandard extension used: 'variable': loop control variable
declared in the for-loop is used outside the for-loop scope; it
conflicts with the declaration in the outer scope
Compiler Warning (level 4) C4289 nonstandard extension used: 'variable': loop control variable
declared in the for-loop is used outside the for-loop scope
Compiler Warning (level 3) C4290 C++ exception specification ignored except to indicate a
function is not __declspec(nothrow)
Compiler Warning (level 1) C4291 'declaration': no matching operator delete found; memory will
not be freed if initialization throws an exception
Compiler Warning (level 1) C4293 'shift_operator': shift count negative or too big, undefined
behavior
Compiler Warning (level 4) C4295 'array': array is too small to include a terminating null
character
Compiler Warning (level 1) C4297 'function': function assumed not to throw an exception but
does
Compiler warning (level 4) C4298 'identifier': identifier in type library 'library' is already a macro;
renaming to '__identifier'
Compiler warning (level 4) C4299 'identifier': identifier in type library 'library' is a keyword;
renaming to '__identifier'
Compiler warning C4303 C-style cast from 'type1' to 'type2' is deprecated, use
static_cast, __try_cast or dynamic_cast
Compiler Warning (level 3) C4306 'conversion': conversion from 'type1' to 'type2' of greater size
Compiler Warning (level 2) C4308 negative integral constant converted to unsigned type
WARNING MESSAGE
Compiler Warning (level 1) C4311 'variable': pointer truncation from 'type1' to 'type2'
Compiler Warning (level 1) C4312 'operation': conversion from 'type1' to 'type2' of greater size
Compiler Warning (level 1) C4313 'function': 'format_specifier' in format string conflicts with
argument 'argument_number' of type 'type'
Compiler warning (level 4) C4315 'classname': 'this' pointer for member 'member' may not be
aligned 'alignment' as expected by the constructor
Compiler warning (level 3) C4316 'identifier': object allocated on the heap may not be aligned
'alignment'
Compiler warning (level 1) C4317 'printf_family' : not enough arguments passed for format
string
Compiler Warning (level 1) C4319 'operator': zero extending 'type1' to 'type2' of greater size
Compiler warning (level 1) C4321 automatically generating an IID for interface 'interface'
Compiler warning (level 1) C4322 automatically generating a CLSID for class 'class'
Compiler warning (level 1) C4323 re-using registered CLSID for class 'class'
Compiler Warning (level 4) C4324 'structname': structure was padded due to __declspec(align())
Compiler Warning (level 1) C4325 attributes for standard section 'section' ignored
Compiler Warning (level 1) C4326 return type of 'function' should be 'type1' instead of 'type2'
Compiler warning (level 1) C4330 attribute 'attribute' for section 'section' ignored
Compiler Warning (level 1) C4333 'shift_operator': right shift by too large amount, data loss
WARNING MESSAGE
Compiler Warning (level 3) C4334 'shift_operator': result of 32-bit shift implicitly converted to 64
bits (was 64-bit shift intended?)
Compiler Warning C4335 Mac file format detected: please convert the source file to
either DOS or UNIX format
Compiler Warning (level 4) C4336 import cross-referenced type library 'library1' before
importing 'library2'
Compiler Warning (level 4) C4337 cross-referenced type library 'library1' in 'library2' is being
automatically imported
Compiler warning (level 4) C4338 #pragma directive: standard section 'section' is used
Compiler Warning (level 4) C4339 'type': use of undefined type detected in 'WinRT|CLR' meta-
data - use of this type may lead to a runtime exception
Compiler Warning (level 1) C4340 'value': value wrapped from positive to negative value
Compiler Warning (level 1) C4342 behavior change: 'function' called, but a member operator was
called in previous versions
Compiler Warning (level 1) C4344 behavior change: use of explicit template arguments results in
call to 'function'
Compiler Warning (level 1) C4350 behavior change: 'member1' called instead of 'member2'
Compiler Warning C4355Compiler warning (level 1 and level 'this': used in base member initializer list
4) C4355
Compiler Warning (level 2) C4356 'member': static data member cannot be initialized via derived
class
Compiler Warning (level 3) C4357 param array argument found in formal argument list for
delegate 'delegate' ignored when generating 'function'
Compiler Warning (level 1) C4358 'operator': return type of combined delegates is not 'void';
returned value is undefined
Compiler Warning (level 3) C4359 'type': Alignment specifier is less than actual alignment
('alignment'), and will be ignored.
WARNING MESSAGE
Compiler warning (level 2) C4362 'type': alignment greater than 8 bytes is not supported by CLR
Compiler Warning (level 1) C4364 #using for assembly 'assembly' previously seen at
'location'('line_number') without as_friend attribute; as_friend
not applied
Compiler Warning (level 4) C4366 The result of the unary 'operator' operator may be unaligned
Compiler warning (level 3) C4367 Conversion from 'type1' to 'type2' may cause datatype
misalignment exception
Compiler Warning (Error) C4368 cannot define 'member' as a member of managed 'type':
mixed types are not supported
Compiler Warning (level 1) C4369 'enumerator': enumerator value 'value' cannot be represented
as 'type', value is 'new_value'
Compiler warning C4370 'classname': layout of class has changed from a previous
version of the compiler due to better packing
Compiler warning (level 3) C4371 'classname': layout of class may have changed from a previous
version of the compiler due to better packing of member
'member'
Compiler Warning (level 1) C4374 'function1': interface method will not be implemented by non-
virtual method 'function2'
Compiler Warning (level 1) C4375 non-public method 'method2' does not override 'method2'
Compiler Warning (level 1) C4376 access specifier 'old_specifier:' is no longer supported: please
use 'new_specifier:' instead
Compiler Warning (level 1) C4377 native types are private by default; -d1PrivateNativeTypes is
deprecated
Compiler Warning (level 1) C4378 Must obtain function pointers to run initializers; consider
System::ModuleHandle::ResolveMethodHandle
Compiler Warning (level 1) C4379 Version 'version_number' of the common language runtime is
not supported by this compiler. Using this version may cause
unexpected results
Compiler warning (level 1, Error) C4380 'class': A default constructor cannot be deprecated
Compiler Warning (level 1) C4381 'function1': interface method will not be implemented by non-
public method 'function2'
WARNING MESSAGE
Compiler Warning (level 1) C4382 throwing 'type': a type with __clrcall destructor or copy
constructor can only be caught in /clr:pure module
Compiler Warning (level 1) C4384 #pragma 'make_public' should only be used at global scope
Compiler Warning (level 3) C4390 ';': empty controlled statement found; is this the intent?
Compiler Warning (level 1) C4391 'function_signature': incorrect return type for intrinsic
function, expected 'type'
Compiler Warning (level 1) C4393 'variable': const has no effect on 'literal' data member;
ignored
Compiler Warning C4394 'function': per-appdomain symbol should not be marked with
__declspec('dllexport')
Compiler Warning (level 1) C4395 'function': member function will be invoked on a copy of the
initonly data member 'member'
Compiler warning (level 2) C4396 'function': the inline specifier cannot be used when a friend
declaration refers to a specialization of a function template
Compiler Warning (level 3) C4398 'variable': per-process global object might not work correctly
with multiple appdomains; consider using
__declspec(appdomain)
Compiler Warning (level 1) C4399 'symbol': per-process symbol should not be marked with
__declspec('dllimport') when compiled with /clr:pure
Compiler Warning (levels 2 and 4) C4200
10/31/2018 • 2 minutes to read • Edit Online
// C4200.cpp
// compile by using: cl /W4 c4200.cpp
struct A {
int a[0]; // C4200
};
int main() {
}
This non-standard extension is often used to interface code with external data structures that have a variable
length. If this scenario applies to your code, you can disable the warning:
Example
// C4200b.cpp
// compile by using: cl /W4 c4200a.cpp
#pragma warning(disable : 4200)
struct A {
int a[0];
};
int main() {
}
Compiler Warning (level 4) C4201
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4201.cpp
// compile with: /W4
struct S
{
float y;
struct
{
int a, b, c; // C4201
};
} *p_s;
int main()
{
}
Compiler Warning (level 4) C4202
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4202.c
// compile with: /W4
void func( a, b, ...) // C4202
int a, b;
{}
int main()
{
}
Compiler Warning (level 4) C4204
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4204.c
// compile with: /W4
int func1()
{
return 0;
}
struct S1
{
int i;
};
int main()
{
struct S1 s1 = { func1() }; // C4204
return s1.i;
}
Example
// C4205.c
// compile with: /W4
void func1()
{
static int func2(); // C4205
};
int main()
{
}
Example
// C4207.c
// compile with: /W4
char c[] = { 'a', 'b', "cdefg" }; // C4207
int main()
{
}
// C4208.cpp
// compile with: /W4
int main()
{
int * MyArray = new int[18];
delete [18] MyArray; // C4208
MyArray = new int[18];
delete [] MyArray; // ok
}
// C4210.c
// compile with: /W4 /c
void func1()
{
extern int func2( double ); // C4210 expected
}
int main()
{
func2( 4 ); // /Ze passes 4 as type double
} // /Za passes 4 as type int
This extension can prevent your code from being portable to other compilers.
Compiler Warning (level 4) C4211
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4211.c
// compile with: /W4
extern int i;
static int i; // C4211
int main()
{
}
See Also
Compiler Warning (level 4) C4212
10/31/2018 • 2 minutes to read • Edit Online
// C4212.c
// compile with: /W4 /Ze /c
void f(int , ...);
void f(int i, int j) {}
Compiler Warning (level 4) C4213
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4213.c
// compile with: /W4
void *a;
void f()
{
int i[3];
a = &i;
*(( int * )a )++ = 3; // C4213
}
int main()
{
}
Example
// C4214.c
// compile with: /W4
struct bitfields
{
unsigned short j:4; // C4214
};
int main()
{
}
// C4215.cpp
// compile with: /W1 /LD
long float a; // C4215
// C4216.cpp
// compile with: /W1
float long a; // C4216
int main() {
}
Compiler Warning (level 1) C4218
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4218.c
// compile with: /W4
i; // C4218
int main()
{
}
Example
// C4220.c
// compile with: /W4
int main()
{
if ( pFunc1 != pFunc2 ) {}; // C4220
}
nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable
With the default Microsoft extensions (/Ze), you can initialize an aggregate type (array, struct , or union) with the
address of a local (automatic) variable.
Example
// C4221.c
// compile with: /W4
struct S
{
int *i;
};
void func()
{
int j;
struct S s1 = { &j }; // C4221
}
int main()
{
}
nonstandard extension used : formal parameter 'identifier' was previously defined as a type
The identifier was previously used as a typedef . This causes a warning under ANSI compatibility (/Za).
Example
// C4224.cpp
// compile with: /Za /W1 /LD
typedef int I;
void func ( int I ); // C4224
Compiler Warning (level 1) C4226
10/31/2018 • 2 minutes to read • Edit Online
The current version of Visual C++ does not use this keyword.
This warning is automatically promoted to an error.
Compiler Warning (level 1) C4227
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4227.cpp
// compile with: /W1 /c
int j = 0;
int &const i = j; // C4227
Compiler Warning (level 1) C4228
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used : qualifiers after comma in declarator list are ignored
Use of qualifiers like const or volatile after a comma when declaring variables is a Microsoft extension (/Ze).
Example
// C4228.cpp
// compile with: /W1
int j, const i = 0; // C4228
int k;
int const m = 0; // ok
int main()
{
}
Compiler Warning (level 1) C4229
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4229.cpp
// compile with: /W1 /LD
int __cdecl counter; // C4229 cdecl ignored
Compiler Warning (level 1) C4230
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4230.cpp
// compile with: /W1 /LD
int __cdecl const function1(); // C4230 const ignored
Compiler Warning (level 4) C4232
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used : 'identifier' : address of dllimport 'dllimport' is not static, identity not guaranteed
Under Microsoft extensions (/Ze), you can give a nonstatic value as the address of a function declared with the
dllimport modifier. Under ANSI compatibility (/Za), this causes an error.
The following sample generates C4232:
// C4232.c
// compile with: /W4 /Ze /c
int __declspec(dllimport) f();
int (*pfunc)() = &f; // C4232
Compiler Warning (level 4) C4233
10/31/2018 • 2 minutes to read • Edit Online
The compiler compiled your source code as C rather than C++, and you used a keyword that is only valid in C++.
The compiler compiles your source file as C if the extension of the source file is .c or you use /Tc.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning. For
example, to make C4233 into a level 4 warning issue, add this line to your source code file:
#pragma warning(4:4233)
Compiler Warning (level 4) C4234
10/31/2018 • 2 minutes to read • Edit Online
#pragma warning(2:4234)
#pragma warning(2:4235)
'keyword' keyword is not yet supported, but reserved for future use
A keyword in the C++ specification is not implemented in the Visual C++ compiler, but the keyword is not
available as a user-defined symbol.
The following sample generates C4237:
// C4237.cpp
// compile with: /W1 /c
int export; // C4237
Compiler Warning (level 4) C4238
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4238.cpp
// compile with: /W4 /c
struct C {
C() {}
};
C * pC = &C(); // C4238
Example
The following sample generates C4239.
// C4239.cpp
// compile with: /W4 /c
struct C {
C() {}
};
void func(void) {
C & rC = C(); // C4239
const C & rC2 = C(); // OK
rC2;
}
Example
Conversion from integral type to enum type is not strictly allowed.
The following sample generates C4239.
// C4239b.cpp
// compile with: /W4 /c
enum E { value };
struct S {
E e : 2;
} s = { 5 }; // C4239
// try the following line instead
// } s = { (E)5 };
Compiler Warning (level 3) C4240
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used : access to 'classname' now defined to be 'access specifier', previously it was defined to
be 'access specifier'
Under ANSI compatibility (/Za), you cannot change the access to a nested class. Under the default Microsoft
extensions (/Ze), you can, with this warning.
Example
// C4240.cpp
// compile with: /W3
class X
{
private:
class N;
public:
class N
{ // C4240
};
};
int main()
{
}
Compiler Warning (level 4) C4242
10/31/2018 • 2 minutes to read • Edit Online
// C4242.cpp
// compile with: /W4
#pragma warning(4:4242)
int func() {
return 0;
}
int main() {
char a;
a = func(); // C4242, return type and variable type do not match
}
Compiler Warning (level 3) C4243
10/31/2018 • 2 minutes to read • Edit Online
// C4243.cpp
// compile with: /W3
// C4243 expected
struct B {
int f() {
return 0;
};
};
int main() {
// Delete the following 2 lines to resolve.
int (D::* d)() = (int(D::*)()) &B::f;
d;
Example
The following sample generates C4244:
// C4244_level2.cpp
// compile with: /W2
// C4244_level4.cpp
// compile with: /W4
int aa;
unsigned short bb;
int main() {
int b = 0, c = 0;
short a = b + c; // C4244
bb += c; // C4244
bb = bb + c; // C4244
bb += (unsigned short)aa; // C4244
bb = bb + (unsigned short)aa; // OK
}
// C4244_level3.cpp
// compile with: /W3
int main() {
__int64 i = 8;
unsigned int ii = i; // C4244
}
Warning C4244 can occur when building code for 64-bit targets that does not generate the warning when building
for 32-bit targets. For example, a difference between pointers is a 32-bit quantity on 32-bit platforms, but a 64-bit
quantity on 64-bit platforms.
The following sample generates C4244 when compiled for 64-bit targets:
// C4244_level3_b.cpp
// compile with: /W3
int main() {
char* p1 = 0;
char* p2 = 0;
int x = p2 - p1; // C4244
}
Compiler Warning (level 4) C4245
10/31/2018 • 2 minutes to read • Edit Online
// C4245.cpp
// compile with: /W4 /c
const int i = -1;
unsigned int j = i; // C4245
const int k = 1;
unsigned int l = k; // okay
int m = -1;
unsigned int n = m; // okay
void Test(size_t i) {}
int main() {
Test( -19 ); // C4245
}
Compiler Warning (level 2) C4250
10/31/2018 • 2 minutes to read • Edit Online
// C4250.cpp
// compile with: /c /W2
#include <stdio.h>
struct vbc {
virtual void func() { printf("vbc::func\n"); }
};
int main() {
diamond d;
d.func(); // C4250
}
Example
The following sample generates C4250.
// C4250_b.cpp
// compile with: /W2 /EHsc
#include <iostream>
using namespace std;
class A {
public:
virtual operator int () {
return 2;
}
};
int main() {
E eObject;
cout << eObject.operator int() << endl;
}
Example
This sample shows a more complex situation. The following sample generates C4250.
// C4250_c.cpp
// compile with: /W2 /EHsc
#include <iostream>
using namespace std;
class V {
public:
virtual int f() {
return 1024;
}
};
int main() {
D d;
cout << "value is: " << d.b(); // invokes M::f()
}
Compiler Warning (level 1) C4251
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
To minimize the possibility of data corruption when exporting a class with __declspec(dllexport), ensure that:
All your static data is access through functions that are exported from the DLL.
No inlined methods of your class can modify static data.
No inlined methods of your class use CRT functions or other library functions use static data (see Potential
Errors Passing CRT Objects Across DLL Boundaries for more information).
No methods of your class (regardless of inlining) can use types where the instantiation in the EXE and DLL
have static data differences.
You can avoid exporting classes by defining a DLL that defines a class with virtual functions, and functions you can
call to instantiate and delete objects of the type. You can then just call virtual functions on the type.
C4251 can be ignored if you are deriving from a type in the C++ Standard Library, compiling a debug release
(/MTd) and where the compiler error message refers to _Container_base.
// C4251.cpp
// compile with: /EHsc /MTd /W2 /c
#include <vector>
using namespace std;
class Node;
class __declspec(dllimport) VecWrapper : vector<Node *> {}; // C4251
Compiler Warning (level 4) C4254
10/31/2018 • 2 minutes to read • Edit Online
// C4254.cpp
// compile with: /W4
#pragma warning(default: 4254)
struct X {
int a : 20;
int b : 12;
};
int main() {
X *x = new X();
x->b = 10;
x->a = 4;
x->a = x->b; // OK
x->b = x->a; // C4254
};
Compiler Warning (level 4) C4255
10/31/2018 • 2 minutes to read • Edit Online
// C4255.c
// compile with: /W4 /WX
#pragma warning (default : 4255)
'function' : constructor for class with virtual bases has '...'; calls may not be compatible with older versions of Visual
C++
Possible incompatibility.
Consider the following code example. If the definition of the constructor S2::S2( int i, ... ) was compiled by using a
version of the Visual C++ compiler before version 7, but the following example is compiled by using the current
version, the call to the constructor for S3 would not work correctly because of a special-case calling-convention
change. If both were compiled by using Visual C++ 6.0, the call would not work quite right either, unless no
parameters were passed for the ellipsis.
To fix this warning,
1. Don't use ellipsis in a constructor.
2. Make sure that all components in their project are built with the current version (including any libraries that
may define or reference this class), then disable the warning using the warning pragma.
The following sample generates C4256:
// C4256.cpp
// compile with: /W4
// #pragma warning(disable : 4256)
struct S1
{
};
void func1()
{
S2 S3( 2, 1, 2 ); // C4256
// try the following line instead
// S2 S3( 2 );
}
int main()
{
}
Compiler Warning (level 1) C4258
10/31/2018 • 2 minutes to read • Edit Online
'variable' : definition from the for loop is ignored; the definition from the enclosing scope is used"
Under /Ze and /Zc:forScope, variables defined in a for loop go out of scope after the for loop ends. This warning
occurs if a variable with the same name as the loop variable, but defined in the enclosing loop, is used again in the
scope containing the for loop. For example:
// C4258.cpp
// compile with: /Zc:forScope /W1
int main()
{
int i;
{
for (int i =0; i < 1; i++)
;
i = 20; // C4258 i (in for loop) has gone out of scope
}
}
Compiler Warning (level 4) C4263
10/31/2018 • 2 minutes to read • Edit Online
'function' : member function does not override any base class virtual member function
A class function definition has the same name as a virtual function in a base class but not the same number or type
of arguments. This effectively hides the virtual function in the base class.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4263:
// C4263.cpp
// compile with: /W4
#pragma warning(default:4263)
#pragma warning(default:4264)
class B {
public:
virtual void func();
};
class D : public B {
void func(int); // C4263
};
int main() {
}
Compiler Warning (level 1) C4264
10/31/2018 • 2 minutes to read • Edit Online
'virtual_function' : no override available for virtual member function from base 'class'; function is hidden
C4264 is always generated after C4263.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Compiler Warning (level 3) C4265
10/31/2018 • 2 minutes to read • Edit Online
// C4265.cpp
// compile with: /W3 /c
#pragma warning(default : 4265)
class B
{
public:
virtual void vmf();
~B();
// try the following line instead
// virtual ~B();
}; // C4265
int main()
{
B b;
}
Compiler Warning (level 4) C4266
10/31/2018 • 2 minutes to read • Edit Online
'function' : no override available for virtual member function from base 'type'; function is hidden
A derived class did not override all overloads of a virtual function.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4266:
// C4266.cpp
// compile with: /W4 /c
#pragma warning (default : 4266)
class Engine {
public:
virtual void OnException(int&,int);
virtual void OnException(int&,int&,int);
};
Possible resolution:
// C4266b.cpp
// compile with: /W4 /c
#pragma warning (default : 4266)
class Engine {
public:
virtual void OnException(int&,int);
virtual void OnException(int&,int&,int);
};
Example
The following example generates C4267.
// C4267.cpp
// compile by using: cl /W4 C4267.cpp
void Func1(short) {}
void Func2(int) {}
void Func3(long) {}
void Func4(size_t) {}
int main() {
size_t bufferSize = 10;
Func1(bufferSize); // C4267 for all platforms
Func2(bufferSize); // C4267 only for 64-bit platforms
Func3(bufferSize); // C4267 only for 64-bit platforms
Func4(bufferSize); // OK for all platforms
}
Compiler Warning (level 4) C4268
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : 'const' static/global data initialized with compiler generated default constructor fills the object with
zeros
A const global or static instance of a non-trivial class is initialized with a compiler-generated default constructor.
Example
// C4268.cpp
// compile with: /c /LD /W4
class X {
public:
int m_data;
};
As this instance of the class is const, the value of m_data cannot be changed.
Compiler Warning (level 1) C4269
10/31/2018 • 2 minutes to read • Edit Online
'identifier' : 'const' automatic data initialized with compiler generated default constructor produces unreliable
results
A const automatic instance of a non-trivial class is initialized with a compiler-generated default constructor.
Example
// C4269.cpp
// compile with: /c /LD /W1
class X {
public:
int m_data;
};
void g() {
const X x1; // C4269
};
Since this instance of the class is generated on the stack, the initial value of m_data can be anything. Also, since it
is a const instance, the value of m_data can never be changed.
Compiler Warning (level 1) C4272
10/31/2018 • 2 minutes to read • Edit Online
'function' : is marked __declspec(dllimport); must specify native calling convention when importing a function.
It is an error to export a function marked with the __clrcall calling convention, and the compiler issues this warning
if you attempt to import a function marked __clrcall .
The following sample generates C4272:
// C4272.cpp
// compile with: /c /W1 /clr
__declspec(dllimport) void __clrcall Test(); // C4272
__declspec(dllimport) void Test2(); // OK
Compiler Warning (level 1) C4273
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4273.
// C4273.cpp
// compile with: /W1 /c
char __declspec(dllimport) c;
char c; // C4273, delete this line or the line above to resolve
Example
The following sample generates C4273.
// C4273_b.cpp
// compile with: /W1 /clr /c
#include <stdio.h>
extern "C" int printf_s(const char *, ...); // C4273
Compiler Warning (level 1) C4274
10/31/2018 • 2 minutes to read • Edit Online
Warning C4274 advises you to use the #pragma comment(exestr, 'string') directive. However, this advice is
deprecated and will be revised in a future release of the compiler. If you use the #pragma directive, the linker tool
(LINK.exe) ignores the comment record produced by the directive and issues warning LNK4229. Instead of the
#ident directive, we recommend that you use a file version resource string in your application.
See Also
comment (C/C++)
Linker Tools Warning LNK4229
Working with Resource Files
Compiler Warning (level 2) C4275
2/11/2019 • 2 minutes to read • Edit Online
non - DLL -interface class 'class_1' used as base for DLL -interface class 'class_2'
// C4275.cpp
// compile with: /EHsc /MTd /W2 /c
#include <vector>
using namespace std;
class Node;
class __declspec(dllimport) VecWrapper : vector<Node *> {}; // C4275
Compiler Warning (level 1) C4276
10/31/2018 • 2 minutes to read • Edit Online
'identifier': identifier in type library 'tlb' is already a macro; use the 'rename' qualifier
When using #import, an identifier in the typelib you are importing is attempting to declare an identifier identifier.
However, this is already a valid symbol.
Use the #import rename attribute to assign an alias to the symbol in the type library.
Compiler Warning (level 3) C4280
10/31/2018 • 2 minutes to read • Edit Online
// C4280.cpp
// compile with: /W3 /WX
struct A
{
int z;
A& operator ->();
};
void f(A y)
{
int i = y->z; // C4280
}
Compiler Warning (level 3) C4281
10/31/2018 • 2 minutes to read • Edit Online
// C4281.cpp
// compile with: /W3 /WX
struct A;
struct B;
struct C;
struct A
{
int z;
B& operator->();
};
struct B
{
C& operator->();
};
struct C
{
A& operator->();
};
void f(A p)
{
int i = p->z; // C4281
}
Compiler Warning (level 3) C4282
10/31/2018 • 2 minutes to read • Edit Online
return type for 'identifier::operator ->' is recursive if applied using infix notation
The specified operator->() function cannot return the type for which it is defined or a reference to the type for
which it is defined.
The following sample generates C4285:
// C4285.cpp
// compile with: /W2
class C
{
public:
C operator->(); // C4285
// C& operator->(); C4285, also
};
int main()
{
}
Compiler Warning (level 1) C4286
10/31/2018 • 2 minutes to read • Edit Online
Example
//C4286.cpp
// compile with: /W1
#include <eh.h>
class C {};
class D : public C {};
int main()
{
try
{
throw "ooops!";
}
catch( C ) {}
catch( D ) {} // warning C4286, D is derived from C
}
Compiler Warning (level 3) C4287
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4287:
// C4287.cpp
// compile with: /W3
#pragma warning(default : 4287)
#include <stdio.h>
int main()
{
unsigned int u = 1;
if (u < -1) // C4287
printf_s("u LT -1");
else
printf_s("u !LT -1");
return 0;
}
Compiler Warning (level 1) C4288
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop
scope; it conflicts with the declaration in the outer scope
When compiling with /Ze and /Zc:forscope-, a variable declared in a for loop was used after the for-loop scope. A
Microsoft extension to the C++ language allows this variable to remain in scope, and C4288 reminds you that the
first declaration of the variable is not used.
See /Zc:forScope for information about how to specify the Microsoft extension in for loops with /Ze.
The following sample generates C4288:
// C4288.cpp
// compile with: /W1 /c /Zc:forScope-
int main() {
int i = 0; // not used in this program
for (int i = 0 ; ; ) ;
i++; // C4288 using for-loop declaration of i
}
Compiler Warning (level 4) C4289
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope
When compiling with /Ze and /Zc:forScope-, a variable declared in a for loop was used after the for-loop scope.
See /Zc:forScope for information about how to specify standard behavior in for loops with /Ze.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4289:
// C4289.cpp
// compile with: /W4 /Zc:forScope-
#pragma warning(default:4289)
int main() {
for (int i = 0 ; ; ) // C4289
break;
i++;
}
Compiler Warning (level 3) C4290
10/31/2018 • 2 minutes to read • Edit Online
// C4290.cpp
// compile with: /EHs /W3 /c
void f1(void) throw(int) {} // C4290
// OK
void f2(void) throw() {}
void f3(void) throw(...) {}
Compiler Warning (level 1) C4291
10/31/2018 • 2 minutes to read • Edit Online
'declaration' : no matching operator delete found; memory will not be freed if initialization throws an exception
A placement new is used for which there is no placement delete.
When memory is allocated for an object with operator new, the object's constructor is called. If the constructor
throws an exception, any memory that was allocated for the object should be deallocated. This cannot take place
unless an operator delete function exists that matches the operator new.
If you use the operator new without any extra arguments and compile with /GX, /EHs, or /EHa options to enable
exception handling, the compiler will generate code to call operator delete if the constructor throws an exception.
If you use the placement form of the new operator (the form with arguments in addition to the size of the
allocation) and the object's constructor throws an exception, the compiler will still generate code to call operator
delete; but it will only do so if a placement form of operator delete exists matching the placement form of the
operator new that allocated the memory. For example:
// C4291.cpp
// compile with: /EHsc /W1
#include <malloc.h>
class CList
{
public:
CList(int)
{
throw "Fail!";
}
};
int main(void)
{
try
{
// This will call ::operator new(unsigned int) to allocate heap
// memory. Heap memory pointed to by pList1 will automatically be
// deallocated by a call to ::operator delete(void*) when
// CList::CList(int) throws an exception.
CList* pList1 = new CList(10);
}
catch (...)
{
}
try
{
// This will call the overloaded ::operator new(size_t, char*, int)
// to allocate heap memory. When CList::CList(int) throws an
// exception, ::operator delete(void*, char*, int) should be called
// to deallocate the memory pointed to by pList2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation cannot occur.
CList* pList2 = new(__FILE__, __LINE__) CList(20); // C4291
}
catch (...)
{
}
}
The above example generates warning C4291 because no placement form of operator delete has been defined
that matches the placement form of operator new. To solve the problem, insert the following code above main.
Notice that all of the overloaded operator delete function parameters match those of the overloaded operator
new, except for the first parameter.
Example
The following sample generates C4293:
// C4293.cpp
// compile with: /c /W1
unsigned __int64 combine (unsigned lo, unsigned hi) {
An array was initialized but the last character in the array is not a null; accessing the array as a string may produce
unexpected results.
Example
The following sample generates C4295. To fix this issue, you could declare the array size larger, to hold a
terminating null from the initializer string, or you could use an array initializer list to make the intent clear that this
is an array of char , not a null-terminated string.
// C4295.c
// compile with: /W4
int main() {
char a[3] = "abc"; // C4295
char b[3] = {'d', 'e', 'f'}; // No warning
a[0] = b[2];
}
Compiler Warning (level 4) C4296
10/31/2018 • 2 minutes to read • Edit Online
// C4296.cpp
// compile with: /W4
#pragma warning(default : 4296)
int main()
{
unsigned int u = 9;
if (u < 0) // C4296
u++;
if (u >= 0) // C4296
u++;
}
Compiler Warning (level 1) C4297
10/31/2018 • 2 minutes to read • Edit Online
// C4297.cpp
// compile with: /W1 /LD
void __declspec(nothrow) f1() // declared nothrow
// try the following line instead
// void f1()
{
throw 1; // C4297
}
Compiler Warning (level 2) C4302
10/31/2018 • 2 minutes to read • Edit Online
// C4302.cpp
// compile with: /W2
#pragma warning(default : 4302)
int main() {
int i;
char c = (char) &i; // C4302
short s = (short) &i; // C4302
}
Compiler Warning (level 1) C4305
10/31/2018 • 2 minutes to read • Edit Online
Remarks
This warning is issued when a value is converted to a smaller type in an initialization or as a constructor argument,
resulting in a loss of information.
Example
This sample shows two ways you might see this warning:
// C4305.cpp
// Compile by using: cl /EHsc /W4 C4305.cpp
struct item
{
item(float) {}
};
int main()
{
float f = 2.71828; // C4305 'initializing'
item i(3.14159); // C4305 'argument'
return static_cast<int>(f);
}
To fix this issue, initialize by using a value of the correct type, or use an explicit cast to the correct type. For example,
use a float literal such as 2.71828f instead of a double (the default type for floating-point literals) to initialize a
float variable, or to pass to a constructor that takes a float argument.
Compiler Warning (level 3) C4306
10/31/2018 • 2 minutes to read • Edit Online
The identifier is type cast to a larger pointer. The unfilled high bits of the new type will be zero-filled.
This warning may indicate an unwanted conversion. The resulting pointer may not be valid.
Compiler Warning (level 2) C4307
10/31/2018 • 2 minutes to read • Edit Online
// C4307.cpp
// compile with: /W2
int i = 2000000000 + 2000000000; // C4307
int j = (unsigned)2000000000 + 2000000000; // OK
int main()
{
}
Compiler Warning (level 2) C4308
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4308.cpp
// compile with: /W2
unsigned int u = (-5 + 3U); // C4308
int main()
{
}
Compiler Warning (level 2) C4309
10/31/2018 • 2 minutes to read • Edit Online
// C4309.cpp
// compile with: /W2
int main()
{
char c = 128; // C4309
}
Compiler Warning (level 3) C4310
10/31/2018 • 2 minutes to read • Edit Online
// C4310.cpp
// compile with: /W4
int main() {
long int a;
a = (char) 128; // C4310, use value 0-127 to resolve
}
Compiler Warning (level 1) C4311
11/9/2018 • 2 minutes to read • Edit Online
// C4311.cpp
// compile by using: cl /W1 C4311.cpp
int main() {
void* p = &p;
unsigned int i = (unsigned int) p; // C4311 for 64-bit targets
unsigned long long j = (unsigned long long) p; // OK
}
Compiler Warning (level 1) C4312
10/31/2018 • 2 minutes to read • Edit Online
// C4312.cpp
// compile by using: cl /W1 /LD C4312.cpp
void* f(int i) {
return (void*)i; // C4312 for 64-bit targets
}
void* f2(__int64 i) {
return (void*)i; // OK
}
Compiler Warning (level 1) C4313
10/31/2018 • 2 minutes to read • Edit Online
'function' : 'format specifier' in format string conflicts with argument number of type 'type'
There is a conflict between the format specified and the value that you are passing. For example, you passed a 64-
bit parameter to an unqualified %d format specifier, which expects a 32-bit integer parameter. This warning is only
in effect when the code is compiled for 64-bit targets.
Example
The following code sample generates C4313 when it is compiled for a 64-bit target.
// C4313.cpp
// Compile by using: cl /W1 C4313.cpp
#include <stdio.h>
int main() {
int * pI = 0;
printf("%d", pI); // C4313 on 64-bit platform code
// Try one of the following lines instead:
// printf("%p\n", pI);
// printf("%Id\n", pI); // %I64d expects 64-bits of information
}
Compiler Warning (level 3) C4316
10/31/2018 • 2 minutes to read • Edit Online
Object allocated on the heap may not be aligned for this type.
An over-aligned object allocated by using operator new may not have the specified alignment. Override operator
new and operator delete for over-aligned types so that they use the aligned allocation routines—for example,
_aligned_malloc and _aligned_free. The following sample generates C4316:
// C4316.cpp
// Test: cl /W3 /c C4316.cpp
int main() {
new S; // C4316
}
Compiler Warning (level 1) C4319
10/31/2018 • 2 minutes to read • Edit Online
The result of the ~ (bitwise complement) operator is unsigned and then zero-extended when it is converted to a
larger type.
Example
In the following example, ~(a - 1) is evaluated as a 32-bit unsigned long expression and then converted to 64
bits by zero extension. This could lead to unexpected operation results.
// C4319.cpp
// compile with: cl /W4 C4319.cpp
int main() {
unsigned long a = 0;
unsigned long long q = 42;
q = q & ~(a - 1); // C4319 expected
}
Compiler Warning (level 4) C4324
10/31/2018 • 2 minutes to read • Edit Online
// C4324.cpp
// compile with: /W4
struct __declspec(align(32)) A
{
char a;
}; // C4324
int main()
{
}
Compiler Warning (level 1) C4325
10/31/2018 • 2 minutes to read • Edit Online
Remarks
You may not change the attributes of a standard section. For example:
This would overwrite the .sdata standard section which uses the short data type with the long data type.
Standard sections whose attributes you may not change include,
.data
.sdata
.bss
.sbss
.text
.const
.sconst
.rdata
.srdata
Additional sections may be added later.
See also
section
Compiler Warning (level 1) C4326
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A function returned a type other than type1. For example, using /Za, main did not return an int.
Example
The following sample generates C4326 and shows how to fix it:
// C4326.cpp
// compile with: /Za /W1
char main()
{
// C4326, instead use int main()
}
Compiler Warning (level 1) C4329
10/31/2018 • 2 minutes to read • Edit Online
// C4329.cpp
// compile with: /W1 /LD
enum __declspec(align(256)) TestEnum { // C4329
TESTVAL1,
TESTVAL2,
TESTVAL3
};
__declspec(align(256)) enum TestEnum1;
Compiler Warning (level 1) C4333
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4333.
// C4333.cpp
// compile with: /c /W1
unsigned shift8 (unsigned char c) {
return c >> 8; // C4333
'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
The result of 32-bit shift was implicitly converted to 64-bits, and the compiler suspects that a 64-bit shift was
intended. To resolve this warning, either use 64-bit shift, or explicitly cast the shift result to 64-bit.
Example
The following sample generates C4334.
// C4334.cpp
// compile with: /W3 /c
void SetBit(unsigned __int64 *p, int i) {
*p |= (1 << i); // C4334
*p |= (1i64 << i); // OK
}
Compiler Warning C4335
10/31/2018 • 2 minutes to read • Edit Online
Mac file format detected: please convert the source file to either DOS or UNIX format
The line termination character of the first line of a source file is Macintosh style ('\r') as opposed to UNIX ('\n') or
DOS ('\r\n').
This warning is always issued as an errror. See warning pragma for information about how to disable this warning.
Also, this warning is only issued once per compiland. Therefore, if there are multiple #include directives that
specify files in Macintosh format, C4335 will only be issued once.
One way to generate files in Macintosh format is by using the Advanced Save Options (on the File menu) in
Visual Studio.
Example
The following sample generates C4335.
// C4335 expected
#include "c4335.h" // assume both include files are in Macintosh format
#include "c4335_2.h"
Compiler Warning (level 4) C4336
10/31/2018 • 2 minutes to read • Edit Online
// c4336a.idl
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12b")]
library c4336aLib
{
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12c")]
enum E_C4336
{
one, two, three
};
};
// c4336b.idl
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12d")]
library C4336bLib
{
importlib ("c4336a.tlb");
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12e")]
struct S_C4336
{
enum E_C4336 e;
};
};
// C4336.cpp
// compile with: /W4 /LD
// #import "C4336a.tlb"
#import "C4336b.tlb" // C4336, uncomment previous line to resolve
Compiler Warning (level 4) C4337
10/31/2018 • 2 minutes to read • Edit Online
// C4337a.idl
[
uuid(F87070BA-C6D9-405C-A8E4-8CD9CA25C12B)
]
library C4337aLib
{
[uuid(F87070BA-C6D9-405C-A8E4-8CD9CA25C12C)]
enum E_C4337a
{
one = 0,
two = 1,
three = 2
};
};
// C4337b.idl
[
uuid(F87070BA-C6D9-405C-A8E4-8CD9CA25C12D)
]
library C4337bLib
{
importlib("c4337a.tlb");
[uuid(F87070BA-C6D9-405C-A8E4-8CD9CA25C12E)]
struct S_C4337b
{
enum E_C4337a e;
};
};
// C4337.cpp
// compile with: /W4 /LD
#import "c4337b.tlb" auto_search // C4337
// explicitly #import all type libraries to resolve
// #import "C4337a.tlb"
// #import "C4337b.tlb"
Compiler Warning (level 4) C4339
10/31/2018 • 2 minutes to read • Edit Online
'type' : use of undefined type detected in WinRT or CLR meta-data - use of this type may lead to a runtime
exception
A type was not defined in code that was compiled for Windows Runtime or the common language runtime. Define
the type to avoid a possible runtime exception.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4339 and shows how to fix it:
// C4339.cpp
// compile with: /W4 /clr /c
// C4339 expected
#pragma warning(default : 4339)
class X {
public:
X() {}
virtual A *mf() {
return 0;
}
};
X * f() {
return new X();
}
Compiler Warning (level 1) C4340
10/31/2018 • 2 minutes to read • Edit Online
behavior change: 'function' called, but a member operator was called in previous versions
In versions of Visual C++ before Visual Studio 2002, a member was called, but this behavior has been changed
and the compiler now finds the best match in namespace scope.
If a member operator was found, the compiler would previously not consider any namespace scope operators. If
there is a better match at namespace scope, the current compiler correctly calls it, whereas previous compilers
wouldn't consider it.
This warning should be disabled after you successfully port your code to the current version. The compiler may
give false positives, generating this warning for code where there is no behavior change.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
The following sample generates C4342:
// C4342.cpp
// compile with: /EHsc /W1
#include <fstream>
#pragma warning(default: 4342)
using namespace std;
struct X : public ofstream {
X();
};
X::X() {
open( "ofs_bug_ev.txt." );
if ( is_open() ) {
*this << "Text" << "<-should be text" << endl; // C4342
*this << ' ' << "<-should be space symbol" << endl; // C4342
}
}
int main() {
X b;
b << "Text" << "<-should be text" << endl;
b << ' ' << "<-should be space symbol" << endl;
}
Compiler Warning (level 4) C4343
10/31/2018 • 2 minutes to read • Edit Online
// C4343.cpp
// compile with: /Og /W4 /LD
// processor: IPF
#pragma optimize ("g", off) // C4343
Compiler Warning (level 1) C4344
10/31/2018 • 2 minutes to read • Edit Online
// C4346.cpp
// compile with: /WX /LD
template<class T>
struct C {
T::X* x; // C4346
// try the following line instead
// typename T::X* x;
};
The following samples shows other examples where the typename keyword is required:
// C4346b.cpp
// compile with: /LD /W1
template<class T>
const typename T::X& f(typename T::Z* p); // Required in both places
template<class T>
struct M : public L<typename T::Type, T::Value>
{ // required on type argument, not on non-type argument
typedef typename T::X Type;
Type f(); // OK: "Type" is a type-specifer
typename T::X g(); // typename required
operator typename T::Z(); // typename required
};
and this,
// C4346c.cpp
// compile with: /LD /WX
struct Y {
typedef int Y_t;
};
template<class T>
struct A {
typedef Y A_t;
};
template<class T>
struct B {
typedef /*typename*/ A<T>::A_t B_t; // C4346 typename needed here
typedef /*typename*/ B_t::Y_t B_t2; // typename also needed here
};
Compiler Warning (level 1) C4348
10/31/2018 • 2 minutes to read • Edit Online
// C4348.cpp
// compile with: /LD /W1
template <class T=int> struct A; // forward declaration
// C4350.cpp
// compile with: /W1
#pragma warning (default : 4350)
class A {};
class B
{
public:
B(B&){}
// try the following instead:
// B(const B&){}
B(A){}
operator A(){ return A();}
};
int main()
{
B ap(source()); // C4350
}
Compiler Warning (level 1) C4353
10/31/2018 • 2 minutes to read • Edit Online
nonstandard extension used: constant 0 as function expression. Use '__noop' function intrinsic instead
You cannot use the constant zero (0) as a function expression. For more information, see __noop.
The following sample generates C4353:
// C4353.cpp
// compile with: /W1
void MyPrintf(void){};
#define X 0
#if X
#define DBPRINT MyPrint
#else
#define DBPRINT 0 // C4353 expected
#endif
int main(){
DBPRINT();
}
Compiler Warning C4355
10/31/2018 • 2 minutes to read • Edit Online
// C4355.cpp
// compile with: /w14355 /c
#include <tchar.h>
class CDerived;
class CBase {
public:
CBase(CDerived *derived): m_pDerived(derived) {};
~CBase();
virtual void function() = 0;
CDerived * m_pDerived;
};
CBase::~CBase() {
m_pDerived -> function();
}
int main() {
CDerived myDerived;
}
Compiler Warning (level 2) C4356
10/31/2018 • 2 minutes to read • Edit Online
// C4356.cpp
// compile with: /W2 /EHsc
#include <iostream>
class A {
public:
static int n;
};
int main() {
using namespace std;
cout << B::n << endl;
}
Compiler Warning (level 3) C4357
10/31/2018 • 2 minutes to read • Edit Online
param array argument in formal argument list for delegate 'del' ignored when generating 'function'
The ParamArray attribute was ignored, and function cannot be called with variable arguments.
The following sample generates C4357:
// C4357.cpp
// compile with: /clr /W3 /c
using namespace System;
public delegate void f(int i, ... array<Object^>^ varargs); // C4357
'operator': return type of combined delegates is not 'void'; returned value is undefined
Two delegates were combined and the return value is not void. If two delegates with non-void return values are
combined, the compiler will not be able to do a proper assignment if the return value of the delegate is used.
The following sample generates C4358:
// C4358.cpp
// compile with: /clr /W1
delegate int D();
delegate void E();
ref class X {
int i;
public:
X(int ii) : i(ii) {}
int f() {
return i;
}
};
ref class Y {
int i;
public:
Y() {}
void g() {}
};
int main() {
D^ d = gcnew D(gcnew X(1), &X::f);
D^ d2 = gcnew D(gcnew X(2), &X::f);
d += d2; // C4358
int j = d(); // return value indeterminate
'type': actual alignment (8) is greater than the value specified in __declspec(align())
The alignment specified for a type is less than the alignment of the type of one of its data members. For more
information, see align.
Example
The following sample generates C4359.
// C4359.cpp
// compile with: /W3 /c
struct __declspec(align(8)) C8 { __int64 i; };
struct __declspec(align(4)) C4 { C8 m8; }; // C4359
struct __declspec(align(8)) C8_b { C8 m8; }; // OK
struct __declspec(align(16)) C16 { C8 m8; }; // OK
Compiler Warning (level 1) C4364
10/31/2018 • 2 minutes to read • Edit Online
#using for assembly 'file' previously seen at location(line_number) without as_friend attribute; as_friend not
applied
A #using directive was repeated for a given metadata file, but the as_friend qualifier was not used in the first
occurrence; the compiler will ignore the second as_friend .
For more information, see Friend Assemblies (C++).
Example
The following sample creates a component.
// C4364.cpp
// compile with: /clr /LD
ref class A {};
Example
The following sample generates C4364.
// C4364_b.cpp
// compile with: /clr /W1 /c
#using " C4364.dll"
#using " C4364.dll" as_friend // C4364
Compiler Warning (level 4) C4365
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4365.
// C4365.cpp
// compile with: /W4
#pragma warning(default:4365)
int main() {
unsigned int n = 10;
int o = 10;
n++;
f(n); // C4365
f(o); // OK
Example
The following sample generates C4366.
// C4366.cpp
// compile with: /W4 /c
// processor: IPF x64
#pragma pack(1)
struct X {
short s1;
int s2;
};
int main() {
X x;
short * ps1 = &x.s1; // OK
int * ps2 = &x.s2; // C4366
}
Compiler Warning C4368
10/31/2018 • 2 minutes to read • Edit Online
cannot define 'member' as a member of managed 'type': mixed types are not supported
You cannot embed a native data member in a CLR type.
You can, however, declare a pointer to a native type and control its lifetime in the constructor and destructor and
finalizer of your managed class. For more information see Destructors and finalizers.
This warning is always issued as an error. Use the warning pragma to disable C4368.
Example
The following sample generates C4368.
// C4368.cpp
// compile with: /clr /c
struct N {};
ref struct O {};
ref struct R {
R() : m_p( new N ) {}
~R() { delete m_p; }
property O ^ prop2; // OK
N * m_p; // OK
};
Compiler Warning (level 1) C4369
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4369.
// C4369.cpp
// compile with: /W1
int main() {
enum Color: char { red = 0x7e, green, blue }; // C4369
enum Color2: char { red2 = 0x7d, green2, blue2}; // OK
}
Compiler Warning (level 3) C4371
10/31/2018 • 2 minutes to read • Edit Online
'classname': layout of class may have changed from a previous version of the compiler due to better packing of
member 'member'
If your code relies on a particular memory layout for a class, warning C4371 tells you that the layout created by
the current compiler may be different from the layout generated by previous versions of the compiler. This may be
significant for serialization operations or operating system interfaces that rely on a particular memory layout. In
most other cases, this warning is safe to ignore.
Warning C4371 is off by default. For more information, see Compiler Warnings That Are Off By Default.
Compiler Warning (level 3) C4373
10/31/2018 • 2 minutes to read • Edit Online
'function': virtual function overrides 'base_function', previous versions of the compiler did not override when
parameters only differed by const/volatile qualifiers
Remarks
Your application contains a method in a derived class that overrides a virtual method in a base class, and the
parameters in the overriding method differ by only a const or volatile qualifier from the parameters of the virtual
method. This means the compiler must bind a function reference to the method in either the base or derived class.
Versions of the compiler prior to Visual Studio 2008 bind the function to the method in the base class, then issue a
warning message. Subsequent versions of the compiler ignore the const or volatile qualifier, bind the function
to the method in the derived class, then issue warning C4373. This latter behavior complies with the C++ standard.
Example
The following code example generates warning C4373. To resolve this issue, you can either make the override use
the same CV -qualifiers as the base member function, or if you did not intend to create an override, you can give the
function in the derived class a different name.
// c4373.cpp
// compile with: /c /W3
#include <stdio.h>
struct Base
{
virtual void f(int i) {
printf("base\n");
}
};
void main()
{
Derived d;
Base* p = &d;
p->f(1);
}
derived
Compiler Warning (level 1) C4374
10/31/2018 • 2 minutes to read • Edit Online
// C4374.cpp
// compile with: /clr /W1 /c /WX
public interface class I {
void f();
};
Example
The following sample generates C4376.
// C4376.cpp
// compile with: /clr /W1 /c
public ref class G {
public public: // C4376
void m2();
};
Example
The following sample generates C4377.
// C4377.cpp
// compile with: /clr /d1PrivateNativeTypes /W1
// C4377 warning expected
int main() {}
Compiler Warning (level 1) C4378
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4378.
// C4378.cpp
// compile with: /W1 /clr /c
typedef void (__cdecl *PF)(void);
int cxpf = 0; // number of destructors to call
PF pfx[200]; // ptrs to those dtors, watch for overflow
struct A {
A() {}
~A() {}
};
A aaaa;
#pragma data_seg(".mine$a")
PF InitSegStart = (PF)1;
#pragma data_seg(".mine$z")
PF InitSegEnd = (PF)1;
#pragma data_seg()
void InitializeObjects () {
PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if (*x)
(*x)();
}
int main () {
InitializeObjects();
}
Example
The following sample shows how to resolve C4378.
// C4378_b.cpp
// compile with: /clr
#pragma warning(disable:4378)
using namespace System;
typedef void (__cdecl *PF)(void);
typedef void (__clrcall * CLRPF)(void);
struct A {
A() {}
~A() {}
};
A aaaa;
#pragma data_seg(".mine$a")
PF InitSegStart = (PF)1;
#pragma data_seg(".mine$z")
PF InitSegEnd = (PF)1;
#pragma data_seg()
void InitializeObjects () {
PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if(*x) {
CLRPF realppfunc;
realppfunc = FuncTokenToFuncPtr(*x);
(realppfunc)();
}
}
#pragma init_seg(".mine$m",myexit)
A bbbb; // constructor call succeeds
int main () {
InitializeObjects();
}
Compiler Warning (level 1) C4379
10/31/2018 • 2 minutes to read • Edit Online
Version version of the common language runtime is not supported by this compiler. Using this version may cause
unexpected results.
You have a previous version of the common language runtime on your machine, but not the current version. To
resolve C4379, install the version of the common language runtime that shipped with your compiler.
Compiler Warning (level 1) C4381
10/31/2018 • 2 minutes to read • Edit Online
throwing 'type' : a type with __clrcall destructor or copy constructor can only be caught in /clr:pure module
Remarks
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
When compiled with /clr (not /clr:pure), exception handling expects the member functions in a native type to be
__cdecl and not __clrcall. Native types with member functions using __clrcall calling convention cannot be
caught in a module compiled with /clr.
If the exception will be caught in a module compiled with /clr:pure, you can ignore this warning.
For more information, see /clr (Common Language Runtime Compilation).
Example
The following sample generates C4382.
// C4382.cpp
// compile with: /clr /W1 /c
struct S {
__clrcall ~S() {}
};
struct T {
~T() {}
};
int main() {
S s;
throw s; // C4382
S * ps = &s;
throw ps; // OK
T t;
throw t; // OK
}
Compiler Warning (level 1) C4383
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4383.
// C4383.cpp
// compile with: /clr /W1
ref struct S {
int operator*() { return 0; } // C4383
};
ref struct T {
static int operator*(T%) { return 0; }
};
int main() {
S s;
S^ pS = %s;
T t;
T^ pT = %t;
T% rT = *pT;
}
Compiler Warning (level 1) C4384
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4384.
// C4384.cpp
// compile with: /c /W1
namespace n {
#pragma make_public(N::C) // C4384
namespace N {
class C {};
}
}
Compiler Warning (level 4) C4389
10/31/2018 • 2 minutes to read • Edit Online
// C4389.cpp
// compile with: /W4
#pragma warning(default: 4389)
int main()
{
int a = 9;
unsigned int b = 10;
if (a == b) // C4389
return 0;
else
return 0;
};
Compiler Warning (level 3) C4390
10/31/2018 • 2 minutes to read • Edit Online
// C4390.cpp
// compile with: /W3
int main() {
int i = 0;
if (i); // C4390
i++;
}
Compiler Warning (level 1) C4391
10/31/2018 • 2 minutes to read • Edit Online
// C4391.cpp
// compile with: /W1
// processor: x86
// uncomment the following line and delete the line that
// generated the warning to resolve
// #include "xmmintrin.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
int main()
{
}
Compiler Warning (level 1) C4392
10/31/2018 • 2 minutes to read • Edit Online
'signature' : incorrect number of arguments for intrinsic function, expected 'number' arguments
A function declaration for a compiler intrinsic had the wrong number of arguments. The resulting image may not
run correctly.
To fix this warning, either correct the declaration or delete the declaration and simply #include the appropriate
header file.
The following sample generates C4392:
// C4392.cpp
// compile with: /W1
// processor: x86
// uncomment the following line and delete the line that
// generated the warning to resolve
// #include "xmmintrin.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
int main()
{
}
Compiler Warning (level 1) C4393
10/31/2018 • 2 minutes to read • Edit Online
// C4393.cpp
// compile with: /clr /W1 /c
ref struct Y1 {
literal const int staticConst = 10; // C4393
literal int staticConst2 = 10; // OK
};
Compiler Warning C4394
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4394.
// C4394.cpp
// compile with: /clr /c
__declspec(dllexport) __declspec(appdomain) int g1 = 0; // C4394
__declspec(dllexport) int g2 = 0; // OK
Compiler Warning (level 1) C4395
10/31/2018 • 2 minutes to read • Edit Online
'function' : member function will be invoked on a copy of the initonly data member 'member'
A member function was called on an initonly (C++/CLI) data member. C4395 warns that the initonly data
member cannot be modified by the function.
The following sample generates C4395:
// C4395.cpp
// compile with: /W1 /clr
public value class V {
public:
V(int data) : m_data(data) {}
void Mutate() {
System::Console::WriteLine("Enter Mutate: m_data = {0}", m_data);
m_data *= 2;
System::Console::WriteLine("Leave Mutate: m_data = {0}", m_data);
}
int m_data;
};
private:
initonly static V v = V(4);
};
int main() {
R::f();
}
Compiler Warning (level 2) C4396
10/31/2018 • 2 minutes to read • Edit Online
"name" : the inline specifier cannot be used when a friend declaration refers to a specialization of a function
template
A specialization of a function template cannot specify any of the inline specifiers. The compiler issues warning
C4396 and ignores the inline specifier.
To correct this error
Remove the inline , __inline , or __forceinline specifier from the friend function declaration.
Example
The following code example shows an invalid friend function declaration with an inline specifier.
// C4396.cpp
// compile with: /W2 /c
class X;
template<class T> void Func(T t, int i);
class X {
friend inline void Func<char>(char t, int i); //C4396
// try the following line instead
// friend void Func<char>(char t, int i);
int i;
};
Compiler Warning (level 1) C4397
10/31/2018 • 2 minutes to read • Edit Online
DefaultCharSetAttribute is ignored
DefaultCharSetAttribute is ignored by the Visual C++ compiler. To specify a character set for the DLL, use the
CharSet option of DllImport. For more information, see Using C++ Interop (Implicit PInvoke).
Example
The following sample generates C4397.
// C4397.cpp
// compile with: /W1 /c /clr
using namespace System;
using namespace System::Runtime::InteropServices;
[module:DefaultCharSetAttribute(CharSet::Unicode)]; // C4397
[StructLayout(LayoutKind::Explicit)]
public ref struct StructDefault1{};
'variable' : per-process global object might not work correctly with multiple appdomains; consider using
__declspec(appdomain)
Remarks
A virtual function with __clrcall calling convention in a native type causes the creation of a per application domain
vtable. Such a variable may not correct correctly when used in multiple application domains.
You can resolve this warning by explicitly marking the variable __declspec(appdomain) . In versions of Visual Studio
before Visual Studio 2017, you can resolve this warning by compiling with /clr:pure, which makes global variables
per appdomain by default. The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in
Visual Studio 2017.
For more information, see appdomain and Application Domains and Visual C++.
Example
The following sample generates C4398.
// C4398.cpp
// compile with: /clr /W3 /c
struct S {
virtual void f( System::String ^ ); // String^ parameter makes function __clrcall
};
S glob_s; // C4398
__declspec(appdomain) S glob_s2; // OK
Compiler Warning (level 1) C4399
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : per-process symbol should not be marked with __declspec(dllimport) when compiled with /clr:pure
Remarks
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
Data from a native image or an image with native and CLR constructs can not be imported into a pure image. To
resolve this warning, compile with /clr (not /clr:pure) or delete __declspec(dllimport) .
Example
The following sample generates C4399.
// C4399.cpp
// compile with: /clr:pure /doc /W1 /c
__declspec(dllimport) __declspec(process) extern const int i; // C4399
Compiler Warnings C4400 Through C4599
3/14/2019 • 16 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the warning messages that are generated by
the compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Warning messages
WARNING MESSAGE
Compiler Warning (level 1) C4600 #pragma 'macro name': expected a valid non-empty string
Compiler Warning (level 4) C4400 'type': const/volatile qualifiers on this type are not supported
Compiler Warning (level 1) C4407 cast between different pointer to member representations,
compiler may generate incorrect code
Compiler Warning (level 4) C4408 anonymous 'struct|union' did not declare any data members
Compiler Warning (level 2) C4412 'function': function signature contains type 'type'; C++ objects
are unsafe to pass between pure code and mixed or native.
Compiler Warning (level 3) C4414 'function': short jump to function converted to near
Compiler warning (level 3) C4419 'symbol' has no effect when applied to private ref class 'class'.
Compiler Warning (level 1) C4420 'checked_operator': operator not available, using 'operator'
instead; run-time checking may be compromised
Compiler warning (level 3) C4423 'std::bad_alloc': will be caught by class ('type') on line number
Compiler warning (level 3) C4424 catch for 'type1' preceded by 'type2' on line number;
unpredictable behavior may result if 'std::bad_alloc' is thrown
Compiler warning (level 1) C4426 optimization flags changed after including header, may be due
to #pragma optimize()
Compiler warning (level 1) C4427 'operator': overflow in constant division, undefined behavior
Compiler Warning (Error) C4430 missing type specifier - int assumed. Note: C++ does not
support default-int
Compiler Warning (level 4) C4431 missing type specifier - int assumed. Note: C no longer
supports default-int
Compiler Warning (level 4) C4434 a static constructor must have private accessibility; changing
to private access
Compiler Warning (level 4) C4435 'derived_class': Object layout under /vd2 will change due to
virtual base 'base_class'
Compiler Warning (level 1) C4436 dynamic_cast from virtual base 'base_class' to 'derived_class'
in constructor or destructor could fail with partially-
constructed object
Compiler Warning (level 4) C4437 dynamic_cast from virtual base 'base_class' to 'derived_class'
could fail in some contexts
Compiler Warning (Error) C4439 'function': function definition with a managed type in the
signature must have a __clrcall calling convention
Compiler warning (level 1) C4442 embedded null terminator in __annotation argument. Value
will be truncated.
Compiler warning (level 1) C4443 expected pragma parameter to be '0', '1', or '2'
Compiler warning (level 3) C4444 'identifier': top level '__unaligned' is not implemented in this
context
Compiler Warning (level 1) C4445 'function': in a 'WinRT|managed' type a virtual method cannot
be private
Compiler warning (level 1) C4446 'type': cannot map member 'name1' into this type, due to
conflict with the type name. The method was renamed to
'name2'
Compiler warning (level 1) C4447 'main' signature found without threading model. Consider
using 'int main(Platform::Array<Platform::String^>^ args)'.
Compiler warning C4448 'type1' does not have a default interface specified in metadata.
Picking: 'type2', which may fail at runtime.
WARNING MESSAGE
Compiler warning (level 1) C4452 'identifier': public type cannot be at global scope. It must be in
a namespace that is a child of the name of the output .winmd
file.
Compiler warning (level 1) C4453 'type': A '[WebHostHidden]' type should not be used on the
published surface of a public type that is not
'[WebHostHidden]'
Compiler warning (level 1) C4454 'function' is overloaded by more than the number of input
parameters without having [DefaultOverload] specified. Picking
'declaration' as the default overload
Compiler warning (level 1) C4455 'operator operator': literal suffix identifiers that do not start
with an underscore are reserved
Compiler warning (level 4) C4456 declaration of 'identifier' hides previous local declaration
Compiler Warning (level 4) C4460 'WinRT|managed' operator 'operator', has parameter passed
by reference. 'WinRT|managed' operator 'operator' has
different semantics from C++ operator 'cpp_operator', did you
intend to pass by value?
Compiler Warning (level 1) C4461 'classname': this class has a finalizer '!finalizer' but no
destructor '~dtor'
Compiler Warning (level 1, Error) C4462 'type' : cannot determine the GUID of the type. Program may
fail at runtime.
Compiler warning (level 4) C4463 overflow; assigning 'value' to bit-field that can only hold
values from 'min_value' to 'max_value'
Compiler Warning (level 1) C4470 floating-point control pragmas ignored under /clr
Compiler warning (level 1) C4472 'identifier' is a native enum: add an access specifier
(private/public) to declare a 'WinRT|managed' enum
Compiler warning (level 1) C4473 'function' : not enough arguments passed for format string
Compiler warning (level 3) C4474 'function' : too many arguments passed for format string
Compiler warning (level 3) C4475 'function' : length modifier 'modifier' cannot be used with type
field character 'character' in format specifier
Compiler warning (level 3) C4476 'function' : unknown type field character 'character' in format
specifier
Compiler warning (level 1) C4477 'function' : format string 'string' requires an argument of type
'type', but variadic argument number has type 'type'
Compiler warning (level 1) C4478 'function' : positional and non-positional placeholders cannot
be mixed in the same format string
Compiler warning (Error) C4480 nonstandard extension used: specifying underlying type for
enum 'enumeration'
Compiler Warning (level 4) C4481 nonstandard extension used: override specifier 'keyword'
Compiler warning (level 1, Error) C4483 syntax error: expected C++ keyword
Compiler Warning (Error) C4484 'override_function': matches base ref class method
'base_class_function', but is not marked 'virtual', 'new' or
'override'; 'new' (and not 'virtual') is assumed
Compiler Warning (Error) C4485 'override_function': matches base ref class method
'base_class_function', but is not marked 'new' or 'override';
'new' (and 'virtual') is assumed
Compiler Warning (level 1) C4486 'function': a private virtual method of a ref class or value class
should be marked 'sealed'
Compiler Warning (level 1) C4488 'function': requires 'keyword' keyword to implement the
interface method 'interface_method'
Compiler Warning (level 1) C4489 'specifier': not allowed on interface method 'method'; override
specifiers are only allowed on ref class and value class methods
Compiler Warning (level 1) C4490 'override': incorrect use of override specifier; 'function' does
not match a base ref class method
Compiler warning (level 1) C4491 'name': has an illegal IDL version format
WARNING MESSAGE
Compiler warning (level 1, Error) C4492 'function1': matches base ref class method 'function2', but is
not marked 'override'
Compiler warning (level 3, Error) C4493 delete expression has no effect as the destructor of 'type' does
not have 'public' accessibility
Compiler warning (level 1) C4494 'function' : Ignoring __declspec(allocator) because the function
return type is not a pointer or reference
Compiler warning C4495 nonstandard extension '__super' used: replace with explicit
base class name
Compiler warning C4496 nonstandard extension 'for each' used: replace with ranged-for
statement
Compiler warning C4497 nonstandard extension 'sealed' used: replace with 'final'
Compiler warning (level 4) C4499 'function' : an explicit specialization cannot have a storage
class (ignored)"
Compiler Warning (level 1) C4502 'linkage specification' requires use of keyword 'extern' and
must precede all other specifiers
Compiler Warning (level 1) C4503 'identifier': decorated name length exceeded, name was
truncated
Compiler Warning (level 4) C4505 'function': unreferenced local function has been removed
Compiler Warning (level 1) C4508 'function': function should return a value; 'void' return type
assumed
Compiler warning C4509 nonstandard extension used: 'function' uses SEH and 'object'
has destructor
Compiler Warning (level 4) C4510 'class': default constructor was implicitly defined as deleted
Compiler Warning (level 3) C4511 'class': copy constructor was implicitly defined as deleted
Compiler Warning (level 4) C4512 'class': assignment operator was implicitly defined as deleted
Compiler Warning (level 4) C4513 'class': destructor was implicitly defined as deleted
Compiler Warning (level 4) C4514 'function': unreferenced inline function has been removed
Compiler Warning (level 1) C4518 'specifier': storage-class or type specifier(s) unexpected here;
ignored
Compiler warning (Error) C4519 default template arguments are only allowed on a class
template
Compiler Warning (level 1) C4526 'function': static member function cannot override virtual
function 'virtual function' override ignored, virtual function
will be hidden
Compiler Warning (level 1) C4530 C++ exception handler used, but unwind semantics are not
enabled. Specify /EHsc
Compiler warning (level 1) C4531 C++ exception handling not available on Windows CE. Use
Structured Exception Handling
Compiler Warning (level 1) C4532 'continue': jump out of '__finally/finally' block has undefined
behavior during termination handling
Compiler Warning (level 3) C4534 'constructor' will not be a default constructor for 'class/struct'
'identifier' due to the default argument
Compiler Warning (level 3) C4538 'type': const/volatile qualifiers on this type are not supported
Compiler Warning (level 1) C4541 'identifier' used on polymorphic type 'type' with /GR-;
unpredictable behavior may result
Compiler warning (level 1) C4542 Skipping generation of merged injected text file, cannot write
filetype file: 'issue': message
Compiler Warning (level 1) C4544 'declaration': default template argument ignored on this
template declaration
Compiler Warning (level 1) C4545 expression before comma evaluates to a function which is
missing an argument list
Compiler Warning (level 1) C4546 function call before comma missing argument list
Compiler Warning (level 1) C4547 'operator': operator before comma has no effect; expected
operator with side-effect
Compiler Warning (level 1) C4548 expression before comma has no effect; expected expression
with side-effect
Compiler Warning (level 1) C4549 'operator': operator before comma has no effect; did you
intend 'operator'?
Compiler Warning (level 1) C4552 'operator': operator has no effect; expected operator with
side-effect
Compiler Warning (level 1) C4553 'operator': operator has no effect; did you intend 'operator?
Compiler Warning (level 3) C4554 C4554 'operator': check operator precedence for possible error; use
parentheses to clarify precedence
Compiler Warning (level 1) C4555 expression has no effect; expected expression with side-effect
Compiler Warning (level 1) C4556 value of intrinsic immediate argument 'value' is out of range
'lower_bound - upper_bound'
Compiler Warning (level 1) C4558 value of operand 'value' is out of range 'lower_bound -
upper_bound'
Compiler Warning (level 4) C4559 'function': redefinition; the function gains __declspec(modifier)
Compiler Warning (level 1) C4561 '__fastcall' incompatible with the '/clr' option: converting to
'__stdcall'
Compiler warning (level 4) C4562 fully prototyped functions are required with the '/clr' option:
converting '()' to '(void)'
Compiler Warning (level 4) C4564 method 'method' of 'class' 'classname' defines unsupported
default parameter 'parameter'
Compiler Warning (level 4) C4565 'function': redefinition; the symbol was previously declared
with __declspec(modifier)
WARNING MESSAGE
Compiler warning (level 1) C4568 'function': no members match the signature of the explicit
override
Compiler warning (level 3) C4569 'function': no members match the signature of the explicit
override
Compiler Warning (level 3) C4570 'type': is not explicitly declared as abstract but has abstract
functions
Compiler Warning (level 4) C4571 Informational: catch(...) semantics changed since Visual C++
7.1; structured exceptions (SEH) are no longer caught
Compiler Warning (level 1) C4572 [ParamArray] attribute is deprecated under /clr, use '...' instead
Compiler warning (level 1) C4573 the usage of 'lambda function' requires the compiler to
capture 'this' but the current default capture mode does not
allow it
Compiler warning (level 4) C4574 'Identifier' is defined to be '0': did you mean to use '#if
identifier'?
Compiler warning (level 1) C4575 '__vectorcall' incompatible with the '/clr' option: converting to
'__stdcall'
Compiler warning (level 1, Error) C4576 a parenthesized type followed by an initializer list is a non-
standard explicit type conversion syntax
Compiler warning (level 1, Off) C4577 'noexcept' used with no exception handling mode specified;
termination on exception is not guaranteed. Specify /EHsc
Compiler warning (level 1, Error) C4578 'abs': conversion from 'type1' to 'type2', possible loss of data
(Did you mean to call 'function' or to #include <cmath>?)
Compiler Warning (level 1) C4581 deprecated behavior: '"string"' replaced with 'string' to process
attribute
Compiler Warning (level 1) C4584 'class1': base-class 'class2' is already a base-class of 'class3'
Compiler warning (level 1, Error) C4585 'class': A WinRT 'public ref class' must either be sealed or
derive from an existing unsealed class
Compiler warning (level 1, Error) C4586 'type': A public type cannot be declared in a top-level
namespace called 'Windows'
WARNING MESSAGE
Compiler warning (level 3) C4592 'function': 'constexpr' call evaluation failed; function will be
called at run-time
Compiler warning (level 1) C4593 'function': 'constexpr' call evaluation step limit of 'limit'
exceeded; use /constexpr:steps<NUMBER> to increase the
limit
Compiler warning (level 3) C4594 'type': destructor will not be implicitly called if an exception is
thrown
Compiler warning (level 1) C4595 'type': behavior change: destructor will no longer be implicitly
called if an exception is thrown
Compiler warning (level 4) C4596 'identifier': illegal qualified name in member declaration
Compiler warning (error) C4597 undefined behavior: offsetof applied to a member of a virtual
base
Compiler warning (level 1 and level 3) C4598 '#include "header"': header number number in the
precompiled header does not match current compilation at
that position
Compiler warning (level 3) C4599 'flag path': command line argument number number does not
match precompiled header
Compiler Warning (level 4) C4400
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4400.
// C4400.cpp
// compile with: /clr /W4
// C4401 expected
using namespace System;
#pragma warning (disable : 4101)
int main() {
const String^ str; // C4400
volatile String^ str2; // C4400
}
Compiler Warning (level 1) C4401
10/31/2018 • 2 minutes to read • Edit Online
// C4401.cpp
// compile with: /W1
// processor: x86
typedef struct bitfield {
signed bit : 1;
} mybitfield;
int main() {
mybitfield bf;
bf.bit = 0;
__asm {
mov bf.bit,0; // C4401
}
// C4405.cpp
// compile with: /W1
// processor: x86
void func1() {
int mov = 0, i = 0;
_asm {
mov mov, 0; // C4405
// instead, try ..
// mov i, 0;
}
}
int main() {
}
Compiler Warning (level 1) C4406
10/31/2018 • 2 minutes to read • Edit Online
cast between different pointer to member representations, compiler may generate incorrect code
An incorrect cast was detected.
C4407 can be generated because of compiler conformance work that was done in Visual C++ 2005. Pointer-to-
member now requires a qualified name and the address-of operator (&).
C4407 can occur if you cast between a multiple inheritance pointer-to-member to a single inheritance pointer-to-
member. Sometimes this can work, but sometimes it can’t because the single inheritance pointer-to-member
representation doesn’t hold sufficient information. Compiling with the /vmm might help (for more information,
see /vmm, /vms, /vmv (General Purpose Representation)). You can also try rearranging your base classes; the
compiler is detecting a loss of information in the conversion because a base class is at a non-zero offset from the
derived.
The following sample generates C4407:
// C4407.cpp
// compile with: /W1 /c
struct C1 {};
struct C2 {};
struct C3 : C1, C2 {};
typedef void(C3::*PMF_C3)();
typedef void(C2::*PMF_C2)();
// C4408.cpp
// compile with: /W4 /LD
static union
{
// int i;
};
// a named union can have no data members
// } MyUnion;
Compiler Warning (level 1) C4409
10/31/2018 • 2 minutes to read • Edit Online
'function' : function signature contains type 'type'; C++ objects are unsafe to pass between pure code and
mixed or native.
Remarks
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017. If you
have code that needs to be pure, we recommend that you port it to C#.
The compiler detected a potentially unsafe situation that could result in a runtime error: a call is being made from a
/clr:pure compiland to a function that was imported via dllimport and the function signature contains an unsafe
type. A type is unsafe if it contains a member function or has a data member that is an unsafe type or an
indirection to an unsafe type.
This is unsafe because of the difference in the default calling conventions between pure and native code (or mixed
native and managed). When importing (via dllimport ) a function into a /clr:pure compiland, ensure that the
declarations of each type in the signature are identical to those in the compiland that exports the function (being
especially careful about differences in implicit calling conventions).
A virtual member function is especially prone to give unexpected results. However, even a non-virtual function
should be tested to ensure that you get the correct results. If you are sure that you are getting the correct results,
you can ignore this warning.
C4412 is off by default. See Compiler Warnings That Are Off by Default and dllexport, dllimport for more
information.
To resolve this warning, remove all functions from the type.
Example
The following sample generates C4412.
// C4412.cpp
// compile with: /c /W2 /clr:pure
#pragma warning (default : 4412)
struct Unsafe {
virtual void __cdecl Test();
};
struct Safe {
int i;
};
int main() {
Unsafe *pUnsafe = func(); // C4412
// pUnsafe->Test();
Example
The following sample is a header file that declares two types. The Unsafe type is unsafe because it has a member
function.
// C4412.h
struct Unsafe {
// will be __clrcall if #included in pure compilation
// defaults to __cdecl in native or mixed mode compilation
virtual void Test(int * pi);
struct Safe {
int i;
};
Example
This sample exports functions with the types defined in the header file.
// C4412_2.cpp
// compile with: /LD
#include "C4412.h"
Example
The default calling convention in a /clr:pure compilation is different from a native compilation. When C4412.h is
included, Test defaults to __clrcall . If you compile and run this program (do not use /c), the program will throw
an exception.
The following sample generates C4412.
// C4412_3.cpp
// compile with: /W2 /clr:pure /c /link C4412_2.lib
#pragma warning (default : 4412)
#include "C4412.h"
int main() {
int n = 7;
Unsafe *pUnsafe = func(); // C4412
pUnsafe->Test(&n);
// C4414.cpp
// compile with: /W3 /c
// processor: x86
int DoParityEven();
int DoParityOdd();
unsigned char global;
int __declspec(naked) DoParityEither()
{
__asm
{
test global,0
jpe SHORT DoParityEven // C4414
jmp SHORT DoParityOdd // C4414
}
}
Compiler Warning (level 1) C4420
10/31/2018 • 2 minutes to read • Edit Online
'operator' : operator not available, using 'operator' instead; run-time checking may be compromised
This warning is generated when you use the /RTCv (vector new/delete checking) and when no vector form is
found. In this case, the non-vector form is used.
In order for /RTCv to work correctly, the compiler should always call the vector form of new/delete if the vector
syntax was used.
Compiler Warning (level 4) C4429
10/31/2018 • 2 minutes to read • Edit Online
// C4429.cpp
// compile with: /W4 /WX
int \ug0e4 = 0; // C4429
// Try the following line instead:
// int \u00e4 = 0; // OK, a well-formed universal character name.
Compiler Warning C4430
10/31/2018 • 2 minutes to read • Edit Online
missing type specifier - int assumed. Note: C++ does not support default-int
This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: all
declarations must explicitly specify the type; int is no longer assumed.
C4430 is always issued as an error. You can turn off this warning with the #pragma warning or /wd; see warning or
/w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we, /wo, /Wv, /WX (Warning Level) for more
information.
Example
The following sample generates C4430.
// C4430.cpp
// compile with: /c
struct CMyClass {
CUndeclared m_myClass; // C4430
int m_myClass; // OK
};
typedef struct {
POINT(); // C4430
// try the following line instead
// int POINT();
unsigned x;
unsigned y;
} POINT;
Compiler Warning (level 4) C4431
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4431.
// C4431.c
// compile with: /c /W4
#pragma warning(default:4431)
i; // C4431
int i; // OK
Compiler Warning (level 4) C4434
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4434.
// C4434.cpp
// compile with: /W4 /c /clr
public ref struct R {
static R(){} // C4434
};
Compiler Warning (level 4) C4435
10/31/2018 • 2 minutes to read • Edit Online
'class1' : Object layout under /vd2 will change due to virtual base 'class2'
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Under the default compile option of /vd1, the derived class does not have a vtordisp field for the indicated virtual
base. If /vd2 or #pragma vtordisp(2) is in effect, a vtordisp field will be present, changing the object layout. This
can lead to binary compatibility problems if interacting modules are compiled with different vtordisp settings.
Example
The following sample generates C4435.
// C4435.cpp
// compile with: /c /W4
#pragma warning(default : 4435)
class A
{
public:
virtual ~A() {}
};
See Also
vtordisp
/vd (Disable Construction Displacements)
Compiler Warning (level 1) C4436
10/31/2018 • 2 minutes to read • Edit Online
dynamic_cast from virtual base 'class1' to 'class2' in constructor or destructor could fail with partially-constructed
object Compile with /vd2 or define 'class2' with #pragma vtordisp(2) in effect
The compiler has encountered a dynamic_cast operation with the following characteristics.
The cast is from a base class pointer to a derived class pointer.
The derived class virtually inherits the base class.
The derived class does not have a vtordisp field for the virtual base.
The cast is found in a constructor or destructor of the derived class, or some class which further inherits
from the derived class.
The warning indicates the dynamic_cast might not perform correctly, if it is operating on a partially-constructed
object. That happens if the derived constructor/destructor is operating on a sub-object of some further derived
object. If the derived class named in the warning is never further derived, the warning can be ignored.
Example
The following sample generates C4436 and demonstrates the code generation issue that arises from the missing
vtordisp field.
// C4436.cpp
// To see the warning and runtime assert, compile with: /W1
// To eliminate the warning and assert, compile with: /W1 /vd2
// or compile with: /W1 /DFIX
#include <cassert>
struct A
{
public:
virtual ~A() {}
};
#if defined(FIX)
#pragma vtordisp(push, 2)
#endif
struct B : virtual A
{
B()
{
A* a = static_cast<A*>(this);
B* b = dynamic_cast<B*>(a); // C4436
assert(this == b); // assert unless compiled with /vd2
}
};
#if defined(FIX)
#pragma vtordisp(pop)
#endif
struct C : B
{
int i;
};
int main()
{
C c;
}
See Also
dynamic_cast Operator
vtordisp
Compiler Warning (level 4) C4437
Compiler Warning (level 4) C4437
10/31/2018 • 2 minutes to read • Edit Online
dynamic_cast from virtual base 'class1' to 'class2' could fail in some contexts Compile with /vd2 or define 'class2'
with #pragma vtordisp(2) in effect
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The compiler has encountered a dynamic_cast operation with the following characteristics.
The cast is from a base class pointer to a derived class pointer.
The derived class virtually inherits the base class.
The derived class does not have a vtordisp field for the virtual base.
The cast is not found in a constructor or destructor of the derived class, or some class which further inherits
from the derived class (otherwise, compiler warning C4436 will be issued).
The warning indicates that the dynamic_cast might not perform correctly if it is operating on a partially-
constructed object. This situation occurs when the enclosing function is called from a constructor or destructor of a
class that inherits the derived class that is named in the warning. If the derived class that is named in the warning
is never further derived, or the enclosing function is not called during object construction or destruction, the
warning can be ignored.
Example
The following sample generates C4437 and demonstrates the code generation issue that arises from the missing
vtordisp field.
// C4437.cpp
// To see the warning and runtime assert, compile with: /W4
// To eliminate the warning and assert, compile with: /W4 /vd2
// or compile with: /W4 /DFIX
#pragma warning(default : 4437)
#include <cassert>
struct A
{
public:
virtual ~A() {}
};
#if defined(FIX)
#pragma vtordisp(push, 2)
#endif
struct B : virtual A
{
B()
{
func();
}
void func()
{
A* a = static_cast<A*>(this);
B* b = dynamic_cast<B*>(a); // C4437
assert(this == b); // assert unless compiled with /vd2
}
};
#if defined(FIX)
#pragma vtordisp(pop)
#endif
struct C : B
{
int i;
};
int main()
{
C c;
}
See Also
dynamic_cast Operator
vtordisp
Compiler Warning (level 1) C4436
Compiler Warning C4439
10/31/2018 • 2 minutes to read • Edit Online
'function' : function definition with a managed type in the signature must have a __clrcall calling convention
The compiler implicitly replaced a calling convention with __clrcall. To resolve this warning, remove the __cdecl or
__stdcall calling convention.
C4439 is always issued as an error. You can turn off this warning with the #pragma warning or /wd; see warning or
/w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we, /wo, /Wv, /WX (Warning Level) for more
information.
Example
The following sample generates C4439.
// C4439.cpp
// compile with: /clr
void __stdcall f( System::String^ arg ) {} // C4439
void __clrcall f2( System::String^ arg ) {} // OK
void f3( System::String^ arg ) {} // OK
Compiler Warning (level 1) C4440
10/31/2018 • 2 minutes to read • Edit Online
// C4440.cpp
// compile with: /W1 /LD /clr
typedef void __clrcall F();
typedef F __cdecl *PFV; // C4440
Compiler Warning (level 1) C4441
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4441.
// C4441.cpp
// compile with: /clr /W1 /c
generic <class ItemType>
void __cdecl Test(ItemType item) {} // C4441
// try the following line instead
// void Test(ItemType item) {}
The declaration of identifier in the local scope hides the declaration of the previous local declaration of the same
name. This warning lets you know that references to identifier in the local scope resolve to the locally declared
version, not the previous local, which may or may not be your intent. To fix this issue, we recommend you give local
variables names that do not conflict with other local names.
Example
The following sample generates C4456 because the loop control variable int x and the local variable double x
in member_fn have the same names. To fix this issue, use different names for the local variables.
// C4456_hide.cpp
// compile with: cl /W4 /c C4456_hide.cpp
struct S {
void member_fn(unsigned u) {
double x = 0;
for (int x = 0; x < 10; ++x) { // C4456
u += x; // uses local int x
}
x += u; // uses local double x
}
} s;
Compiler Warning (level 4) C4457
10/31/2018 • 2 minutes to read • Edit Online
The declaration of identifier in the local scope hides the declaration of the identically-named function parameter.
This warning lets you know that references to identifier in the local scope resolve to the locally declared version,
not the parameter, which may or may not be your intent. To fix this issue, we recommend you give local variables
names that do not conflict with parameter names.
Example
The following sample generates C4457 because the parameter x and the local variable x in member_fn have the
same names. To fix this issue, use different names for the parameters and local variables.
// C4457_hide.cpp
// compile with: cl /W4 /c C4457_hide.cpp
struct S {
void member_fn(unsigned x) {
double a = 0;
for (int x = 0; x < 10; ++x) { // C4457
a += x; // uses local x
}
a += x; // uses parameter x
}
} s;
Compiler Warning (level 4) C4458
10/31/2018 • 2 minutes to read • Edit Online
The declaration of identifier in the local scope hides the declaration of the identically-named identifier at class
scope. This warning lets you know that references to identifier in this scope resolve to the locally declared version,
not the class member version, which may or may not be your intent. To fix this issue, we recommend you give local
variables names that do not conflict with class member names.
Example
The following sample generates C4458 because the parameter x and the local variable y in member_fn have the
same names as data members in the class. To fix this issue, use different names for the parameters and local
variables.
// C4458_hide.cpp
// compile with: cl /W4 /c C4458_hide.cpp
struct S {
int x;
float y;
void member_fn(long x) { // C4458
double y; // C4458
y = x;
// To fix this issue, change the parameter name x
// and local name y to something that does not
// conflict with the data member names.
}
} s;
Compiler Warning (level 4) C4459
10/31/2018 • 2 minutes to read • Edit Online
The declaration of identifier in the local scope hides the declaration of the identically-named identifier in global
scope. This warning lets you know that references to identifier in this scope resolve to the locally declared version,
not the global version, which may or may not be your intent. Generally, we recommend you minimize the use of
global variables as a good engineering practice. To minimize pollution of the global namespace, we recommend
use of a named namespace for global variables.
This warning was new in Visual Studio 2015, in Visual C++ compiler version 18.00. To suppress warnings from
that version of the compiler or later while migrating your code, use the /Wv:18 compiler option.
Example
The following sample generates C4459:
// C4459_hide.cpp
// compile with: cl /W4 /EHsc C4459_hide.cpp
int global_or_local = 1;
int main() {
int global_or_local; // warning C4459
global_or_local = 2;
}
One way to fix this issue is to create a namespace for your globals, but not use a using directive to bring that
namespace into scope, so all references must use the unambiguous qualified names:
// C4459_namespace.cpp
// compile with: cl /W4 /EHsc C4459_namespace.cpp
namespace globals {
int global_or_local = 1;
}
int main() {
int global_or_local; // OK
global_or_local = 2;
globals::global_or_local = 3;
}
Compiler Warning (level 4) C4460
10/31/2018 • 2 minutes to read • Edit Online
WinRT or CLR operator 'operator', has parameter passed by reference. WinRT or CLR operator 'operator' has
different semantics from C++ operator 'operator', did you intend to pass by value?
You passed a value by reference to a user-defined Windows Runtime or CLR operator. If the value is changed
inside the function, note that the value returned after the function call will be assigned the return value of the
function. In standard C++, the changed value is reflected after the function call.
Example
The following sample generates C4460 and shows how to fix it.
// C4460.cpp
// compile with: /W4 /clr
#include <stdio.h>
int main() {
V v;
v.m_i = 0;
Example
The following sample generates C4461.
// C4461.cpp
// compile with: /W1 /clr /c
ref class A {
protected:
!A() {} // C4461
};
// OK
ref struct B {
~B() {
B::!B();
}
!B() {}
};
Compiler Warning (level 1) C4462
11/8/2018 • 2 minutes to read • Edit Online
cannot determine the GUID of the type. Program may fail at runtime.
Warning C4462 occurs in a Windows Runtime app or component when a public TypedEventHandler has as one of
its type parameters a reference to the enclosing class.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning. For
example, to make C4462 into a level 4 warning issue, add this line to your source code file:
#pragma warning(4:4462)
Example
This sample generates warning C4462:
namespace N
{
public ref struct EventArgs sealed {};
public ref struct R sealed
{
R() {}
event Windows::Foundation::TypedEventHandler<R ^, EventArgs^>^ e;
};
}
[Platform::MTAThread]
int main()
{
auto x = ref new N::R();
}
There are two ways to work around the error. One way, shown in the next example, is to give the event internal
accessibility so that it is available to code in the same executable but not to code in other Windows Runtime
components.
internal:
event Windows::Foundation::TypedEventHandler<R ^, EventArgs^>^ e;
If the event must be public, then you can use the other workaround, which is to expose it through a default
interface:
ref struct R;
public interface struct IR{ event Windows::Foundation::TypedEventHandler<R ^, EventArgs^>^ e;};
overflow; assigning value to bit-field that can only hold values from low_value to high_value
The assigned value is outside the range of values that the bit-field can hold. Signed bit-field types use the high-
order bit for the sign, so if n is the bit-field size, the range for signed bit-fields is -2n-1 to 2n-1-1, while unsigned bit-
fields have a range from 0 to 2n -1.
Example
This example generates C4463 because it attempts to assign a value of 3 to a bit-field of type int with a size of 2,
which has a range from -2 to 1.
To fix this issue, you can change the assigned value to something in the allowed range. If the bit-field is intended to
hold unsigned values in the range from 0 to 3, you can change the declaration type to unsigned . If the field is
intended to hold values in the range -4 to 3, then you can change the bit-field size to 3.
// C4463_overflow.cpp
// compile with: cl /W4 /EHsc C4463_overflow.cpp
struct S {
int x : 2; // int type treats high-order bit as sign
};
int main() {
S s;
s.x = 3; // warning C4463: overflow; assigning 3
// to bit-field that can only hold values from -2 to 1
// To fix, change assigned value to fit in range,
// increase size of bitfield, and/or change base type
// to unsigned.
}
Compiler Warning (level 4) C4464
10/31/2018 • 2 minutes to read • Edit Online
A #include directive has a path that includes a '..' parent directory specifier.
Remarks
Starting in Visual Studio 2015 Update 1, the compiler can detect an include directive that contains a '..' path
segment and issue a warning, if enabled. Code written in this way is usually intended to include headers that exist
outside of the project by incorrectly using project-relative paths. This creates a risk that the program could be
compiled by including a different source file than the programmer intends, or that these relative paths would not be
portable to other build environments. Although there is no specific warning for it, we also recommend that you do
not use a parent directory path segment to specify your project include directories.
This warning is new in Visual Studio 2015 Update 1, and is off by default. Use /Wall to enable all warnings that are
off by default, or /wn4464 to enable C4464 as a level n warning. For more information, see Compiler Warnings
That Are Off By Default. For information on how to disable warnings by compiler version, see Compiler warnings
by compiler version.
Example
Source code files that use '..' path segments can trigger this warning when the /Wall option is specified:
// To fix this issue, specify only the header file name, and add
// the absolute path to 'headers\' to your project's include directories
#include "C4426.h"
Compiler Warning (level 1) C4470
10/31/2018 • 2 minutes to read • Edit Online
// C4470.cpp
// compile with: /clr /W1 /LD
#pragma float_control(except, on) // C4470
Compiler Warning (level 4) C4471
10/31/2018 • 3 minutes to read • Edit Online
'enumeration': a forward declaration of an unscoped enumeration must have an underlying type (int assumed)
A forward declaration of an unscoped enumeration was found without a specifier for the underlying type. By
default, Visual C++ assumes int is the underlying type for an enumeration. This can cause issues if a different
type is used in the enumeration definition, for example, if a different explicit type is specified, or if a different type is
implicitly set by an initializer. You may also have portability issues; other compilers do not assume int is the
underlying type of an enumeration.
This warning is off by default; you can use /Wall or /wN4471 to enable it on the command line, or use #pragma
warning in your source file.
In some cases, this warning is spurious. If a forward declaration for an enumeration appears after the definition,
this warning may fire. For example, this code is valid, even though it may cause C4471:
// C4471a.cpp
// Compile with: cl /c /w14471 C4471a.cpp
enum Example { item = 0x80000000UL };
enum Example; // Spurious C4471
// ...
Example
In general, it's safe to use the full definition for an unscoped enumeration instead of a forward declaration. You can
put the definition in a header file and include it in source files that refer to it. This works in code written for C++98
and later. We recommend this solution for portability and ease of maintenance.
// C4471b.cpp
// Compile with: cl /c /w14471 C4471b.cpp
enum Example; // C4471
// To fix, replace the line above with the enumeration definition:
// enum Example { item = 0x80000000UL };
// ...
Example
In C++11, you can add an explicit type to an unscoped enumeration and to its forward declaration. We
recommend this solution only if complex header inclusion logic prevents use of the definition instead of a forward
declaration. This solution can lead to a maintenance issue: if you change the underlying type used for the
enumeration definition, you must also change all of the forward declarations to match, or you may have silent
errors in your code. You can put the forward declaration into a header file to minimize this issue.
// C4471c.cpp
// Client code for enumeration defined in C4471d.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example; // C4471, int assumed
// To fix, replace the lines above with the forward declarations:
// enum Example : unsigned;
// ...
// C4471d.cpp
// Definition for enumeration used in C4471c.cpp
// Compile with: cl /c /w14471 C4471c.cpp C4471d.cpp
enum Example : unsigned { item = 0x80000000 }; // explicit type
// ...
If you specify an explicit type for an enumeration, we recommend you also enable warning C4369, which is on by
default. This identifies cases where an enumeration item requires a different type than the explicitly specified type.
Example
You can change your code to use a scoped enum, a feature that is new in C++11. Both the definition and any client
code that uses the enumeration type must be changed to use a scoped enum. We recommend you use a scoped
enum if you have issues with namespace pollution, as the names of defined enumeration items are limited to the
scope of the enum. Another feature of a scoped enum is that its members can't be implicitly converted to another
integral or enumeration type, which can be a source of subtle bugs.
// C4471e.cpp
// Client code for scoped enumeration defined in C4471f.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum Example; // C4471
// To fix, replace the line above with the forward declaration:
// enum class Example;
// ...
// C4471f.cpp
// Definition for scoped enumeration used in C4471e.cpp
// Compile with: cl /c /w14471 C4471e.cpp C4471f.cpp
enum class Example { item = 0 };
// ...
Compiler Warning (level 1) C4473
10/31/2018 • 2 minutes to read • Edit Online
'function' : not enough arguments passed for format string placeholders and their parameters expect number
variadic arguments, but number were provided the missing variadic argument index is required by format
string 'format_string' this argument is used by a conversion specifier this argument is used as a field width this
argument is used as a precision this argument is used as a buffer size
The compiler detected a mismatch between the number of arguments required to satisfy the placeholders in a
format string, and the number of arguments supplied. Correct use of the printf and scanf families of variadic
functions requires that you supply as many arguments as specified by the format string. Certain placeholders
require additional arguments, to specify the width, precision, or buffer size, as well as an argument for the content.
A mismatch generally means there is a bug in your code.
For information on the arguments associated with printf family format string placeholders, see Format
specification syntax: printf and wprintf functions. See the documentation for information specific to function
function.
This warning is new in Visual Studio 2015.
Example
These samples show two ways warning C4473 can result from a format string mismatch with its arguments, and
also show how to fix the issues.
// c4473p.cpp
// compile with: cl /c /W4 c4473p.cpp
#include <stdio.h>
In the first error message, the compiler detects that an argument is missing, but can't tell whether the missing
argument is the width or the content, so it assumes the supplied argument is the first one, for the width, and the
missing argument is the second one, for the type conversion specifier. You must examine the format string to
determine the actual missing argument.
// c4473s.cpp
// compile with: cl /c /W4 c4473s.cpp
#include <stdio.h>
In this example, scanf_s requires two arguments for each placeholder, one to supply the address to write to, and a
second to supply the size of the first. Check the documentation for each library function for an explanation of the
required arguments.
Compiler Warning (level 1) C4477
10/31/2018 • 2 minutes to read • Edit Online
'function' : format string 'string' requires an argument of type 'type', but variadic argument number has type
'type'
The compiler detected a mismatch between the type of argument required to satisfy the placeholder in a format
string, and the type of argument supplied. Correct use of the printf and scanf families of variadic functions requires
that you supply arguments of the types specified by the format string. A mismatch generally means there is a bug
in your code.
For information on the arguments associated with printf family format string placeholders, see Format
specification syntax: printf and wprintf functions. See the documentation for information specific to function
function.
This warning is new in Visual Studio 2015.
Example
This sample shows two C4477 warnings for the first printf_s function, when two arguments are found to be of the
wrong type, and also shows how to fix the issues.
// C4477p.cpp
// compile with: cl /c /W4 C4477p.cpp
#include <stdio.h>
In the first error message, the compiler detects that a double argument is supplied when an int is expected. A
float is automatically promoted to double in the variadic argument list. The second error message shows that the
compiler expected a double argument, but an int was supplied. The compiler can't tell that you have swapped the
order of the arguments. You must examine the format string to determine the actual argument order and supply
the correct argument types.
Compiler Warning (level 4) C4481
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4481.
// C4481.cpp
// compile with: /W4 /c
class B {
virtual void f(unsigned);
};
class C : B {
void f(unsigned) override; // C4481
void f2(unsigned);
};
Compiler Warning C4484
10/31/2018 • 2 minutes to read • Edit Online
'override_function' : matches base ref class method 'base_class_function', but is not marked 'virtual', 'new' or
'override'; 'new' (and not 'virtual') is assumed
When compiling with /clr, the compiler will not implicitly override a base class function, which means the function
will get a new slot in the vtable. To resolve, explicitly specify whether a function is an override.
For more information, see:
/clr (Common Language Runtime Compilation)
override
new (new slot in vtable)
C4484 is always issued as an error. Use the warning pragma to suppress C4484.
Example
The following sample generates C4484.
// C4484.cpp
// compile with: /clr
ref struct A {
virtual void Test() {}
};
ref struct B : A {
void Test() {} // C4484
};
// OK
ref struct C {
virtual void Test() {}
virtual void Test2() {}
};
ref struct D : C {
virtual void Test() new {}
virtual void Test2() override {}
};
Compiler Warning C4485
10/31/2018 • 2 minutes to read • Edit Online
'override_function' : matches base ref class method 'base_class_function ', but is not marked 'new' or 'override';
'new' (and 'virtual') is assumed
An accessor overrides, with or without the virtual keyword, a base class accessor function, but the override or
new specifier was not part of the overriding function signature. Add the new or override specifier to resolve this
warning.
See override and new (new slot in vtable) for more information.
C4485 is always issued as an error. Use the warning pragma to suppress C4485.
Example
The following sample generates C4485
// C4485.cpp
// compile with: /clr
delegate void Del();
ref struct A {
virtual event Del ^E;
};
ref struct B : A {
virtual event Del ^E; // C4485
};
ref struct C : B {
virtual event Del ^E {
void raise() override {}
void add(Del ^) override {}
void remove(Del^) override {}
}
};
Compiler Warning (level 1) C4486
10/31/2018 • 2 minutes to read • Edit Online
'function' : a private virtual method of a ref class or value class should be marked 'sealed'
Since a private virtual member function of a managed class or struct cannot be accessed or overridden, it should
be marked sealed.
Example
The following sample generates C4486.
// C4486.cpp
// compile with: /clr /c /W1
ref class B {
private:
virtual void f() {} // C4486
virtual void f1() sealed {} // OK
};
Example
The following sample shows one possible use of a private sealed, virtual function.
// C4486_b.cpp
// compile with: /clr /c
ref class B {};
interface class I {
B^ mf();
};
ref class E : I {
private:
virtual B^ g() sealed = I::mf {
return gcnew B;
}
public:
virtual D^ mf() {
return gcnew D;
}
};
Compiler Warning (level 4) C4487
10/31/2018 • 2 minutes to read • Edit Online
'derived_class_function' : matches inherited non-virtual method 'base_class_function' but is not explicitly marked
'new'
A function in a derived class has the same signature as a non-virtual base class function. C4487 reminds you that
the derived class function does not override the base class function. Explicitly mark the derived class function as
new to resolve this warning.
Example
The following sample generates C4487.
// C4487.cpp
// compile with: /W4 /clr
using namespace System;
public ref struct B {
void f() { Console::WriteLine("in B::f"); }
void g() { Console::WriteLine("in B::g"); }
};
int main() {
B ^ a = gcnew D;
// will call base class functions
a->f();
a->g();
}
Compiler Warning (level 1) C4488
10/31/2018 • 2 minutes to read • Edit Online
Example
C4488 can occur if an implemented member is not public. The following sample generates C4488.
// C4488.cpp
// compile with: /clr /c /W1 /WX
interface struct MyI {
void f1();
};
// OK
ref class C : MyI {
public:
virtual void f1() {}
};
Example
C4488 can occur if an implemented member is not marked virtual. The following sample generates C4488.
// C4488_b.cpp
// compile with: /clr /c /W1 /WX
interface struct MyI {
void f1();
};
'specifier' : not allowed on interface method 'method'; override specifiers are only allowed on ref class and value
class methods
A specifier keyword was incorrectly used on an interface method.
For more information, see Override Specifiers.
Example
The following sample generates C4489.
// C4489.cpp
// compile with: /clr /c /W1
public interface class I {
void f() new; // C4489
virtual void b() override; // C4489
void g(); // OK
};
Compiler Warning (level 1) C4490
10/31/2018 • 2 minutes to read • Edit Online
'override' : incorrect use of override specifier; 'function' does not match a base ref class method
An override specifier was used incorrectly. For example, you do not override an interface function, you implement
it.
For more information, see Override Specifiers.
Example
The following sample generates C4490.
// C4490.cpp
// compile with: /clr /c /W1
'linkage specification' requires use of keyword 'extern' and must precede all other specifiers
A linkage was specified without the extern keyword. Linkage is not relevant to non-extern types.
The compiler assumed the extern keyword.
Compiler Warning (level 1) C4503
10/31/2018 • 2 minutes to read • Edit Online
Remarks
This compiler warning is obsolete and is not generated in Visual Studio 2017 and later compilers.
The decorated name was longer than the compiler limit (4096), and was truncated. To avoid this warning and the
truncation, reduce the number of arguments or the name lengths of identifiers used. Decorated names that are
longer than the compiler limit have a hash applied and are not in danger of a name collision.
When using an older version of Visual Studio, this warning can be issued when your code contains templates
specialized on templates repeatedly. For example, a map of maps (from the C++ Standard Library). In this
situation, you can make your typedefs a type (a struct, for example) that contains the map.
You might, however, decide to not restructure your code. It is possible to ship an application that generates C4503,
but if you get link time errors on a truncated symbol, it can be more difficult to determine the type of the symbol in
the error. Debugging may also be more difficult; the debugger may have difficultly mapping the symbol name to
the type name. The correctness of the program, however, is unaffected by the truncated name.
Example
The following sample generates C4503 in compilers before Visual Studio 2017:
// C4503.cpp
// compile with: /W1 /EHsc /c
// C4503 expected
#include <string>
#include <map>
class Field{};
This sample shows one way to rewrite your code to resolve C4503:
// C4503b.cpp
// compile with: /W1 /EHsc /c
#include <string>
#include <map>
class Field{};
struct Screen2 {
std::map<std::string, Field> Element;
};
struct WebApp2 {
std::map<std::string, Screen2> Element;
};
struct WebAppTest2 {
std::map<std::string, WebApp2> Element;
};
struct Hello2 {
std::map<std::string, WebAppTest2> Element;
};
Hello2 MyWAT2;
Compiler Warning (level 4) C4505
10/31/2018 • 2 minutes to read • Edit Online
// C4508.cpp
// compile with: /W1 /c
#pragma warning (disable : 4430)
func() {} // C4508
void func2() {} // OK
Compiler Warning (level 4) C4510
10/31/2018 • 2 minutes to read • Edit Online
// C4510.cpp
// compile with: /W4
struct A {
const int i;
int &j;
A& operator=( const A& ); // C4510 expected
// uncomment the following line to resolve this C4510
// A(int ii, int &jj) : i(ii), j(jj) {}
}; // C4510
int main() {
}
Compiler Warning (level 3) C4511
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4512.
// C4512.cpp
// compile with: /EHsc /W4
// processor: x86
class Base {
private:
const int a;
public:
Base(int val = 0) : a(val) {}
int get_a() { return a; }
}; // C4512 warning
class Base2 {
private:
const int a;
public:
Base2(int val = 0) : a(val) {}
Base2 & operator=( const Base2 & ) { return *this; }
int get_a() { return a; }
};
public:
Base3(char& r) : cr(r) {}
// Uncomment the following line to explicitly disable copying:
// Base3(const Base3&) = delete;
}; // C4512 warning
int main() {
Base first;
Base second;
// OK
Base2 first2;
Base2 second2;
char c = 'x';
Base3 first3(c);
Base3 second3 = first3; // C2280 if no default copy ctor
}
Compiler Warning (level 4) C4513
10/31/2018 • 2 minutes to read • Edit Online
// C4514.cpp
// compile with: /W4
#pragma warning(default : 4514)
class A
{
public:
void func() // C4514, remove the function to resolve
{
}
};
int main()
{
}
Compiler Warning (level 4) C4515
10/31/2018 • 2 minutes to read • Edit Online
// C4515.cpp
// compile with: /W4
namespace A
{
using namespace A; // C4515
}
int main()
{
}
Compiler Warning (level 4) C4516
10/31/2018 • 2 minutes to read • Edit Online
// C4516.cpp
// compile with: /W4
class A
{
public:
void x(char);
};
class B : protected A
{
public:
A::x; // C4516 on access-declaration
// use the following line instead
// using A::x; // using-declaration, ok
};
int main()
{
}
Compiler Warning (level 4) C4517
10/31/2018 • 2 minutes to read • Edit Online
// C4518.cpp
// compile with: /c /W1
_declspec(dllexport) extern "C" void MyFunction(); // C4518
Example
The following sample generates C4521.
// C4521.cpp
// compile with: /EHsc /W3
#include <iostream>
int main() {
A o1; // Calls default constructor.
A o2( o1 ); // Calls A( A& ).
const A o3; // Calls default constructor.
A o4( o3 ); // Calls A( const A& ).
}
Compiler Warning (level 3) C4522
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4522.
// C4522.cpp
// compile with: /EHsc /W3
#include <iostream>
int main() {
A o1, o2;
o2 = o1;
const A o3;
o1 = o3;
}
Compiler Warning (level 3) C4523
10/31/2018 • 2 minutes to read • Edit Online
'function' : static member function cannot override virtual function 'virtual function'override ignored, virtual
function will be hidden
The static member function meets the criteria to override the virtual function, which makes the member function
both virtual and static.
The following code generates C4526:
// C4526.cpp
// compile with: /W1 /c
// C4526 expected
struct myStruct1 {
virtual void __stdcall func( int ) = 0;
};
C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
C++ exception handling was used but /EHsc was not selected.
When the /EHsc option has not been enabled, an object with automatic storage in the frame, between the function
doing the throw and the function catching the throw, will not be destroyed. However, an object with automatic
storage created in a try or catch block will be destroyed.
The following sample generates C4530:
// C4530.cpp
// compile with: /W1
int main() {
try{} catch(int*) {} // C4530
}
'continue' : jump out of __finally/finally block has undefined behavior during termination handling
The compiler encountered one of the following keywords:
continue
break
goto
causing a jump out of a __finally or finally block during abnormal termination.
If an exception occurs, and while the stack is being unwound during execution of the termination handlers (the
__finally or finally blocks), and your code jumps out of a __finally block before the __finally block ends, the
behavior is undefined. Control may not return to the unwinding code, so the exception may not be handled
properly.
If you must jump out of a __finally block, check for abnormal termination first.
The following sample generates C4532; simply comment out the jump statements to resolve the warnings.
// C4532.cpp
// compile with: /W1
// C4532 expected
int main() {
int i;
for (i = 0; i < 10; i++) {
__try {
} __finally {
// Delete the following line to resolve.
continue;
}
__try {
} __finally {
// Delete the following line to resolve.
break;
}
}
}
Compiler Warning (level 1) C4533
10/31/2018 • 2 minutes to read • Edit Online
// C4533.cpp
// compile with: /W1
#include <stdio.h>
struct A
{
int m_data;
};
int main()
{
if (1)
{
goto Label;
}
A a = { 100 };
Label: // C4533
printf("\n%d", a.m_data); // prints an uninitialized value
}
Compiler Warning (level 3) C4534
10/31/2018 • 2 minutes to read • Edit Online
'constructor' will not be a default constructor for class 'class' due to the default argument
An unmanaged class can have a constructor with parameters that have default values and the compiler will use this
as the default constructor. A class marked with the value keyword will not use a constructor with default values
for its parameters as a default constructor.
For more information, see Classes and Structs.
The following sample generates C4534:
// C4534.cpp
// compile with: /W3 /clr /WX
value class MyClass {
public:
int ii;
MyClass(int i = 9) { // C4534, will not be the default constructor
i++;
}
};
int main() {
MyClass ^ xx = gcnew MyClass;
xx->ii = 0;
}
Compiler Warning (level 3) C4535
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4535.
// C4535.cpp
// compile with: /W3 /EHsc /c
// C4535 expected
// to fix, compile with /EHa instead
#include <stdio.h>
#include <windows.h>
#include <eh.h>
void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );
class SE_Exception {
private:
unsigned int nSE;
public:
SE_Exception() {}
SE_Exception( unsigned int n ) : nSE( n ) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};
int main() {
try {
_set_se_translator( trans_func );
SEFunc();
}
catch( SE_Exception e ) {
printf_s( "Caught a __try exception with SE_Exception.\n" );
}
}
void SEFunc() {
__try {
int x, y=0;
x = 5 / y;
}
__finally {
printf_s( "In finally\n" );
}
}
Remarks
A reference was passed where an object (user-defined type) was expected. A reference is not an object, but inline
assembler code is not able to make the distinction. The compiler generates code as though object were an instance.
Example
The following sample generates C4537 and shows how to fix it:
// C4537.cpp
// compile with: /W1 /c
// processor: x86
struct S {
int member;
};
// C4538.cpp
// compile with: /clr /W3 /LD
const array<int> ^f1(); // C4538
array<const int> ^f2(); // OK
Compiler Warning (level 1) C4540
10/31/2018 • 2 minutes to read • Edit Online
dynamic_cast used to convert to inaccessible or ambiguous base; run-time test will fail ('type1' to 'type2')
You used dynamic_cast to convert from one type to another. The compiler determined that the cast would always
fail (return NULL ) because a base class is inaccessible ( private , for instance) or ambiguous (appears more than
once in the class hierarchy, for instance).
The following shows an example of this warning. Class B is derived from class A. The program uses dynamic_cast
to cast from class B (the derived class) to class A, which will always fail because class B is private and thus
inaccessible. Changing the access of A to public will resolve the warning.
// C4540.cpp
// compile with: /W1
struct A {
virtual void g() {}
};
struct B : private A {
virtual void g() {}
};
int main() {
B b;
A * ap = dynamic_cast<A*>(&b); // C4540
}
Compiler Warning (level 1) C4541
10/31/2018 • 2 minutes to read • Edit Online
'identifier' used on polymorphic type 'type' with /GR -; unpredictable behavior may result
You tried to use a feature that requires run-time type information without enabling run-time type information.
Recompile with /GR.
Compiler Warning (level 3) C4543
10/31/2018 • 2 minutes to read • Edit Online
// C4544.cpp
// compile with: /W1 /LD
template <class T>
struct S
{
template <class T1>
struct S1;
void f();
};
// C4544b.cpp
// compile with: /LD
template <class T = int>
struct S
{
template <class T1>
struct S1;
void f();
};
// C4545.cpp
// compile with: /W1
#pragma warning (default : 4545)
void f() { }
int main()
{
*(&f), 10; // C4545
// try the following line instead
// (*(&f))(), 10;
}
Compiler Warning (level 1) C4546
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4546:
// C4546.cpp
// compile with: /W1
#pragma warning (default : 4546)
void f(int i) {
i++;
}
int main() {
int i = 0, k = 0;
if ( f, k ) // C4546
// try the following line instead
// if ( f(i), k )
i++;
}
Compiler Warning (level 1) C4547
10/31/2018 • 2 minutes to read • Edit Online
'operator' : operator before comma has no effect; expected operator with side-effect
The compiler detected an ill-formed comma expression.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
The following sample generates C4547:
// C4547.cpp
// compile with: /W1
#pragma warning (default : 4547)
int i = 0;
int j = 1;
int main() {
int l = (i != i,0); // C4547
// try the following line instead
// int l = (i != i);
// or
// int l = ((void)(i != i),0);
}
Compiler Warning (level 1) C4548
10/31/2018 • 2 minutes to read • Edit Online
// C4548.cpp
// compile with: /W1
#pragma warning (default : 4548)
int main()
{
int i = 0, k = 0;
if ( i, k ) // C4548
// try the following line instead
// if ( i = 0, k )
i++;
}
Compiler Warning (level 1) C4549
10/31/2018 • 2 minutes to read • Edit Online
'operator' : operator before comma has no effect; did you intend 'operator'?
The compiler detected an ill-formed comma expression.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
The following sample generates C4549:
// C4549.cpp
// compile with: /W1
#pragma warning (default : 4549)
int main() {
int i = 0, k = 0;
if ( i == 0, k ) // C4549
// try the following line instead
// if ( i == 0 )
i++;
}
Compiler Warning (level 1) C4550
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4550.cpp
// compile with: /W1
bool f()
{
return true;
}
int main()
{
pf_t pf = f;
if (*pf) {} // C4550
return 0;
}
Compiler Warning (level 1) C4551
10/31/2018 • 2 minutes to read • Edit Online
// C4551.cpp
// compile with: /W1
void function1() {
}
int main() {
function1; // C4551
function1(); // OK
}
Compiler Warning (level 1) C4552
10/31/2018 • 2 minutes to read • Edit Online
// C4552.cpp
// compile with: /W1
int main() {
int i, j;
i + j; // C4552
// try the following line instead
// (i + j);
}
Compiler Warning (level 1) C4553
10/31/2018 • 2 minutes to read • Edit Online
// C4553.cpp
// compile with: /W1
int func()
{
return 0;
}
int main()
{
int i;
i == func(); // C4553
// try the following line instead
// i = func();
}
Compiler Warning (level 3) C4554
10/31/2018 • 2 minutes to read • Edit Online
'operator' : check operator precedence for possible error; use parentheses to clarify precedence
The following sample generates C4554:
// C4554.cpp
// compile with: /W3 /WX
int main() {
int a = 0, b = 0, c = 0;
a = a << b + c; // C4554
// probably intended (a << b) + c,
// but will get a << (b + c)
}
Compiler Warning (level 1) C4555
10/31/2018 • 2 minutes to read • Edit Online
// C4555.cpp
// compile with: /W1
#pragma warning(default:4555)
void func1()
{
1; // C4555
}
void func2()
{
int x;
x; // C4555
}
int main()
{
}
Compiler Warning (level 1) C4556
3/12/2019 • 2 minutes to read • Edit Online
Remarks
An intrinsic matches a hardware instruction. The hardware instruction has a fixed number of bits to encode the
constant. If value is out of range, it will not encode properly. The compiler truncates the extra bits.
Example
The following sample generates C4556:
// C4556.cpp
// compile with: /W1
// processor: x86 IPF
#include <xmmintrin.h>
void test()
{
__m64 m;
_m_pextrw(m, 5); // C4556
}
int main()
{
}
Compiler Warning (level 3) C4557
10/31/2018 • 2 minutes to read • Edit Online
// C4557.cpp
// compile with: /W3
#pragma warning(default : 4557)
int main()
{
int i;
__assume(i++); // C4557
}
Compiler Warning (level 1) C4558
10/31/2018 • 2 minutes to read • Edit Online
// C4558.cpp
// compile with: /W1
// processor: x86
void asm_test() {
__asm pinsrw mm1, eax, 8; // C4558
}
int main() {
}
Compiler Warning (level 4) C4559
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A function was redefined or redeclared and the second definition or declaration added a __declspec modifier
(modifier). This warning is informational. To fix this warning, delete one of the definitions.
Example
The following sample generates C4559:
// C4559.cpp
// compile with: /W4 /LD
void f();
__declspec(noalias) void f(); // C4559
Compiler Warning (level 1) C4561
10/31/2018 • 2 minutes to read • Edit Online
// C4561.cpp
// compile with: /clr /W1 /c
// processor: x86
void __fastcall Func(void *p); // C4561, remove __fastcall to resolve
Compiler Warning (level 4) C4564
10/31/2018 • 2 minutes to read • Edit Online
' C4564.vb
' compile with: vbc /t:library C4564.vb
Public class TestClass
Public Sub MyMethod (a as Integer, _
Optional c as Integer=1)
End Sub
End class
And the following C++ sample that uses the .dll created with Visual Basic,
// C4564.cpp
// compile with: /clr /W4 /WX
#using <C4564.dll>
int main() {
TestClass ^ myx = gcnew TestClass(); // C4564
myx->MyMethod(9);
// try the following line instead, to avoid an error
// myx->MyMethod(9, 1);
}
Compiler Warning (level 4) C4565
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A symbol was redefined or redeclared and the second definition or declaration, unlike the first definition or
declaration, did not have a __declspec modifier (modifier). This warning is informational. To fix this warning,
delete one of the definitions.
Example
The following sample generates C4565:
// C4565.cpp
// compile with: /W4 /LD
__declspec(noalias) void f();
void f(); // C4565
Compiler Warning (level 1) C4566
10/31/2018 • 2 minutes to read • Edit Online
character represented by universal-character-name 'char' cannot be represented in the current code page (page)
Not every Unicode character can be represented in your current ANSI code page.
Narrow strings (one-byte characters) are converted to multi-byte characters whereas wide strings (two-byte
characters) are not.
The following sample generates C4566:
// C4566.cpp
// compile with: /W1
int main() {
char c1 = '\u03a0'; // C4566
char c2 = '\u0642'; // C4566
wchar_t c3 = L'\u03a0'; // OK
wchar_t c4 = L'\u0642'; // OK
}
Compiler Warning (level 3) C4570
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4570.
// C4570.cpp
// compile with: /clr /W3 /c
ref struct X { // C4570
// try the following line instead
// ref class X abstract {
virtual void f() abstract;
};
Compiler Warning (level 4) C4571
10/31/2018 • 2 minutes to read • Edit Online
Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught
C4571 is generated for every catch(...) block when compiling with /EHs.
When compiling with /EHs, a catch(...) block will not catch a structured exception (divide by zero, null pointer, for
example); a catch(...) block will only catch explicitly-thrown, C++ exceptions. For more information, see Exception
Handling.
This warning is off by default. Turn this warning on to ensure that when you compile with /EHs your catch (...)
blocks do not intend to catch structured exceptions. See Compiler Warnings That Are Off by Default for more
information.
You can resolve C4571 in one of the following ways,
Compile with /EHa if you still want your catch(...) blocks to catch structured exceptions.
Do not enable C4571 if you do not want your catch(...) blocks to catch structured exceptions, but you still
want to use catch(...) blocks. You can still catch structured exceptions using the structured exception handling
keywords (__try, __except, and __finally). But remember, when compiled /EHs destructors will only be
called when a C++ exception is thrown, not when an SEH exception occurs.
Replace catch(...) block with catch blocks for specific C++ exceptions, and optionally, add structured
exception handling around the C++ exception handling (__try, __except, and __finally). See Structured
Exception Handling (C/C++) for more information.
See /EH (Exception Handling Model) for more information.
Example
The following sample generates C4571.
// C4571.cpp
// compile with: /EHs /W4 /c
#pragma warning(default : 4571)
int main() {
try {
int i = 0, j = 1;
j /= i; // this will throw a SE (divide by zero)
}
catch(...) {} // C4571 warning
}
Compiler Warning (level 1) C4572
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4572.
// C4572.cpp
// compile with: /clr /W1
void Func([System::ParamArray] array<int> ^); // C4572
void Func2(... array<int> ^){} // OK
int main() {
Func2(1, 2, 3);
}
Compiler Warning (level 3) C4580
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C3454 and shows how to fix it.
// C4580.cpp
// compile with: /W3 /c /clr
[attribute] // C4580
public ref class Attr {
public:
int m_t;
};
Example
The following sample generates C4581.
// C4581.cpp
// compile with: /c /W1
#include "unknwn.h"
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface IMyI : IUnknown {};
// C4584.cpp
// compile with: /W1 /LD
class A {
};
class B : public A {
};
In this case, a warning would be issued on class C because it inherits both from class A and class B, which also
inherits from class A. This warning serves as a reminder that you must fully qualify the use of members from these
base classes or a compiler error will be generated due to the ambiguity as to which class member you refer.
Compiler Warnings C4600 Through C4799
3/14/2019 • 13 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the warning messages that are generated by
the compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Warning messages
WARNING MESSAGE
Compiler Warning (level 1) C4600 #pragma 'macro name': expected a valid non-empty string
Compiler warning (level 1) C4602 #pragma pop_macro: 'macro name' no previous #pragma
push_macro for this identifier
Compiler warning (level 1) C4603 'identifier': macro is not defined or definition is different after
precompiled header use
Compiler warning (level 1) C4604 'type': passing argument by value across native and managed
boundary requires valid copy constructor. Otherwise the
runtime behavior is undefined
Compiler warning (level 1) C4605 '/Dmacro' specified on current command line, but was not
specified when precompiled header was built
WARNING MESSAGE
Compiler Warning (level 1) C4606 #pragma warning: 'warning number' ignored; Code Analysis
warnings are not associated with warning levels
Compiler Warning (level 3) C4608 'union_member' has already been initialized by another union
member in the initializer list, 'union_member'
Compiler warning (level 3, Error) C4609 'type1' derives from default interface 'interface' on type
'type2'. Use a different default interface for 'type1', or break
the base/derived relationship.
Compiler Warning (level 4) C4610 object 'class' can never be instantiated - user defined
constructor required
Compiler Warning (level 4) C4611 interaction between 'function' and C++ object destruction is
non-portable
Compiler Warning (level 1) C4615 #pragma warning: unknown user warning type
Compiler Warning (level 1) C4616 #pragma warning: warning number 'number' not a valid
compiler warning
Compiler Warning (level 1) C4618 pragma parameters included an empty string; pragma ignored
Compiler Warning (level 3) C4619 #pragma warning: there is no warning number 'number'
Compiler warning (level 1) C4620 no postfix form of 'operator ++' found for type 'type', using
prefix form
Compiler Warning (level 1) C4621 no postfix form of 'operator --' found for type 'type', using
prefix form
Compiler warning (level 3) C4622 overwriting debug information formed during creation of the
precompiled header in object file: 'file'
Compiler Warning (level 4) C4623 'derived class': default constructor was implicitly defined as
deleted because a base class default constructor is inaccessible
or deleted
Compiler Warning (level 1) C4624 'derived class': destructor was implicitly defined as deleted
because a base class destructor is inaccessible or deleted
Compiler Warning (level 4) C4625 'derived class': copy constructor was implicitly defined as
deleted because a base class copy constructor is inaccessible
or deleted
Compiler Warning (level 4) C4626 'derived class': assignment operator was implicitly defined as
deleted because a base class assignment operator is
inaccessible or deleted
WARNING MESSAGE
Compiler Warning (level 1) C4627 '<identifier>': skipped when looking for precompiled header
use
Compiler Warning (level 1) C4628 digraphs not supported with -Ze. Character sequence
'digraph' not interpreted as alternate token for '%s'
Compiler warning (level 4) C4629 digraph used, character sequence 'digraph' interpreted as
token 'char' (insert a space between the two characters if this
is not what you intended)
Compiler Warning (level 1) C4630 'symbol': 'extern' storage-class specifier illegal on member
definition
Compiler warning (level 2) C4631 MSXML or XPath unavailable, XML document comments will
not be processed. reason
Compiler Warning (level 1) C4632 XML document comment: file - access denied: reason
Compiler Warning (level 3) C4633 XML document comment target: error: reason
Compiler warning (level 4) C4634 XML document comment target: cannot be applied: reason
Compiler warning (level 3) C4635 XML document comment target: badly-formed XML: reason
Compiler warning (level 3) C4636 XML document comment applied to construct: tag requires
non-empty 'attribute' attribute.
Compiler warning (level 3 and level 4) C4637 XML document comment target: <include> tag discarded.
Reason
Compiler warning (level 3) C4638 XML document comment target: reference to unknown
symbol 'symbol'.
Compiler Warning (level 4) C4639 MSXML error, XML document comments will not be
processed. Reason
Compiler Warning (level 3) C4640 'instance': construction of local static object is not thread-safe
Compiler Warning (level 3) C4641 XML document comment has an ambiguous cross reference:
Compiler warning (level 3) C4645 function declared with __declspec(noreturn) has a return
statement
Compiler warning (level 3) C4646 function declared with __declspec(noreturn) has non-void
return type
Compiler warning (level 3) C4647 behavior change: __is_pod(type) has different value in previous
versions
Compiler Warning (level 1) C4650 debugging information not in precompiled header; only global
symbols from the header will be available
Compiler Warning (level 1) C4651 'definition' specified for precompiled header but not for current
compile
Compiler Warning (level 1) C4652 compiler option 'option' inconsistent with precompiled header;
current command-line option will override that defined in the
precompiled header
Compiler Warning (level 2) C4653 compiler option 'option' inconsistent with precompiled header;
current command-line option ignored
Compiler warning (level 4) C4654 Code placed before include of precompiled header line will be
ignored. Add code to precompiled header.
Compiler warning (level 1) C4655 'symbol': variable type is new since the latest build, or is
defined differently elsewhere
Compiler Warning (level 1) C4656 'symbol': data type is new or has changed since the latest
build, or is defined differently elsewhere
Compiler warning (level 1) C4657 expression involves a data type that is new since the latest
build
Compiler warning (level 1) C4658 'function': function prototype is new since the latest build, or is
declared differently elsewhere
Compiler Warning (level 1) C4659 #pragma 'pragma': use of reserved segment 'segment' has
undefined behavior, use #pragma comment(linker, ...)
Compiler Warning (level 1) C4661 'identifier': no suitable definition provided for explicit template
instantiation request
Compiler Warning (level 1) C4667 'function': no function template defined that matches forced
instantiation
Compiler Warning (level 4) C4668 'symbol' is not defined as a preprocessor macro, replacing with
'0' for 'directive'
Compiler Warning (level 1) C4669 'cast': unsafe conversion: 'class' is a managed type object
Compiler Warning (level 4) C4673 throwing 'identifier' the following types will not be considered
at the catch site
WARNING MESSAGE
Compiler warning (level 1) C4674 'method' should be declared 'static' and have exactly one
parameter
Compiler Warning (level 1) C4677 'function': signature of non-private member contains assembly
private type 'private_type'
Compiler warning (level 1) C4678 base class 'base_type' is less accessible than 'derived_type'
Compiler Warning (level 4) C4680 'class': coclass does not specify a default interface
Compiler warning (level 4) C4681 'class': coclass does not specify a default interface that is an
event source
Compiler Warning (level 1) C4683 'function': event source has an 'out'-parameter; exercise
caution when hooking multiple event handlers
Compiler Warning (level 1) C4684 'attribute': WARNING!! attribute may cause invalid code
generation: use with caution
Compiler warning (level 1) C4685 expecting '> >' found '>>' when parsing template parameters
Compiler Warning (level 3) C4686 'user-defined type': possible change in behavior, change in
UDT return calling convention
Compiler Warning (Error) C4687 'class': a sealed abstract class cannot implement an interface
'interface'
Compiler warning (level 1) C4688 'constraint': constraint list contains assembly private type
'type'
Compiler warning (level 4) C4690 [ emitidl( pop ) ]: more pops than pushes
Compiler Warning (level 1) C4691 'type': type referenced was expected in unreferenced assembly
'file', type defined in current translation unit used instead
Compiler Warning (level 1) C4692 'function': signature of non-private member contains assembly
private native type 'native_type'
Compiler warning (level 1, Error) C4693 'class': a sealed abstract class cannot have any instance
members 'instance member'
Compiler warning (level 1, Error) C4694 'class': a sealed abstract class cannot have a base-class
'base_class'
WARNING MESSAGE
Compiler warning (level 1) C4696 /ZBvalue1 option out of range; assuming 'value2'
Compiler Warning (level 1 and level 4) C4700 uninitialized local variable 'name' used
Compiler Warning (level 4) C4701 potentially uninitialized local variable 'name' used
Compiler Warning (level 4) C4703 potentially uninitialized local pointer variable '%s' used
Compiler Warning (level 4) C4709 comma operator within array index expression
Compiler Warning (level 1) C4711 function 'function' selected for automatic inline expansion
Compiler Warning (level 4) C4714 function 'function' marked as __forceinline not inlined
Compiler Warning (level 1) C4715 'function': not all control paths return a value
Compiler Warning (level 1) C4717 'function': recursive on all control paths, function will cause
runtime stack overflow
Compiler warning (level 4) C4718 'function call': recursive call has no side effects, deleting
Compiler warning (level 1) C4719 Double constant found when Qfast specified - use 'f' as a suffix
to indicate single precision
Compiler warning (level 1) C4722 'function': destructor never returns, potential memory leak
Compiler Warning (level 1) C4727 PCH named pch_file with same timestamp found in obj_file_1
and obj_file_2. Using first PCH.
Compiler warning (level 1) C4728 /Yl- option ignored because PCH reference is required
WARNING MESSAGE
Compiler warning (level 4) C4729 function too big for flow graph based warnings
Compiler Warning (Level 1) C4730Compiler warning (level 1) 'main': mixing _m64 and floating point expressions may result
C4730 in incorrect code
Compiler Warning (Level 1) C4731 'pointer': frame pointer register 'register' modified by inline
assembly code
Compiler warning (level 1) C4732 intrinsic '%s' is not supported in this architecture
Compiler Warning (Level 1) C4733 Inline asm assigning to 'FS:0': handler not registered as safe
handler
Compiler Warning (Level 3) C4738 storing 32-bit float result in memory, possible loss of
performance
Compiler warning (level 1) C4739 reference to variable 'var' exceeds its storage space
Compiler Warning (Level 4) C4740 flow in or out of inline asm code suppresses global
optimization
Compiler Warning (Level 1) C4742 'var' has different alignment in 'file1' and 'file2': number and
number
Compiler Warning (Level 1) C4743 'type' has different size in 'file1' and 'file2': number and
number bytes
Compiler Warning (Level 1) C4744 'var' has different type in 'file1' and 'file2': 'type1' and 'type2'
Compiler Warning (level 1) C4747 Calling managed 'entrypoint': Managed code may not be run
under loader lock, including the DLL entrypoint and calls
reached from the DLL entrypoint
Compiler warning (level 1) C4750 'identifier': function with _alloca() inlined into a loop
Compiler warning (level 4) C4751 /arch:AVX does not apply to Intel(R) Streaming SIMD
Extensions that are within inline ASM
Compiler warning (level 4) C4752 found Intel(R) Advanced Vector Extensions; consider using
/arch:AVX
Compiler warning (level 4) C4754 Conversion rules for arithmetic operations in the comparison
at %s(%d) mean that one branch cannot be executed. Cast
'%s' to '%s' (or similar type of %d bytes).
WARNING MESSAGE
Compiler warning C4755 Conversion rules for arithmetic operations in the comparison
at %s(%d) mean that one branch cannot be executed in an
inlined function. Cast '%s' to '%s' (or similar type of %d bytes).
Compiler warning (level 4) C4757 subscript is a large unsigned value, did you intend a negative
constant?
Compiler warning (level 4) C4764 Can not align catch objects to greater than 16 bytes
Compiler warning (level 4) C4767 section name '%s' is longer than 8 characters and will be
truncated by the linker
Compiler warning (level 3) C4768 __declspec attributes before linkage specification are ignored
Compiler warning C4771 Bounds must be created using a simple pointer; MPX intrinsic
function ignored
Compiler Warning (level 1, Error) C4772 #import referenced a type from a missing type library;
'missing_type' used as a placeholder
Compiler warning (level 4) C4774 'string' : format string expected in argument number is not a
string literal
Compiler warning (level 3) C4775 nonstandard extension used in format string 'string' of
function 'function'
Compiler warning (level 1) C4776 '%character' is not allowed in the format string of function
'function'
Compiler warning (level 4) C4777 'function' : format string 'string' requires an argument of type
'type1', but variadic argument number has type 'type2'
Compiler Warning (Level 1) C4788 'identifier': identifier was truncated to 'number' characters
Compiler Warning (Level 1) C4789 buffer 'identifier' of size N bytes will be overrun; M bytes will
be written starting at offset L
Compiler warning (level 2) C4792 function '%s' declared using sysimport and referenced from
native code; import library required to link
Compiler warning (level 1) C4794 segment of thread local storage variable '%s' changed from
'%s' to '%s'
// C4600.cpp
// compile with: /W1
int main()
{
#pragma push_macro("") // C4600 passing an empty string
}
Compiler Warning (level 1) C4602
10/31/2018 • 2 minutes to read • Edit Online
#pragma pop_macro : 'macro name' no previous #pragma push_macro for this identifier
If you use pop_macro for a particular macro, you must first have passed that macro name to push_macro. For
example, the following sample generates C4602:
// C4602.cpp
// compile with: /W1
int main()
{
#pragma pop_macro("x") // C4602 x is not on the stack
}
Compiler Warning (level 1) C4603
3/12/2019 • 2 minutes to read • Edit Online
'<identifier>' : macro is not defined or definition is different after precompiled header use
The macro specified by the identifier placeholder is either different or no longer defined after the precompiler
header is used.
See Also
Creating Precompiled Header Files
Compiler Warning (level 1) C4606
10/31/2018 • 2 minutes to read • Edit Online
#pragma warning : 'warning_number' ignored; Code Analysis warnings are not associated with warning levels
For Code Analysis warnings, only error , once , and default are supported with the warning pragma.
Example
The following sample generates C4606.
// C4606.cpp
// compile with: /c /W1
#pragma warning(1: 6001) // C4606
#pragma warning(once: 6001) // OK
Compiler Warning (level 3) C4608
10/31/2018 • 2 minutes to read • Edit Online
'union_member' has already been initialized by another union member in the initializer list, 'union_member'
Two members of the same union were initialized in an initialization list. You can only access one member of the
union.
The following sample generates C4608:
// C4608.cpp
// compile with: /W3 /c
class X {
public:
X(char c) : m_i( c + 1), m_c(c) {} // C4608
// try the following line instead
// X(char c) : m_c(c) {}
private:
union {
int m_i;
char m_c;
};
};
union Y {
public:
Y(char * name) : m_number(0.3), m_string( name ) {} // C4608
private:
double m_number;
char * m_string;
};
Compiler Warning (level 4) C4610
10/31/2018 • 2 minutes to read • Edit Online
// C4610.cpp
// compile with: /W4
struct A {
int &j;
B(int i = 0) : k(i) {
}
int main() {
}
Compiler Warning (level 4) C4611
10/31/2018 • 2 minutes to read • Edit Online
Remarks
This warning occurs with #pragma include_alias when a filename is incorrect or missing.
The arguments to the #pragma include_alias statement can use the quote form ("filename") or angle-bracket
form (<filename>), but both must use the same form.
Example
// C4612.cpp
// compile with: /W1 /LD
#pragma include_alias("StandardIO", <stdio.h>) // C4612
Compiler Warning (level 1) C4613
10/31/2018 • 2 minutes to read • Edit Online
// C4615.cpp
// compile with: /W1 /LD
#pragma warning(enable : 4401) // C4615, 'enable' not valid specifier
// C4616.cpp
// compile with: /W1 /c
#pragma warning( disable : 0 ) // C4616
#pragma warning( disable : 999 ) // OK
#pragma warning( disable : 4998 ) // OK
Compiler Warning (level 1) C4618
10/31/2018 • 2 minutes to read • Edit Online
// C4618.cpp
// compile with: /W1 /LD
#pragma code_seg("") // C4618
Compiler Warning (level 3) C4619
10/31/2018 • 2 minutes to read • Edit Online
// C4619.cpp
// compile with: /W3 /c
#pragma warning(default : 4619)
#pragma warning(disable : 4354) // C4619, C4354 does not exist
Compiler Warning (level 1) C4620
10/31/2018 • 2 minutes to read • Edit Online
no postfix form of 'operator ++' found for type 'type', using prefix form
There is no postfix increment operator defined for the given type. The compiler used the overloaded prefix
operator.
This warning can be avoided by defining a postfix ++ operator. Create a two-argument version of the ++ operator
as shown here:
// C4620.cpp
// compile with: /W1
class A
{
public:
A(int nData) : m_nData(nData)
{
}
A operator++()
{
m_nData -= 1;
return *this;
}
// A operator++(int)
// {
// A tmp = *this;
// m_nData -= 1;
// return tmp;
// }
private:
int m_nData;
};
int main()
{
A a(10);
++a;
a++; // C4620
}
Compiler Warning (level 1) C4621
10/31/2018 • 2 minutes to read • Edit Online
no postfix form of 'operator --' found for type 'type', using prefix form
There was no postfix decrement operator defined for the given type. The compiler used the overloaded prefix
operator.
This warning can be avoided by defining a postfix -- operator. Create a two-argument version of the --
operator as shown below:
// C4621.cpp
// compile with: /W1
class A
{
public:
A(int nData) : m_nData(nData)
{
}
A operator--()
{
m_nData -= 1;
return *this;
}
// A operator--(int)
// {
// A tmp = *this;
// m_nData -= 1;
// return tmp;
// }
private:
int m_nData;
};
int main()
{
A a(10);
--a;
a--; // C4621
}
Compiler Warning (level 3) C4622
10/31/2018 • 2 minutes to read • Edit Online
Overwriting debug information formed during creation of the precompiled header in object file: 'file'
CodeView information in the specified file was lost when it was compiled with the /Yu (Use Precompiled Headers)
option.
Rename the object file (using /Fo) when creating or using the precompiled header file, and link using the new
object file.
Compiler Warning (level 4) C4623
10/31/2018 • 2 minutes to read • Edit Online
' derived class ' : default constructor was implicitly defined as deleted because a base class default constructor is
inaccessible or deleted
A constructor was not accessible in a base class and was not generated for the derived class. Any attempt to create
an object of this type on the stack will cause a compiler error.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Example
The following sample generates C4623.
// C4623.cpp
// compile with: /W4
#pragma warning(default : 4623)
class B {
B();
};
class C {
public:
C();
};
int main() {
// D d; will cause an error
}
Compiler Warning (level 1) C4624
10/31/2018 • 2 minutes to read • Edit Online
'derived class' : destructor was implicitly defined as deleted because a base class destructor is inaccessible or
deleted
A destructor was not accessible or deleted in a base class and was therefore not generated for a derived class. Any
attempt to create an object of this type on the stack will cause a compiler error.
The following sample generates C4624 and shows how to fix it:
// C4624.cpp
// compile with: /W1 /c
class B {
// Uncomment the following line to fix.
// public:
~B();
};
'derived class' : copy constructor was implicitly defined as deleted because a base class copy constructor is
inaccessible or deleted
A copy constructor was deleted or not accessible in a base class and was therefore not generated for a derived
class. Any attempt to copy an object of this type will cause a compiler error.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Example
The following sample generates C4625 and shows how to fix it.
// C4625.cpp
// compile with: /W4 /c
#pragma warning(default : 4625)
struct A {
A() {}
private:
A(const A&) {}
};
struct D : A {};
struct E : D {}; // OK
Compiler Warning (level 4) C4626
10/31/2018 • 2 minutes to read • Edit Online
'derived class' : assignment operator was implicitly defined as deleted because a base class assignment operator is
inaccessible or deleted
An assignment operator was deleted or not accessible in a base class and was therefore not generated for a
derived class. Any attempt to assign objects of this type will cause a compiler error.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4626 and shows how to fix it:
// C4626
// compile with: /W4
#pragma warning(default : 4626)
class B
{
// public:
B& operator = (const B&)
{
return *this;
}
};
class D : public B
{
int main()
{
D m;
D n;
// m = n; // this line will cause an error
}
Compiler Warning (level 1) C4627
3/12/2019 • 2 minutes to read • Edit Online
If the current source file has the /Yu (Use precompiled header file) option set, then the compiler ignores everything
in the file before the precompiled header is included. Warning C4627 is generated in Visual Studio 2015 and
earlier versions if header_file is included before the precompiled header file, and if the precompiled header does
not also include header_file.
Example
This sample demonstrates how the error can occur, and shows how to fix it:
// c4627.cpp
#include <iostream> // C4627 - iostream not included by pch.h
#include "pch.h" // precompiled header file that does not include iostream
// #include <iostream> // To fix, move the iostream header include here from above
int main()
{
std::cout << "std::cout is defined!\n";
}
See Also
Creating Precompiled Header Files
Compiler Warning (level 1) C4628
10/31/2018 • 2 minutes to read • Edit Online
digraphs not supported with -Ze. Character sequence 'digraph' not interpreted as alternate token for 'char'
Digraphs are not supported under /Ze. This warning will be followed by an error.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4628:
// C4628.cpp
// compile with: /WX
#pragma warning(default : 4628)
int main()
<% // C4628 <% digraph for {
}
Compiler Warning (level 4) C4629
10/31/2018 • 2 minutes to read • Edit Online
digraph used, character sequence 'digraph' interpreted as token 'char' (insert a space between the two characters if
this is not what you intended)
Under /Za, the compiler warns when it detects a digraph.
The following sample generates C4629:
// C4629.cpp
// compile with: /Za /W4
int main()
<% // C4629 <% digraph for {
}
Compiler Warning (level 1) C4630
10/31/2018 • 2 minutes to read • Edit Online
// C4630.cpp
// compile with: /W1 /LD
class A {
void func();
};
MSXML or XPath unavailable, XML document comments will not be processed. reason
Your common language runtime installation did not have the necessary files to support processing doc comment.
Reinstall the common language runtime.
Compiler Warning (level 1) C4632
10/31/2018 • 2 minutes to read • Edit Online
// C4632.cpp
// compile with: /clr /docv:\\falsedir /LD /W1
// C4632 expected
// C4633.cpp
// compile with: /clr /doc /LD /W3
Example
The following sample generates C4634.
// C4634.cpp
// compile with: /W4 /doc /c
/// This is a namespace. // C4634
namespace hello {
class MyClass {};
};
Example
The following sample generates C4634.
// C4634_b.cpp
// compile with: /W4 /doc /c
/// This is a template. // C4634
template <class T>
class MyClass {};
Compiler Warning (level 3) C4635
10/31/2018 • 2 minutes to read • Edit Online
// C4635.cpp
// compile with: /doc /clr /W3 /c
/// <summary>
/// The contents of the folder have changed.
/// <summary/> // C4635
Notice that the output for this sample says: End tag 'member' does not match the start tag 'summary'.
The problem with this sample is that the end tag for <summary> is poorly formed, and the compiler does not
recognize it as the <summary> end tag. The <member> tag is embedded in the .xdc file by the compiler in every
/doc compilation. So, the problem here is that the end tag </member>, does not match the previous start tag that
the compiler processed (<summary>.
Compiler Warning (level 3) C4636
10/31/2018 • 2 minutes to read • Edit Online
XML document comment applied to 'construct': tag requires non-empty '' attribute.
A tag, such as cref , did not have a value.
Example
The following sample generates C4636.
// C4636.cpp
// compile with: /clr /doc /W3 /c
/// <see cref=''/>
// /// <see cref='System::Exception'/>
ref struct A { // C4636
void f(int);
};
// OK
/// <see cref='System::Exception'/>
ref struct B {
void f(int);
};
Compiler Warning (level 3) C4637
3/12/2019 • 2 minutes to read • Edit Online
// C4637.cpp
// compile with: /clr /doc /LD /W3
using namespace System;
Remarks
The compiler was unable to resolve a symbol (symbol). The symbol must be valid in the compilation.
Example
The following sample generates C4638:
// C4638.cpp
// compile with: /clr /doc /LD /W3
using namespace System;
// C4640.cpp
// compile with: /W3
#pragma warning(default:4640)
class X {
public:
X() {
}
};
void f() {
static X aX; // C4640
}
int main() {
f();
}
Compiler Warning (level 3) C4641
3/12/2019 • 2 minutes to read • Edit Online
Example
The following sample generates C4641.
// C4641.cpp
// compile with: /W3 /doc /clr /c
// C4645.cpp
// compile with: /W3
void __declspec(noreturn) func() {
return; // C4645, delete this line to resolve
}
int main() {
}
Compiler Warning (level 3) C4646
10/31/2018 • 2 minutes to read • Edit Online
// C4646.cpp
// compile with: /W3 /WX
int __declspec(noreturn) TestFunction()
{ // C4646 make return type void
}
Compiler Warning (level 1) C4650
10/31/2018 • 2 minutes to read • Edit Online
debugging information not in precompiled header; only global symbols from the header will be available
The precompiled header file was not compiled with Microsoft symbolic debugging information.
When linked, the resulting executable or dynamic-link library file will not include debugging information for local
symbols contained in the precompiled header.
This warning can be avoided by recompiling the precompiled header file with the /Zi command-line option.
Compiler Warning (level 1) C4651
10/31/2018 • 2 minutes to read • Edit Online
'definition' specified for precompiled header but not for current compile
The definition was specified when the precompiled header was generated, but not in this compilation.
The definition will be in effect inside the precompiled header, but not in the rest of the code.
If a precompiled header was built with /DSYMBOL, the compiler will generate this warning if the /Yu compile
doesn't have /DSYMBOL. Adding /DSYMBOL to the /Yu command line resolves this warning.
Compiler Warning (level 1) C4652
10/31/2018 • 2 minutes to read • Edit Online
compiler option 'option' inconsistent with precompiled header; current command-line option will override that
defined in the precompiled header
The given command-line option differed from that given when the precompiled header (.pch) was created. The
option specified in the current command line was used.
This warning can be avoided by regenerating the precompiled header with the given command-line option.
Compiler Warning (level 2) C4653
10/31/2018 • 2 minutes to read • Edit Online
compiler option 'option' inconsistent with precompiled header; current command-line option ignored
An option specified with the Use Precompiled Headers (/Yu) option was inconsistent with the options specified
when the precompiled header was created. This compilation used the option specified when the precompiled
header was created.
This warning can occur when a different value for the Pack Structures option (/Zp) was specified during
compilation of the precompiled header.
Compiler Warning (level 1) C4655
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : variable type is new since the last build, or is defined differently elsewhere
Remarks
You changed or added a new data type since the last successful build. Edit and Continue does not support changes
to existing data types.
This warning is followed by a Fatal Error C1092. For further information, see the Supported Code Changes.
To remove this warning without ending the current debug session
1. Change the data type back to its state prior to the error.
2. From the Debug menu, choose Apply Code Changes.
To remove this warning without changing your source code
1. From the Debug menu, choose Stop Debugging.
2. From the Build menu, choose Build.
Compiler Warning (level 1) C4656
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : data type is new or has changed since the last build, or is defined differently elsewhere
You added or changed a data type, making it new to your source code since the last successful build. Edit and
Continue does not support changes to existing data types.
This warning will always be followed by Fatal Error C1092. For further information, see the Supported Code
Changes.
To remove this warning without ending the current debug session
1. Change the data type back to its state prior to the error.
2. From the Debug menu, choose Apply Code Changes.
To remove this error without changing your source code
1. From the Debug menu, choose Stop Debugging.
2. From the Build menu, choose Build.
Compiler Warning (level 1) C4657
10/31/2018 • 2 minutes to read • Edit Online
expression involves a data type that is new since the last build
You added or changed a data type, making it new to your source code since the last successful build. Edit and
Continue does not support changes to existing data types.
This warning will always be followed by Fatal Error C1092. For further information, see the Supported Code
Changes.
To remove this warning without ending the current debug session
1. Change the data type back to its state prior to the error.
2. From the Debug menu, choose Apply Code Changes.
To remove this error without changing your source code
1. From the Debug menu, choose Stop Debugging.
2. From the Build menu, choose Build.
Compiler Warning (level 1) C4659
10/31/2018 • 2 minutes to read • Edit Online
#pragma 'pragma' : use of reserved segment 'segment' has undefined behavior, use #pragma comment(linker, ...)
The .drectve option was used to pass an option to the linker. Instead use pragma comment for passing a linker
option.
// C4659.cpp
// compile with: /W1 /LD
#pragma code_seg(".drectve") // C4659
Compiler Warning (level 1) C4661
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4661.cpp
// compile with: /W1 /LD
template<class T> class MyClass {
public:
void i(); // declaration but not definition
};
template MyClass< int >; // C4661
Compiler Warning (level 1) C4662
10/31/2018 • 2 minutes to read • Edit Online
explicit instantiation; template-class 'identifier1' has no definition from which to specialize 'identifier2'
The specified template-class was declared, but not defined.
Example
// C4662.cpp
// compile with: /W1 /LD
template<class T, int i> class MyClass; // no definition
template MyClass< int, 1>; // C4662
Compiler Warning (level 1) C4667
10/31/2018 • 2 minutes to read • Edit Online
// C4667a.cpp
// compile with: /LD /W1
template
void max(const int &, const int &); // C4667 expected
// C4667b.cpp
// compile with: /LD
// Declare the function template
template<typename T>
const T &max(const T &a, const T &b) {
return (a > b) ? a : b;
}
// Then forcibly instantiate it with a desired type ... i.e. 'int'
//
template
const int &max(const int &, const int &);
Compiler Warning (level 4) C4668
10/31/2018 • 2 minutes to read • Edit Online
'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
A symbol that was not defined was used with a preprocessor directive. The symbol will evaluate to false. To define
a symbol, you can use either the #define directive or /D compiler option.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Example
The following sample generates C4668:
// C4668.cpp
// compile with: /W4
#include <stdio.h>
int main()
{
#if q // C4668, q is not defined
printf_s("defined");
#else
printf_s("undefined");
#endif
}
Compiler Warning (level 1) C4669
10/31/2018 • 2 minutes to read • Edit Online
// C4669.cpp
// compile with: /clr /W1
ref struct A {
int i;
Object ^ pObj; // remove the managed member to fix the warning
};
ref struct B {
int j;
};
int main() {
A ^ a = gcnew A;
B ^ b = reinterpret_cast<B ^>(a); // C4669
}
Compiler Warning (level 4) C4670
10/31/2018 • 2 minutes to read • Edit Online
// C4670.cpp
// compile with: /EHsc /W4
class A
{
};
class B : /* public */ A
{
} b; // inherits A with private access by default
int main()
{
try
{
throw b; // C4670
}
catch( B )
{
}
}
Compiler Warning (level 4) C4672
10/31/2018 • 2 minutes to read • Edit Online
throwing 'identifier' the following types will not be considered at the catch site
A throw object cannot be handled in the catch block. Each type that cannot be handled is listed in the error output
immediately following the line containing this warning. Each unhandled type has its own warning. Read the
warning for each specific type for more information.
The following sample generates C4673:
// C4673.cpp
// compile with: /EHsc /W4
class Base {
private:
char * m_chr;
public:
Base() {
m_chr = 0;
}
~Base() {
if(m_chr)
delete m_chr;
}
};
int main() {
try {
Derv D1;
// delete previous line, uncomment the next line to resolve
// Base D1;
throw D1; // C4673
}
catch(...) {}
}
Compiler Warning (level 1) C4674
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4674.
// C4674.cpp
// compile with: /clr /WX /W1 /LD
ref class G {
int op_Implicit(int i) { // C4674
return 0;
}
};
Compiler Warning (level 1) C4677
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4677.
// C4677.cpp
// compile with: /clr /c /W1
delegate void TestDel();
public delegate void TestDel2();
The compiler encountered a construct that it cannot support, that cannot be imported from metadata.
Do not try to use the construct.
Compiler Warning (level 4) C4680
10/31/2018 • 2 minutes to read • Edit Online
// C4680.cpp
// compile with: /W4
#include <windows.h>
[module(name="MyModule")];
[ object, uuid(373a1a4c-469b-11d3-a6b0-00c04f79ae8f) ]
__interface IMyIface1
{
HRESULT f1();
};
[ object, uuid(37331a4c-469b-11d3-a6b0-00c04f79ae8f) ]
__interface IMyIface2
{
HRESULT f1();
};
int main()
{
}
Compiler Warning (level 4) C4681
10/31/2018 • 2 minutes to read • Edit Online
'class' : coclass does not specify a default interface that is an event source
A source interface was not specified for a class.
The following sample generates C4681:
// C4681.cpp
// compile with: /W4 /c
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="test")];
[dual, uuid("00000000-0000-0000-0000-000000000000")]
__interface IEvent { [id(3)] HRESULT myEvent(); };
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface ISource { HRESULT Fire(); };
[ coclass,
source(IEvent),
default(ISource),
// Uncomment the following line to resolve.
// default(IEvent),
uuid("00000000-0000-0000-0000-000000000002")
]
struct CSource : ISource { // C4681
HRESULT Fire() { return 0; }
};
Compiler Warning (level 4) C4682
10/31/2018 • 2 minutes to read • Edit Online
// C4682.cpp
// compile with: /W4
#pragma warning(default : 4682)
#include <windows.h>
[module(name="MyModule")];
int main()
{
}
Compiler Warning (level 1) C4683
10/31/2018 • 2 minutes to read • Edit Online
'function': event source has an 'out'-parameter; exercise caution when hooking multiple event handlers
Remarks
If more than one event sink is listening to a COM event source, the value of an out parameter may be ignored.
Be aware that a memory leak will occur in the following situations:
1. If a method has an out parameter that is internally allocated, for example a BSTR *.
2. If the event has more than one handler (is a multicast event).
The reason for the leak is that the out parameter will be set by more than one handler, but returned to the call site
only by the last handler.
Example
The following sample generates C4683 and shows how to fix it:
// C4683.cpp
// compile with: /W1 /LD
#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"
[ module(name="xx") ];
[ object ]
__interface I {
HRESULT f([out] int* pi);
// try the following line instead
// HRESULT f(int* pi);
};
[ coclass, event_source(com) ]
struct E {
__event __interface I; // C4683
};
Compiler Warning (level 1) C4684
10/31/2018 • 2 minutes to read • Edit Online
'attribute' : WARNING!! attribute may cause invalid code generation: use with caution
You used an attribute that should not commonly be used.
The following sample generates C4684:
// C4684.cpp
// compile with: /W1 /LD
[module(name="xx")]; // C4684 expected
[no_injected_text];
Compiler Warning (level 1) C4685
10/31/2018 • 2 minutes to read • Edit Online
'user-defined type' : possible change in behavior, change in UDT return calling convention
Remarks
A class template specialization was not is defined before it was used in a return type. Anything that instantiates the
class will resolve C4686; declaring an instance or accessing a member (C<int>::anything) are also options.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Example
Try the following instead:
// C4686.cpp
// compile with: /W3
#pragma warning (default : 4686)
template <class T>
class C;
int main() {
f(1); // C4686
}
Example
The following sample generates C4687.
// C4687.cpp
// compile with: /clr /c
interface class A {};
Example
The following sample generates C4688.
// C4688.cpp
// compile with: /clr /c /W1
ref struct A {}; // private type
public ref struct B {};
Remarks
The emitidl attribute was popped one more time that it was pushed.
Example
The following sample generates C4690. To fix this issue, make sure the attribute is popped exactly as many times
as it is pushed.
// C4690.cpp
// compile with: /c /W4
[emitidl(pop)]; // C4690
class x {};
Compiler Warning (level 1) C4691
10/31/2018 • 2 minutes to read • Edit Online
'type' : type referenced was expected in unreferenced assembly 'file', type defined in current translation unit used
instead
The metadata file containing the original type definition is not referenced, and the compiler is using a local type
definition.
In the case where you are rebuilding file, C4691 can be ignored or turned off with pragma warning. That is, if the
file you are building is the same as the file where the compiler expects to find the type definition, you can ignore
C4691.
However, unexpected behavior can occur if the compiler uses a definition that is not from the same assembly that
is referenced in metadata; CLR types are typed not only by the name of the type, but also by the assembly. That is,
a type Z from assembly z.dll is different from a type Z from assembly y.dll.
Example
This sample contains the original type definition.
// C4691_a.cpp
// compile with: /clr /LD /W1
public ref class Original_Type {};
Example
This sample references C4691_a.dll and declares a field of type Original_Type.
// C4691_b.cpp
// compile with: /clr /LD
#using "C4691_a.dll"
public ref class Client {
public:
Original_Type^ ot;
};
Example
The following sample generates C4691. Notice this sample contains a definition for Original_Type and does not
reference C4691a.dll.
To resolve, reference the metadata file that contains the original type definition and remove the local declaration
and definition.
// C4691_c.cpp
// compile with: /clr /LD /W1
// C4691 expected
'function': signature of non-private member contains assembly private native type 'native_type'
A type that is visible outside the assembly contains a member function whose signature contains a native type that
is not visible outside the assembly. Therefore, the member function should not be called if its containing type is
instantiated outside the assembly.
For more information, see Type visibility.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
Example
The following sample generates C4692.
// C4692.cpp
// compile with: /W1 /c /clr
#pragma warning(default:4692)
class Private_Native_Class {};
public class Public_Native_Class {};
public ref class Public_Ref_Class {
public:
void Test(Private_Native_Class *) {} // C4692
void Test2(Public_Native_Class *) {} // OK
};
Compiler Warning C4693
10/31/2018 • 2 minutes to read • Edit Online
'class': a sealed abstract class cannot have any instance members 'Test'
If a type is marked sealed and abstract, it can only have static members.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning.
Example
The following sample generates C4693.
// C4693.cpp
// compile with: /clr /c
public ref class Public_Ref_Class sealed abstract {
public:
void Test() {} // C4693
static void Test2() {} // OK
};
Compiler Warning C4694
10/31/2018 • 2 minutes to read • Edit Online
An abstract and sealed class cannot inherit from a reference type; a sealed and abstract class can neither
implement the base class functions nor allow itself to be used as a base class.
For more information, see abstract, sealed, and Classes and Structs.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning.
Example
The following sample generates C4694.
// C4694.cpp
// compile with: /c /clr
ref struct A {};
ref struct B sealed abstract : A {}; // C4694
Compiler Warning (level 1 and level 4) C4700
10/31/2018 • 2 minutes to read • Edit Online
The local variable name has been used, that is, read from, before it has been assigned a value. In C and C++, local
variables are not initialized by default. Uninitialized variables can contain any value, and their use leads to
undefined behavior. Warning C4700 almost always indicates a bug that can cause unpredictable results or crashes
in your program.
To fix this issue, you can initialize local variables when they are declared, or assign a value to them before they are
used. A function can be used to initialize a variable that's passed as a reference parameter, or when its address is
passed as a pointer parameter.
Example
This sample generates C4700 when variables t, u, and v are used before they are initialized, and shows the kind of
garbage value that can result. Variables x, y, and z do not cause the warning, because they are initialized before use:
// c4700.cpp
// compile by using: cl /EHsc /W4 c4700.cpp
#include <iostream>
int main()
{
int s, t, u, v; // Danger, uninitialized variables
When this code is run, t, u, and v are uninitialized, and the output for s is unpredictable:
Value in s: 37816963
Value in w: 42
Compiler Warning (level 4) C4701
11/9/2018 • 2 minutes to read • Edit Online
Example
The following code generates C4701 and C4703.
#include <malloc.h>
void main()
{
func(9);
}
#include <malloc.h>
if (p != nullptr)
free(p);
}
void main()
{
func(9);
}
See Also
Compiler Warning (level 4) C4703
Warnings, /sdl, and improving uninitialized variable detection
Compiler Warning (level 4) C4702
10/31/2018 • 2 minutes to read • Edit Online
unreachable code
This warning is the result of compiler conformance work that was done for Visual Studio .NET 2003: unreachable
code. When the compiler (back end) detects unreachable code, it will generate C4702, a level 4 warning.
For code that is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, remove
the unreachable code or assure that all source code is reachable by some flow of execution.
Example
The following sample generates C4702.
// C4702.cpp
// compile with: /W4
#include <stdio.h>
int main() {
return 1;
printf_s("I won't print.\n"); // C4702 unreachable
}
Example
When compiling with /GX, /EHc, /EHsc, or /EHac and using extern C functions, code can become unreachable
because extern C functions are assumed to not throw, thus the catch block isn't reachable. If you feel that this
warning is not valid because a function can throw, compile with /EHa or /EHs, depending on the exception
thrown.
For more information, see /EH (Exception Handling Model) for more information.
The following sample generates C4702.
// C4702b.cpp
// compile with: /W4 /EHsc
#include <iostream>
int main() {
try {
Function2();
}
catch (...) {
cout << "Exp: Function2!" << endl; // C4702
}
}
Compiler Warning (level 4) C4703
11/9/2018 • 2 minutes to read • Edit Online
Example
The following code generates C4701 and C4703.
#include <malloc.h>
void main()
{
func(9);
}
#include <malloc.h>
if (p != nullptr)
free(p);
}
void main()
{
func(9);
}
See Also
Compiler Warning (level 4) C4701
Warnings, /sdl, and improving uninitialized variable detection
Compiler Warning (level 4) C4706
10/31/2018 • 2 minutes to read • Edit Online
// C4706a.cpp
// compile with: /W4
int main()
{
int a = 0, b = 0;
if ( a = b ) // C4706
{
}
}
The warning will occur even if you double the parentheses around the test condition:
// C4706b.cpp
// compile with: /W4
int main()
{
int a = 0, b = 0;
if ( ( a = b ) ) // C4706
{
}
}
If your intention is to test a relation and not to make an assignment, use the == operator. For example, the
following line tests whether a and b are equal:
// C4706c.cpp
// compile with: /W4
int main()
{
int a = 0, b = 0;
if ( a == b )
{
}
}
If you intend to make your test value the result of an assignment, test to ensure that the assignment is non-zero or
not null. For example, the following code will not generate this warning:
// C4706d.cpp
// compile with: /W4
int main()
{
int a = 0, b = 0;
if ( ( a = b ) != 0 )
{
}
}
Compiler Warning (level 4) C4709
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4709:
// C4709.cpp
// compile with: /W4
#include <stdio.h>
int main()
{
int arr[2][2];
arr[0][0] = 10;
arr[0][1] = 11;
// C4714.cpp
// compile with: /Ob1 /GX /W4
__forceinline void func1()
{
try
{
}
catch (...)
{
}
}
void func2()
{
func1(); // C4714
}
int main()
{
}
Compiler Warning (level 1) C4715
10/31/2018 • 2 minutes to read • Edit Online
Example
// C4715a.cpp
// compile with: /W1 /LD
int func1( int i )
{
if( i )
return 3; // C4715 warning, nothing returned if i == 0
}
To prevent this warning, modify the code so that all paths assign a return value to the function:
// C4715b.cpp
// compile with: /LD
int func1( int i )
{
if( i ) return 3;
else return 0; // OK, always returns a value
}
It is possible that your code may contain a call to a function that never returns, as in the following example:
// C4715c.cpp
// compile with: /W1 /LD
void fatal()
{
}
int glue()
{
if(0)
return 1;
else if(0)
return 0;
else
fatal(); // C4715
}
This code also generates a warning, because the compiler does not know that fatal never returns. To prevent this
code from generating an error message, declare fatal using __declspec(noreturn).
Compiler Warning (level 1) C4716
10/31/2018 • 2 minutes to read • Edit Online
// C4716.cpp
// compile with: /c /W1
// C4716 expected
#pragma warning(default:4716)
int test() {
// uncomment the following line to resolve
// return 0;
}
Compiler Warning (level 1) C4717
10/31/2018 • 2 minutes to read • Edit Online
'function' : recursive on all control paths, function will cause runtime stack overflow
Every path through a function contains a call to the function. Since there is no way to exit the function without first
calling itself recursively, the function will never exit.
The following sample generates C4717:
// C4717.cpp
// compile with: /W1 /c
// C4717 expected
int func(int x) {
if (x > 1)
return func(x - 1); // recursive call
else {
int y = func(0) + 1; // recursive call
return y;
}
}
int main(){
func(1);
}
Compiler Warning (level 4) C4718
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4722:
// C4722.cpp
// compile with: /O1 /W1 /c
#include <stdlib.h>
class C {
public:
C();
~C() { exit(1); }; // C4722
};
void Test(){
C x;
func(&x);
// control will not leave Test because destructor will exit
}
Compiler Warning (level 3) C4723
10/31/2018 • 2 minutes to read • Edit Online
potential divide by 0
The second operand in a divide operation evaluated to zero at compile time, giving undefined results.
This warning is issued only when using /Og or an optimization option that implies /Og.
The compiler may have generated the zero operand.
Compiler Warning (level 3) C4724
10/31/2018 • 2 minutes to read • Edit Online
potential mod by 0
The second operand in a remainder operation evaluated to zero at compile time, giving undefined results.
Compiler Warning (level 4) C4725
10/31/2018 • 2 minutes to read • Edit Online
// C4725.cpp
// compile with: /W4
// processor: x86
double m32fp = 2.0003e-17;
void f() {
__asm
{
FDIV m32fp // C4725
}
}
int main() {
}
Compiler Warning (level 1) C4727
10/31/2018 • 2 minutes to read • Edit Online
"PCH named pch_file with same timestamp found in obj_file_1 and obj_file_2. Using first PCH.
C4727 occurs when compiling multiple compilands with /Yc, and where the compiler was able to mark all .obj files
with the same .pch timestamp.
To resolve, compile one source file with /Yc /c (creates pch), and the others compile separately with /Yu /c (uses
pch), then link them together.
So, if you did the following and generates C4727:
cl /clr /GL a.cpp b.cpp c.cpp /Ycstdafx.h
You would do the following instead:
cl /clr /GL a.cpp /Ycstdafx.h /c
cl /clr /GL b.cpp c.cpp /Yustdafx.h /link a.obj
For more information, see
/Yc (Create Precompiled Header File)
/Yu (Use Precompiled Header File)
Compiler Warning (Level 1) C4729
10/31/2018 • 2 minutes to read • Edit Online
'main' : mixing _m64 and floating point expressions may result in incorrect code
A function uses __m64 and float/double types. Because the MMX and floating-point registers share the same
physical register space (cannot be used simultaneously), using __m64 and float/double types in the same
function can result in data corruption, possibly causing an exception.
To safely use __m64 types and floating-point types in the same function, each instruction that uses one of the types
should be separated by the _m_empty() (for MMX) or _m_femms() (for 3DNow!) intrinsic.
The following sample generates C4730:
// C4730.cpp
// compile with: /W1
// processor: x86
#include "mmintrin.h"
void func(double)
{
}
// C4731.cpp
// compile with: /W1 /LD
// processor: x86
// C4731 expected
void bad(int p) {
__asm
{
mov ebp, 1
}
if (p == 1)
{
// ...
}
}
EBP is the frame pointer (FPO is disallowed) and it is being modified. When p is later referenced, it is referenced
relative to EBP . But EBP has been overwritten by the code, so the program will not work properly and may even
fault.
Compiler Warning (Level 1) C4733
10/31/2018 • 2 minutes to read • Edit Online
// C4733.cpp
// compile with: /W1 /c
// processor: x86
#include "stdlib.h"
#include "stdio.h"
void my_handler()
{
printf("Hello from my_handler\n");
exit(1);
}
int main()
{
_asm {
push my_handler
mov eax, DWORD PTR fs:0
push eax
mov DWORD PTR fs:0, esp // C4733
}
*(int*)0 = 0;
}
Compiler Warning (Level 3) C4738
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4738:
// C4738.cpp
// compile with: /c /fp:precise /O2 /W3
// processor: x86
#include <stdio.h>
float func(float f)
{
return f;
}
int main()
{
extern float f, f1, f2;
double d = 0.0;
f1 = func(d);
f2 = (float) d;
f = f1 + f2; // C4738
printf_s("%f\n", f);
}
Compiler Warning (Level 1) C4739
10/31/2018 • 2 minutes to read • Edit Online
// C4739.cpp
// compile with: /RTCs /Zi /W1 /c
char *pc;
int main() {
char c;
*(int *)&c = 1; // C4739
// OK
*(char *)&c = 1;
}
Compiler Warning (Level 4) C4740
10/31/2018 • 2 minutes to read • Edit Online
// C4740.cpp
// compile with: /O2 /W4
// processor: x86
int main() {
__asm jmp tester
tester:;
}
Compiler Warning (Level 1) C4742
10/31/2018 • 2 minutes to read • Edit Online
'var' has different alignment in 'file1' and 'file2': number and number
An external variable that was referenced or defined in two files has different alignment in those files. This warning
is emitted when compiler finds that __alignof for the variable in file1 differs from __alignof for the variable in
file2. This can be caused by using incompatible types when declaring variable in different files, or by using non-
matching #pragma pack in different files.
To resolve this warning, either use the same type definition or use different names for the variables.
For more information, see pack and __alignof Operator.
Example
This is the first file that defines the type.
// C4742a.c
// compile with: /c
struct X {
char x, y, z, w;
} global;
Example
The following sample generates C4742.
// C4742b.c
// compile with: C4742a.c /W1 /GL
// C4742 expected
extern struct X {
int a;
} global;
int main() {
global.a = 0;
}
Compiler Warning (Level 1) C4743
10/31/2018 • 2 minutes to read • Edit Online
'type' has different size in 'file1' and 'file2': number and number bytes
An external variable referenced or defined in two files has different types in those files, and the compiler
determined that the size of the variable in file1 differs from the size of the variable in file2.
There is important case when this warning can be emitted for C++. If you declare the same types with the same
name in two different files, if those declarations contain virtual functions, and if the declarations are not the same,
then the compiler can emit warning C4744 for the virtual function tables. The warning occurs because there are
two different sized virtual function tables for the same type, and linker must choose one of them to incorporate
into the executable. It is possible that this can result in your program calling the wrong virtual function.
To resolve this warning, either use the same type definition or use different names for the types or variables.
Example
This sample contains one definition of the type.
// C4743a.cpp
// compile with: /c
class C {
public:
virtual void f1(void);
virtual void f2(void);
virtual void f3(void);
};
void C::f1(void) {}
void C::f2(void) {}
void C::f3(void) {}
C q;
Example
The following sample generates C4743.
// C4743b.cpp
// compile with: C4743a.cpp /W1 /GL /O2
// C4743 expected
class C {
public:
virtual void f1(void);
virtual void f2(void);
virtual void f3(void);
virtual void f4(void);
virtual void f5(void);
};
void C::f4(void) {}
void C::f5(void) {}
C x;
int main() {}
Compiler Warning (Level 1) C4744
10/31/2018 • 2 minutes to read • Edit Online
'var' has different type in 'file1' and 'file2': 'type1' and 'type2'
An external variable referenced or defined in two files has different types in those files. To resolve, either make the
type definitions the same, or change variable name in one of the files.
C4744 is emitted only when files are compiled with /GL. For more information, see /GL (Whole Program
Optimization).
NOTE
C4744 usually occurs in C (not C++) files, because in C++ a variable name is decorated with type information. When the
sample (below) is compiles as C++, you’ll get linker error LNK2019.
Example
This sample contains the first definition.
// C4744.c
// compile with: /c /GL
int global;
Example
The following sample generates C4744.
// C4744b.c
// compile with: C4744.c /GL /W1
// C4744 expected
#include <stdio.h>
main()
{
printf_s("%d\n", global);
}
Compiler Warning C4746
10/31/2018 • 2 minutes to read • Edit Online
Calling managed 'entrypoint': Managed code may not be run under loader lock, including the DLL entrypoint and
calls reached from the DLL entrypoint
The compiler found a (probable) DLL entry point compiled to MSIL. Because of potential problems with loading a
DLL whose entry point has been compiled to MSIL, you are strongly discouraged from compiling a DLL entry
point function to MSIL.
For more information, see Initialization of Mixed Assemblies and Linker Tools Error LNK1306.
To correct this error
1. Do not compile the module with /clr.
2. Mark the entry point function with #pragma unmanaged .
Example
The following sample generates C4747.
// C4747.cpp
// compile with: /clr /c /W1
// C4747 expected
#include <windows.h>
Example
The following code example calls MyFunction in a loop, and MyFunction calls the _alloca function. The
__forceinline modifier causes the inline expansion of the _alloca function.
// c4750.cpp
// compile with: /O2 /W1 /c
#include <intrin.h>
int main(void)
{
for (int i=0; i<50000; i++)
myFunction();
return 0;
}
See Also
_alloca
Compiler Warning (level 4) C4754
11/9/2018 • 3 minutes to read • Edit Online
Conversion rules for arithmetic operations in a comparison mean that one branch cannot be executed.
The C4754 warning is issued because the result of the comparison is always the same. This indicates that one of
the branches of the condition is never executed, most likely because the associated integer expression is incorrect.
This code defect often occurs in incorrect integer overflow checks on 64-bit architectures.
Integer conversion rules are complex and there are many subtle pitfalls. As an alternative to fixing each C4754
warning, you can update the code to use the SafeInt Library.
Example
This sample generates C4754:
// C4754a.cpp
// Compile with: /W4 /c
#include "errno.h"
if (x > 0xFFFFFFFF)
{
// never executes!
return EOVERFLOW;
}
return 0;
}
The addition a + b could cause an arithmetic overflow before the result is upcast to a 64-bit value and assigned to
the 64-bit variable x . This means that the check on x is redundant and will never catch an overflow. In this case,
the compiler emits this warning:
Warning C4754: Conversion rules for arithmetic operations in the comparison at C4754a.cpp (7) mean that one
branch cannot be executed. Cast '(a + ...)' to 'ULONG64' (or similar type of 8 bytes).
To eliminate the warning, you can change the assignment statement to cast the operands to 8-byte values:
Example
The next sample also generates C4754.
// C4754b.cpp
// Compile with: /W4 /c
#include "errno.h"
The sizeof() operator returns a size_t , whose size is architecture-dependent. The example code works on 32-bit
architectures where a size_t is a 32-bit type. However, on 64-bit architectures, size_t is a 64-bit type. The
conversion rules for integers mean that a is upcast to a 64-bit value in the expression a + b < a as if it were
written (size_t)a + (size_t)b < (size_t)a . When a and b are 32-bit integers, the 64-bit addition operation can
never overflow, and the constraint never holds. As a result, the code never detects an integer overflow condition on
64-bit architectures. This example causes the compiler to emit this warning:
Warning C4754: Conversion rules for arithmetic operations in the comparison at C4754b.cpp (7) mean that one
branch cannot be executed. Cast '4' to 'ULONG' (or similar type of 4 bytes).
Notice that the warning message explicitly lists the constant value 4 instead of the original source string—by the
time the warning analysis encounters the offending code, sizeof(unsigned long) has already been converted to a
constant. Therefore, you may have to track down which expression in the source code is associated with the
constant value in the warning message. The most common sources of code resolved to constants in C4754
warning messages are expressions such as sizeof(TYPE) and strlen(szConstantString) .
In this case, the fixed code would resemble this:
Note The line number referred to in compiler warnings is the last line of a statement. In a warning message about
a complex conditional statement that's spread over multiple lines, the line that has the code defect may be several
lines before the line that's reported. For example:
unsigned long a;
// C4756.cpp
// compile with: /W2 /Od
int main()
{
float f = 1e100+1e100; // C4756
}
Compiler Warning (level 4) C4764
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4764:
// C4764.cpp
// compile with: /W4 /EHsc
// processor: x64 IPF
#include <stdio.h>
class A
{
public:
int x;
};
int main()
{
ALIGNEDA a;
try
{
a.x = 15;
throw a;
}
catch (ALIGNEDA b) // can’t align b to > 16 bytes
{
printf_s("%d\n", b.x);
}
} // C4764
Compiler Warning (level 1) C4772
10/31/2018 • 2 minutes to read • Edit Online
#import referenced a type from a missing type library; 'missing -type' used as a placeholder
A type library was referenced with the #import directive. However, the type library contained a reference to
another type library that was not referenced with #import . This other .tlb file was not found by the compiler.
Note that the compiler will not find type libraries in different directories if you use the /I (Additional Include
Directories) compiler option to specify those directories. If you want the compiler to find type libraries in different
directories, add those directories to the PATH environment variable.
By default this warning is issued as an error. C4772 cannot be suppressed with /W0.
Example
This is the first type library needed to reproduce C4772.
// c4772a.idl
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12b")]
library C4772aLib
{
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c100")]
enum E_C4772a
{
one, two, three
};
};
// c4772b.idl
// post-build command: del /f C4772a.tlb
// C4772a.tlb is available when c4772b.tlb is built
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12d")]
library C4772bLib
{
importlib ("c4772a.tlb");
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12e")]
struct S_C4772b
{
enum E_C4772a e;
};
};
// C4772.cpp
// assumes that C4772a.tlb is not available to the compiler
// #import "C4772a.tlb"
#import "C4772b.tlb" // C4772 uncomment previous line to resolve
// and make sure c4772a.tlb is on disk
Compiler Warning (Level 1) C4788
10/31/2018 • 2 minutes to read • Edit Online
C1<x, y, z<T>>::C2<a,b,c>::f
buffer 'identifier' of size N bytes will be overrun; M bytes will be written starting at offset L
Remarks
Warns about buffer overrun when specific C run-time (CRT) functions are used, parameters are passed, and
assignments are performed, such that the data sizes are known at compile time. This warning is for situations that
might elude typical data-size mismatch detection.
The warning appears when data, whose length is known at compile time, is copied and put into a data block whose
size is known at compile time to be too small for the data. The copy must be done by using the intrinsic form of
one of the following CRT functions:
strcpy
memset
memcpy, wmemcpy
The warning also appears when a parameter datatype is mismatched by using a cast, and then a copy assignment
from an lvalue reference is attempted.
Visual C++ might generate this warning for a code path that does not ever execute. You can temporarily disable
the warning by using #pragma , as shown in this example:
#pragma(push)
#pragma warning ( disable : 4789 )
// unused code that generates compiler warning C4789`
#pragma(pop)
This keeps Visual C++ from generating the warning for that specific block of code. The #pragma(push) preserves
the existing state before #pragma warning(disable: 4789) changes it. The #pragma(pop) restores the pushed state,
and removes the effects of the #pragma warning(disable:4789) . For more information about the C++ preprocessor
directive #pragma , see warning and Pragma Directives and the __Pragma Keyword.
Example
The following sample generates C4789.
// C4789.cpp
// compile with: /Oi /W1 /c
#include <string.h>
#include <stdio.h>
int main()
{
char a[20];
strcpy(a, "0000000000000000000000000\n"); // C4789
char buf2[20];
memset(buf2, 'a', 21); // C4789
char c;
wchar_t w = 0;
memcpy(&c, &w, sizeof(wchar_t));
}
Example
The following sample also generates C4789.
// C4789b.cpp
// compile with: /W1 /O2 /c
// processor: x86
short G;
void main()
{
int * p = (int *)&G;
*p = 3; // C4789 - writes an int through a pointer to short
}
Compiler Warning (level 3) C4792
10/31/2018 • 2 minutes to read • Edit Online
function 'function' declared using sysimport and referenced from native code; import library required to link
A native function that was imported into the program with DllImport was called from an unmanaged function.
Therefore, you must link to the import library for the DLL.
This warning cannot be resolved in code or by changing the way you compile. Use the warning pragma to disable
this warning.
The following sample generates C4792:
// C4792.cpp
// compile with: /clr /W3
// C4792 expected
using namespace System::Runtime::InteropServices;
[DllImport("msvcrt")]
extern "C" int __cdecl puts(const char *);
int main() {}
Remarks
The compiler cannot compile function into managed code, even though the /clr compiler option is specified.
Instead, the compiler emits warning C4793 and an explanatory continuation message, and then compiles function
into native code. The continuation message contains the reason text that explains why function cannot be compiled
to MSIL .
This is a level 1 warning when you specify the /clr:pure compiler option. The /clr:pure compiler option is
deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
The following table lists all possible continuation messages.
Aligned data types are not supported in managed code The CLR must be able to allocate data as needed, which might
not be possible if the data is aligned with declarations such as
__m128 or align.
Functions that use '__ImageBase' are not supported in __ImageBase is a special linker symbol that is typically used
managed code only by low-level native code to load a DLL.
varargs are not supported by the '/clr' compiler option Native functions cannot call managed functions that have
variable argument lists (varargs) because the functions have
different stack layout requirements. However, if you specify
the /clr:pure compiler option, variable argument lists are
supported because the assembly can contain only managed
functions. For more information, see Pure and Verifiable Code
(C++/CLI).
The 64-bit CLR does not support data declared with the A pointer must be the same size as a native pointer on the
__ptr32 modifier current platform. For more information, see __ptr32, __ptr64.
The 32-bit CLR does not support data declared with the A pointer must be the same size as a native pointer on the
__ptr64 modifier current platform. For more information, see __ptr32, __ptr64.
One or more intrinsics is not supported in managed code The name of the intrinsic is not available at the time the
message is emitted. However, an intrinsic that causes this
message typically represents a low-level machine instruction.
Inline native assembly ('__asm') is not supported in managed Inline assembly code can contain arbitrary native code, which
code cannot be managed.
A non-__clrcall virtual function thunk must be compiled as A non-__clrcall virtual function thunk must use an unmanaged
native address.
REASON MESSAGE REMARKS
A function using '_setjmp' must be compiled as native The CLR must be able to control program execution. However,
the setjmp function bypasses regular program execution by
saving and restoring low-level information such as registers
and execution state.
Example
The following sample generates C4793.
// C4793.cpp
// compile with: /c /clr /W3
// processor: x86
int asmfunc(void) { // C4793, compiled as unmanaged, native code
__asm {
mov eax, 0
}
}
// C4793_b.cpp
// compile with: /c /clr /W3
#include <setjmp.h>
jmp_buf test_buf;
void f() {
setjmp(test_buf); // C4793 warning
}
segment of thread local storage variable 'variable' changed from 'section name' to '.tls$'
You used #pragma data_seg to put a tls variable in a section not starting with .tls$.
The .tls$x section will exist in the object file where __declspec(thread) variables are defined. A .tls section in the EXE
or DLL will result from these sections.
Example
The following sample generates C4794:
// C4794.cpp
// compile with: /W1 /c
#pragma data_seg(".someseg")
__declspec(thread) int i; // C4794
// OK
#pragma data_seg(".tls$9")
__declspec(thread) int j;
Compiler Warning (level 1) C4799
10/31/2018 • 2 minutes to read • Edit Online
The function has at least one MMX instruction, but does not have an EMMS instruction. When a multimedia
instruction is used, an EMMS instruction or _mm_empty intrinsic should also be used to clear the multimedia tag
word at the end of the MMX code.
You may get C4799 when using ivec.h, indicating that the code does not use properly execute the EMMS
instruction before returning. This is a false warning for these headers. You may turn these off by defining
_SILENCE_IVEC_C4799 in ivec.h. However, be aware that this will also keep the compiler from giving correct
warnings of this type.
For related information, see Intel's MMX Instruction Set.
Compiler Warnings C4800 Through C5999
3/14/2019 • 12 minutes to read • Edit Online
The articles in this section of the documentation explain a subset of the warning messages that are generated by
the compiler.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Warning messages
WARNING MESSAGE
Compiler Warning (level 3) C4800 'type': forcing value to bool 'true' or 'false' (performance
warning)
Compiler Warning (level 1) C4803 'method': the raise method has a different storage class from
that of the event, 'event'
Compiler Warning (level 1) C4804 'operation': unsafe use of type 'bool' in operation
Compiler Warning (level 1) C4805 'operation': unsafe mix of type 'type1' and type 'type2' in
operation
Compiler warning (level 1) C4806 'operation': unsafe operation: no value of type 'type1'
promoted to type 'type2' can equal the given constant
WARNING MESSAGE
Compiler warning (level 1) C4807 'operation': unsafe mix of type 'type1' and signed bit field of
type 'type2'
Compiler warning (level 1) C4808 case 'value' is not a valid value for switch condition of type
'bool'
Compiler warning (level 1) C4809 switch statement has redundant 'default' label; all possible
'case' labels are given
Compiler warning (level 1) C4812 obsolete declaration style: please use 'new_syntax' instead
Compiler warning (level 1) C4813 'function': a friend function of a local class must have been
previously declared
Compiler warning (level 4) C4816 'param': parameter has a zero-sized array which will be
truncated (unless the object is passed by reference)
Compiler warning (level 1) C4817 'member': illegal use of '.' to access this member; compiler
replaced with '->'
Compiler Warning (level 1) C4819 The file contains a character that cannot be represented in the
current code page (number). Save the file in Unicode format to
prevent data loss
Compiler Warning (level 4) C4820 'bytes' bytes padding added after construct 'member_name'
Compiler Warning (level 1) C4821 Unable to determine Unicode encoding type, please save the
file with signature (BOM)
Compiler warning (level 1) C4822 'member function': local class member function does not have
a body
Compiler Warning (level 3) C4823 'function': uses pinning pointers but unwind semantics are not
enabled. Consider using /EHa
Compiler warning (level 2) C4826 Conversion from 'type1' to 'type2' is sign-extended. This may
cause unexpected runtime behavior.
Compiler warning (level 3) C4827 A public 'ToString' method with 0 parameters should be
marked as virtual and override
Compiler Warning (level 1) C4829 Possibly incorrect parameters to function main. Consider 'int
main(Platform::Array<Platform::String^>^ argv)'
Compiler Warning (level 1) C4835 'variable': the initializer for exported data will not be run until
managed code is first executed in the host assembly
Compiler Warning (level 1) C4838 conversion from 'type_1' to 'type_2' requires a narrowing
conversion
Compiler warning (level 3) C4839 non-standard use of class 'type' as an argument to a variadic
function
Compiler warning (level 4) C4840 non-portable use of class 'type' as an argument to a variadic
function
Compiler warning (level 4) C4841 non-standard extension used: compound member designator
used in offsetof
Compiler warning (level 4) C4842 the result of 'offsetof' applied to a type using multiple
inheritance is not guaranteed to be consistent between
compiler releases
Compiler warning C4844 'export module module_name;' is now the preferred syntax for
declaring a module interface
Compiler warning (level 4) C4866 compiler may not enforce left-to-right evaluation order for call
to operator_name
Compiler Warning (Error) C4867 'function': function call missing argument list; use 'call' to
create a pointer to member
Compiler Warning (level 4) C4868 'file(line_number)' compiler may not enforce left-to-right
evaluation order in braced initialization list
Compiler warning (level 2) C4872 floating point division by zero detected when compiling the
call graph for the concurrency::parallel_for_each at: 'location'
Compiler warning (level 1) C4880 casting from 'const type_1' to 'type_2': casting away constness
from a pointer or reference may result in undefined behavior
in an amp restricted function
Compiler warning (level 4) C4881 the constructor and/or the destructor will not be invoked for
tile_static variable 'variable'
Compiler warning (level 1) C4882 passing functors with non-const call operators to
concurrency::parallel_for_each is deprecated
Compiler warning C4900 Il mismatch between 'tool1' version 'version1' and 'tool2'
version 'version2'
Compiler warning (level 1) C4912 'attribute': attribute has undefined behavior on a nested UDT
Compiler warning (level 4) C4913 user defined binary operator ',' exists but no overload could
convert all operands, default built-in binary operator ',' used
Compiler warning (level 1) C4916 in order to have a dispid, 'description': must be introduced by
an interface
Compiler Warning (level 1) C4917 'declarator': a GUID can only be associated with a class,
interface or namespace
Compiler warning (level 4) C4918 'character': invalid character in pragma optimization list
Compiler warning (level 1) C4920 enum enum member member_1=value_1 already seen in
enum enum as member_2=value_2
Compiler warning (level 3) C4921 'description': attribute value 'attribute' should not be multiply
specified
Compiler warning (level 1) C4925 'method': dispinterface method cannot be called from script
Compiler warning (level 1) C4926 'identifier': symbol is already defined: attributes ignored
Compiler Warning (level 1) C4927 illegal conversion; more than one user-defined conversion has
been implicitly applied
Compiler Warning (level 1) C4928 illegal copy-initialization; more than one user-defined
conversion has been implicitly applied
Compiler Warning (level 1) C4929 'file': typelibrary contains a union; ignoring the 'embedded_idl'
qualifier
Compiler Warning (level 1) C4930 'prototype': prototyped function not called (was a variable
definition intended?)
Compiler Warning (level 4) C4931 we are assuming the type library was built for number-bit
pointers
Compiler warning (level 1) C4935 assembly access specifier modified from 'access'
Compiler warning (level 1, Error) C4936 this __declspec is supported only when compiled with /clr or
/clr:pure
Compiler warning (level 4) C4937 'text1' and 'text2' are indistinguishable as arguments to
'directive'
Compiler warning (level 4) C4938 'var': Floating point reduction variable may cause inconsistent
results under /fp:strict or #pragma fenv_access
WARNING MESSAGE
Compiler warning (level 1) C4944 'symbol': cannot import symbol from 'assembly1': as 'symbol'
already exists in the current scope
Compiler Warning (level 1) C4945 'symbol': cannot import symbol from 'assembly1': as 'symbol'
has already been imported from another assembly
'assembly2'
Compiler Warning (level 1) C4946 reinterpret_cast used between related classes: 'class1' and
'class2'
Compiler Warning (level 2) C4948 return type of 'accessor' does not match the last parameter
type of the corresponding setter
Compiler Warning (level 1 and level 4) C4949 pragmas 'managed' and 'unmanaged' are meaningful only
when compiled with '/clr[:option]'
Compiler warning (level 1) C4951 'function' has been edited since profile data was collected,
function profile data not used
Compiler warning (level 1) C4952 'function': no profile data found in program database 'pgd_file'
Compiler warning (level 1) C4953 Inlinee 'function' has been edited since profile data was
collected, profile data not used
Compiler warning C4954 'function': not profiled (contains __int64 switch expression)
Compiler warning C4955 'import2': import ignored; already imported from 'import1'
Compiler warning (level 1, Error) C4956 'type': this type is not verifiable
Compiler warning (level 1, Error) C4957 'cast': explicit cast from 'cast_from' to 'cast_to' is not verifiable
Compiler warning (level 1, Error) C4958 'operation': pointer arithmetic is not verifiable
Compiler warning (level 1, Error) C4959 cannot define unmanaged type 'type' in /clr:safe because
accessing its members yields unverifiable code
Compiler warning (level 1) C4961 No profile data was merged into '.pgd file', profile-guided
optimizations disabled
Compiler warning (level 1) C4963 'description': no profile data found; different compiler options
were used in instrumented build
Compiler Warning (level 1) C4964 No optimization options were specified; profile info will not be
collected
Compiler Warning (level 1) C4965 implicit box of integer 0; use nullptr or explicit cast
Compiler warning (level 1) C4966 'function' has __code_seg annotation with unsupported
segment name, annotation ignored
Compiler warning C4970 delegate constructor: target object ignored since 'type' is static
Compiler warning (level 1) C4971 Argument order: <target object>, <target function> for
delegate constructor is deprecated, use <target function>,
<target object="">
Compiler warning (level 1, Error) C4972 Directly modifying or treating the result of an unbox operation
as an lvalue is unverifiable
Compiler warning (level 3) C4981 Warbird: function 'function' marked as __forceinline not inlined
because it contains exception semantics
Compiler warning (level 3) C4985 symbol name': attributes not present on previous declaration.
Compiler Warning C4986 'declaration': exception specification does not match previous
declaration
Compiler warning (level 4) C4988 'variable': variable declared outside class/function scope
Compiler warning (level 3) C4991 Warbird: function 'function' marked as __forceinline not inlined
because protection level of inlinee is greater than the parent
Compiler warning (level 3) C4992 Warbird: function 'function' marked as __forceinline not inlined
because it contains inline assembly which cannot be protected
Compiler Warning (level 3) C4995 'function': name was marked as #pragma deprecated
Compiler warning (level 1) C4997 'class': coclass does not implement a COM interface or
pseudo-interface
WARNING MESSAGE
Compiler warning C4999 UNKNOWN WARNING Please choose the Technical Support
command on the Visual C++ Help menu, or open the
Technical Support help file for more information
Compiler warning (level 4) C5024 'type': move constructor was implicitly defined as deleted
Compiler warning (level 4) C5025 'type': move assignment operator was implicitly defined as
deleted
Compiler warning (level 1 and level 4) C5026 'type': move constructor was implicitly defined as deleted
Compiler warning (level 1 and level 4) C5027 'type': move assignment operator was implicitly defined as
deleted
Compiler warning (level 1) C5028 'name': Alignment specified in prior declaration (number) not
specified in definition
Compiler warning (level 4) C5029 nonstandard extension used: alignment attributes in C++
apply to variables, data members and tag types only
Compiler warning (level 4) C5031 #pragma warning(pop): likely mismatch, popping warning
state pushed in different file
Compiler warning (level 1) C5036 varargs function pointer conversion when compiling with
/hybrid:x86arm64 'type1' to 'type2'
Compiler warning (level 4) C5038 data member 'member1' will be initialized after data member
'member2'
WARNING MESSAGE
Compiler warning (level 4) C5039 'function': pointer or reference to potentially throwing function
passed to extern C function under -EHc. Undefined behavior
may occur if this function throws an exception.
Compiler warning (level 3) C5040 dynamic exception specifications are valid only in C++14 and
earlier; treating as noexcept(false)
Compiler warning (level 1) C5041 'definition': out-of-line definition for constexpr static data
member is not needed and is deprecated in C++17
Compiler warning (level 3) C5042 'declaration': function declarations at block scope cannot be
specified 'inline' in standard C++; remove 'inline' specifier
Compiler warning (level 2) C5043 'specification': exception specification does not match previous
declaration
Compiler warning (level 4) C5044 An argument to command-line option option points to a path
'path' that does not exist
Compiler warning C5045 Compiler will insert Spectre mitigation for memory load if
/Qspectre switch specified
Compiler warning (level 2) C5046 'function' : Symbol involving type with internal linkage not
defined
Compiler Warning (level 3) C4800
10/31/2018 • 2 minutes to read • Edit Online
This warning is generated when a value that is not bool is assigned or coerced into type bool . Typically, this
message is caused by assigning int variables to bool variables where the int variable contains only values
true and false, and could be redeclared as type bool . If you cannot rewrite the expression to use type bool , then
you can add " !=0 " to the expression, which gives the expression type bool . Casting the expression to type bool
does not disable the warning, which is by design.
This warning is no longer generated in Visual Studio 2017.
Example
The following sample generates C4800 and shows how to fix it:
// C4800.cpp
// compile with: /W3
int main() {
int i = 0;
bool j = i; // C4800
j++;
}
Compiler Warning (level 1) C4803
10/31/2018 • 2 minutes to read • Edit Online
'method' : the raise method has a different storage class from that of the event, 'event'
Event methods must have the same storage class as the event declaration. The compiler adjusts the event's
methods so that the storage classes are the same.
This warning can occur if you have a class that implements an event from an interface. The compiler does not
implicitly generate a raise method for an event in an interface. When you implement that interface in a class, the
compiler does implicitly generate a raise method and that method will not be virtual, hence the warning. For more
information on events, see event.
See warning pragma for information on how to turn a warning off.
Example
The following sample generates C4803.
// C4803.cpp
// compile with: /clr /W1
using namespace System;
ref struct E {
Del ^ _pd1;
event Del ^ E1 {
void add (Del ^ pd1) {
_pd1 = dynamic_cast<Del ^>(Delegate::Combine(_pd1, pd1));
}
void func() {
Console::WriteLine("In E::func()");
}
};
int main() {
E ^ ep = gcnew E;
ep->E1 += gcnew Del(ep, &E::func);
ep->E1();
ep->E1 -= gcnew Del(ep, &E::func);
ep->E1();
}
Compiler Warning (level 1) C4804
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4804:
// C4804.cpp
// compile with: /W1
int main()
{
bool i = true;
if (-i) // C4804, remove the '-' to resolve
{
i = false;
}
}
Compiler Warning (level 1) C4805
10/31/2018 • 2 minutes to read • Edit Online
// C4805.cpp
// compile with: /W1
int main() {
int i = 1;
bool b = true;
'operation' : unsafe operation: no value of type 'type' promoted to type 'type' can equal the given constant
This message warns against code such as b == 3 , where b has type bool . The promotion rules cause bool to
be promoted to int . This is legal, but it can never be true. The following sample generates C4806:
// C4806.cpp
// compile with: /W1
int main()
{
bool b = true;
// try..
// int b = true;
if (b == 3) // C4806
{
b = false;
}
}
Compiler Warning (level 1) C4807
10/31/2018 • 2 minutes to read • Edit Online
'operation' : unsafe mix of type 'type' and signed bitfield of type 'type'
This warning is generated when comparing a one-bit signed bit field to a bool variable. Because a one-bit, signed
bit field can only contain the values -1 or 0, it is dangerous to compare it to bool . No warnings are generated
about mixing bool and one-bit, unsigned bitfields since they are identical to bool and can only hold 0 or 1.
Example
The following sample generates C4807:
// C4807.cpp
// compile with: /W1
typedef struct bitfield {
signed mybit : 1;
} mybitfield;
int main() {
mybitfield bf;
bool b = true;
// try..
// int b = true;
bf.mybit = -1;
if (b == bf.mybit) { // C4807
b = false;
}
}
Compiler Warning (level 1) C4810
10/31/2018 • 2 minutes to read • Edit Online
// C4810.cpp
// compile with: /W1 /LD
// C4810 expected
#pragma pack(show)
#pragma pack(4)
#pragma pack(show)
Compiler Warning (level 1) C4811
10/31/2018 • 2 minutes to read • Edit Online
// C4812.cpp
// compile with: /W1 /c
template <class T>
class MyClass;
template<class T>
class MyClass<T*> {
MyClass();
};
template<class T>
MyClass<T*>::MyClass<T*>() {} // C4812
// try the following line instead
// MyClass<T*>::MyClass() {}
Compiler Warning (level 1) C4813
10/31/2018 • 2 minutes to read • Edit Online
'function' : a friend function of a local class must have been previously declared
A friend function in an inner class was not declared in the outer class.
The following sample generates C4813:
// C4813.cpp
// compile with: /W1 /LD
void MyClass()
{
// void func();
class InnerClass
{
friend void func(); // C4813 uncomment declaration above
};
}
Compiler Warning (level 4) C4816
10/31/2018 • 2 minutes to read • Edit Online
'param' : parameter has a zero-sized array which will be truncated (unless the object is passed by reference)
A parameter to an object with a zero-size array was not passed by reference. The array will not get copied when the
object is passed.
Example
The following sample generates C4816:
// C4816.cpp
// compile with: /W4
#include <stdio.h>
struct S1
{
int i;
char cArr[];
};
int main()
{
S1 myS_1 = { 6, 'a', 'b', 'c' };
TestErr(myS_1);
TestOk(myS_1);
}
Compiler Warning (level 1) C4817
10/31/2018 • 2 minutes to read • Edit Online
'member' : illegal use of '.' to access this member; compiler replaced with '->'
The wrong member access operator was used.
Example
The following sample generates C4817.
// C4817.cpp
// compile with: /clr /W1
using namespace System;
int main() {
array<Int32> ^ a = gcnew array<Int32>(100);
Console::WriteLine( a.Length ); // C4817
Console::WriteLine( a->Length ); // OK
}
Compiler Warning (level 1) C4819
10/31/2018 • 2 minutes to read • Edit Online
The file contains a character that cannot be represented in the current code page (number). Save the file in Unicode
format to prevent data loss.
C4819 occurs when an ANSI source file is compiled on a system with a codepage that cannot represent all
characters in the file.
To resolve C4819, save the file in Unicode format. In Visual Studio, choose File, Advanced Save Options. In the
Advanced Save Options dialog box, select an encoding that can represent all the characters in the file—for
example, UTF -8—and then choose OK.
Compiler Warning (level 4) C4820
10/31/2018 • 2 minutes to read • Edit Online
// C4820.cpp
// compile with: /W4 /c
#pragma warning(default : 4820)
// OK
#pragma pack(1)
__declspec(align(1)) struct MyStruct2 {
char a;
int i;
};
Compiler Warning (level 1) C4821
10/31/2018 • 2 minutes to read • Edit Online
Unable to determine Unicode encoding type, please save the file with signature (BOM )
The compiler could not determine the encoding type for a file. To resolve this warning, save the file with a byte
order marker. See Manage Files with Encoding for more information.
Compiler Warning (level 1) C4822
10/31/2018 • 2 minutes to read • Edit Online
// C4822.cpp
// compile with: /W1
int main() {
struct C {
void func1(int); // C4822
// try the following line instead
// void func1(int){}
};
}
Compiler Warning (level 3) C4823
10/31/2018 • 2 minutes to read • Edit Online
'function' : uses pinning pointers but unwind semantics are not enabled. Consider using /EHa
To unpin an object on the managed heap pointed to by a pinning pointer declared in a block scope, the compiler
simulates the behavior of destructors of local classes, "pretending" the pinning pointer has a destructor that
nullifies the pointer. To enable a call to a destructor after throwing an exception, you must enable object unwinding,
which you can do by using /EHsc.
You can also manually unpin the object and ignore the warning.
Example
The following sample generates C4823.
// C4823.cpp
// compile with: /clr /W3 /EHa-
using namespace System;
ref struct G {
int m;
};
int main() {
f( gcnew G );
}
Compiler Warning (level 1) C4829
11/9/2018 • 2 minutes to read • Edit Online
// C4829.cpp
// compile by using: cl /EHsc /ZW /W4 /c C4829.cpp
int main(Platform::String ^ s) {} // C4829
Compiler Warning (level 1) C4835
10/31/2018 • 2 minutes to read • Edit Online
'variable' : the initializer for exported data will not be run until managed code is first executed in the host assembly
When accessing data between managed components, it is recommended that you not use native C++ import and
export mechanisms. Instead, declare your data members inside a managed type and reference the metadata with
#using in the client. For more information, see #using Directive.
Example
The following sample generates C4835.
// C4835.cpp
// compile with: /W1 /clr /LD
int f() { return 1; }
int n = 9;
Example
The following sample consumes the component built in the previous sample, showing that the value of the
variables is not as expected.
// C4835_b.cpp
// compile with: /clr C4835.lib
#include <stdio.h>
__declspec(dllimport) int m;
__declspec(dllimport) int *p;
int main() {
printf("%d\n", m);
printf("%d\n", p);
}
0
268456008
Compiler Warning (level 1) C4838
10/31/2018 • 2 minutes to read • Edit Online
struct S1 {
int m1;
double m2, m3;
};
Classes or structs that are passed to a variadic function such as printf must be trivially copyable. When passing
such objects, the compiler simply makes a bitwise copy and does not call the constructor or destructor.
This warning is available beginning in Visual Studio 2017.
Example
The following sample generates C4839:
// C4839.cpp
// compile by using: cl /EHsc /W3 C4839.cpp
#include <atomic>
#include <memory>
#include <stdio.h>
int main()
{
std::atomic<int> i(0);
printf("%i\n", i); // error C4839: non-standard use of class 'std::atomic<int>'
// as an argument to a variadic function
// note: the constructor and destructor will not be called;
// a bitwise copy of the class will be passed as the argument
// error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)':
// attempting to reference a deleted function
}
To correct the error, you can call a member function that returns a trivially copyable type,
std::atomic<int> i(0);
printf("%i\n", i.load());
For strings built and managed using CStringW , the provided operator LPCWSTR() should be used to cast a
CStringW object to the C pointer expected by the format string.
CStringW str1;
CStringW str2;
// ...
str1.Format("%s", static_cast<LPCWSTR>(str2));
Compiler Warning (level 4) C4840
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Classes or structs that are passed to a variadic function must be trivially copyable. When passing such objects, the
compiler simply makes a bitwise copy and does not call the constructor or destructor.
This warning is available beginning in Visual Studio 2017.
Example
The following sample generates C4840 and shows how to fix it:
// C4840.cpp
// compile by using: cl /EHsc /W4 C4840.cpp
#include <stdio.h>
int main()
{
struct S {
S(int i) : i(i) {}
S(const S& other) : i(other.i) {}
operator int() { return i; }
private:
int i;
} s(0);
For strings built and managed using CStringW , the provided operator LPCWSTR() should be used to cast a
CStringW object to the C -style string pointer expected by the format string:
CStringW str1;
CStringW str2;
// ...
str1.Format("%s", static_cast<LPCWSTR>(str2));
Compiler Warning (level 4) C4866
2/25/2019 • 2 minutes to read • Edit Online
'file(line_number)' compiler may not enforce left-to-right evaluation order for call to operator_name
Remarks
Starting in C++17, the operands of the operators ->*, [], >>, and << must be evaluated in left-to-right order. There
are two cases in which the compiler is unable to guarantee this order:
when one of the operand expressions is an object passed by value or contains an object passed by value, or
when compiled by using /clr, and one of the operands is a field of an object or an array element.
The compiler emits warning C4866 when it can't guarantee left-to-right evaluation. This warning is only generated
if /std:c++17 or later is specified, as the left-to-right order requirement of these operators was introduced in
C++17.
This warning is off by default; you can use /Wall or /wN4866 to enable it on the command line as a level N
warning, or use #pragma warning in your source file. For more information, see Compiler warnings that are off by
default.
This warning was introduced in Visual Studio 2017 version 15.9 as a result of compiler conformance work for the
C++17 standard. Code that compiled without warnings in versions of the compiler before Visual C++ 2017
version 15.9 can now generate C4866. For information on how to disable warnings introduced in a particular
compiler version or later, see Compiler Warnings by compiler version.
To resolve this warning, first consider whether left-to-right evaluation of the operator elements is necessary, such
as when evaluation of the elements might produce order-dependent side-effects. In many cases, the order in which
elements are evaluated does not have an observable effect.
If the order of evaluation must be left-to-right, consider whether you can pass the elements by const reference
instead. This change eliminates the warning in the following code sample.
Example
This sample generates C4866, and shows a way to fix it:
// C4866.cpp
// compile with: /w14866 /std:c++17
class HasCopyConstructor
{
public:
int x;
HasCopyConstructor(int x) : x(x) {}
HasCopyConstructor(const HasCopyConstructor& h) : x(h.x) { }
};
int main()
{
HasCopyConstructor a{ 1 };
HasCopyConstructor b{ 2 };
'function': function call missing argument list; use 'call' to create a pointer to member
A pointer to member function was initialized incorrectly.
This warning can be generated as a result of compiler conformance work that was done for Visual C++ 2005:
enhanced pointer-to-member conformance. Code that compiled prior to Visual C++ 2005 will now generate
C4867.
This warning is always issued as an error. Use the warning pragma to disable this warning. For more information
about C4867 and MFC/ATL, see _ATL_ENABLE_PTM_WARNING.
Example
The following sample generates C4867.
// C4867.cpp
// compile with: /c
class A {
public:
void f(int) {}
struct B {
TAmtd p;
};
void g() {
B b = {f}; // C4867
B b2 = {&A::f}; // OK
}
};
Compiler Warning (level 4) C4868
10/31/2018 • 2 minutes to read • Edit Online
'file(line_number)' compiler may not enforce left-to-right evaluation order in braced initializer list
The elements of a braced initializer list are to be evaluated in left-to-right order. There are two cases in which the
compiler is unable to guarantee this order: the first is when some of the elements are objects passed by value; the
second is when compiling with /clr and some of the elements are fields of objects or are array elements. When
the compiler can't guarantee left-to-right evaluation it emits warning C4868.
This warning can be generated as a result of compiler conformance work that was done for Visual C++ 2015
Update 2. Code that compiled prior to Visual C++ 2015 Update 2 can now generate C4868.
This warning is off by default. Use /Wall to activate this warning.
To resolve this warning, first consider whether left-to-right evaluation of the initializer list elements is necessary,
such as when evaluation of the elements might produce order-dependent side-effects. In many cases, the order in
which elements are evaluated does not have an observable effect.
If the order of evaluation must be left-to-right, consider if it's possible to pass the elements by const reference
instead. A change such as this eliminates the warning in the following code sample.
Example
This sample generates C4868, and shows a way to fix it:
// C4868.cpp
// compile with: /c /Wall
#include <cstdio>
class HasCopyConstructor
{
public:
int x;
class TripWarning4868
{
public:
// note that taking "HasCopyConstructor" parameters by-value will trigger copy-construction.
TripWarning4868(HasCopyConstructor a, HasCopyConstructor b) {}
int main()
{
HasCopyConstructor a{1};
HasCopyConstructor b{2};
// the warning will indicate the below line, the usage of the braced initializer list.
TripWarning4868 warningOnThisLine{a, b};
};
Compiler Warning (level 1) C4900
10/31/2018 • 2 minutes to read • Edit Online
intermediate language mismatch between 'tool1' version 'version1' and 'tool2' version 'version2'
The intermediate language used in tool1 and tool2 did not match. Check that the most current version of each tool
has been installed.
Compiler Warning (level 1) C4905
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4905.
// C4905.cpp
// compile with: /W1
#pragma warning(default : 4905)
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
LPSTR y = (LPSTR)L"1234"; // C4905
return 0;
}
Compiler Warning (level 1) C4906
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4906:
// C4906.cpp
// compile with: /W1
#pragma warning(default : 4906)
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
LPWSTR x = (LPWSTR)"1234"; // C4906
return 0;
}
Compiler Warning (level 1) C4910
10/31/2018 • 2 minutes to read • Edit Online
See Also
Explicit Instantiation
dllexport, dllimport
General Rules and Limitations
Compiler Warning (level 1) C4912
10/31/2018 • 2 minutes to read • Edit Online
// C4912.cpp
// compile with: /W1
#include <windows.h>
[emitidl, module(name="xx")];
[object, uuid("00000000-0000-0000-0000-000000000002")]
__interface IMy
{
};
user defined binary operator ',' exists but no overload could convert all operands, default built-in binary
operator ',' used
A call to the built-in comma operator occurred in a program that also had an overloaded comma operator; a
conversion that you thought may have occurred did not.
The following code sample generates C4913:
// C4913.cpp
// compile with: /W4
struct A
{
};
struct S
{
};
struct B
{
// B() { }
// B(S &s) { s; }
};
B operator , (A a, B b)
{
a;
return b;
}
int main()
{
A a;
B b;
S s;
Example
The following code sample generates C4917:
// C4917.cpp
// compile with: /W1
#pragma warning(default : 4917)
__declspec(uuid("00000000-0000-0000-0000-000000000001")) struct S
{
} s; // C4917, don't put uuid on a struct
int main()
{
}
Compiler Warning (level 4) C4918
10/31/2018 • 2 minutes to read • Edit Online
// C4918.cpp
// compile with: /W4
#pragma optimize("X", on) // C4918 expected
int main()
{
}
Compiler Warning (level 1) C4920
10/31/2018 • 2 minutes to read • Edit Online
library MyLib
{
typedef enum {
enumMember = 512
} AProblem;
typedef enum {
enumMember = 1024
} BProblem;
};
// C4920.cpp
// compile with: /W1
#import "t4920.tlb" // C4920
int main() {
}
Compiler Warning (level 1) C4925
10/31/2018 • 2 minutes to read • Edit Online
// C4925.cpp
// compile with: /LD /W1
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[ module(name="Test")];
[ dispinterface, uuid("00000000-0000-0000-0000-000000000001") ]
__interface IDisp {
[id(9)] void f([in] int*);
};
[ coclass, uuid("00000000-0000-0000-0000-000000000002") ]
struct CDisp : IDisp { // C4925
void f(int*) {}
};
Compiler Warning (level 1) C4926
10/31/2018 • 2 minutes to read • Edit Online
// C4926.cpp
// compile with: /W1
[module(name="MyLib")];
[coclass]
struct a {
};
[coclass]
struct a; // C4926
int main() {
}
Compiler Warning (level 1) C4927
10/31/2018 • 2 minutes to read • Edit Online
illegal conversion; more than one user-defined conversion has been implicitly applied
More than one user-defined conversion is implicitly applied to a single value -- the compiler did not find an explicit
conversion but did find a conversion, which it used.
The following sample generates C4927:
// C4927.cpp
// compile with: /W1
struct B
{
operator int ()
{
return 0;
}
};
struct A
{
A(int i)
{
}
/*
// uncomment this constructor to resolve
A(B b)
{
}
*/
};
A f1( B& b)
{
return A(b);
}
A f()
{
B b;
return A(b); // ok
return f1(b); // ok
return b; // C4927
return B(b); // C4927
return f2(b); // C4927
}
int main()
{
B b;
A a = b;
A a2(b);
}
Compiler Warning (level 1) C4928
10/31/2018 • 2 minutes to read • Edit Online
illegal copy-initialization; more than one user-defined conversion has been implicitly applied
More than one user-defined conversion routine was found. The compiler executed the code in all such routines.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4928:
// C4928.cpp
// compile with: /W1
#pragma warning(default: 4928)
struct I
{
};
struct I1 : I
{
};
struct I2 : I
{
};
Ptr()
{
}
Ptr(I*)
{
}
};
int main()
{
Ptr<I1> p1;
Ptr<I2> p2 = p1; // C4928
// try one of the following two lines to resolve this error
// Ptr<I2> p2(p1);
// Ptr<I2> p2 = (I1*) p1;
}
Compiler Warning (level 1) C4929
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample defines a component.
// C4929a.cpp
// compile with: /LD /link /TLBOUT:C4929a.tlb
#include <objbase.h>
[module(name="Test")];
[public, switch_type(short)] typedef union _TD_UNION_TYPE {
[case(24)]
float fM;
[case(25)]
double dMN;
[default]
int x;
} TD_UNION_TYPE;
[object, uuid("00000000-0000-0000-0000-000000000001")]
__interface I {
HRESULT f(TD_TYPE*);
};
[coclass, uuid("00000000-0000-0000-0000-000000000002")]
struct C : I {
HRESULT f(TD_TYPE*) { return 0; }
};
Example
The following sample generates C4929.
// C4929b.cpp
// compile with: /c /W1
#import "C4929a.tlb" embedded_idl // C4929
Compiler Warning (level 1) C4930
10/31/2018 • 2 minutes to read • Edit Online
// C4930.cpp
// compile with: /W1
class Lock {
public:
int i;
};
void f() {
Lock theLock(); // C4930
// try the following line instead
// Lock theLock;
}
int main() {
}
C4930 can also occur when the compiler cannot distinguish between a function prototype declaration and a
function call.
The following sample generates C4930:
// C4930b.cpp
// compile with: /EHsc /W1
class BooleanException
{
bool _result;
public:
BooleanException(bool result)
: _result(result)
{
}
template<class T = BooleanException>
class IfFailedThrow
{
public:
IfFailedThrow(bool result)
{
if (!result)
{
throw T(result);
}
}
};
class MyClass
{
public:
bool MyFunc()
{
try
{
IfFailedThrow<>(MyMethod()); // C4930
return true;
}
catch (BooleanException e)
{
return e.GetResult();
}
}
private:
bool MyMethod()
{
return true;
}
};
int main()
{
MyClass myClass;
myClass.MyFunc();
}
In the above sample, the result of a method that takes zero arguments is passed as an argument to the constructor
of an unnamed local class variable. The call can be disambiguated by either naming the local variable or prefixing
the method call with an object instance along with the appropriate pointer-to-member operator.
Compiler Warning (level 4) C4931
10/31/2018 • 2 minutes to read • Edit Online
we are assuming the type library was built for number-bit pointers
Explicit information was not supplied with the ptrsize attribute of the #import directive; the compiler concluded
that pointer size of the type library is number.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Compiler Warning (level 4) C4932
10/31/2018 • 2 minutes to read • Edit Online
// C4932.cpp
// compile with: /clr /W4 /WX
int main() {
int __identifier(_finally) = 245; // C4932
int __identifier(__finally) = 25; // C4932
}
Compiler Warning (level 1) C4935
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
A __declspec modifier was used but that __declspec modifier is only valid when compiled with one of the /clr
options.
For more information, see appdomain and process.
C4936 is always issued as an error. You can disable C4936 with the warning pragma.
Example
The following sample generates C4936:
// C4936.cpp
// compile with: /c
// #pragma warning (disable : 4936)
__declspec(process) int i; // C4936
__declspec(appdomain) int j; // C4936
Compiler Warning (level 4) C4937
10/31/2018 • 2 minutes to read • Edit Online
// C4937.cpp
// compile with: /openmp /W4
#include "omp.h"
int main() {
#pragma omp critical ( __leave ) // C4937
;
// OK
#pragma omp critical ( leave )
;
}
Compiler Warning (level 4) C4938
10/31/2018 • 2 minutes to read • Edit Online
'var' : Floating point reduction variable may cause inconsistent results under /fp:strict or #pragma fenv_access
You should not use /fp:strict or fenv_access with OpenMP floating-point reductions, because the sum is computed
in a different order. Thus, results can differ from the results without /openmp.
The following sample generates C4938:
// C4938.cpp
// compile with: /openmp /W4 /fp:strict /c
// #pragma fenv_access(on)
extern double *a;
With explicit parallelization (and two threads), the sum is computed as follows:
#pragma vtordisp is deprecated and will be removed in a future release of Visual C++
The vtordisp pragma will be removed in a future release of Visual C++.
Example
The following sample generates C4939.
// C4939.cpp
// compile with: /c /W1
#pragma vtordisp(off) // C4939
Compiler Warning (level 1) C4944
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : cannot import symbol from 'assembly1': as 'symbol' already exists in the current scope
A symbol was defined in a source code file and then a #using statement referenced an assembly that also defined
the symbol. The symbol in the assembly is ignored.
Example
The following sample creates a component with a type called ClassA.
// C4944.cs
// compile with: /target:library
// C# source code to create a dll
public class ClassA {
public int i;
}
Example
The following samples generate C4944.
// C4944b.cpp
// compile with: /clr /W1
class ClassA {
public:
int u;
};
int main() {
ClassA * x = new ClassA();
x->u = 9;
System::Console::WriteLine(x->u);
}
Compiler Warning (level 1) C4945
10/31/2018 • 2 minutes to read • Edit Online
'symbol' : cannot import symbol from 'assembly2': as 'symbol' has already been imported from another assembly
'assembly1'
A symbol was imported from a referenced assembly but that symbol was already imported from another
referenced assembly. Either do not reference one of the assemblies or get the symbol name changed in one of the
assemblies.
The following samples generate C4945.
// C4945a.cs
// compile with: /target:library
// C# source code to create a dll
public class ClassA {
public int i;
}
and then,
// C4945b.cs
// compile with: /target:library
// C# source code to create a dll
public class ClassA {
public int i;
}
and then,
// C4945c.cpp
// compile with: /clr /LD /W1
#using "C4945a.dll"
#using "C4945b.dll" // C4945
Compiler Warning (level 1) C4946
10/31/2018 • 2 minutes to read • Edit Online
// C4946.cpp
// compile with: /W1
#pragma warning (default : 4946)
class a {
public:
a() : m(0) {}
int m;
};
int main() {
c* pC = new c;
a* pA = reinterpret_cast<a*>(pC); // C4946
// try the following line instead
// a* pA = static_cast<a*>(pC);
}
Compiler Warning (level 1) C4947
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4947:
// C4947.cpp
// compile with: /clr /W1
// C4947 expected
using namespace System;
[System::ObsoleteAttribute]
ref struct S {
[System::ObsoleteAttribute]
int i;
[System::ObsoleteAttribute]
void mFunc(){}
};
int main() {
Int32 MyInt1 = ::Func1(2, 2);
Int32 MyInt2 = ::Func2(2, 2);
S^ s = gcnew S();
s->i = 10;
s->mFunc();
}
Compiler Warning (level 2) C4948
10/31/2018 • 2 minutes to read • Edit Online
return type of 'accessor' does not match the last parameter type of the corresponding setter
The compiler found a mismatch between what data type is being get and set for an indexed property.
C4948 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Warning (level 1 and level 4) C4949
10/31/2018 • 2 minutes to read • Edit Online
pragmas 'managed' and 'unmanaged' are meaningful only when compiled with '/clr[:option]'
The compiler ignores the managed and unmanaged pragmas if the source code is not compiled with /clr. This
warning is informational.
The following sample generates C4949:
// C4949.cpp
// compile with: /LD /W1
#pragma managed // C4949
// C4949b.cpp
// compile with: /LD /W4
#pragma unmanaged // C4949
Compiler Warning C4950
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4950:
// C4950.cpp
// compile with: /clr
using namespace System;
int main() {
Int32 MyInt3 = ::Func3(2, 2); // C4950
}
Compiler Warning (level 1) C4951
10/31/2018 • 2 minutes to read • Edit Online
'function' has been edited since profile data was collected, function profile data not used
A function has been edited in an input module to /LTCG:PGUPDATE, so that the profile data is now not valid. The
input module was recompiled after /LTCG:PGINSTRUMENT and has a function (function) with a different flow of
control than was in the module at the time of the /LTCG:PGINSTRUMENT operation.
This warning is informational. To resolve this warning, run /LTCG:PGINSTRUMENT, redo all test runs, and run
/LTCG:PGOPTIMIZE.
This warning would be replaced with an error if /LTCG:PGOPTIMIZE had been used.
Compiler Warning (level 1) C4952
10/31/2018 • 2 minutes to read • Edit Online
When using /LTCG:PGUPDATE, the compiler detected an input module that was recompiled after
/LTCG:PGINSTRUMENT and has a new function (function) present.
This warning is informational. To resolve this warning, run /LTCG:PGINSTRUMENT , redo all test runs, and run
/LTCG:PGOPTIMIZE .
This warning would be replaced with an error if /LTCG:PGOPTIMIZE had been used.
Compiler Warning (level 1) C4953
10/31/2018 • 2 minutes to read • Edit Online
Inlinee 'function' has been edited since profile data was collected, profile data not used
When using /LTCG:PGUPDATE, the compiler detected an input module that was recompiled after
/LTCG:PGINSTRUMENT and has a function (function) that was edited and where existing test runs identified the
function as a candidate for inlining. However, as a result of recompiling the module, the function will no longer be a
candidate for inlining.
This warning is informational. To resolve this warning, run /LTCG:PGINSTRUMENT , redo all test runs, and run
/LTCG:PGOPTIMIZE .
This warning would be replaced with an error if /LTCG:PGOPTIMIZE had been used.
Compiler Warning C4956
10/31/2018 • 2 minutes to read • Edit Online
Remarks
This warning is generated when /clr:safe is specified and your code contains a type that is not verifiable. The
/clr:safe compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
For more information, see Pure and Verifiable Code (C++/CLI).
This warning is issued as an error and can be disabled with the warning pragma or the /wd compiler option.
Example
The following sample generates C4956:
// C4956.cpp
// compile with: /clr:safe
int* p; // C4956
Compiler Warning C4957
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A cast will result in an unverifiable image.
Some casts are safe (for example, a static_cast that triggers user-defined conversions and a const_cast ). A
safe_cast is guaranteed to produce verifiable code.
For more information, see Pure and Verifiable Code (C++/CLI).
The /clr:safe compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
This warning is issued as an error and can be disabled with the warning pragma or the /wd compiler option.
Example
The following sample generates C4957:
// C4957.cpp
// compile with: /clr:safe
// #pragma warning( disable : 4957 )
using namespace System;
int main() {
Object ^ o = "Hello, World!";
String ^ s = static_cast<String^>(o); // C4957
String ^ s2 = safe_cast<String^>(o); // OK
}
Compiler Warning C4958
10/31/2018 • 2 minutes to read • Edit Online
Remarks
Using pointer arithmetic will produce an unverifiable image.
For more information, see Pure and Verifiable Code (C++/CLI).
The /clr:safe compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
This warning is issued as an error and can be disabled with the warning pragma or the /wd compiler option.
Example
The following sample generates C4958:
// C4958.cpp
// compile with: /clr:safe
// #pragma warning( disable : 4958 )
using namespace System;
int main( ) {
Int32 arr[] = new Int32[10];
Int32* p = &arr[0];
p++; // C4958
}
The compiler implements array operations with pointer arithmetic. Therefore, native arrays are not verifiable; use a
CLR array instead. For more information, see array.
The following sample generates C4958:
// C4958b.cpp
// compile with: /clr:safe
// #pragma warning( disable : 4958 )
int main() {
int array[5];
array[4] = 0; // C4958
}
Compiler Warning C4959
10/31/2018 • 2 minutes to read • Edit Online
cannot define unmanaged struct 'type' in /clr:safe because accessing its members yields unverifiable code
Remarks
Accessing a member of an unmanaged type will produce an unverifiable (peverify.exe) image.
For more information, see Pure and Verifiable Code (C++/CLI).
The /clr:safe compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
This warning is issued as an error and can be disabled with the warning pragma or the /wd compiler option.
Example
The following sample generates C4959:
// C4959.cpp
// compile with: /clr:safe
int main() {
X x;
x.data = 10; // C4959
}
Compiler Warning (level 4) C4960
10/31/2018 • 2 minutes to read • Edit Online
No profile data was merged into '.pgd file', profile-guided optimizations disabled
No profile data (.pgc files) were available, so profile-guided optimizations cannot take place.
Compiler Warning C4962
10/31/2018 • 2 minutes to read • Edit Online
'function' : Profile-guided optimizations disabled because optimizations caused profile data to become
inconsistent"
A function was not compiled with /LTCG:PGO, because count (profile) data for the function was unreliable. Redo
profiling to regenerate the .pgc file that contains the unreliable profile data for that function.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
Compiler Warning (level 1) C4964
10/31/2018 • 2 minutes to read • Edit Online
// C4964.cpp
// compile with: /W1 /GL /link /ltcg:pgi
// C4964 expected
// Add /O2, for example, to the command line to resolve this warning.
int main() {
int i;
}
Compiler Warning (level 1) C4965
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4965.
// C4965.cpp
// compile with: /clr /W1
int main() {
System::Object ^o = 0; // C4965
// OK
System::Object ^o2 = nullptr;
System::Object ^o3 = safe_cast<System::Object^>(0);
}
Compiler Warning C4972
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4972.
// C4972.cpp
// compile with: /clr:safe
using namespace System;
ref struct R {
int ^ p; // a value type
};
int main() {
R ^ r = gcnew R;
*(r->p) = 10; // C4972
// OK
r->p = 10;
Console::WriteLine( r->p );
Console::WriteLine( *(r->p) );
}
Compiler Warning (level 4) C4985
10/31/2018 • 2 minutes to read • Edit Online
See Also
SAL Annotations
Compiler Warning C4986
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4986.
class X { };
void f1() throw (X*);
// ...
void f1()
{
// ...
}
Example
The following sample eliminates this warning.
class X { };
void f1() throw (X*);
// ...
void f1() throw (X*)
{
// ...
}
Compiler Warning (level 3) C4995
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates C4995:
// C4995.cpp
// compile with: /W3
#include <stdio.h>
int main()
{
func1();
#pragma deprecated(func1)
func1(); // C4995
}
Compiler Warning (level 3) C4996
3/12/2019 • 10 minutes to read • Edit Online
The compiler encountered a deprecated declaration. This warning is always a deliberate message from the
author of the library or included header file that you should not use the deprecated symbol without
understanding the consequences. The actual warning message is specified by the deprecation modifier or
attribute at the site of the declaration.
These are some common C4996 messages generated by the C Runtime Library and the Standard Library, but not
an exhaustive list. Follow the links or read on for ways to fix the issue or to turn the warning off.
The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name:
new_name. See online help for details.
This function or variable may be unsafe. Consider using safe_version instead. To disable deprecation, use
_CRT_SECURE_NO_WARNINGS. See online help for details.
'std::function_name::_Unchecked_iterators::_Deprecate' Call to std::function_namewith parameters that may
be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning,
use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
This function or variable has been superseded by newer library or operating system functionality. Consider
using new_item instead. See online help for details.
Cause
C4996 occurs when the compiler encounters a function or variable that is marked as deprecated by using a
__declspec(deprecated) modifier, or when you attempt to access a function, class member or typedef that has the
C++14 [[deprecated]] attribute. You can use the __declspec(deprecated) modifier or [[deprecated]] attribute
yourself in your libraries or header files to warn your clients about deprecated functions, variables, members, or
typedefs.
Remarks
Many functions, member functions, template functions, and global variables in the libraries in Visual Studio are
marked as deprecated. These functions are deprecated because they may have a different preferred name, may be
insecure or have a more secure variant, or may be obsolete. Many deprecation messages include a suggested
replacement for the deprecated function or global variable.
To fix this issue, we usually recommend you change your code to use the suggested safer or updated functions and
global variables instead. If you need to use the existing functions or variables for portability reasons, the warning
can be turned off.
To turn the warning off without fixing the issue
You can turn off the warning for a specific line of code by using the warning pragma,
#pragma warning(suppress : 4996) . You can also turn the warning off within a file by using the warning pragma,
#pragma warning(disable : 4996) .
You can turn the warning off globally in command line builds by using the /wd4996 command line option.
To turn off the warning for an entire project in the Visual Studio IDE:
Open the Property Pages dialog for your project. For information on how to use the Property Pages dialog,
see Property Pages.
Select the Configuration Properties, C/C++, Advanced page.
Edit the Disable Specific Warnings property to add 4996 . Choose OK to apply your changes.
You can also use preprocessor macros to turn off certain specific classes of deprecation warnings used in the
libraries. These macros are described below.
To define a preprocessor macro in Visual Studio:
Open the Property Pages dialog for your project. For information on how to use the Property Pages dialog,
see Property Pages.
Expand Configuration Properties > C/C++ > Preprocessor.
In the Preprocessor Definitions property, add the macro name. Choose OK to save, and then rebuild your
project.
To define a macro only in specific source files, add a line such as #define EXAMPLE_MACRO_NAME before any line that
includes a header file.
// C4996_copyarray.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_copyarray.cpp
#include <algorithm>
Several standard library algorithms were updated to have "dual range" versions in C++14. If you use the dual
range versions, the second range provides the necessary bounds checking:
// C4996_containers.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_containers.cpp
#include <algorithm>
bool example(
char const * const left,
const size_t leftSize,
char const * const right,
const size_t rightSize)
{
bool result = false;
result = std::equal(left, left + leftSize, right); // C4996
// To fix, try this form instead:
// result = std::equal(left, left + leftSize, right, right + rightSize); // OK
return result;
}
This example demonstrates several more ways the standard library may be used to check iterator usage, and when
unchecked usage may be dangerous:
// C4996_standard.cpp
// compile with: cl /EHsc /W4 /MDd C4996_standard.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <numeric>
#include <string>
#include <vector>
int main()
{
vector<int> v(16);
iota(v.begin(), v.end(), 0);
print("v: ", v);
If you have verified that your code cannot have a buffer overrun error in the Standard Library functions that
trigger this warning, you may want to turn this warning off. To turn off warnings for these functions, define
_SCL_SECURE_NO_WARNINGS.
Checked iterators enabled
C4996 can also occur if you do not use a checked iterator when compiling with _ITERATOR_DEBUG_LEVEL defined as
1 or 2. It is set to 2 by default for debug mode builds, and to 0 for retail builds. See Checked Iterators for more
information.
// C4996_checked.cpp
// compile with: /EHsc /W4 /MDd C4996_checked.cpp
#define _ITERATOR_DEBUG_LEVEL 2
#include <algorithm>
#include <iterator>
int main() {
int a[] = { 1, 2, 3 };
int b[] = { 10, 11, 12 };
copy(a, a + 3, b + 1); // C4996
// try the following line instead:
// copy(a, a + 3, checked_array_iterator<int *>(b, 3)); // OK
}
// C4996_Marshal.cpp
// compile with: /clr
// C4996 expected
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
int main() {
String^ message = gcnew String("Test String to Marshal");
const char* result;
result = marshal_as<const char*>( message );
return 0;
}
// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>
int main() {
func1();
func1(1); // C4996
}
Compiler Warning (level 1) C4997
10/31/2018 • 2 minutes to read • Edit Online
// C4997.cpp
// compile with: /WX
// to resolve this C4997, uncomment all code
#include <objbase.h>
[ object ]
__interface I {
HRESULT func();
};
[ coclass ]
struct C /*: I*/ {
/*
HRESULT func() {
return S_OK;
}
*/
}; // C4997
Compiler Warning (level 1) C4999
10/31/2018 • 2 minutes to read • Edit Online
UNKNOWN WARNING From the Help menu choose the Technical Support command or open the Technical
Support help file for more information
Note the circumstances of the error, try to isolate the problem and create a reproducible test case, then contact
Microsoft Product Support Services.
Compiler Warning C5038
11/15/2018 • 2 minutes to read • Edit Online
data member 'member1' will be initialized after data member 'member2' data member 'member' will be
initialized after base class 'base_class'
Class members are initialized in the order they are declared, not the order they appear in initializer lists. This
warning indicates that the order of initialization is not the same as the declaration order of data members or base
classes. This can lead to undefined runtime behavior if the initialization of one member in the list depends on the
initialization of a member that is declared later.
This warning is new in Visual Studio 2017 version 15.3, and is off by default. Use /Wall to enable all warnings that
are off by default, or /wn5038 to enable C5038 as a level n warning. For more information, see Compiler
Warnings That Are Off By Default. For information on how to disable warnings by compiler version, see Compiler
warnings by compiler version.
Example
In the following example, Visual Studio 2017 version 15.3 (with /Wall) raises "warning C5038: data member 'A::y'
will be initialized after data member 'A::x'":
struct A
{
A(int a) : y(a), x(y) {} // C5938 Initialized in reverse, y reused
int x;
int y;
};
To fix this issue, arrange the initializer list to have the same order as the declarations. A similar warning is raised
when one or both initializers refer to base class members.
Compiler Warning C5045
10/31/2018 • 2 minutes to read • Edit Online
Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
Remarks
Warning C5045 lets you see what patterns in your code cause a Spectre mitigation, such as an LFENCE, to be
inserted when the /Qspectre compiler option is specified. This lets you identify which code files are affected by the
security issue. This warning is purely informational: the mitigation is not inserted until you recompile using the
/Qspectre switch. The functionality of C5045 is independent of the /Qspectre switch, so you can use them both in
the same compilation.
This warning is new in Visual Studio 2017 version 15.7, and is off by default. Use /Wall to enable all warnings that
are off by default, or /wn5038 to enable C5045 as a level n warning. In the IDE, the default warning level is /W3
and this warning can be enabled in the project Property Pages dialog. Open Configuration Properties >
C/C++ > Command Line and in the Additional options box, add /w35045, then choose OK. For more
information, see Compiler warnings that are off by default. For information on how to disable warnings by
compiler version, see Compiler warnings by compiler version.
Example
The following example raises warning C5045 when compiled by Visual Studio 2017 version 15.7 with the /Wall or
the /w35045 and /W3 options:
// C5045.cpp
// Compile with: cl /EHsc /W3 /w35045 C5045.cpp
__forceinline
int * bar(int **p, int i)
{
return p[i];
}
__forceinline
void bar1(int ** p, int i)
{
if (i < G1) {
auto x = p[i]; // C5045: mitigation here
G = *x;
}
}
__forceinline
void foo(int * p)
{
G = *p;
}
int main() { }
The compiler output when the warning is enabled looks something like this:
C5045.cpp
c:\users\username\source\repos\c5045\c5045.cpp(16) : warning C5045: Compiler will insert Spectre mitigation
for memory load if /Qspectre switch specified
c:\users\username\source\repos\c5045\c5045.cpp(15) : note: index 'i' range checked by comparison on this line
c:\users\username\source\repos\c5045\c5045.cpp(17) : note: feeds memory load on this line
Microsoft (R) Incremental Linker Version 14.14.26431.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:C5045.exe
C5045.obj
The warning messages show that a mitigation would have been inserted on line 16. It also notes that the
mitigation is needed because the index i on line 15 feeds the memory load on line 17. The speculation is done
across bar and bar1 but the mitigation is effective when placed at line 16.
See also
C++ Developer Guidance for Speculative Execution Side Channels
/Qspectre
spectre
Compiler Warning (level 2) C5046
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The compiler has detected a use of a function that does not have a definition, but the signature of this function
involves types that are not visible outside this translation unit. Because these types are not externally visible, no
other translation unit can provide a definition for this function, so the program can't be successfully linked.
Types that are not visible across translation units include:
Types declared inside an anonymous namespace
Local or unnamed classes
Specializations of templates that use these types as template arguments.
This warning is new in Visual Studio 2017.
Example
This sample shows two C5046 warnings:
// C5046p.cpp
// compile with: cl /c /W2 C5046p.cpp
namespace {
struct S {
// S::f is inside an anonymous namespace and cannot be defined outside
// of this file. If used, it must be defined somewhere in this file.
int f();
};
}
int main()
{
S s;
s.f(); // C5046 f is undefined and can't be defined in another file.
g(nullptr); // C5046 g is undefined and can't be defined in another file.
}
You can use the Visual C++ compiler options /Qpar-report and /Qvec-report to set the Auto-Parallelization and
Auto-Vectorization to output reason codes and informational messages about its activity. This article explains the
reason codes and the messages.
Informational Messages
5xx
10xx
11xx
12xx
13xx
14xx
15xx
Informational Messages
Depending on the reporting level that you specify, one of the following informational messages appears for each
loop.
For information about reason codes, refer to the next part of this article.
Reason Codes
The following sections list possible reason codes for the auto-parallelizer and auto-vectorizer.
5xx
The 5xx reason codes apply to both the auto-parallelizer and the auto-vectorizer.
int i = 0;
while (i<1000)
{
if (i == 4)
{
break;
}
++i;
A[i] = A[i] + 1;
}
// To resolve code 500, use a 'for' loop with single increment of
// induction variable.
int bound();
void code_501_example1(int *A)
{
// Code 501 is emitted if the compiler cannot discern the
// induction variable of this loop. In this case, when it checks
// the upperbound of 'i', the compiler cannot prove that the
// function call "bound()" returns the same value each time.
// Also, the compiler cannot prove that the call to "bound()"
// does not modify the values of array A.
int i;
void code_501_example2(int *A)
{
// Code 501 is emitted if the compiler cannot discern the
// induction variable of this loop. In this case, 'i' is
// a global.
if (i < 100)
{
++i;
}
}
int code_504_helper();
class C504
{
public:
C504();
~C504();
};
10xx
The 10xx reason codes apply to the auto-parallelizer.
1002 The compiler tried to parallelize a loop that has an inner loop
that was already parallelized.
1003 The loop body contains an intrinsic call that may read or write
to memory.
1007 The loop induction variable or the loop bounds are not signed
32-bit numbers ( int or long ). Resolve this by changing
the type of the induction variable.
REASON CODE EXPLANATION
1008 The compiler detected that this loop does not perform
enough work to warrant auto-parallelization.
1010 The compiler detected that the loop is using "not-equals" (!=)
for its condition.
int A[1000];
void func();
void code_1000()
{
// Code 1000 is emitted if the compiler detects a
// data dependence in the loop body.
#pragma loop(hint_parallel(0))
//#pragma loop(ivdep) // ivdep will force this through.
for (int i=0; i<1000; ++i)
{
A[i] = A[i-1] + 1; // data dependence here
func(); // data dependence here
}
}
int code_1001()
{
// Code 1001 is emitted if the compiler detects
// a store to a scalar variable in the loop
// body, and that scalar has a use beyond the loop.
int s = 0;
#pragma loop(hint_parallel(0))
for (int i=0; i<1000; ++i)
{
s = A[i];
}
return s;
}
void code_1002()
{
// Code 1002 is emitted when the compiler tries to
// parallelize a loop that has an inner loop that
// has already been parallelized.
#pragma loop(hint_parallel(0))
for (int i=0; i<1000; ++i) // emit code 1002 for this loop
{
#pragma loop(hint_parallel(0))
for (int j=0; j<1000; ++j) // this loop gets parallelized
{
A[j] = A[j] + 1;
}
}
}
}
#pragma loop(hint_parallel(0))
//#pragma loop(ivdep) // ivdep will force this through.
for (int i=0; i<1000; ++i)
{
__stosb(dst, 'c', 10);
A[i] = A[i] + 1;
}
}
int code_1004()
{
// Code 1004 is emitted when there is a scalar reduction
// in the loop body, which can occur if the loop has been
// vectorized.
int s = 0;
#pragma loop(hint_parallel(0))
for (int i=0; i<1000; ++i)
{
s += A[i];
}
return s;
}
void code_1005()
{
// Code 1005 is emitted when the
// no_parallel pragma is specified.
#pragma loop(no_parallel)
for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
}
#include <omp.h>
void code_1007()
{
// Code 1007 is emitted when the loop induction variable
// or the loop bounds are not signed 32-bit numbers (int
// or long). Resolve this by changing the type of the
// induction variable.
#pragma loop(hint_parallel(0))
for (unsigned int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
}
void code_1008()
{
// Code 1008 is emitted when the compiler detects that
// this loop does not perform enough work to warrant
// auto-parallelization.
void code_1009()
{
// Code 1009 is emitted when the compiler tries to parallelize a
// "do-while" loop. The auto-parallelizer only targets "for" loops.
int i = 0;
#pragma loop(hint_parallel(0))
do
{
A[i] = A[i] + 1;
}
while (++i < 1000);
}
void code_1010()
{
// Code 1010 is emitted when the compiler tries to parallelize a
// loop with a condition code of "!=".
11xx
The 11xx reason codes apply to the auto-vectorizer.
1103 Loop body includes shift operations whose size might vary
within the loop.
int x = B[i];
A[i] = A[i] >> x; // not vectorizable
}
int x = B[0];
for (int i=0; i<1000; ++i)
{
A[i] = A[i] >> x; // vectorizable
}
}
int x;
for (int i=0; i<1000; ++i)
{
x = B[i];
A[i] = A[i] + x;
}
return x;
}
int s = 0;
for (int i=0; i<1000; ++i)
{
s += A[i]; // vectorizable
}
// The reduction pattern must resemble the loop in the example. The
// compiler emits code 1105 if it cannot deduce the reduction
// pattern, as shown in this example:
return s;
}
12xx
The 12xx reason codes apply to the auto-vectorizer.
struct S_1202
{
short a;
short b;
} s[1000];
13xx
The 13xx reason codes apply to the auto-vectorizer.
REASON CODE EXPLANATION
int i = 0;
do
{
A[i] = A[i] + 1;
} while (++i < 1000);
}
int s = 0;
for (int i=0; i<4; ++i)
{
s += A[i];
}
return s;
}
#pragma loop(no_vector)
for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
}
15xx
The block of 15xx reason codes apply to aliasing. Aliasing occurs when a location in memory can be accessed by
two different names.
int x = 0;
for (int i=0; i<100; ++i)
{
A[i] = B[i + x] + 1;
++x; // 'x' varies in the loop
}
}
void code_1503(int *A, int *B, int x, int y)
{
// Code 1503 is emitted when runtime pointer
// disambiguation checks are required, and
// an array reference has multiple offsets.
See Also
Auto-Parallelization and Auto-Vectorization
Parallel Programming in Native Code
#pragma loop()
/Q Options (Low -Level Operations)
/Qpar-report (Auto-Parallelizer Reporting Level)
/Qvec-report (Auto-Vectorizer Reporting Level)
BSCMAKE Errors BK1500 through BK4505
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors and warnings generated by the BSCMAKE build tool.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
BSCMAKE Error BK1503
10/31/2018 • 2 minutes to read • Edit Online
See Also
BSCMAKE Options
BSCMAKE Error BK1504
10/31/2018 • 2 minutes to read • Edit Online
source file for sbrfile compiled with both /Yc and /Yu
The .sbr file refers to itself. It was probably recompiled with /Yu after compiling with /Yc. Reset the compiler option
for the source file to /Yc, then select Rebuild to generate new .sbr files. Do not recompile the source file with /Yu.
BSCMAKE Warning BK4502
3/12/2019 • 2 minutes to read • Edit Online
file contains too many references; ignoring further references from this source
The .cpp file contains more than 64,000 symbol references. When BSCMAKE has encountered 64,000 references in
a file, it ignores all further references.
To correct the problem, either split the file into two or more files, each of which has fewer than 64,000 symbol
references, or use the #pragma component(browser) preprocessor directive to limit symbols that are generated for
particular references. For more information, see component.
Expression Evaluator Errors CXX0000 Through
CXX0072
10/31/2018 • 2 minutes to read • Edit Online
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Expression Evaluator Error CXX0000
10/31/2018 • 2 minutes to read • Edit Online
no error condition
No error has occurred. You can continue debugging normally.
Note the circumstances and notify Microsoft Product Support Services.
Expression Evaluator Error CXX0001
10/31/2018 • 2 minutes to read • Edit Online
syntax error
The syntax of the expression is incorrect.
Retype the expression with the correct syntax.
This error is identical to CAN0004.
Expression Evaluator Error CXX0005
10/31/2018 • 2 minutes to read • Edit Online
missing operator
An operator was expected in the expression but was not found. Check the syntax of the expression.
This error is identical to CAN0013.
Expression Evaluator Error CXX0014
10/31/2018 • 2 minutes to read • Edit Online
missing operand
An operator was specified without a required operand. Check the syntax of the expression.
This error is identical to CAN0014.
Expression Evaluator Error CXX0015
10/31/2018 • 2 minutes to read • Edit Online
(char **)h_message
bad radix
The C expression evaluator does not recognize the radix specified. Only decimal, hexadecimal, and octal radixes are
valid.
This error is identical to CAN0023.
Expression Evaluator Error CXX0024
10/31/2018 • 2 minutes to read • Edit Online
divide by 0
The expression contains a divisor of zero, which is illegal. This divisor may be the literal number zero, or it may be
an expression that evaluates to zero.
This error is identical to CAN0032.
Expression Evaluator Error CXX0033
10/31/2018 • 2 minutes to read • Edit Online
out of memory
The C expression evaluator ran out of memory evaluating the expression.
This error is identical to CAN0037.
Expression Evaluator Error CXX0038
10/31/2018 • 2 minutes to read • Edit Online
symbol is ambiguous
The C expression evaluator cannot determine which instance of a symbol to use in an expression. The symbol
occurs more than once in the inheritance tree.
You must use the scope resolution operator ( :: ) to explicitly specify the instance to use in the expression.
This error is identical to CAN0039.
Expression Evaluator Error CXX0040
10/31/2018 • 2 minutes to read • Edit Online
not a function
An argument list was supplied for a symbol in the program that is not the name of a function.
Example
queue( alpha, beta )
pClass->vfunc( int );
A breakpoint can be set on a virtual function by entering the class, such as:
Class::vfunc( int );
The articles in this section provide a reference to the command-line errors generated by the build tools.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
See also
C/C++ Build Errors
Command-Line Error D8016
10/31/2018 • 2 minutes to read • Edit Online
cl /B1 file1.c
Command-Line Error D8036
10/31/2018 • 2 minutes to read • Edit Online
See Also
Command-Line Errors D8000 Through D9999
MSVC Compiler Options
Command-Line Error D8045
10/31/2018 • 2 minutes to read • Edit Online
the file VERDI.c will be compiled using the /G5 option, not the /G4 default.
This behavior is different from that of some previous versions, which applied only the options specified before the
filename, resulting in VERDI.c being compiled using /G4 and PUCCINI.c being compiled using /G5.
Command-Line Warning D9027
10/31/2018 • 2 minutes to read • Edit Online
Because there is a space between /Fo and output.obj , CL.exe takes output.obj as the name of the input file. To fix
the problem, remove the space:
cl /c /Fooutput.obj input.c
Command-Line Warning D9028
10/31/2018 • 2 minutes to read • Edit Online
option 'option' has been deprecated and will be removed in a future release
Remarks
You specified a compiler option that will be removed in a future release of the compiler. If there is a suggested
replacement for option, this warning is followed by warning D9036.
The specified option still works, but you should update your build configuration now. As a result, your project is
more likely to continue to build when you upgrade the compiler.
See also
Deprecated and removed compiler options
Command-Line Warning D9036
Command-Line Warning D9036
12/11/2018 • 2 minutes to read • Edit Online
Remarks
Warning D9036 is a continuation of Command-Line Warning D9035. If one compiler option is preferred instead
of the deprecated option, it is listed here. For links to more information, see Deprecated and removed compiler
options.
See also
Deprecated and removed compiler options
Command-Line Warning D9035
Command-Line Warning D9040
3/12/2019 • 2 minutes to read • Edit Online
ignoring option '/analyze'; Code Analysis warnings are not available in this edition of the compiler
The /analyze command line option is not available in all editions of Visual Studio. To remedy this warning, either
switch to a supported edition of Visual Studio, or remove the command line option.
See Also
Command-Line Errors D8000 Through D9999
MSVC Compiler Options
Command-Line Warning D9041
3/12/2019 • 2 minutes to read • Edit Online
invalid value 'value' for '/option'; assuming 'value'; add '/analyze' to command-line options when specifying this
warning
A Code Analysis warning number was added to the /wd, /we, /wo, or /wl command line option without also
specifying the /analyze command line option. To remedy this error, either add the /analyze command line option,
or remove the invalid warning number from the appropriate /w command line option.
Example
The following command line example generates the warning D9041:
To fix the warning, add the /analyze command line option. If /analyze is not supported on your version of the
compiler, remove the invalid warning number from the /wd option.
See Also
Command-Line Errors D8000 Through D9999
MSVC Compiler Options
Command-Line Warning D9043
10/31/2018 • 2 minutes to read • Edit Online
invalid value 'warning_level' for 'compiler_option'; assuming '4999'; Code Analysis warnings are not associated
with warning levels
Example
The following sample generates C9043.
// D9043.cpp
// compile with: /analyze /w16001
// D9043 warning expected
int main() {}
Linker Tools Errors and Warnings
10/31/2018 • 4 minutes to read • Edit Online
LINK, LIB, DUMPBIN, and EDITBIN generate these errors and warnings.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Linker errors
Linker Tools Error LNK1000
Linker Tools Error LNK1103
Linker Tools Error LNK1104
Linker Tools Error LNK1106
Linker Tools Error LNK1107
Linker Tools Error LNK1112
Linker Tools Error LNK1113
Linker Tools Error LNK1120
Linker Tools Error LNK1123
Linker Tools Error LNK1127
Linker Tools Error LNK1136
Linker Tools Error LNK1140
Linker Tools Error LNK1141
Linker Tools Error LNK1143
Linker Tools Error LNK1152
Linker Tools Error LNK1158
Linker Tools Error LNK1164
Linker Tools Error LNK1166
Linker Tools Error LNK1168
Linker Tools Error LNK1169
Linker Tools Error LNK1179
Linker Tools Error LNK1181
Linker Tools Error LNK1188
Linker Tools Error LNK1189
Linker Tools Error LNK1196
Linker Tools Error LNK1200
Linker Tools Error LNK1201
Linker Tools Error LNK1211
Linker Tools Error LNK1215
Linker Tools Error LNK1218
Linker Tools Error LNK1221
Linker Tools Error LNK1223
Linker Tools Error LNK1224
Linker Tools Error LNK1237
Linker Tools Error LNK1240
Linker Tools Error LNK1241
Linker Tools Error LNK1245
Linker Tools Error LNK1248
Linker Tools Error LNK1256
Linker Tools Error LNK1264
Linker Tools Error LNK1277
Linker Tools Error LNK1282
Linker Tools Error LNK1287
Linker Tools Error LNK1296
Linker Tools Error LNK1301
Linker Tools Error LNK1302
Linker Tools Error LNK1306
Linker Tools Error LNK1309
Linker Tools Error LNK1312
Linker Tools Error LNK1313
Linker Tools Error LNK1314
Linker Tools Error LNK1318
Linker Tools Error LNK1332
Linker Tools Error LNK1561
Linker Tools Error LNK2001
Linker Tools Error LNK2004
Linker Tools Error LNK2005
Linker Tools Error LNK2008
Linker Tools Error LNK2011
Linker Tools Error LNK2013
Linker Tools Error LNK2017
Linker Tools Error LNK2019
Linker Tools Error LNK2020
Linker Tools Error LNK2022
Linker Tools Error LNK2023
Linker Tools Error LNK2026
Linker Tools Error LNK2027
Linker Tools Error LNK2028
Linker Tools Error LNK2031
Linker Tools Error LNK2033
Linker Tools Error LNK2039
Linker warnings
Linker Tools Warning LNK4001
Linker Tools Warning LNK4002
Linker Tools Warning LNK4006
Linker Tools Warning LNK4010
Linker Tools Warning LNK4014
Linker Tools Warning LNK4020
Linker Tools Warning LNK4022
Linker Tools Warning LNK4039
Linker Tools Warning LNK4044
Linker Tools Warning LNK4049
Linker Tools Warning LNK4065
Linker Tools Warning LNK4070
Linker Tools Warning LNK4071
Linker Tools Warning LNK4073
Linker Tools Warning LNK4075
Linker Tools Warning LNK4076
Linker Tools Warning LNK4078
Linker Tools Warning LNK4086
Linker Tools Warning LNK4092
Linker Tools Warning LNK4096
Linker Tools Warning LNK4098
Linker Tools Warning LNK4099
Linker Tools Warning LNK4102
Linker Tools Warning LNK4104
Linker Tools Warning LNK4105
Linker Tools Warning LNK4194
Linker Tools Warning LNK4197
Linker Tools Warning LNK4199
Linker Tools Warning LNK4200
Linker Tools Warning LNK4204
Linker Tools Warning LNK4205
Linker Tools Warning LNK4206
Linker Tools Warning LNK4210
Linker Tools Warning LNK4216
Linker Tools Warning LNK4217
Linker Tools Warning LNK4219
Linker Tools Warning LNK4220
Linker Tools Warning LNK4221
Linker Tools Warning LNK4222
Linker Tools Warning LNK4224
Linker Tools Warning LNK4227
Linker Tools Warning LNK4229
Linker Tools Warning LNK4237
Linker Tools Warning LNK4247
Linker Tools Warning LNK4248
Linker Tools Warning LNK4253
Linker Tools Warning LNK4254
Linker Tools Error LNK1000
10/31/2018 • 2 minutes to read • Edit Online
Note the circumstances of the error, then try to isolate the problem and create a reproducible test case. For
information on how to investigate and report these errors, see How to report a problem with the Visual C++
toolset or documentation.
You may get this error if you mix standard header files (for example, Windows.h) and your own files. Include a
precompiled header, if any, first, then the standard headers, followed by your own header files.
Linker Tools Error LNK1103
10/31/2018 • 2 minutes to read • Edit Online
The linker could not open the specified file. The most common causes of this problem are that the file is in use or
locked by another process, does not exist, can't be found in one of the directories the linker searches, or you may
not have sufficient permission to access the file. Less commonly, you may have run out of disk space, the file may
be too large, or the path to the file may be too long.
// LNK1107.cpp
// compile with: /clr /LD
public ref class MyClass {
public:
void Test(){}
};
and then specify link LNK1107.dll on the command line, you will get LNK1107. To resolve the error, specify link
LNK1107.obj instead.
Linker Tools Error LNK1112
10/31/2018 • 2 minutes to read • Edit Online
module machine type 'type1' conflicts with target machine type 'type2'
Remarks
The object files specified as input were compiled for different computer types.
For example, if you try to link an object file compiled with /clr and an object file compiled with /clr:pure (machine
type CEE ), the linker will generate the error LNK1112. The /clr:pure compiler option is deprecated in Visual
Studio 2015 and unsupported in Visual Studio 2017.
Similarly, if you create one module with the x64 compiler and another module with the x86 compiler, and try to
link them, the linker will generate LNK1112.
A possible reason for this error is if you are developing a 64-bit application but have not installed one of the Visual
C++ 64-bit compilers. In this case, 64-bit configurations will not be available. To fix this issue, run the installer for
Visual Studio and install the missing C++ components.
This error can also occur if you change the Active solution configuration in the Configuration Manager and
then try to build the project before you delete the intermediate project files. To resolve this error, select Rebuild
Solution from the Build menu. You can also select Clean Solution from the Build menu and then build the
solution.
See also
Linker Tools Errors and Warnings
Linker Tools Error LNK1113
10/31/2018 • 2 minutes to read • Edit Online
Error LNK1120 reports the count ( number) of unresolved external symbol errors for this link operation. Most
unresolved external symbol errors are reported individually by Linker Tools Error LNK2001 and Linker Tools Error
LNK2019, which precede this error message, once for each unresolved external symbol error.
To fix this error, correct all of the other unresolved external errors or other linker errors that precede it in the build
output. This error is not reported when no unresolved external errors remain.
Linker Tools Error LNK1123
10/31/2018 • 2 minutes to read • Edit Online
Input files must have the Common Object File Format (COFF ) format. If an input file is not COFF, the linker
automatically tries to convert 32-bit OMF objects to COFF, or runs CVTRES.EXE to convert resource files. This
message indicates that the linker could not convert the file. This can also occur when using an incompatible version
of CVTRES.EXE from another installation of Visual Studio, the Windows Development Kit, or .NET Framework.
NOTE
If you are running an earlier version of Visual Studio, automatic conversion may not be supported.
See also
.Obj Files as Linker Input
EDITBIN Reference
DUMPBIN Reference
Linker Tools Error LNK1127
10/31/2018 • 2 minutes to read • Edit Online
library is corrupt
The library file is corrupt. Rebuild the library.
Linker Tools Error LNK1136
10/31/2018 • 2 minutes to read • Edit Online
See Also
.Exp Files as Linker Input
Linker Tools Error LNK1143
10/31/2018 • 2 minutes to read • Edit Online
Example
In the following code, function1 and function2 are identical in the first eight characters. Compiling with /Gy and
/H8 produces a link error.
void function1(void);
void function2(void);
int main() {
function1();
function2();
}
void function1(void) {}
void function2(void) {}
Linker Tools Error LNK1181
10/31/2018 • 2 minutes to read • Edit Online
To resolve the above issues, ensure any files referenced on the linker line are present on the system. Also ensure
there is a /LIBPATH statement for each directory containing a linker-dependent file.
For more information, see .lib Files as Linker Input.
Another possible cause for LNK1181 is that a long file name with embedded spaces was not enclosed in quotation
marks. In that case, the linker will only recognize a file name up to the first space, and then assume a file extension
of .obj. The solution to this situation is to enclose the long file name (path plus file name) in quotation marks.
Compiling with the /P (Preprocess to a File) option can result in LNK1181 because that option suppresses the
creation of .obj files.
See Also
/LIBPATH (Additional Libpath)
Linker Tools Error LNK1188
10/31/2018 • 2 minutes to read • Edit Online
error writing to program database 'filename'; check for insufficient disk space, invalid path, or insufficient privilege
LINK could not write to the program database (PDB ) for the output file.
To fix by checking the following possible causes
1. File is corrupt. Delete the PDB file and relink.
2. Not enough disk space to write the file.
3. Drive is not available, possibly due to a network problem.
4. The debugger is active on the program you are trying to link.
5. Out of heap space. See C1060 for more information.
Linker Tools Error LNK1211
10/31/2018 • 2 minutes to read • Edit Online
The filename object file, compiled by using /Yc, was not specified in the LINK command or was overwritten.
If you are creating a debug library that uses precompiled headers and if you specify /Yc and /Z7, Visual C++
generates a precompiled object file that contains debug information. The error occurs only when you store the
precompiled object file in a library, use the library to build an executable image, and the object files that are
referenced have no transitive references to any of the functions the precompiled object file defines.
There are two methods to work around this situation:
Specify the /Yd compiler option to add the debug information from the precompiled header to each object
module. This method is less desirable because it generally produces large object modules that can increase
the time required to link the application.
Specify /Yl and pass the name of any arbitrary string, when you create a precompiled header file that does
not contain any function definitions. This directs the compiler to create a symbol in the precompiled object
file and to emit a reference to that symbol in each object file that used the precompiled header file that is
associated with the precompiled object file.
When you compile a module with /Yc and /Yl, the compiler creates a symbol similar to
__@@_PchSym_@00@...@symbol_name , where the ellipsis (...) represents a compiler -generated character string, and
stores it in the object module. Any source file that you compile with this precompiled header refers to the specified
symbol, which causes the linker to include the object module and its debugging information from the library.
Linker Tools Error LNK1215
10/31/2018 • 2 minutes to read • Edit Online
during code generation, compiler introduced reference to symbol 'symbol' defined in module 'module' compiled
with /GL
During code generation, the compiler should not introduce symbols that are later resolved to definitions compiled
/GL. symbol is a symbol that was introduced and later resolved to a definition compiled with /GL.
For more information, see /GL (Whole Program Optimization).
To resolve LNK1237, do not compile the symbol with /GL or use /INCLUDE (Force Symbol References) to force a
reference to the symbol.
Example
The following sample generates LNK1237. To resolve this error, do not initialize the array in LNK1237_a.cpp and
add /include:__chkstk to the link command.
// LNK1237_a.cpp
int main() {
char c[5000] = {0};
}
// LNK1237_b.cpp
// compile with: /GS- /GL /c LNK1237_a.cpp
// processor: x86
// post-build command: (lib LNK1237_b.obj /LTCG & link LNK1237_a.obj LNK1237_b.lib /nodefaultlib /entry:main
/LTCG)
extern "C" void _chkstk(size_t s) {}
Linker Tools Error LNK1240
10/31/2018 • 2 minutes to read • Edit Online
The linker determined that the size of the output file will exceed the largest possible size for a 32-bit program
image. You may want to make your program into multiple DLLs.
Linker Tools Error LNK1256
3/12/2019 • 2 minutes to read • Edit Online
// LNK1256.cpp
// compile with: /clr /LD
// LNK1256 expected
[assembly:System::Reflection::AssemblyVersionAttribute("1.0.65535")];
public class CMyClass {
public:
int value;
};
Linker Tools Error LNK1264
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates LNK1301:
// LNK1301.cpp
// compile with: /clr /GL /link /LTCG:PGI LNK1301.obj
// LNK1301 expected
class MyClass {
public:
int i;
};
Linker Tools Error LNK1302
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates LNK1306.
// LNK1306.cpp
// compile with: /clr /link /dll /entry:NewDllMain
// LNK1306 error expected
#include <windows.h>
int __stdcall NewDllMain( HINSTANCE h, ULONG ulReason, PVOID pvReserved ) {
return 1;
}
To fix this issue, do not use the /clr option to compile this file, or use a #pragma directive to put the entry point
definition in an unmanaged section as shown in this example:
// LNK1306fix.cpp
// compile with: /clr /link /dll /entry:NewDllMain
#include <windows.h>
#pragma managed(push, off)
int __stdcall NewDllMain( HINSTANCE h, ULONG ulReason, PVOID pvReserved ) {
return 1;
}
#pragma managed(pop)
Linker Tools Error LNK1309
10/31/2018 • 2 minutes to read • Edit Online
Remarks
A CLR image type was requested with /CLRIMAGETYPE but the linker could not produce an image of that type
because one or more modules were incompatible with that type.
For example, you will see LNK1309 if you specify /CLRIMAGETYPE:safe and you pass a module built with
/clr:pure.
The /clr:pure and /clr:safe compiler options and support libraries are deprecated in Visual Studio 2015 and
unsupported in Visual Studio 2017.
You will also see LNK1309 if you attempt to build a partially trusted CLR pure application using ptrustu[d].lib. For
information on how to create a partially trusted application, see How to: Create a Partially Trusted Application by
Removing Dependency on the CRT Library DLL.
For more information, see /clr (Common Language Runtime Compilation) and /CLRIMAGETYPE (Specify Type of
CLR Image).
Linker Tools Error LNK1312
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample created the .obj file.
// LNK1312.cpp
// compile with: /clr /LD
public ref class A {
public:
int i;
};
Example
The following sample generates LNK1312.
// LNK1312_b.cpp
// compile with: /clr /LD /link /assemblymodule:LNK1312.obj
// LNK1312 error expected
public ref class M {};
Linker Tools Error LNK1313
10/31/2018 • 2 minutes to read • Edit Online
Remarks
The current version of Visual C++ does not support linking native or mixed managed/native .obj files with .obj files
compiled with /clr:pure.
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
Example
// LNK1313.cpp
// compile with: /c /clr:pure
// a pure module
int main() {}
Example
// LNK1313_b.cpp
// compile with: /c /clr
// an IJW module
void test(){}
Example
The following sample will generate LNK1313.
// LNK1313_c.cpp
// compile with: /link LNK1313.obj LNK1313_b.obj
// LNK1313 warning expected
Linker Tools Error LNK1314
10/31/2018 • 2 minutes to read • Edit Online
The linker encountered an unexpected error when opening, reading, or writing to a PDB file.
This error message is produced for uncommon issues in PDB files. The cause and details represent the information
available to the linker when the failure occurred. This may not be very useful, as common errors when dealing with
PDB files have separate, more informative error messages.
Because the source of the error is uncommon, there is only generic advice available for resolving this issue:
Perform a clean operation in your build directories, and then do a full build of your solution.
Reboot your computer, or check for stray or hung mspdbsrv.exe processes and kill them in TaskManager.
Turn off antivirus checks in your project directories.
Use the /Zf compiler option if using /MP with MSBuild or another parallel build process.
Try building by using the 64-bit hosted toolset.
Serialize linking to mitigate parallel link issues if needed. This error can be caused if mspdbsrv.exe is
launched by one instance of link, and is shut down before another instance of link is done using it. The
downside to this fix is that your project builds may take considerably longer to complete.
Linker Tools Error LNK1332
10/31/2018 • 2 minutes to read • Edit Online
detected<count> Windows Runtime types imported in one module and defined in another module
When it produced the current target, the linker detected < count > Windows Runtime types, each of which is
imported in one module and also defined in another module.
To correct this error
Correct each of the LNK2039 errors in the build according to the suggestion in the error message.
See Also
Linker Tools Error LNK2039
Linker Tools Errors and Warnings
Linker Tools Error LNK1561
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates LNK1561:
// LNK1561.cpp
// LNK1561 expected
int i;
// add a main function to resolve this error
Linker Tools Error LNK2001
3/12/2019 • 10 minutes to read • Edit Online
Possible causes
There are many ways to get this error, but all of them involve a reference to a function or variable that the linker
can't resolve, or find a definition for. The compiler can identify when a symbol is not declared, but not when it is
not defined, because the definition may be in a different source file or library. If a symbol is referred to but never
defined, the linker generates an error.
Coding issues
This error can be caused by mismatched case in your source code or module-definition (.def) file. For example, if
you name a variable var1 in one C++ source file and try to access it as VAR1 in another, this error is generated.
To fix this issue, use consistently spelled and cased names.
This error can be caused in a project that uses function inlining if you define the functions in a source file rather
than in a header file. Inlined functions can't be seen outside the source file that defines them. To fix this issue,
define the inlined functions in the headers where they are declared.
This error can be caused if you call a C function from a C++ program without using an extern "C" declaration for
the C function. The compiler uses different internal symbol naming conventions for C and C++ code, and it is the
internal symbol name that the linker looks for when resolving symbols. To fix this issue, use an extern "C"
wrapper around all declarations of C functions used in your C++ code, which causes the compiler to use the C
internal naming convention for those symbols. Compiler options /Tp and /Tc cause the compiler to compile files as
C++ or C, respectively, regardless of the filename extension. These options can cause internal function names
different from what you expect.
This error can be caused by an attempt to reference functions or data that don't have external linkage. In C++,
inline functions and const data have internal linkage unless explicitly specified as extern . To fix this issue, use
explicit extern declarations on symbols referred to outside the defining source file.
This error can be caused by a missing function body or variable definition. This error is common when you
declare, but don't define, variables, functions, or classes in your code. The compiler only needs a function prototype
or extern variable declaration to generate an object file without error, but the linker cannot resolve a call to the
function or a reference to the variable because there is no function code or variable space reserved. To fix this
issue, make sure that every referenced function and variable is fully defined in a source file or library included in
your link.
This error can be caused by a function call that uses return and parameter types or calling conventions that do not
match those in the function definition. In C++ object files, Name decoration incorporates the calling convention,
class or namespace scope, and return and parameter types of a function into the final decorated function name,
which is used as the symbol to match when calls to the function from other object files are resolved. To fix this
issue, make sure that the declaration, definition, and calls to the function all use the same scopes, types, and calling
conventions.
This error can be caused in C++ code when you include a function prototype in a class definition but fail to include
the implementation of the function, and then call it. To fix this issue, be sure to provide a definition for all called
declared members of a class.
This error can be caused by an attempt to call a pure virtual function from an abstract base class. A pure virtual
function has no base class implementation. To fix this issue, make sure all called virtual functions are implemented.
This error can be caused by trying to use a variable declared within a function ( a local variable) outside the scope
of that function. To fix this issue, remove the reference to the variable that is not in scope, or move the variable to a
higher scope.
This error can occur when you build a Release version of an ATL project, producing a message that CRT startup
code is required. To fix this issue, do one of the following,
Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT startup code to be included. See
General Property Page (Project) for more information.
If possible, remove calls to CRT functions that require CRT startup code. Instead, use their Win32
equivalents. For example, use lstrcmp instead of strcmp . Known functions that require CRT startup code
are some of the string and floating point functions.
Compilation and link issues
This error can occur when the project is missing a reference to a library (.LIB ) or object (.OBJ ) file. To fix this issue,
add a reference to the required library or object file to your project. For more information, see .lib Files as Linker
Input.
This error can occur if you use the /NODEFAULTLIB or /Zl options. When you specify these options, libraries that
contain required code are not linked into the project unless you have explicitly included them. To fix this issue,
explicitly include all the libraries you use on the link command line. If you see many missing CRT or Standard
Library function names when you use these options, explicitly include the CRT and Standard Library DLLs or
library files in the link.
If you compile using the /clr option, there can be a missing reference to .cctor. To fix this issue, see Initialization of
Mixed Assemblies for more information.
This error can occur if you link to the release mode libraries when building a debug version of an application.
Similarly, if you use options /MTd or /MDd or define _DEBUG and then link to the release libraries, you should
expect many potential unresolved externals, among other problems. Linking a release mode build with the debug
libraries also causes similar problems. To fix this issue, make sure you use the debug libraries in your debug builds,
and retail libraries in your retail builds.
This error can occur if your code refers to a symbol from one version of a library, but you supply a different
version of the library to the linker. Generally, you can't mix object files or libraries that are built for different
versions of the compiler. The libraries that ship in a new version may contain symbols that cannot be found in the
libraries included with previous versions, and vice-versa. To fix this issue, build all the object files and libraries with
the same version of the compiler before linking them together.
The Tools | Options | Projects | VC++ Directories dialog, under the Library files selection, allows you to
change the library search order. The Linker folder in the project's Property Pages dialog box may also
contain paths that could be out of date.
This problem may appear when a new SDK is installed (perhaps to a different location), and the search
order is not updated to point to the new location. Normally, you should put the path to new SDK include
and lib directories in front of the default Visual C++ location. Also, a project containing embedded paths
may still point to old paths that are valid, but out of date for new functionality added by the new version
that is installed to a different location.
If you build at the command line and have created your own environment variables, verify that the paths to
tools, libraries, and header files go to a consistent version. For more information, see Set the Path and
Environment Variables for Command-Line Builds
There is currently no standard for C++ naming between compiler vendors or even between different versions of a
compiler. Therefore, linking object files compiled with other compilers may not produce the same naming scheme
and thus cause error LNK2001.
Mixing inline and non-inline compile options on different modules can cause LNK2001. If a C++ library is created
with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the functions has
inlining turned off (no inline keyword), this error occurs. To fix this issue, define the functions inline in the
header file you include in other source files.
If you use the #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set, and make
sure you also use the /Ob1 or /Ob2 compiler option.
This error can occur if you omit the LINK option /NOENTRY when you create a resource-only DLL. To fix this
issue, add the /NOENTRY option to the link command.
This error can occur if you use incorrect /SUBSYSTEM or /ENTRY settings in your project. For example, if you
write a console application and specify /SUBSYSTEM:WINDOWS, an unresolved external error is generated for
WinMain . To fix this issue, make sure you match the options to the project type. For more information on these
options and entry points, see the /SUBSYSTEM and /ENTRY linker options.
Exported symbol issues
This error occurs when an export listed in a .def file is not found. This could be because it does not exist, is spelled
incorrectly, or uses C++ decorated names. A .def file does not take decorated names. To fix this issue, remove
unneeded exports, and use extern "C" declarations for exported symbols.
Additional resources
For more information about possible causes and solutions for LNK2001, see the Stack Overflow question What is
an undefined reference/unresolved external symbol error and how do I fix it?.
Name Decoration
10/31/2018 • 2 minutes to read • Edit Online
Name decoration usually refers to C++ naming conventions, but can apply to a number of C cases as well. By
default, C++ uses the function name, parameters, and return type to create a linker name for the function.
Consider the following function:
The following table shows the linker name for various calling conventions.
Use extern "C" to call a C function from C++. Extern "C" forces use of the C naming convention for non-class C++
functions. Be aware of compiler switches /Tc or /Tp, which tell the compiler to ignore the filename extension and
compile the file as C or C++, respectively. These options may cause names you do not expect.
Having function prototypes that have mismatched parameters can also cause this error. Name decoration
incorporates the parameters of a function into the final decorated function name. Calling a function with the
parameter types that do not match those in the function declaration may also cause LNK2001.
There is currently no standard for C++ naming between compiler vendors or even between different versions of a
compiler. Therefore linking object files compiled with other compilers may not produce the same naming scheme
and thus causes unresolved externals.
See Also
Linker Tools Error LNK2001
Linker Tools Error LNK2004
11/9/2018 • 2 minutes to read • Edit Online
gp relative fixup overflow to 'target'; short section 'section' is too large or out of range.
The section was too large.
To resolve this error, reduce the size of the short section, either by explicitly putting data in the long sections via
#pragma section(".sectionname", read, write, long) and using __declspec(allocate(".sectionname")) on data
definitions and declarations. For example,
You can also move logically-grouped data into its own structure that will be a collection of data greater than 8
bytes, which the compiler will allocate in a long data section. For example,
// from this...
int w1 = 23;
int w2 = 46;
int w3 = 23*3;
int w4 = 23*4;
// to this...
struct X {
int w1;
int w2;
int w3;
int w4;
} x = { 23, 23*2, 23*3, 23*4 };
// LNK2005_global.h
int global_int; // LNK2005
// LNK2005_func.h
int sample_function(int k) { return 42 * (k % 167); } // LNK2005
Remove the function body from the header file and leave only the declaration, then implement the
function in one and only one source file:
```h
// LNK2005_func_decl.h
int sample_function(int);
```
```cpp
// LNK2005_func_impl.cpp
int sample_function(int k) { return 42 * (k % 167); }
```
This error can also occur if you define member functions outside the class declaration in a header file:
// LNK2005_member_outside.h
class Sample {
public:
int sample_function(int);
};
int Sample::sample_function(int k) { return 42 * (k % 167); } // LNK2005
To fix this issue, move the member function definitions inside the class. Member functions defined inside a
class declaration are implicitly inlined.
// LNK2005_member_inline.h
class Sample {
public:
int sample_function(int k) { return 42 * (k % 167); }
};
This error can occur if you link more than one version of the standard library or CRT. For example, if you
attempt to link both the retail and debug CRT libraries, or both the static and dynamic versions of a library,
or two different versions of a standard library to your executable, this error may be reported many times. To
fix this issue, remove all but one copy of each library from the link command. We do not recommend you
mix retail and debug libraries, or different versions of a library, in the same executable.
To tell the linker to use libraries other than the defaults, on the command line, specify the libraries to use,
and use the /NODEFAULTLIB option to disable the default libraries. In the IDE, add references to your
project to specify the libraries to use, and then open the Property Pages dialog for your project, and in the
Linker, Input property page, set either Ignore All Default Libraries, or Ignore Specific Default
Libraries properties to disable the default libraries.
This error can occur if you mix use of static and dynamic libraries when you use the /clr option. For
example, this error can occur if you build a DLL for use in your executable that links in the static CRT. To fix
this issue, use only static libraries or only dynamic libraries for the entire executable and for any libraries
you build to use in the executable.
This error can occur if the symbol is a packaged function (created by compiling with /Gy) and it was
included in more than one file, but was changed between compilations. To fix this issue, recompile all files
that include the packaged function.
This error can occur if the symbol is defined differently in two member objects in different libraries, and
both member objects are used. One way to fix this issue when the libraries are statically linked is to use the
member object from only one library, and include that library first on the linker command line. To use both
symbols, you must create a way to distinguish them. For example, if you can build the libraries from source,
you can wrap each library in a unique namespace. Alternatively, you can create a new wrapper library that
uses unique names to wrap references to one of the original libraries, link the new library to the original
library, then link the executable to your new library instead of the original library.
This error can occur if an extern const variable is defined twice, and has a different value in each definition.
To fix this issue, define the constant only once, or use namespaces or enum class definitions to distinguish
the constants.
This error can occur if you use uuid.lib in combination with other .lib files that define GUIDs (for example,
oledb.lib and adsiid.lib). For example:
To fix this issue, add /FORCE:MULTIPLE to the linker command line options, and make sure that uuid.lib is
the first library referenced.
Linker Tools Error LNK2008
10/31/2018 • 2 minutes to read • Edit Online
cl /c /Yccommon.h stub.cpp
cl /c /Yucommon.h prog1.cpp
cl /c /Yucommon.h prog2.cpp
link /out:prog.exe stub.obj prog1.obj prog2.obj
Linker Tools Error LNK2013
10/31/2018 • 2 minutes to read • Edit Online
Possible causes
There are many ways to get this error, but all of them involve a reference to a function or variable that the linker
can't resolve, or find a definition for. The compiler can identify when a symbol is not declared, but not when it is
not defined, because the definition may be in a different source file or library. If a symbol is referred to but never
defined, the linker generates an unresolved external symbol error.
Here are some common problems that cause LNK2019:
The object file or library that contains the definition of the symbol is not linked
In Visual Studio, verify that the source file that contains the definition is built and linked as part of your project.
On the command line, verify that the source file that contains the definition is compiled, and that the resulting
object file is included in the list of files to link.
The declaration of the symbol is not spelled the same as the definition of the symbol
Verify the correct spelling and capitalization is used in both the declaration and the definition, and wherever the
symbol is used or called.
A function is used but the type or number of the parameters do not match the function definition
The function declaration must match the definition. Verify that the function call matches the declaration, and that
the declaration matches the definition. Code that invokes template functions must also have matching template
function declarations that include the same template parameters as the definition. For an example of a template
declaration mismatch, see sample LNK2019e.cpp in the Examples section.
A function or variable is declared but not defined
This usually means a declaration exists in a header file, but no matching definition is implemented. For member
functions or static data members, the implementation must include the class scope selector. For an example, see
Missing Function Body or Variable.
The calling convention is different between the function declaration and the function definition
Calling conventions (__cdecl, __stdcall, __fastcall, or __vectorcall) are encoded as part of the decorated name.
Verify that the calling convention is the same.
A symbol is defined in a C file, but declared without using extern "C" in a C++ file
Symbols defined in a file that is compiled as C have different decorated names than symbols declared in a C++
file unless you use an extern "C" modifier. Verify that the declaration matches the compilation linkage for each
symbol. Similarly, if you define a symbol in a C++ file that will be used by a C program, use extern "C" in the
definition.
A symbol is defined as static and then later referenced outside the file
In C++, unlike C, global constants have static linkage. To get around this limitation, you can include the const
initializations in a header file and include that header in your .cpp files, or you can make the variable non-constant
and use a constant reference to access it.
A static member of a class is not defined
A static class member must have a unique definition, or it will violate the one-definition rule. A static class
member that cannot be defined inline must be defined in one source file by using its fully-qualified name. If it is
not defined at all, the linker generates LNK2019.
A build dependency is only defined as a project dependency in the solution
In earlier versions of Visual Studio, this level of dependency was sufficient. However, starting with Visual Studio
2010, Visual Studio requires a project-to-project reference. If your project does not have a project-to-project
reference, you may receive this linker error. Add a project-to-project reference to fix it.
You build a console application by using settings for a Windows application
If the error message is similar to unresolved external symbol WinMain referenced in function
function_name, link by using /SUBSYSTEM:CONSOLE instead of /SUBSYSTEM:WINDOWS. For more
information about this setting, and for instructions on how to set this property in Visual Studio, see /SUBSYSTEM
(Specify Subsystem).
You attempt to link 64-bit libraries to 32-bit code, or 32-bit libraries to 64-bit code
Libraries and object files linked to your code must be compiled for the same architecture as your code. Verify that
the libraries your project references are compiled for the same architecture as your project. Make sure the
/LIBPATH or Additional Library Directories path option used by the linker points to libraries built for the
correct architecture.
You use different compiler options for function inlining in different source files
Using inlined functions defined in .cpp files and mixing function inlining compiler options in different source files
can cause LNK2019. For more information, see Function Inlining Problems.
You use automatic variables outside their scope
Automatic (function scope) variables can only be used in the scope of that function. These variables can't be
declared extern and used in other source files. For an example, see Automatic (Function Scope) Variables.
You call instrinsic functions or pass argument types to intrinsic functions that are not supported on your target
architecture
For example, if you use an AVX2 intrinsic, but do not specify the /ARCH:AVX2 compiler option, the compiler
assumes that the intrinsic is an external function. Instead of generating an inline instruction, the compiler
generates a call to an external symbol with the same name as the intrinsic. When the linker tries to find the
definition of this missing function, it generates LNK2019. Verify that you only use intrinsics and types supported
by your target architecture.
You mix code that uses native wchar_t with code that doesn't
C++ language conformance work that was done in Visual C++ 2005 made wchar_t a native type by default. You
must use the /Zc:wchar_t- compiler option to generate code compatible with library and object files compiled by
using earlier versions of Visual C++. If not all files have been compiled by using the same /Zc:wchar_t settings,
type references may not resolve to compatible types. Verify that wchar_t types in all library and object files are
compatible, either by updating the types that are used, or by using consistent /Zc:wchar_t settings when you
compile.
Diagnosis tools
It can be difficult to tell why the linker can't find a particular symbol definition. Often the problem is that you have
not included the code that contains the definition in your build, or build options have created different decorated
names for external symbols. There are several tools and options that can help you diagnose a LNK2019 error.
The /VERBOSE linker option can help you determine which files the linker references. This can help you
verify whether the file that contains the definition of the symbol is included in your build.
The /EXPORTS and /SYMBOLS options of the DUMPBIN utility can help you discover which symbols are
defined in your .dll and object or library files. Verify that the exported decorated names match the
decorated names the linker searches for.
The UNDNAME utility can show you the equivalent undecorated external symbol for a decorated name.
Examples
Here are several examples of code that causes a LNK2019 error, together with information about how to fix the
error.
A symbol is declared but not defined
In this example, an external variable is declared but not defined:
// LNK2019.cpp
// Compile by using: cl /EHsc /W4 LNK2019.cpp
// LNK2019 expected
extern char B[100]; // B is not available to the linker
int main() {
B[0] = ' '; // LNK2019
}
Here is another example where a variable and function are declared as extern but no definition is provided:
// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Unless i and g are defined in one of the files included in the build, the linker generates LNK2019. You can fix
the errors by including the source code file that contains the definitions as part of the compilation. Alternatively,
you can pass .obj files or .lib files that contain the definitions to the linker.
A static data member is declared but not defined
LNK2019 can also occur when a static data member is declared but not defined. The following sample generates
LNK2019, and shows how to fix it.
// LNK2019b.cpp
// Compile by using: cl /EHsc LNK2019b.cpp
// LNK2019 expected
struct C {
static int s;
};
int main() {
C c;
C::s = 1;
}
// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;
template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
return os;
}
int main() {
Test<int> t;
cout << "Test: " << t << endl; // LNK2019 unresolved external
}
// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
The next sample uses the DLL in the previous sample, and generates LNK2019 because the types unsigned
short* and WCHAR* are not the same.
// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
To fix this error, change unsigned short to wchar_t or WCHAR , or compile LNK2019g.cpp by using /Zc:wchar_t-.
Additional resources
For more information about possible causes and solutions for LNK2001, see the Stack Overflow question What is
an undefined reference/unresolved external symbol error and how do I fix it?.
Global Constants in C++
10/31/2018 • 2 minutes to read • Edit Online
C++ global constants have static linkage. This is different than C. If you try to use a global constant in C++ in
multiple files you get an unresolved external error. The compiler optimizes global constants out, leaving no space
reserved for the variable.
One way to resolve this error is to include the const initializations in a header file and include that header in your
CPP files when necessary, just as if it was function prototype. Another possibility is to make the variable non-
constant and use a constant reference when assessing it.
The following sample generates C2019:
// global_constants.cpp
// LNK2019 expected
void test(void);
const int lnktest1 = 0;
int main() {
test();
}
And then,
// global_constants_2.cpp
// compile with: global_constants.cpp
extern int lnktest1;
void test() {
int i = lnktest1; // LNK2019
}
See Also
Linker Tools Error LNK2019
Function Inlining Problems
10/31/2018 • 2 minutes to read • Edit Online
// LNK2019_function_inline.cpp
// compile with: /c
// post-build command: lib LNK2019_function_inline.obj
#include <stdio.h>
struct _load_config_used {
void Test();
void Test2() { printf("in Test2\n"); }
};
And then,
// LNK2019_function_inline_2.cpp
// compile with: LNK2019_function_inline.lib
struct _load_config_used {
void Test();
void Test2();
};
int main() {
_load_config_used x;
x.Test();
x.Test2(); // LNK2019
}
If you are using the #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set. A
value of zero will turn off inlining. Also make sure you are using the /Ob1 or /Ob2 compiler options.
Mixing inline and non-inline compile options on different modules can sometimes cause problems. If a C++
library is created with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the
functions has inlining turned off (no option), you will get error LNK2001. The functions do not get inlined into the
code from the header file, but since they are not in the library file there is no address to resolve the reference.
Similarly, a project that uses function inlining yet defines the functions in a .cpp file rather than in the header file
will also get LNK2019. The header file is included everywhere deemed appropriate, but the functions are only
inlined when the .cpp file passes through the compiler; therefore, the linker sees the functions as unresolved
externals when used in other modules.
// LNK2019_FIP.h
struct testclass {
void PublicStatMemFunc1(void);
};
and then,
// LNK2019_FIP.cpp
// compile with: /c
#include "LNK2019_FIP.h"
inline void testclass::PublicStatMemFunc1(void) {}
and then,
// LNK2019_FIP_2.cpp
// compile with: LNK2019_FIP.cpp
// LNK2019 expected
#include "LNK2019_FIP.h"
int main() {
testclass testclsObject;
See Also
Linker Tools Error LNK2019
Automatic (Function Scope) Variables
10/31/2018 • 2 minutes to read • Edit Online
A variable declared within a function can only be used within the scope of that function.
// LNK2019_AV.cpp
// compile with: /c
void test(void);
int main() {
static int lnktest1 = 1;
int lnktest2 = 2;
test();
}
and then,
// LNK2019_AV_2.cpp
// compile with: LNK2019_AV.cpp
// LNK2019 expected
extern int lnktest1;
extern int lnktest2;
extern int lnktest3;
extern int lnktest4;
void test(void) {
int i = 0;
i = lnktest1;
i = lnktest2;
i = lnktest3;
i = lnktest4; // OK
}
See Also
Linker Tools Error LNK2019
Missing Function Body or Variable
10/31/2018 • 2 minutes to read • Edit Online
With just a function prototype, the compiler can continue without error, but the linker cannot resolve a call to an
address because there is no function code or variable space reserved. You will not see this error until you create a
call to the function that the linker must resolve.
Example
The function call in main will cause LNK2019 because the prototype allows the compiler to think the function
exists. The linker finds that it doesn't.
// LNK2019_MFBV.cpp
// LNK2019 expected
void DoSomething(void);
int main() {
DoSomething();
}
Example
In C++, make sure that you include the implementation of a specific function for a class and not just a prototype in
the class definition. If you are defining the class outside of the header file, be sure to include the class name before
the function ( Classname::memberfunction ).
// LNK2019_MFBV_2.cpp
// LNK2019 expected
struct A {
static void Test();
};
int main() {
A AObject;
AObject.Test();
}
See Also
Linker Tools Error LNK2019
Linker Tools Error LNK2020
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates LNK2020.
// LNK2020.cpp
// compile with: /clr /LD
ref struct A {
A(int x); // LNK2020
static int f(); // LNK2020
};
// OK
ref struct B {
B(int x) {}
static int f() { return 0; }
};
Example
LNK2020 will also occur if you create a variable of a managed template type, but do not also instantiate the type.
The following sample generates LNK2020.
// LNK2020_b.cpp
// compile with: /clr
int main() {
Base<int>^ p; // LNK2020
Base2<int>^ p2 = gcnew Base2<int>(); // OK
};
Linker Tools Error LNK2022
10/31/2018 • 2 minutes to read • Edit Online
The linker detected an error while merging metadata. The metadata errors must be resolved to link successfully.
One way to diagnose this problem is to run ildasm -tokens on the object files to find which types have the tokens
listed in error_message , and look for differences. In metadata, two different types with the same name is not valid,
even if the just LayoutType attribute is different.
One reason for LNK2022 is when a type (such as a struct) exists in multiple compilands with the same name, but
with conflicting definitions, and when you compile with /clr. In this case, make sure that the type has an identical
definition in all compilands. The type name is listed in error_message .
Another possible cause for LNK2022 is when the linker finds a metadata file in a different location than was
specified to the compiler (with #using ). Make sure that the metadata file (.dll or .netmodule) is in the same location
when passed to the linker, as it was when it was passed to the compiler.
When building an ATL application, the use of the macro _ATL_MIXED is required in all compilands, if it is used in at
least one.
Example
The following sample defines an empty type.
// LNK2022_a.cpp
// compile with: /clr /c
public ref class Test {};
Example
This sample shows that you cannot link two source code files that contain types of the same name but different
definitions.
The following sample generates LNK2022.
// LNK2022_b.cpp
// compile with: LNK2022_a.cpp /clr /LD
// LNK2022 expected
public ref class Test {
void func() {}
int var;
};
Linker Tools Error LNK2023
10/31/2018 • 2 minutes to read • Edit Online
Remarks
When attempting to import a native function into a pure image, remember that the implicit calling conventions
differ between native and pure compilations.
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
Example
This code sample generates a component with an exported, native, function whose calling convention is implicitly
__cdecl.
// LNK2028.cpp
// compile with: /LD
__declspec(dllexport) int func() {
return 3;
}
Example
The following sample creates a pure client that consumes the native function. However, the calling convention
under /clr:pure is __clrcall. The following sample generates LNK2028.
// LNK2028_b.cpp
// compile with: /clr:pure lnk2028.lib
// LNK2028 expected
int func();
int main() {
return func();
}
Linker Tools Error LNK2031
10/31/2018 • 2 minutes to read • Edit Online
Remarks
When attempting to import a native function into a pure image, remember that the implicit calling conventions
differ between native and pure compilations. For more information about pure images, see Pure and Verifiable
Code (C++/CLI).
The /clr:pure compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
Example
This code sample generates a component with an exported, native, function whose calling convention is implicitly
__cdecl.
// LNK2031.cpp
// compile with: /LD
extern "C" {
__declspec(dllexport) int func() { return 3; }
};
Example
The following sample creates a pure client that consumes the native function. However, the calling convention
under /clr:pure is __clrcall. The following sample generates LNK2031.
// LNK2031_b.cpp
// compile with: /clr:pure LNK2031.lib
// LNK2031 expected
extern "C" int func();
int main() {
return func();
}
Example
The following sample shows how to consume the native function from a pure image. Note the explicit __cdecl
calling convention specifier.
// LNK2031_c.cpp
// compile with: /clr:pure LNK2031.lib
extern "C" int __cdecl func();
int main() {
return func();
}
Linker Tools Error LNK2033
10/31/2018 • 2 minutes to read • Edit Online
Example
The following sample generates LNK2033.
// LNK2033.cpp
// compile with: /clr:safe
// LNK2033 expected
ref class A;
ref class B {};
int main() {
A ^ aa = nullptr;
B ^ bb = nullptr; // OK
};
Linker Tools Error LNK2038
10/31/2018 • 2 minutes to read • Edit Online
mismatch detected for 'name': value 'value_1' doesn't match value 'value_2' in filename.obj
A symbol mismatch has been detected by the linker. This error indicates that different parts of an app, including
libraries or other object code that the app links to, use conflicting definitions of the symbol. The detect mismatch
pragma is used to define such symbols and detect their conflicting values.
See also
Linker Tools Errors and Warnings
Linker Tools Error LNK2039
10/31/2018 • 2 minutes to read • Edit Online
importing ref class '<type>' that is defined in another.obj; it should be either imported or defined, but not both
The ref class '< type >' is imported in the specified .obj file but is also defined in another .obj file. This condition
can cause runtime failure or other unexpected behavior.
To correct this error
1. Check whether ' type ' must be defined in the other .obj file and check whether it must be imported from
the .winmd file.
2. Remove either the definition or the import.
See Also
Linker Tools Errors and Warnings
Linker Tools Error LNK1332
Linker Tools Warning LNK4001
10/31/2018 • 2 minutes to read • Edit Online
You can get this warning if you try to merge two import libs into one.
If you are rebuilding the C run-time library, you can ignore this message.
To fix by using the following possible solutions
1. The given symbol may be a packaged function, created by compiling with /Gy. This symbol was included in
more than one file but was changed between compilations. Recompile all files that include the symbol .
2. The given symbol may have been defined differently in two member objects in different libraries.
3. An absolute may have been defined twice, with a different value in each definition.
4. If the error message is received when combining libraries, symbol already exists in the library being added
to.
Linker Tools Warning LNK4010
10/31/2018 • 2 minutes to read • Edit Online
a type record in 'filename' is corrupted; some symbols and types may not be accessible from the debugger
The decorated name symbol could not be ordered by using the /ORDER option because it could not be found in
the program. Check the specification of symbol in the order response file. For more information, see the /ORDER
(Put functions in order) linker option.
NOTE
LINK cannot order static functions because static function names are not public symbol names. When /ORDER is specified,
this linker warning is generated for each symbol in the order response file that is either static or not found.
Linker Tools Warning LNK4039
10/31/2018 • 2 minutes to read • Edit Online
Example
Linking the following two modules will generate LNK4049. The first module generates an object file containing a
single exported function.
// LNK4049a.cpp
// compile with: /c
Example
The second module generates an object file containing a forward declaration to the function exported in the first
module, along with a call to this function inside the main function. Linking this module with the first module will
generate LNK4049. Removing the __declspec(dllimport) declaration will resolve the warning.
// LNK4049b.cpp
// compile with: /link /WX /LTCG LNK4049a.obj
// LNK4049 expected
int main()
{
return func();
}
See Also
Linker Tools Warning LNK4217
dllexport, dllimport
Linker Tools Warning LNK4065
10/31/2018 • 2 minutes to read • Edit Online
/OUT:filename directive in .EXP differs from output filename 'filename'; ignoring directive
The filename specified in the NAME or LIBRARY statement when the .exp file was created differs from the output
filename that was either assumed by default or specified with the /OUT option.
You will see this warning if you change the name of an output file in the development environment and where the
project's .def file was not updated. Manually update the .def file to resolve this warning.
A client program that uses the resulting DLL might encounter problems.
Linker Tools Warning LNK4071
10/31/2018 • 2 minutes to read • Edit Online
Example
LNK4078 can also be caused by a breaking change: the section named by init_seg on x86 was read/write, it is now
read only.
The following sample generates LNK4078.
// LNK4078.cpp
// compile with: /W1
// LNK4078 expected
#include <stdio.h>
#pragma warning(disable : 4075)
typedef void (__cdecl *PF)(void);
int cxpf = 0; // number of destructors to call
PF pfx[200]; // pointers to destructors.
struct A { A() {} };
#pragma data_seg()
#pragma init_seg(".mine$m", myexit)
A bbbb;
A cccc;
int main() {}
Linker Tools Warning LNK4086
10/31/2018 • 2 minutes to read • Edit Online
entrypoint 'function' is not __stdcall with 'number' bytes of arguments; image may not run
The entry point for a DLL must be __stdcall . Either recompile the function with the /Gz option or specify
__stdcall or WINAPI when you define the function.
Linker Tools Warning LNK4092
10/31/2018 • 2 minutes to read • Edit Online
shared writable section 'section' contains relocations; image may not run correctly
The linker emits this warning whenever you have a shared section to warn you of a potentially serious problem.
One way to share data between multiple processes is to mark a section as "shared." However, marking a section as
shared can cause problems. For example, you have a DLL that contains declarations like this in a shared data
section:
int var = 1;
int *pvar = &var;
The linker cannot resolve pvar because its value depends on where the DLL is loaded in memory, so it puts a
relocation record in the DLL. When the DLL is loaded into memory, the address of var can be resolved and pvar
assigned. If another process loads the same DLL but cannot load it at the same address, the relocation for the
address of var will be updated for the second process and the first process's address space will point to the wrong
address.
Linker Tools Warning LNK4096
10/31/2018 • 2 minutes to read • Edit Online
/BASE value "number" is invalid for Windows 95 and Windows 98; image may not run
The base address you specified is invalid. Windows 95 and Windows 98 executable files must have a base address
greater than 0x400000. For more information on base addresses, see the /BASE linker option.
Linker Tools Warning LNK4098
10/31/2018 • 2 minutes to read • Edit Online
NOTE
The run-time libraries now contain directives to prevent mixing different types. You will receive this warning if you try to use
different types or debug and non-debug versions of the run-time library in the same program. For example, if you compiled
one file to use one kind of run-time library and another file to use another kind (for example, single-threaded versus
multithreaded) and tried to link them, you will get this warning. You should compile all source files to use the same run-time
library. See the Use Run-Time Library (/MD, /MT, /LD) compiler options for more information.
You can use the linker's /VERBOSE:LIB switch to determine which libraries the linker is searching. If you receive
LNK4098 and want to create an executable file that uses, for example, the single-threaded, non-debug run-time
libraries, use the /VERBOSE:LIB option to find out which libraries the linker is searching. The linker should print
LIBC.lib and not LIBCMT.lib, MSVCRT.lib, LIBCD.lib, LIBCMTD.lib, or MSVCRTD.lib as the libraries searched. You
can tell the linker to ignore the incorrect run-time libraries by using /NODEFAULTLIB for each library you want to
ignore.
The table below shows which libraries should be ignored depending on which run-time library you want to use.
Debug Multithreaded using DLL (msvcrtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
For example, if you received this warning and you want to create an executable file that uses the non-debug,
single-threaded version of the run-time libraries, you could use the following options with the linker:
PDB 'filename' was not found with 'object/library' or at 'path'; linking object as if no debug info
The linker was unable to find your .pdb file. Copy it into the directory that contains object/library .
To find the name of the .pdb file associated with the object file:
1. Extract an object file from the library with lib /extract: objectname .obj xyz .lib.
2. Check the path to the .pdb file with dumpbin /section:.debug$T /rawdata objectname .obj.
You could also compile with /Z7, so the pdb doesn't need to be used, or remove the /DEBUG linker option if you
do not have .pdb files for the objects you are linking.
Linker Tools Warning LNK4102
10/31/2018 • 2 minutes to read • Edit Online
DllGetClassObject
DllGetClassFactoryFromClassString
DllGetDocumentation
DllInitialize
DllInstall
DllRegisterServer
DllRegisterServerEx
DllRegisterServerExW
DllUnload
DllUnregisterServer
RasCustomDeleteEntryNotify
RasCustomDial
RasCustomDialDlg
RasCustomEntryDlg
This warning is emitted when you are building an import library for a DLL and export one of the above functions
without specifying it as PRIVATE in the module-definition file. In general, these functions are exported for use only
by OLE. Placing them in the import library can lead to unusual behavior when a program linked to the library
incorrectly makes calls to them. For more information about the PRIVATE keyword, see EXPORTS.
Linker Tools Warning LNK4105
10/31/2018 • 2 minutes to read • Edit Online
Example
link /libpath:c:\filepath\lib bar.obj
would direct the linker to search for the required libraries in c:\filepath\lib before searching in the default
locations.
Linker Tools Warning LNK4194
10/31/2018 • 2 minutes to read • Edit Online
An export is specified in multiple and different ways. The linker uses the first specification and ignores the rest.
If you are rebuilding the C run-time library, you can ignore this message.
If an export is specified exactly the same way multiple times, the linker will not issue a warning.
For example, the following contents of a .def file would cause this warning:
EXPORTS
functioname NONAME
functioname @10
'filename' is missing debugging information for referencing module; linking object as if no debug info
The .pdb file has an erroneous signature. The linker will continue to link the object without debug information. You
may want to recompile the object file using the /Zi option.
LNK4204 can occur if some of the objects in the library refer to a file that no longer exists. This could happen
when rebuilding the solution, for example; an object file might be deleted and not rebuilt because of a compilation
error. In this case, either compile with /Z7, or /Fd, to update the objects to refer to a single file per-library (that is
not the default .pdb file name). For more information, see /Fd (Program Database File Name). Ensure that the .pdb
is saved with the library every time it is updated in the source control system.
Linker Tools Warning LNK4205
10/31/2018 • 2 minutes to read • Edit Online
'filename' is missing current debugging information for referencing module; linking object as if no debug info
The .pdb file has out-of-date information. The linker will continue to link object without debug information. You
may want to recompile the object file using the /Zi option.
Linker Tools Warning LNK4206
10/31/2018 • 2 minutes to read • Edit Online
precompiled type information not found; 'filename' not linked or overwritten; linking object as if no debug
info
The filename object file, compiled by using /Yc, was either not specified in the LINK command or was overwritten.
A common scenario for this warning is when the .obj that was compiled with /Yc is in a library, and where there
are no symbol references to that .obj from your code. In that case, the linker will not use (or even see) the .obj file.
In this situation, you should recompile your code and use /Yl for the objects compiled by using /Yu.
Linker Tools Warning LNK4210
3/12/2019 • 2 minutes to read • Edit Online
Remarks
Some code has introduced static initializers or terminators, but the VCRuntime library startup code or its
equivalent (which needs to run the static initializers or terminators) isn't run when the application starts. Here are
some examples of code that requires static initializers or terminators:
Global class variable with a constructor, destructor, or virtual function table.
Global variable initialized with a non-compile-time constant.
To fix this problem, try one of the following:
Remove all code with static initializers.
Do not use /NOENTRY. After you remove /NOENTRY, you may also have to remove /NODEFAULTLIB
from your linker command line.
If your build uses /MT, add libcmt.lib, libvcruntime.lib, and libucrt.lib to your linker command line. If your
build uses /MTd, add libcmtd.lib, vcruntimed.lib, and libucrtd.lib.
When moving from /clr:pure compilation to /clr, remove the /ENTRY option from the linker-line. This
enables CRT initialization and allows static initializers to be executed at application startup. The /clr:pure
compiler option is deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
The /GS compiler option requires initialization by the __security_init_cookie function. This initialization is
provided by default in the VCRuntime library startup code that runs in _DllMainCRTStartup .
If your project is built using /ENTRY, and if /ENTRY is passed a function other than _DllMainCRTStartup , the
function must call _CRT_INIT to initialize the CRT. This call alone is not sufficient if your DLL uses /GS, requires
static initializers, or is called in the context of MFC or ATL code. See DLLs and Visual C++ run-time library
behavior for more information.
See also
Setting Linker Options
Linker Tools Warning LNK4216
10/31/2018 • 2 minutes to read • Edit Online
symbol is the symbol name that's defined within the image. function is the function that is importing the symbol.
This warning will not appear when you compile by using the option /clr.
LNK4217 can also occur if you attempt to link two modules together, when instead you should compile the second
module with the import library of the first module.
// LNK4217.cpp
// compile with: /LD
#include "windows.h"
__declspec(dllexport) void func(unsigned short*) {}
And then,
// LNK4217b.cpp
// compile with: /c
#include "windows.h"
__declspec(dllexport) void func(unsigned short*) {}
Attempting to link these two modules will result in LNK4217, compile the second sample with the import library
of the first sample to resolve.
Linker Tools Warning LNK4219
10/31/2018 • 2 minutes to read • Edit Online
fixup name fixup overflow. Target 'target symbol name' is out of range, inserting thunk
The linker inserted a thunk in a situation where the address or offset was unable to fit in the given instruction
because the target symbol is too far away from the instruction's location.
You may want to reorder the image (using the /ORDER option, for example) to avoid the extra level of indirection.
Linker Tools Warning LNK4220
10/31/2018 • 2 minutes to read • Edit Online
This object file does not define any previously undefined public symbols, so it will not be used by any link
operation that consumes this library
Consider the following two code snippets.
// a.cpp
#include <atlbase.h>
// b.cpp
#include <atlbase.h>
int function()
{
return 0;
}
To compile the files and create two object files, run cl /c a.cpp b.cpp at a command prompt. If you link the object
files by running link /lib /out:test.lib a.obj b.obj, you will receive the LNK4221 warning. If you link the objects
by running link /lib /out:test.lib b.obj a.obj, you will not receive a warning.
No warning is issued in the second scenario because the linker operates in a last-in first-out (LIFO ) manner. In the
first scenario, b.obj is processed before a.obj, and a.obj has no new symbols to add. By instructing the linker to
process a.obj first, you can avoid the warning.
A common cause of this error is when two source files specify the option /Yc (Create Precompiled Header File)
with the same header file name specified in the Precompiled Header field. A common cause of this problem
deals with stdafx.h since, by default, stdafx.cpp includes stdafx.h and does not add any new symbols. If another
source file includes stdafx.h with /Yc and the associated .obj file is processed before stdafx.obj, the linker will throw
LNK4221.
One way to resolve this problem is to make sure that for each precompiled header, there is only one source file that
includes it with /Yc. All other source files must use precompiled headers. For more information about how to
change this setting, see /Yu (Use Precompiled Header File).
Linker Tools Warning LNK4222
10/31/2018 • 2 minutes to read • Edit Online
DllGetClassObject
DllGetClassFactoryFromClassString
DllInstall
DllRegisterServer
DllRegisterServerEx
DllUnregisterServer
These functions are always located by name, using GetProcAddress . The linker warns about this kind of export is
because it could result in a larger image. This could happen if the range of your ordinal exports is large with
relatively few exports. For example,
EXPORTS
DllGetClassObject @1
MyOtherAPI @100
will require 100 slots in the export address table with 98 of them (2-99) just filler. On the other hand,
EXPORTS
DllGetClassObject
MyOtherAPI @100
will require two slots. (Be aware that you can also export with the /EXPORT linker option.)
Linker Tools Warning LNK4224
10/31/2018 • 2 minutes to read • Edit Online
Remarks
An invalid, obsolete linker option was specified and ignored.
For example, LNK4224 can occur if a /comment directive appears in .obj. The /comment directive would have
been added via the comment (C/C++) pragma, using the deprecated exestr option. Use dumpbin /ALL to view the
linker directives in an .obj file.
If possible, modify the source for the .obj and remove the pragma. If you do ignore this warning, it is possible that
an .executable compiled with /clr:pure will not run as expected. The /clr:pure compiler option is deprecated in
Visual Studio 2015 and unsupported in Visual Studio 2017.
Example
The following sample generates LNK4224.
// LNK4224.cpp
// compile with: /c /Zi
// post-build command: link LNK4224.obj /debug /debugtype:map
int main () {
return 0;
}
Linker Tools Warning LNK4227
10/31/2018 • 2 minutes to read • Edit Online
Example
LNK4227 is generated when a referenced assembly was signed differently than the assembly that references it.
The following sample generates LNK4227:
// LNK4227.cpp
// compile with: /clr
using namespace System::Reflection;
[assembly:AssemblyDelaySignAttribute(false)];
int main() {}
and then,
// LNK4227b.cpp
// compile with: /clr LNK4227.cpp /FeLNK4227b.exe
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
[assembly:AssemblyDelaySignAttribute(true)];
// Try the following line instead
// [assembly:AssemblyDelaySignAttribute(false)];
Example
LNK4227 can also be generated when version numbers in the wrong format are passed to assembly attributes.
The '*' notation is specific to the AssemblyVersionAttribute . To resolve this warning, use only numbers in the
version attributes other than AssemblyVersionAttribute .
The following sample generates LNK4227:
// LNK4227e.cpp
// compile with: /clr /LD /W1
using namespace System::Reflection;
[assembly:AssemblyVersionAttribute("2.3.*")]; // OK
[assembly:AssemblyFileVersionAttribute("2.3.*")]; // LNK4227
// try the following line instead
// [assembly:AssemblyFileVersionAttribute("2.3")];
Linker Tools Warning LNK4229
10/31/2018 • 2 minutes to read • Edit Online
// LNK4247.cpp
// compile with: /clr /c
// post-build command: link /CLRTHREADATTRIBUTE:STA LNK4247.obj /entry:functionTitle /SUBSYSTEM:Console
[System::MTAThreadAttribute]
void functionTitle (){}
Linker Tools Warning LNK4248
10/31/2018 • 2 minutes to read • Edit Online
unresolved typeref token (token) for 'type'; image may not run
A type doesn’t have a definition in MSIL metadata.
LNK4248 can occur when there is only a forward declaration for a type in an MSIL module (compiled with /clr),
where the type is referenced in the MSIL module, and where the MSIL module is linked with a native module that
has a definition for the type.
In this situation, the linker will provide the native type definition in the MSIL metadata, and this may provide for
the correct behavior.
However, if a forward type declaration is a CLR type, then the linker's native type definition may not be correct
For more information, see /clr (Common Language Runtime Compilation).
To correct this error
1. Provide the type definition in the MSIL module.
Example
The following sample generates LNK4248. Define struct A to resolve.
// LNK4248.cpp
// compile with: /clr /W1
// LNK4248 expected
struct A;
void Test(A*){}
int main() {
Test(0);
}
Example
The following sample has a forward definition of a type.
// LNK4248_2.cpp
// compile with: /clr /c
class A; // provide a definition for A here to resolve
A * newA();
int valueA(A * a);
int main() {
A * a = newA();
return valueA(a);
}
Example
The following sample generates LNK4248.
// LNK4248_3.cpp
// compile with: /c
// post-build command: link LNK4248_2.obj LNK4248_3.obj
class A {
public:
int b;
};
A* newA() {
return new A;
}
int valueA(A * a) {
return (int)a;
}
Linker Tools Warning LNK4253
10/31/2018 • 2 minutes to read • Edit Online
section 'section1' not merged into 'section2'; already merged into 'section3'
The linker detected multiple, conflicting merge requests. The linker will ignore one of the requests.
A /MERGE option or directive is encountered and the from section has already been merged into a different
section due to a previous /MERGE option or directive (or due to an implicit merge from the linker).
To resolve LNK4253, remove one of the merge requests.
When targeting x86 machines and Windows CE targets (ARM, MIPS, SH4, and Thumb) with Visual C++, the .CRT
section is now read only. If your code depends on the previous behavior (.CRT sections are read/write), you could
see unexpected behavior.
For more information, see,
/MERGE (Combine Sections)
comment (C/C++)
Example
In the following sample, the linker is instructed to merge the .rdata section twice, but into different sections. The
following sample generates LNK4253.
// LNK4253.cpp
// compile with: /W1 /link /merge:.rdata=text2
// LNK4253 expected
#pragma comment(linker, "/merge:.rdata=.text")
int main() {}
Linker Tools Warning LNK4254
10/31/2018 • 2 minutes to read • Edit Online
section 'section1' (offset) merged into 'section2' (offset) with different attributes
The contents of one section were merged into another, but the attributes of the two sections are different. Your
program may give unexpected results. For example, data you wanted to be read only may now be in a writable
section.
To resolve LNK4254, modify or remove the merge request.
When targeting x86 machines and Windows CE targets (ARM, MIPS, SH4, and Thumb) with Visual C++, the .CRT
section is read-only. If your code depends on previous behavior (.CRT sections are read/write), you could see
unexpected behavior.
For more information, see,
/MERGE (Combine Sections)
comment (C/C++)
Example
The following sample generates LNK4254.
// LNK4254.cpp
// compile with: /W1 /link /WX
// LNK4254 expected
#pragma comment(linker, "/merge:.data=.text")
int main() {}
Profile-Guided Optimization Errors and Warnings
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors generated by the build tools. For help with a particular error message,
either click the error number in the Output window and press F1, type the error number in the Look for box in the
Index, or click the appropriate link:
Profile-Guided Optimization Error PG0165
Profile-Guided Optimization Warning PG1039
Profile-Guided Optimization Warning PG1087
Profile-Guided Optimization Warning PG1039
3/12/2019 • 2 minutes to read • Edit Online
This section is a reference to the errors generated by the runtime floating-point math library.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. The Visual C++ General forum is for questions about
Visual C++ that are not discussed in other forums. You may also search for errors and warnings and ask questions
on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Math Error M6101
10/31/2018 • 2 minutes to read • Edit Online
invalid
Invalid operation.
This error can be caused when an operand is NaN (not a number) or infinity.
Program terminates with exit code 129.
Math Error M6102
10/31/2018 • 2 minutes to read • Edit Online
denormal
An operation generated a very small floating-point number, which be invalid due loss of significance. Denormal
floating-point exceptions are usually masked, causing them to be trapped and operated upon.
Program terminates with exit code 130.
Math Error M6107
10/31/2018 • 2 minutes to read • Edit Online
unemulated
An attempt was made to execute a coprocessor instruction that is invalid or is not supported by the emulator.
Program terminates with exit code 135.
Math Error M6108
10/31/2018 • 2 minutes to read • Edit Online
square root
The operand in a square-root operation was negative.
Program terminates with exit code 136.
NOTE
The sqrt function in the C run-time library and the FORTRAN intrinsic function SQRT do not generate this error. The C
sqrt function checks the argument before performing the operation and returns an error value if the operand is negative.
The FORTRAN SQRT function generates the DOMAIN error M6201 instead of this error.
Math Error M6110
10/31/2018 • 2 minutes to read • Edit Online
stack overflow
A floating-point expression caused a floating-point stack overflow.
Stack-overflow floating-point exceptions are trapped up to a limit of seven levels in addition to the eight levels
usually supported by the 8087/287/387 coprocessor.
Program terminates with exit code 138.
Math Error M6111
10/31/2018 • 2 minutes to read • Edit Online
stack underflow
A floating-point operation resulted in a stack underflow on the 8087/287/387 coprocessor or the emulator.
This error is often caused by a call to a long double function that does not return a value. For example, the
following generates this error when compiled and run:
Example
result = sqrt(-1.0) // C statement
result = SQRT(-1.0) ! FORTRAN statement
This error calls the _matherr function with the function name, its arguments, and the error type. You can rewrite
the _matherr function to customize the handling of certain run-time floating-point math errors.
Math Error M6202
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors and warnings generated by the NMAKE build tool.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
NMAKE Fatal Error U1000
10/31/2018 • 2 minutes to read • Edit Online
A left parenthesis, (, appeared without a matching right parenthesis, ), in a macro invocation. The correct form is
$(name); $n is allowed for one-character names.
NMAKE Fatal Error U1001
10/31/2018 • 2 minutes to read • Edit Online
2. If a macro definition in the makefile contained an equal sign (=) without a preceding name or if the name
being defined is a macro that expands to nothing, the following error occurs:
3. If the semicolon (;) in a comment line in TOOLS.INI is not at the beginning of the line, the following error
occurs:
4. If the makefile has been formatted by a word processor, the following error can occur:
message
The message specified with the !ERROR directive was displayed.
NMAKE Fatal Error U1051
10/31/2018 • 2 minutes to read • Edit Online
out of memory
NMAKE ran out of memory, including virtual memory, because the makefile was too large or complex.
To fix by using the following possible solutions
1. Free some space on disk.
2. Increase the size of the Windows NT paging file or the Windows swap file.
3. If only part of the makefile is being used, either divide the makefile into separate files or use !IF
preprocessing directives to limit the amount that NMAKE must process. The !IF directives include !IF,
!IFDEF , !IFNDEF, !ELSE IF, !ELSE IFDEF , and !ELSE IFNDEF .
NMAKE Fatal Error U1052
10/31/2018 • 2 minutes to read • Edit Online
NMAKE could not find the file specified with one of the following:
/F option
!INCLUDE preprocessing directive
At sign (@) specifier for a response file
Check that the file exists and the filename is spelled correctly.
NMAKE Fatal Error U1055
10/31/2018 • 2 minutes to read • Edit Online
A search path for a dependent was incorrectly specified. Either a space existed in the path or the closing brace (})
was omitted.
The syntax for a directory specification for a dependent is
{ directories }dependent
where directories specifies one or more paths, each separated by a semicolon (;). No spaces are allowed.
If part or all of a search path is replaced by a macro, make sure no spaces exist in the macro expansion.
NMAKE Fatal Error U1064
10/31/2018 • 2 minutes to read • Edit Online
Example
The following macro definitions
ONE=$(TWO)
TWO=$(ONE)
stack overflow
The makefile being processed was too complex for the current stack allocation in NMAKE. NMAKE has an
allocation of 0x3000 (12K).
To increase NMAKE's stack allocation, run the editbin /stack utility with a larger stack option:
editbin /STACK:reserve NMAKE.EXE
where reserve is a number greater than the current stack allocation in NMAKE.
NMAKE Fatal Error U1100
10/31/2018 • 2 minutes to read • Edit Online
A command file, which is invoked by the at sign (@) specifier, cannot contain a specification for another command
file. Such nesting is not allowed. The specification was ignored.
NMAKE Warning U4004
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors that can be generated by the C Runtime Library (CRT) when your app is
loaded or running. Even though the message refers to the Microsoft Visual C++ runtime, these errors indicate
either a bug in your app's code, or a condition that the runtime library can't handle, such as low memory. End users
of your app may see these errors if you do not code your app to prevent the conditions that cause them, or write
code to capture these errors and present a friendly message to your users.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. The Visual C++ General forum is for questions about
Visual C++ that are not discussed in other forums. You may also search for errors and warnings and ask questions
on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
C Runtime errors
C Runtime Error R6002
C Runtime Error R6008
C Runtime Error R6009
C Runtime Error R6016
C Runtime Error R6017
C Runtime Error R6018
C Runtime Error R6019
C Runtime Error R6024
C Runtime Error R6025
C Runtime Error R6028
C Runtime Error R6030
C Runtime Error R6031
C Runtime Error R6032
C Runtime Error R6033
C Runtime Error R6035
See also
C/C++ Build Errors
C Runtime Error R6002
10/31/2018 • 2 minutes to read • Edit Online
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. There
are several possible reasons for this error, but often it's caused by a defect in the app's code, or by attempting to run an app
that was not built for your particular computer processor.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are several possible reasons for this error, but often it's caused by an extremely low memory condition, too
much memory taken by environment variables, or a bug in the program.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Reduce the number and size of command-line arguments to the app.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are several possible reasons for this error, but often it's caused by an extremely low memory condition, too
much memory taken by environment variables, or a bug in the program.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are many possible reasons for this error, but often it's caused by an extremely low memory condition, a bug
in the app, or by a bug in an add-in or extension used by the app.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the app.
Use the Apps and Features or Programs and Features page in the Control Panel to remove, repair or reinstall add-ins
or extensions used by the app.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
When a new thread is started, the library must create an internal database for the thread. If the database cannot be
expanded by using memory provided by the operating system, the thread does not begin and the calling process
stops. This can happen when too many threads have been created by the process, or if thread local storage has
been exhausted.
We recommend that an executable that calls the C runtime library (CRT) should use _beginthreadex for thread
creation rather than the Windows API CreateThread . _beginthreadex initializes internal static storage used by
many CRT functions in thread local storage. If you use CreateThread to create a thread, the CRT may terminate the
process with R6016 when a call is made to a CRT function that requires initialized internal static storage.
C Runtime Error R6017
10/31/2018 • 2 minutes to read • Edit Online
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. There
are several possible reasons for this error, but often it's caused by a defect in the app's code.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. There
are several possible reasons for this error, but often it's caused by a defect in the app's code.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it attempted to access the
console, but it didn't have sufficient permission. There are several possible reasons for this error, but it's usually because the
program must be run as an administrator, or there is a bug in the program.
You can try these steps to fix this error:
Run the program as an administrator.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. This error is usually caused by an extremely low memory condition, or rarely, by a bug in the program or by
corruption of the Visual C++ libraries that it uses.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall all copies of the
Microsoft Visual C++ Redistributable.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. The
most common reason for this error is a bug in the app, or a corrupted installation.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are several possible reasons for this error, but usually it's caused by an extremely low memory condition. It
can also be caused by a bug in the app, by corruption of the Visual C++ libraries that it uses, or by a driver.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
If the app was working before a recent installation of another app or driver, use the Apps and Features or Programs
and Features page in the Control Panel to remove the new app or driver, and try your app again.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall all copies of the
Microsoft Visual C++ Redistributable.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are several possible reasons for this error, but usually it's caused by an extremely low memory condition. It
can also be caused by a bug in the app, by corruption of the Visual C++ libraries that it uses, or by a driver.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
If the app was working before a recent installation of another app or driver, use the Apps and Features or Programs
and Features page in the Control Panel to remove the new app or driver, and try your app again.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall all copies of the
Microsoft Visual C++ Redistributable.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are many possible reasons for this error, but often it's caused by an extremely low memory condition, a bug
in the program, or by defective hardware drivers.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
If the app was working before a recent installation of another app or driver, use the Apps and Features or Programs
and Features page in the Control Panel to remove the new app or driver, and try your app again.
Check your hardware vendor's website or Windows Update in the Control Panel for software and driver updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. This
problem is most often caused by certain security software programs, or rarely, by a bug in the program.
You can try these steps to fix this error:
Your security software may have specific instructions for mitigating this issue. Check your security software vendor's
website for details. Alternatively, check for updated versions of your security software, or try different security software.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
Attempt to initialize the CRT more than once. This indicates a bug in your application.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. This
may be caused bug in the app, or by a bug in an add-on or extension that the app uses.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Use the Apps and Features or Programs and Features page in the Control Panel to remove, repair or reinstall any
add-on or extension programs used by the app.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal memory
problem. There are several possible reasons for this error, but often it's caused by an extremely low memory condition, or by
a bug in the program.
You can try these steps to fix this error:
Close other running applications or restart your computer to free up memory.
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
Attempt to use MSIL code from this assembly during native code initialization. This indicates a bug in your
application. It is most likely the result of calling an MSIL -compiled (/clr) function from a native constructor or from
DllMain.
NOTE
If you encounter this error message while running an app, the app was shut down because it has an internal problem. This
error can be caused by a bug in the app, or by a bug in an add-in or extension that it uses.
You can try these steps to fix this error:
Use the Apps and Features or Programs and Features page in the Control Panel to repair or reinstall the program.
Use the Apps and Features or Programs and Features page in the Control Panel to remove, repair or reinstall any
extensions or add-ins.
Check Windows Update in the Control Panel for software updates.
Check for an updated version of the app. Contact the app vendor if the problem persists.
Microsoft Visual C++ Runtime Library, Error R6035 - A module in this application is initializing the module's
global security cookie while a function relying on that security cookie is active. Call __security_init_cookie earlier.
__security_init_cookie must be called before the first use of the global security cookie.
The global security cookie is used for buffer overrun protection in code compiled with /GS (Buffer Security Check)
and in code that uses structured exception handling. Essentially, on entry to an overrun-protected function, the
cookie is put on the stack, and on exit, the value on the stack is compared against the global cookie. Any difference
between them indicates that a buffer overrun has occurred and results in immediate termination of the program.
Error R6035 indicates that a call to __security_init_cookie was made after a protected function was entered. If
execution were to continue, a spurious buffer overrun would be detected because the cookie on the stack would no
longer match the global cookie.
Consider the following DLL example. The DLL entry point is set to DllEntryPoint through the linker /ENTRY
(Entry-Point Symbol) option. This bypasses the CRT's initialization which would ordinarily initialize the global
security cookie, so the DLL itself must call __security_init_cookie .
void DllInitialize() {
__security_init_cookie();
}
This example will generate error R6035 because DllEntryPoint uses structured exception handling and therefore
uses the security cookie to detect buffer overruns. By the time DllInitialize is called, the global security cookie has
already been put on the stack.
The correct way is demonstrated in this example:
// Correct way to call __security_init_cookie
DllEntryPoint(...) {
__security_init_cookie();
DllEntryHelper();
}
void DllEntryHelper() {
...
__try {
...
} __except()... {
...
}
}
In this case, DllEntryPoint is not protected against buffer overruns (it has no local string buffers and doesn't use
structured exception handling); therefore it can safely call __security_init_cookie . It then calls a helper function
that is protected.
NOTE
Error message R6035 is only generated by the x86 debug CRT, and only for structured exception handling, but the condition
is an error on all platforms, and for all forms of exception handling, such as C++ EH.
See Also
Security Features in MSVC
Resource Compiler Errors RC1000 through RC4413
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors generated by the build tools. To get help on a particular error message,
either click the mouse on an error number in the Output window and press F1, or type the error number in the
Look for box in the Index.
Resource Compiler Fatal Error RC1002
10/31/2018 • 2 minutes to read • Edit Online
unexpected '#elif'
The #elif directive did not appear within an #if , #ifdef, or #ifndef construct.
Make sure that there is an #if , #ifdef, or #ifndef statement in effect before this statement.
Resource Compiler Fatal Error RC1019
10/31/2018 • 2 minutes to read • Edit Online
unexpected '#else'
The #else directive did not appear within an #if , #ifdef, or #ifndef construct.
Make sure that there is an #if , #ifdef, or #ifndef statement in effect before this statement.
Resource Compiler Fatal Error RC1020
10/31/2018 • 2 minutes to read • Edit Online
unexpected '#endif'
An #endif directive appeared without a matching #if , #ifdef, or #ifndef directive.
Make sure that there is a matching #endif for each #if , #ifdef, and #ifndef statement.
Resource Compiler Fatal Error RC1021
10/31/2018 • 2 minutes to read • Edit Online
expected '#endif'
An #if , #ifdef, or #ifndef directive was not terminated with an #endif directive.
Make sure that there is an #if , #ifdef, or #ifndef statement in effect before this statement.
Resource Compiler Fatal Error RC1047
10/31/2018 • 2 minutes to read • Edit Online
newline in constant
A string constant was continued on a second line without either a backslash (\) or closing and opening double
quotation marks (").
To break a string constant that is on two lines in the source file, do one of the following:
End the first line with the line-continuation character, a backslash.
Close the string on the first line with a double quotation mark and open the string on the next line with
another quotation mark.
It is not sufficient to end the first line with \n, the escape sequence for embedding a newline character in a string
constant.
Resource Compiler Error RC2007
10/31/2018 • 2 minutes to read • Edit Online
#define syntax
An identifier was expected following #define in a preprocessing directive.
Resource Compiler Error RC2015
10/31/2018 • 2 minutes to read • Edit Online
#ifndef RC_INVOKED
#pragma pack(2) // C/C++ only, ignored by Resource Compiler
#endif
The #pragma preprocessor directive has no meaning in an .RC file. The #include preprocessor directive is used
frequently in an .RC file to include a header file (either a project-based custom header file or a standard header file
provided by Microsoft with one of its products). Some of these include files contain the #pragma directive.
Because a header file can include one or more other header files, the file that contains the offending #pragma
directive may not be immediately obvious.
The #ifndef RC_INVOKED technique can control including header files in project-based header files.
Resource Compiler Error RC2103
10/31/2018 • 2 minutes to read • Edit Online
#include <winresrc.h>
Resource Compiler Error RC2107
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors generated by the build tools. To get help on a particular error message,
either click the mouse on an error number in the Output window and press F1, or type the error number in the
Look for box in the Index.
Resource Compiler Fatal Error RW1004
10/31/2018 • 2 minutes to read • Edit Online
Output Error
This error can be caused if the Resource Compiler was not able to create the destination file. Make sure that there
is enough disk space and that you have write permission on the volume.
Resource Compiler Error RW2001
10/31/2018 • 2 minutes to read • Edit Online
#ifndef RC_INVOKED
#pragma pack(2) // C/C++ only, ignored by Resource Compiler
#endif
The #pragma preprocessor directive has no meaning in an .RC file. The #include preprocessor directive is used
frequently in an .RC file to include a header file (either a project-based custom header file or a standard header file
provided by Microsoft with one of its products). Some of these include files contain the #pragma directive.
Because a header file can include one or more other header files, the file that contains the offending #pragma
directive may not be immediately obvious.
The #ifndef RC_INVOKED technique can control including header files in project-based header files.
Resource Compiler Error RW2002
11/9/2018 • 5 minutes to read • Edit Online
Parsing error
To fix by checking the following possible causes
1. Accelerator type required (ASCII or VIRTKEY )
The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.
2. BEGIN expected in accelerator table
The BEGIN keyword must immediately follow the ACCELERATORS keyword.
3. BEGIN expected in dialog
The BEGIN keyword must immediately follow the DIALOG keyword.
4. BEGIN expected in menu
The BEGIN keyword must immediately follow the MENU keyword.
5. BEGIN expected in RCData
The BEGIN keyword must immediately follow the RCDATA keyword.
6. BEGIN keyword expected in string table
The BEGIN keyword must immediately follow the STRINGTABLE keyword.
7. Cannot re-use string constants
You are using the same value twice in a STRINGTABLE statement. Make sure you are not mixing
overlapping decimal and hexadecimal values. Each ID in a STRINGTABLE must be unique. For maximum
efficiency, use contiguous constants that start on a multiple of 16.
8. Control character out of range [^A - ^Z ]
A control character in the ACCELERATORS statement is invalid. The character following the caret (^) must
be between A and Z, inclusive.
9. Empty menus not allowed
An END keyword appears before any menu items are defined in the MENU statement. The Resource
Compiler does not permit empty menus . Make sure you do not have any open quotation marks within the
MENU statement.
10. END expected in dialog
The END keyword must occur at the end of a DIALOG statement. Make sure there are no open quotes left
from the preceding statement.
11. END expected in menu
The END keyword must come at the end of a MENU statement. Make sure you do not have any open
quotation marks or a mismatched pair of BEGIN and END statements.
12. Expected comma in accelerator Table
The Resource Compiler requires a comma between the event and idvalue fields in the ACCELERATORS
statement.
13. Expected control class name
The class field of a CONTROL statement in the DIALOG statement must be one of the following types:
BUTTON, COMBOBOX, EDIT, LISTBOX, SCROLLBAR, STATIC, or user-defined. Make sure the class is
spelled correctly.
14. Expected font face name
The typeface field of the FONT option in the DIALOG statement must be an ASCII character string
enclosed in double quotation marks. This field specifies the name of a font.
15. Expected ID value for menuitem
The MENU statement must contain a menuID field, which specifies the name or number that identifies the
menu resource.
16. Expected menu string
Each MENUITEM and POPUP statement must contain a text field, which is a string enclosed in double
quotation marks that specifies the name of the menu item or pop-up menu. A MENUITEM SEPARATOR
statement requires no quoted string.
17. Expected numeric command value
The Resource Compiler was expecting a numeric idvalue field in the ACCELERATORS statement. Make
sure that you have used a #define constant to specify the value and that the constant is spelled correctly.
18. Expected numeric constant in string table
A numeric constant, defined in a #define statement, must immediately follow the BEGIN keyword in a
STRINGTABLE statement.
19. Expected numeric point size
The pointsize field of the FONT option in the DIALOG statement must be an integer point size value.
20. Expected numerical dialog constant
A DIALOG statement requires integer values for the x, y, width, and height fields. Make sure that these
values are included after the DIALOG keyword and that they are not negative.
21. Expected string in STRINGTABLE
A string is expected after each stringid value in a STRINGTABLE statement.
22. Expected string or constant accelerator command
The Resource Compiler was not able to determine what kind of key is being set up for the accelerator. The
event field in the ACCELERATORS statement might be invalid.
Generation Error
To fix by checking the following possible causes
1. Error: Bitmap file resource-file is not in 3.00 format
Bitmaps using the Windows version 2.x format cannot be used in version 3.x resource files. The bitmap must
be redrawn or converted to 3.x format.
2. Error: Old DIB in resource-name. Pass it through SDKPAINT
A Device Independent Bitmap (DIB ) in the specified resource is not compatible with the Windows 3.0
format. The bitmap must be redrawn or converted to the 3.x format.
3. Error: Resource file resource-name is not in 3.00 format
An icon or cursor in the specified resource used a format from a previous version of Windows. The icon or
cursor must be redrawn or converted to the 3.x format.
4. Unknown DIB header format
The bitmap header is not a BITMAPCOREHEADER or BITMAPINFOHEADER structure.
5. Unable to initialize symbol information
This error occurs only in Visual C++. The probable cause is that you have too many open files or you cannot
open or write to the data files needed for Visual C++ to import the symbols in your script. Visual C++
attempts to create these files in the directory specified by the TMP environment variable or the current
directory if none is specified.
6. Unable to save symbol information
This error occurs only in Visual C++. The probable cause is that you have too many open files or you cannot
close or write to the data files needed for Visual C++ to import the symbols in your script. Visual C++
attempts to use these files in the directory specified by the TMP environment variable or the current
directory if none is specified.
7. Bitmap file resource file is not in 2.03 format
A bitmap used a format earlier than version 2.03. The bitmap must be converted or redrawn using the
format for version 3.00 or later.
8. Resource too large
For Windows 3.1 a resource cannot exceed approximately 65000 bytes. If your resource does, then you will
not be able to compile it with Visual C++ or the command-line resource compiler. This limit does not apply
to cursors, icons, bitmaps, or other file-based resources.
9. Resource file is not in 3.00 format
A cursor or icon used a format earlier than version 3.00. The resource must be converted or redrawn using
the format for version 3.00 or later.
10. Unable to open temporary file
The Resource Compiler/Visual C++ was unable to open a temporary file. The probable cause is either that
you do not have write permissions for the directory or that the directory does not exist. The Resource
Compiler/Visual C++ attempts to use these files in the directory specified by the TMP environment variable
or the current directory if none is specified.
Resource Compiler Warning RW4001
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors and warnings generated by the CVTRES build tool.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
CVTRES Fatal Error CVT1100
10/31/2018 • 2 minutes to read • Edit Online
CVTRES did not find a machine specification. It assumed the given machine type. If the default is incorrect, rerun
CVTRES using the /MACHINE option.
Project Build Errors and Warnings (PRJxxxx)
10/31/2018 • 2 minutes to read • Edit Online
This section is a reference to the errors generated by the Project build tools.
The Visual Studio compilers and build tools can report many kinds of errors and warnings. After an error or
warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more
issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not
apply to your project. When you correct issues in your project, always start with the first error or warning that's
reported, and rebuild often. One fix may make many subsequent errors go away.
To get help on a particular diagnostic message in Visual Studio, select it in the Output window and press the F1
key to open the documentation page for that error, if one exists. You can also use the search tool above to find
articles about specific errors or warnings, or browse the list of errors and warnings by tool and type in the
navigation pane.
NOTE
Not every Visual Studio error or warning is documented. In many cases, the diagnostic message provides all of the
information that's available. If you landed on this page when you used F1 and you think the error or warning message needs
additional explanation, let us know. You can use the feedback form on this page, add a comment in the comments section, or
raise an issue on GitHub. You can also send feedback and enter bugs in the IDE. In Visual Studio, go to the menu bar and
choose Help > Send Feedback > Report a Problem, or submit a suggestion by using Help > Send Feedback > Send a
Suggestion.
You may find additional assistance for errors and warnings in Microsoft's public forums. You can search for the
error or warning number on the Developer Community site. You may also search for errors and warnings and ask
questions on Stack Overflow to find solutions.
For links to additional help and community resources, see Visual C++ Help and Community.
Project Build Error PRJ0002
10/31/2018 • 2 minutes to read • Edit Online
A command, command line, which was formed from user input in the Property Pages dialog box, returned an
error code but no information will appear in the Output window.
The resolution to this error depends on which tool generated the error. For MIDL, you will get an idea of what went
wrong if /o (Redirect Output) is defined.
A batch file, such as a custom build step or build event, that is not informative about failure conditions could also
be the reason for this error.
Project Build Error PRJ0003
3/12/2019 • 2 minutes to read • Edit Online
The command line command formed from input in the Property Pages dialog box returned an error code, but no
information appears in the Output window.
Possible reasons for this error include:
Your project depends on ATL Server. Beginning in Visual Studio 2008, ATL Server is no longer included as
part of Visual Studio, but has been released as a shared-source project at CodePlex. To download the ATL
Server source code and tools, go to ATL Server Library and Tools.
Low system resources. Close some applications to resolve this.
Insufficient security privileges. Verify that you have sufficient security privileges.
The executable paths specified in VC++ Directories do not include the path for the tool that you are
attempting to run. For information, see Set compiler and build properties
For makefile projects, you are missing a command to run on either Build Command Line or Rebuild
Command Line.
See Also
Project Build Errors and Warnings (PRJxxxx)
Project Build Error PRJ0004
3/12/2019 • 2 minutes to read • Edit Online
One or more properties were specified in such a way as to make the syntax of the call to tool illegal:
You may have specified badly formed or unknown macros.
Your computer may be low on free disk space.
You may want to review the settings for the tool by looking at the Command Line property page.
Project Build Error PRJ0005
10/31/2018 • 2 minutes to read • Edit Online
Could not open the temporary file 'file'. Make sure the file exists and that the directory is not write-protected.
Visual C++ could not create a temporary file during the build process. Reasons for this include:
No temp directory.
Read-only temp directory.
Out of disk space.
The $(IntDir) folder is either read-only or contains temporary files that are read-only.
This error will also occur following error PRJ0007: Could not create output directory 'directory'. Error PRJ0007
means that the $(IntDir) directory could not be created, implying the creation of temporarily files will also fail.
Temp files are created whenever you specify:
A response file.
A custom build step.
A build event.
Project Build Error PRJ0007
10/31/2018 • 2 minutes to read • Edit Online
System resource could be critically low. Unable to create a pipe required to launch a build.
This error indicates that system resources are low. To resolve this error, decrease system resource usage by other
processes/applications.
This error can also occur if your security level is insufficient to create pipes (see CreatePipe).
Project Build Error PRJ0014
10/31/2018 • 2 minutes to read • Edit Online
The job object used to control the spawned processes has failed. The build cannot continue.
An error occurred in the development environment.
To resolve this error, close and reload the project. If necessary, exit and restart Visual Studio.
Project Build Error PRJ0015
10/31/2018 • 2 minutes to read • Edit Online
The NULL device is missing from your system. We are unable to launch a build.
This error can be caused by low system resources. Close some applications or reboot.
It can also be caused if you do not have sufficient privileges to the NULL device on the computer.
Project Build Error PRJ0016
10/31/2018 • 2 minutes to read • Edit Online
The user's security settings prevent the process from being created. These settings are required for building.
You are logged in as a user who does not have permissions to create processes using a process. You must change
the permission levels for this user account, or contact your account administrator.
This error can also occur if the following registry key is set:
\\HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\RestrictRun
To resolve this error, delete the RestrictRun key. If this registry key is needed, append vcspawn.exe to the list of
entries in the key.
Another cause for this error is that your Policy Setting does not include VCSpawn.exe under the registry key
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\RestrictRun as an allowed
Window program for this user account.
For additional information, see Adhering to System Policy Settings, in the section on "Run only allowed Windows
applications".
Project Build Error PRJ0017
10/31/2018 • 2 minutes to read • Edit Online
The file name file, specified in the property property for the tool tool, was invalid.
You may have used an unknown or invalid macro.
See Setting Visual C++ Project Properties for information on how to access your project's properties.
Project Build Error PRJ0021
3/12/2019 • 2 minutes to read • Edit Online
The file name specified in the property property for the tool tool was invalid.
You may have used an unknown or invalid macro.
See Setting Visual C++ Project Properties for information on how to access your project's properties.
Project Build Error PRJ0022
3/12/2019 • 2 minutes to read • Edit Online
The file name file specified in the property property was invalid.
You may have used an unknown or invalid macro.
See Setting Visual C++ Project Properties for information on how to access your project's properties.
Project Build Error PRJ0023
3/12/2019 • 2 minutes to read • Edit Online
The file name file specified for the tool tool was invalid.
You may have used an unknown or invalid macro.
See Setting Visual C++ Project Properties for information on how to access your project's properties.
Project Build Error PRJ0024
10/31/2018 • 2 minutes to read • Edit Online
Unicode path 'path' could not be translated to user's ANSI code page.
path is the original Unicode version of the path string. This error can occur in cases where there is a Unicode path
that cannot be directly translated to ANSI for the current system code page.
This error may occur if you are working with a project that was developed on a system using a code page that is
not on your computer.
The resolution for this error is to update the path to use ANSI text or to install the code page on your computer
and set it as the system default.
Project Build Error PRJ0025
3/12/2019 • 2 minutes to read • Edit Online
Batch file 'file' contains Unicode contents that could not be translated to user's ANSI code page.
UNICODE contents of file
The project system found Unicode contents in a custom build rule or build event that cannot be translated properly
to the user's current ANSI code page.
The resolution for this error is to update the contents of the build rule or build event to use ANSI or to install the
code page on your computer and set it as the system default.
For more information on custom build steps and build events, see Understanding Custom Build Steps and Build
Events.
Project Build Error PRJ0026
10/31/2018 • 2 minutes to read • Edit Online
Response file 'file' contains Unicode contents that could not be translated to user's ANSI code page.
UNICODE contents of file
The project system found Unicode contents in a response file that cannot be translated properly to the user's
current ANSI code page.
The resolution for this error is to update the contents of the response file to use ANSI or to install the code page on
your computer and set it as the system default.
Project Build Error PRJ0027
10/31/2018 • 2 minutes to read • Edit Online
Unicode log message 'contents' contains content that could not be translated to the user's ANSI code page.
You will typically only see this warning in conjunction with errors in creating batch and/or response files.
The resolution for this error is to update the contents of the build log to use ANSI or to install the code page on
your computer and set it as the system default.
Project Build Error PRJ0028
10/31/2018 • 2 minutes to read • Edit Online
Temporary file 'file' contains Unicode contents that could not be translated to user's ANSI code page.
A value was specified with the /MIDL (Specify MIDL Command Line Options) linker option that could not be
resolved by the system code page.
The code page used when you specify the MIDL command (the input code page) must be the same as the system
code page.
Project Build Warning PRJ0029
10/31/2018 • 2 minutes to read • Edit Online
The 'Outputs' property for the project-level custom build step is not set. The custom build step will be skipped.
A custom build step was not executed because no output was specified.
To resolve this error, do one the following:
Exclude the custom build step from the build.
Add an output.
Delete the contents of the custom build step's command.
Project Build Error PRJ0030
3/12/2019 • 2 minutes to read • Edit Online
The 'Outputs' property for the custom build step for file 'file' contained 'macro' which evaluates out to
'macro_expansion'.
A custom build step on a file had bad output probably due to a macro evaluation problem. This error could also
mean that the path is badly formed, containing characters or combinations of characters that are illegal in a file
path.
To resolve this error, fix the macro or fix the path specification. The evaluated path is an absolute path from the
project directory.
Project Build Error PRJ0032
10/31/2018 • 2 minutes to read • Edit Online
The 'Outputs' property for the project-level custom build step contained 'macro' which evaluates out to
'macro_expansion'.
A custom build step on a project had bad output probably due to a macro evaluation problem. This error could also
mean that the path is badly formed, containing characters or combinations of characters that are illegal in a file
path.
To resolve this error, fix the macro or fix the path specification. The evaluated path is an absolute path from the
project directory.
Project Build Error PRJ0033
10/31/2018 • 2 minutes to read • Edit Online
The 'Additional Dependencies' property for the custom build step for file 'file' contained 'macro' which evaluates
out to 'macro_expansion'.
A custom build step on a file contained an error in its additional dependency probably due to a macro evaluation
problem. This error could also mean that the path is badly formed, containing characters or combinations of
characters that are illegal in a file path.
To resolve this error, fix the macro or fix the path specification. The evaluated path is an absolute path from the
project directory.
Project Build Error PRJ0034
10/31/2018 • 2 minutes to read • Edit Online
The 'Additional Dependencies' property for the project-level custom build step contained 'macro' which evaluates
out to 'macro_expansion'.
A custom build step on a project contained an error in its additional dependency probably due to a macro
evaluation problem. This error could also mean that the path is badly formed, containing characters or
combinations of characters that are illegal in a file path.
To resolve this error, fix the macro or fix the path specification. The evaluated path is an absolute path from the
project directory.
Project Build Error PRJ0035
10/31/2018 • 2 minutes to read • Edit Online
XML file 'file' contains Unicode contents that could not be translated to user's ANSI code page.
UNICODE contents of file
file is the XML file created as the command line to the Web Deployment tool.
The project system found Unicode characters in some property on the Web Deployment property page that can't
properly be translated to ANSI.
The resolution for this error is to update the contents of the property to use ANSI or to install the code page on
your computer and set it as the system default.
Project Build Error PRJ0036
10/31/2018 • 2 minutes to read • Edit Online
The 'Additional Files' property for the Web Deployment Tool contained an invalid entry.
The Additional Files property on the Web Deployment property page contained an error, possibly due to a macro
evaluation problem. This error could also mean that the path is badly formed, containing characters or
combinations of characters that are illegal in a file path.
To resolve this error, fix the macro or fix the path specification. The evaluated path is an absolute path from the
project directory.
This error could also mean that one of the files referenced doesn't exist.
Project Build Error PRJ0040
10/31/2018 • 2 minutes to read • Edit Online
Internal error on build. Cannot continue. Please reload project and try again.
The project system was unable to process your project.
Try reloading the project.
Project Build Warning PRJ0041
10/31/2018 • 2 minutes to read • Edit Online
Cannot find missing dependency 'dependency' for file 'file'. Your project may still build, but may continue to appear
out of date until this file is found.
A file (resource file or .idl/.odl file, for example, contained an include statement that the project system could not
resolve.
Because the project system does not process preprocessor statements (#if, for example), the offending statement
may not actually be part of the build.
To resolve this warning, delete all unnecessary code in .rc files or add placeholder files of the appropriate name.
Project Build Warning PRJ0042
10/31/2018 • 2 minutes to read • Edit Online
The 'Outputs' property for the custom build step for file 'file' is not set. The custom build step will be skipped.
A custom build step was not executed because no output was specified.
To resolve this error, do one the following:
Exclude the custom build step from the build.
Add an output.
Delete the contents of the custom build step's command.
Project Build Error PRJ0044
3/12/2019 • 2 minutes to read • Edit Online
The 'Additional Dependencies' property for custom build rule 'rule' assigned to file 'file' is invalid. The property
contained 'string' which evaluates to 'value'.
The Additional Dependencies property evaluated to an empty string, or to a string that contained invalid
characters (any character that could not be in a file or directory name). Custom build rules need the output of the
build action.
For more information, see Specifying Custom Build Tools.
See Also
Project Build Errors and Warnings (PRJxxxx)
Project Build Error PRJ0046
10/31/2018 • 2 minutes to read • Edit Online
Could not spawn command line because the one specified was empty.
An empty command line was specified for a makefile configuration; the command line is required.
Project Build Error PRJ0047
10/31/2018 • 2 minutes to read • Edit Online
Could not resume the suspended process. The build has failed.
An error occurred in the development environment.
To resolve this error, close and reload the project. If necessary, exit and restart Visual Studio.
Project Build Warning PRJ0049
3/12/2019 • 2 minutes to read • Edit Online
Referenced target '<Reference>' requires .NET Framework <MinFrameworkVersion> and will fail to run on this
project's target framework
Applications created by using Visual Studio 2008 can specify which version of the .NET Framework they should
target. If you add a reference to an assembly or project that depends on a version of the .NET Framework that is
later than the targeted version, you will get this warning at compile time.
To correct this warning
1. Choose one of the following:
Change the targeted framework in the project's Property Pages dialog box so that it is later than or
equal to the minimal framework version of all referenced assemblies and projects. For more
information, see Adding references.
Remove the reference to the assembly or project that has a minimal framework version that is later
than the targeted framework. These items will be marked with a warning icon in the project's
Property Pages.
See Also
Project Build Errors and Warnings (PRJxxxx)
Project Build Error PRJ0050
10/31/2018 • 2 minutes to read • Edit Online
Failed to register output. Please ensure you have the appropriate permissions to modify the registry.
The Visual C++ build system was not able to register the output of the build (dll or .exe). You need to be logged on
as an administrator to modify the registry.
If you are building a .dll, you can try to register the .dll manually using regsvr32.exe, this should display
information about why the build failed.
If you are not building a .dll, look at the build log for the command that causes an error.
XML Documentation (Visual C++)
3/12/2019 • 2 minutes to read • Edit Online
In Visual C++, you can add comments to your source code that will be processed to an .xml file. This file can
then be the input to a process that creates documentation for the classes in your code.
In a Visual C++ code file, XML documentation comments must be located directly prior to a method or type
definition. The comments can be used to populate the IntelliSense QuickInfo data tip in the following scenarios:
1. when the code is compiled as a Windows Runtime component with an accompanying .winmd file
2. when the source code is included in the current project
3. in a library whose type declarations and implementations are located in the same header file
NOTE
In the current release, code comments are not processed on templates or anything containing a template type (for
example, a function taking a parameter as a template). Adding such comments will result in undefined behavior.
For details on creating an .xml file with documentation comments, see the following topics.
Tags you can use to provide commonly used functionality in Recommended Tags for Documentation Comments
documentation
The ID strings that the compiler produces to identify the Processing the .xml File
constructs in your code
How to delimit documentation tags Delimiters for Visual C++ Documentation Tags
Generating an .xml file from one or more .xdc files. XDCMake Reference
Links to information about XML as it relates to Visual Studio XML in Visual Studio
feature areas
If you need to put XML special characters in the text of a documentation comment, you must use XML entities
or a CDATA section.
See also
Component Extensions for Runtime Platforms
Recommended Tags for Documentation Comments
3/12/2019 • 2 minutes to read • Edit Online
The MSVC compiler will process documentation comments in your code and creates an .xdc file for each
compiland, and xdcmake.exe will process the .xdc files to an .xml file. Processing the .xml file to create
documentation is a detail that needs to be implemented at your site.
Tags are processed on constructs such as types and type members.
Tags must immediately precede types or members.
NOTE
Documentation comments cannot be applied to a namespace or on out of line definition for properties and events;
documentation comments must on the in-class declarations.
The compiler will process any tag that is valid XML. The following tags provide commonly used functionality in
user documentation:
<value>
See Also
XML Documentation
<c>
3/12/2019 • 2 minutes to read • Edit Online
The <c> tag indicates that text within a description should be marked as code. Use <code> to indicate multiple
lines as code.
Syntax
<c>text</c>
Parameters
text
The text you want to indicate as code.
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_c_tag.cpp
// compile with: /doc /LD
// post-build command: xdcmake xml_c_tag.xdc
See also
XML Documentation
<code>
3/12/2019 • 2 minutes to read • Edit Online
The <code> tag gives you a way to indicate one or more lines as code.
Syntax
<code>content</code>
Parameters
content
The text you want marked as code.
Remarks
Use <c> to indicate a portion of text should be marked as code.
Compile with /doc to process documentation comments to a file.
Example
See the <example> topic for an example of how to use the <code> tag.
See Also
XML Documentation
<example>
3/12/2019 • 2 minutes to read • Edit Online
The <example> tag lets you specify an example of how to use a method or other library member. Commonly, this
would also involve use of the <code> tag.
Syntax
<example>description</example>
Parameters
description
A description of the code sample.
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_example_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_example_tag.dll
See also
XML Documentation
<exception>
3/12/2019 • 2 minutes to read • Edit Online
The <exception> tag lets you specify which exceptions can be thrown. This tag is applied to a method definition.
Syntax
<exception cref="member">description</exception>
Parameters
member
A reference to an exception that is available from the current compilation environment. Using name lookup rules,
the compiler checks that the given exception exists, and translates member to the canonical element name in the
output XML. The compiler issues a warning if it does not find member .
Enclose the name in single or double quotation marks.
For information on how to create a cref reference to a generic type, see <see>.
description
A description.
Remarks
Compile with /doc to process documentation comments to a file.
The MSVC compiler will attempt to resolve cref references in one pass through the documentation comments.
Therefore, if using the C++ lookup rules, a symbol is not found by the compiler the reference will be marked as
unresolved. See <seealso> for more information.
Example
// xml_exception_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_exception_tag.dll
using namespace System;
The <include> tag lets you refer to comments in another file that describe the types and members in your source
code. This is an alternative to placing documentation comments directly in your source code file. For example, you
can use <include> to insert standard "boilerplate" comments that are used throughout your team or company.
Syntax
<include file='filename' path='tagpath' />
Parameters
filename
The name of the file containing the documentation. The file name can be qualified with a path. Enclose the name in
single or double quotation marks. The compiler issues a warning if it does not find filename .
tagpath
A valid XPath expression that selects the desired node-set contained in the file.
name
The name specifier in the tag that precedes the comments; name will have an id .
id
The ID for the tag that precedes the comments. Enclose the name in single or double quotation marks.
Remarks
The <include> tag uses the XML XPath syntax. Refer to XPath documentation for ways to customize using
<include>.
Compile with /doc to process documentation comments to a file.
Example
This is a multifile example. The first file, which uses <include>, contains the following documentation comments:
// xml_include_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_include_tag.dll
<MyMembers name="test">
<summary>
The summary for this type.
</summary>
</MyMembers>
<MyMembers name="test2">
<summary>
The summary for this other type.
</summary>
</MyMembers>
</MyDocs>
Program Output
<?xml version="1.0"?>
<doc>
<assembly>
<name>t2</name>
</assembly>
<members>
<member name="T:Test">
<summary>
The summary for this type.
</summary>
</member>
<member name="T:Test2">
<summary>
The summary for this other type.
</summary>
</member>
</members>
</doc>
See also
XML Documentation
<list>
3/12/2019 • 2 minutes to read • Edit Online
The <listheader> block is used to define the heading row of either a table or definition list. When defining a table,
you only need to supply an entry for term in the heading.
Syntax
<list type="bullet" | "number" | "table">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>term</term>
<description>description</description>
</item>
</list>
Parameters
term
A term to define, which will be defined in description .
description
Either an item in a bullet or numbered list or the definition of a term .
Remarks
Each item in the list is specified with an <item> block. When creating a definition list, you will need to specify both
term and description . However, for a table, bulleted list, or numbered list, you only need to supply an entry for
description .
Example
// xml_list_tag.cpp
// compile with: /doc /LD
// post-build command: xdcmake xml_list_tag.dll
/// <remarks>Here is an example of a bulleted list:
/// <list type="bullet">
/// <item>
/// <description>Item 1.</description>
/// </item>
/// <item>
/// <description>Item 2.</description>
/// </item>
/// </list>
/// </remarks>
class MyClass {};
See also
XML Documentation
<para>
3/12/2019 • 2 minutes to read • Edit Online
The <para> tag is for use inside a tag, such as <summary>, <remarks>, or <returns>, and lets you add structure
to the text.
Syntax
<para>content</para>
Parameters
content
The text of the paragraph.
Remarks
Compile with /doc to process documentation comments to a file.
Example
See <summary> for an example of using <para>.
See Also
XML Documentation
<param>
3/12/2019 • 2 minutes to read • Edit Online
The <param> tag should be used in the comment for a method declaration to describe one of the parameters for
the method.
Syntax
<param name='name'>description</param>
Parameters
name
The name of a method parameter. Enclose the name in single or double quotation marks. The compiler issues a
warning if it does not find name .
description
A description for the parameter.
Remarks
The text for the <param> tag will be displayed in IntelliSense, the Object Browser, and in the Code Comment Web
Report.
Compile with /doc to process documentation comments to a file.
Example
// xml_param_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_param_tag.dll
/// Text for class MyClass.
public ref class MyClass {
/// <param name="Int1">Used to indicate status.</param>
void MyMethod(int Int1) {
}
};
See also
XML Documentation
<paramref>
3/12/2019 • 2 minutes to read • Edit Online
The <paramref> tag gives you a way to indicate that a word is a parameter. The .xml file can be processed to
format this parameter in some distinct way.
Syntax
<paramref name="name"/>
Parameters
name
The name of the parameter to refer to. Enclose the name in single or double quotation marks. The compiler issues
a warning if it does not find name .
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_paramref_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_paramref_tag.dll
/// Text for class MyClass.
public ref class MyClass {
/// <summary>MyMethod is a method in the MyClass class.
/// The <paramref name="Int1"/> parameter takes a number.
/// </summary>
void MyMethod(int Int1) {}
};
See also
XML Documentation
<permission>
3/12/2019 • 2 minutes to read • Edit Online
The <permission> tag lets you document the access of a member. PermissionSet lets you specify access to a
member.
Syntax
<permission cref="member">description</permission>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. The
compiler checks that the given code element exists and translates member to the canonical element name in the
output XML. Enclose the name in single or double quotation marks.
The compiler issues a warning if it does not find member .
For information on how to create a cref reference to a generic type, see <see>.
description
A description of the access to the member.
Remarks
Compile with /doc to process documentation comments to a file.
The MSVC compiler will attempt to resolve cref references in one pass through the documentation comments.
Therefore, if using the C++ lookup rules, a symbol is not found by the compiler the reference will be marked as
unresolved. See <seealso> for more information.
Example
// xml_permission_tag.cpp
// compile with: /clr /doc /LD
// post-build command: xdcmake xml_permission_tag.dll
using namespace System;
/// Text for class TestClass.
public ref class TestClass {
/// <permission cref="System::Security::PermissionSet">Everyone can access this method.</permission>
void Test() {}
};
See also
XML Documentation
<remarks>
3/12/2019 • 2 minutes to read • Edit Online
The <remarks> tag is used to add information about a type, supplementing the information specified with
<summary>. This information is displayed in the Object Browser and in the Code Comment Web Report.
Syntax
<remarks>description</remarks>
Parameters
description
A description of the member.
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_remarks_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_remarks_tag.dll
/// <summary>
/// You may have some primary information about this class.
/// </summary>
/// <remarks>
/// You may have some additional information about this class.
/// </remarks>
public ref class MyClass {};
See also
XML Documentation
<returns>
3/12/2019 • 2 minutes to read • Edit Online
The <returns> tag should be used in the comment for a method declaration to describe the return value.
Syntax
<returns>description</returns>
Parameters
description
A description of the return value.
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_returns_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_returns_tag.dll
See also
XML Documentation
<see>
3/12/2019 • 2 minutes to read • Edit Online
The <see> tag lets you specify a link from within text. Use <seealso> to indicate text that you might want to
appear in a See Also section.
Syntax
<see cref="member"/>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. Enclose
the name in single or double quotation marks.
The compiler checks that the given code element exists and resolves member to the element name in the output
XML. The compiler issues a warning if it does not find member .
Remarks
Compile with /doc to process documentation comments to a file.
See <summary> for an example of using <see>.
The MSVC compiler will attempt to resolve cref references in one pass through the documentation comments.
Therefore, if using the C++ lookup rules, a symbol is not found by the compiler the reference will be marked as
unresolved. See <seealso> for more information.
Example
The following sample shows how you can make cref reference to a generic type, such that, the compiler will
resolve the reference.
// xml_see_cref_example.cpp
// compile with: /LD /clr /doc
// the following cref shows how to specify the reference, such that,
// the compiler will resolve the reference
/// <see cref="C{T}">
/// </see>
ref class A {};
See also
XML Documentation
<seealso>
3/12/2019 • 2 minutes to read • Edit Online
The <seealso> tag lets you specify the text that you might want to appear in a See Also section. Use <see> to
specify a link from within text.
Syntax
<seealso cref="member"/>
Parameters
member
A reference to a member or field that is available to be called from the current compilation environment. Enclose
the name in single or double quotation marks.
The compiler checks that the given code element exists and resolves member to the element name in the output
XML. The compiler issues a warning if it does not find member .
For information on how to create a cref reference to a generic type, see <see>.
Remarks
Compile with /doc to process documentation comments to a file.
See <summary> for an example of using <seealso>.
The MSVC compiler will attempt to resolve cref references in one pass through the documentation comments.
Therefore, if using the C++ lookup rules, a symbol is not found by the compiler the reference will be marked as
unresolved.
Example
In the following sample, an unresolved symbol is referenced in a cref. The XML comment for the cref to B::Test will
be <seealso cref="!:B::Test" /> , whereas the reference to A::Test is well-formed <seealso cref="M:A.Test" /> .
// xml_seealso_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_seealso_tag.dll
/// text
void Test() {}
};
See also
XML Documentation
<summary>
3/12/2019 • 2 minutes to read • Edit Online
The <summary> tag should be used to describe a type or a type member. Use <remarks> to add supplemental
information to a type description.
Syntax
<summary>description</summary>
Parameters
description
A summary of the object.
Remarks
The text for the <summary> tag is the only source of information about the type in IntelliSense, and is also
displayed in the Object Browser and in the Code Comment Web Report.
Compile with /doc to process documentation comments to a file.
Example
// xml_summary_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_summary_tag.dll
/// text
void MyMethod2() {}
};
See also
XML Documentation
<value>
3/12/2019 • 2 minutes to read • Edit Online
The <value> tag lets you describe a property and property accessor methods. Note that when you add a property
with a code wizard in the Visual Studio integrated development environment, it will add a <summary> tag for the
new property. You should then manually add a <value> tag to describe the value that the property represents.
Syntax
<value>property-description</value>
Parameters
property-description
A description for the property.
Remarks
Compile with /doc to process documentation comments to a file.
Example
// xml_value_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_value_tag.dll
using namespace System;
/// Text for class Employee.
public ref class Employee {
private:
String ^ name;
/// <value>Name accesses the value of the name data member</value>
public:
property String ^ Name {
String ^ get() {
return name;
}
void set(String ^ i) {
name = i;
}
}
};
See also
XML Documentation
.Xml File Processing
3/12/2019 • 4 minutes to read • Edit Online
The compiler generates an ID string for each construct in your code that is tagged to generate documentation. For
more information, see Recommended Tags Documentation Comments. The ID string uniquely identifies the
construct. Programs that process the .xml file can use the ID string to identify the corresponding .NET Framework
metadata or reflection item to which the documentation applies.
The .xml file is not a hierarchical representation of your code, it is a flat list with a generated ID for each element.
The compiler observes the following rules when it generates the ID strings:
No white space is placed in the string.
The first part of the ID string identifies the kind of member being identified, with a single character followed
by a colon. The following member types are used:
CHARACTER DESCRIPTION
N namespace
D typedef
F field
E event
! error string
The second part of the string is the fully qualified name of the item, starting at the root of the namespace.
The name of the item, its enclosing type or types, and namespace are separated by periods. If the name of
the item itself has periods, they are replaced by the hash-sign ('#'). It is assumed that no item has an hash-
sign directly in its name. For example, the fully qualified name of the String constructor would be
"System.String.#ctor".
For properties and methods, if there are arguments to the method, the argument list enclosed in
parentheses follows. If there are no arguments, no parentheses are present. The arguments are separated by
commas. The encoding of each argument follows directly how it is encoded in a .NET Framework signature:
Base types. Regular types (ELEMENT_TYPE_CLASS or ELEMENT_TYPE_VALUETYPE ) are
represented as the fully qualified name of the type.
Intrinsic types (for example, ELEMENT_TYPE_I4, ELEMENT_TYPE_OBJECT,
ELEMENT_TYPE_STRING, ELEMENT_TYPE_TYPEDBYREF. and ELEMENT_TYPE_VOID ) are
represented as the fully qualified name of the corresponding full type, for example, System.Int32 or
System.TypedReference.
ELEMENT_TYPE_PTR is represented as a '*' following the modified type.
ELEMENT_TYPE_BYREF is represented as a '@' following the modified type.
ELEMENT_TYPE_PINNED is represented as a '^' following the modified type. The MSVC compiler
never generates this.
ELEMENT_TYPE_CMOD_REQ is represented as a '|' and the fully qualified name of the modifier
class, following the modified type. The MSVC compiler never generates this.
ELEMENT_TYPE_CMOD_OPT is represented as a '!' and the fully qualified name of the modifier
class, following the modified type.
ELEMENT_TYPE_SZARRAY is represented as "[]" following the element type of the array.
ELEMENT_TYPE_GENERICARRAY is represented as "[?]" following the element type of the array.
The MSVC compiler never generates this.
ELEMENT_TYPE_ARRAY is represented as [lowerbound: size ,lowerbound: size ] where the number
of commas is the rank - 1, and the lower bounds and size of each dimension, if known, are
represented in decimal. If a lower bound or size is not specified, it is simply omitted. If the lower
bound and size for a particular dimension are omitted, the ':' is omitted as well. For example, a 2-
dimensional array with 1 as the lower bounds and unspecified sizes is [1:,1:].
ELEMENT_TYPE_FNPTR is represented as "=FUNC: type (signature)", where type is the return
type, and signature is the arguments of the method. If there are no arguments, the parentheses are
omitted. The MSVC compiler never generates this.
The following signature components are not represented because they are never used for differentiating
overloaded methods:
calling convention
return type
ELEMENT_TYPE_SENTINEL
For conversion operators only, the return value of the method is encoded as a '~' followed by the return
type, as previously encoded.
For generic types, the name of the type will be followed by a back tick and then a number that indicates the
number of generic type parameters. For example,
<member name="T:MyClass`2">
// xml_id_strings.cpp
// compile with: /clr /doc /LD
///
namespace N {
// "N:N"
protected:
///
!X(){}
// "M:N.X.Finalize", destructor's representation in metadata
public:
///
X() {}
// "M:N.X.#ctor"
///
static X() {}
// "M:N.X.#cctor"
///
X(int i) {}
// "M:N.X.#ctor(System.Int32)"
///
~X() {}
// "M:N.X.Dispose", Dispose function representation in metadata
///
System::String^ q;
// "F:N.X.q"
///
double PI;
// "F:N.X.PI"
///
int f() { return 1; }
// "M:N.X.f"
///
int bb(System::String ^ s, int % y, void * z) { return 1; }
// "M:N.X.bb(System.String,System.Int32@,System.Void*)"
///
int gg(array<short> ^ array1, array< int, 2 >^ IntArray) { return 0; }
// "M:N.X.gg(System.Int16[], System.Int32[0:,0:])"
///
static X^ operator+(X^ x, X^ xx) { return x; }
// "M:N.X.op_Addition(N.X,N.X)"
///
property int prop;
// "M:N.X.prop"
///
property int prop2 {
// "P:N.X.prop2"
// "P:N.X.prop2"
///
int get() { return 0; }
// M:N.X.get_prop2
///
void set(int i) {}
// M:N.X.set_prop2(System.Int32)
}
///
delegate void D(int i);
// "T:N.X.D"
///
event D ^ d;
// "E:N.X.d"
///
ref class Nested {};
// "T:N.X.Nested"
///
static explicit operator System::Int32 (X x) { return 1; }
// "M:N.X.op_Explicit(N.X!System.Runtime.CompilerServices.IsByValue)~System.Int32"
};
}
See also
XML Documentation
Delimiters for Visual C++ Documentation Tags
3/12/2019 • 2 minutes to read • Edit Online
The use of documentation tags requires delimiters, which indicate to the compiler where a documentation
comment begins and ends.
You can use the following kinds of delimiters with the XML documentation tags:
There are some formatting rules when using the /** */ delimiters:
For the line that contains the /** delimiter, if the remainder of the line is white space, the line is not
processed for comments. If the first character is white space, that white space character is ignored and the
rest of the line is processed. Otherwise, the entire text of the line after the /** delimiter is processed as part
of the comment.
For the line that contains the */ delimiter, if there is only white space up to the */ delimiter, that line is
ignored. Otherwise, the text on the line up to the */ delimiter is processed as part of the comment, subject
to the pattern-matching rules described in the following bullet.
For the lines after the one that begins with the /** delimiter, the compiler looks for a common pattern at
the beginning of each line that consists of optional white space and an asterisk ( * ), followed by more
optional white space. If the compiler finds a common set of characters at the beginning of each line, it will
ignore that pattern for all lines after the /** delimiter, up to and possibly including the line that contains
the */ delimiter.
Some examples:
The only part of the following comment that will be processed is the line that begins with <summary> . The
following two tag formats will produce the same comments:
/**
<summary>text</summary>
*/
/** <summary>text</summary> */
The compiler applies a pattern of " * " to ignore at the beginning of the second and third lines.
/**
* <summary>
* text </summary>*/
The compiler finds no pattern in this comment because there is no asterisk on the second line. Therefore, all
text on the second and third lines, up till the */ , will be processed as part of the comment.
/**
* <summary>
text </summary>*/
The compiler finds no pattern in this comment for two reasons. First, there is no line that begins with a
consistent number of spaces before the asterisk. Second, the fifth line begins with a tab, which does not
match spaces. Therefore, all text from the second line until the */ will be processed as part of the
comment.
/**
* <summary>
* text
* text2
* </summary>
*/
See also
XML Documentation