You are on page 1of 3640

Contents

C/C++ Building Reference


MSBuild reference for C++ projects
MSBuild internals for C++ projects
Common macros for build commands and properties
File types used in C++ projects
Project and solution files
C++ project templates
C++ new item templates
Resource files
Files Created for CLR Projects
ATL Program or Control Source and Header Files
MFC Program or Control Source and Header Files
HTML Help Files
Winhelp Help Files
Hint Files for Intellisense
Property Page XML Files
.vcxproj and .props file structure
Example project file
C++ project properties reference
General Property Page
General Property Page
VC++ Directories Property Page
Command Line Property Pages
NMake Property Page
Linker Property Pages
Manifest Tool Property Pages
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
Resources Property Pages
Managed Resources Property Page
MIDL Property Pages
MIDL Property Pages: General
MIDL Property Pages: Output
MIDL Property Pages: Advanced
Web References Property Page
XML Data Generator Tool Property Page
XML Document Generator Tool Property Pages
Custom Build Step Property Page: General
HLSL Property Pages
HLSL Property Pages: General
HLSL Property Pages: Advanced
HLSL Property Pages: Output Files
MSVC Compiler Reference
MSVC Compiler Command-Line Syntax
CL Filename Syntax
Order of CL Options
Return Value of cl.exe
CL Environment Variables
CL Command Files
CL Invokes the Linker
MSVC Compiler Options
Compiler Options Listed by Category
Compiler Options Listed Alphabetically
@ (Specify a Compiler Response File)
/AI (Specify Metadata Directories)
/analyze (Code Analysis)
/arch (Minimum CPU Architecture)
/arch (x86)
/arch (x64)
/arch (ARM)
/await (Enable coroutine support)
/bigobj (Increase Number of Sections in .Obj file)
/C (Preserve Comments During Preprocessing)
/c (Compile Without Linking)
/cgthreads (Code Generation Threads)
/clr (Common Language Runtime Compilation)
/clr Restrictions
/constexpr (Control constexpr evaluation)
/D (Preprocessor Definitions)
/diagnostics (Compiler diagnostics options)
/doc (Process Documentation Comments) (C/C++)
/E (Preprocess to stdout)
/EH (Exception Handling Model)
/EP (Preprocess to stdout Without #line Directives)
/errorReport (Report Internal Compiler Errors)
/execution/charset (Set Execution Character Set)
/F (Set Stack Size)
Output-File (/F) Options
/FA, /Fa (Listing File)
Specifying the Pathname
/FD (IDE Minimal Rebuild)
/Fd (Program Database File Name)
/Fe (Name EXE File)
/Fi (Preprocess Output File Name)
/FI (Name Forced Include File)
/Fm (Name Mapfile)
/Fo (Object File Name)
/Fp (Name .Pch File)
/FR, /Fr (Create .Sbr File)
/FU (Name Forced #using File)
/Fx (Merge Injected Code)
/favor (Optimize for Architecture Specifics)
/FC (Full Path of Source Code File in Diagnostics)
/fp (Specify Floating-Point Behavior)
MSVC floating point optimization
/FS (Force Synchronous PDB Writes)
/GA (Optimize for Windows Application)
/Gd, /Gr, /Gv, /Gz (Calling Convention)
/Ge (Enable Stack Probes)
/GF (Eliminate Duplicate Strings)
/GH (Enable _pexit Hook Function)
/Gh (Enable _penter Hook Function)
/GL (Whole Program Optimization)
/Gm (Enable Minimal Rebuild)
/GR (Enable Run-Time Type Information)
/GS (Buffer Security Check)
/Gs (Control Stack Checking Calls)
/guard (Enable Control Flow Guard)
/GT (Support Fiber-Safe Thread-Local Storage)
/Gw (Optimize Global Data)
/GX (Enable Exception Handling)
/Gy (Enable Function-Level Linking)
/GZ (Enable Stack Frame Run-Time Error Checking)
/H (Restrict Length of External Names)
/HELP (Compiler Command-Line Help)
/homeparams (Copy Register Parameters to Stack)
/hotpatch (Create Hotpatchable Image)
/I (Additional Include Directories)
/J (Default char Type Is unsigned)
/JMC (Just My Code debugging)
/kernel (Create Kernel Mode Binary)
/link (Pass Options to Linker)
/LN (Create MSIL Module)
/MD, /MT, /LD (Use Run-Time Library)
/MP (Build with Multiple Processes)
/nologo (Suppress Startup Banner) (C/C++)
/O Options (Optimize Code)
/O1, /O2 (Minimize Size, Maximize Speed)
/Ob (Inline Function Expansion)
/Od (Disable (Debug))
/Og (Global Optimizations)
/Oi (Generate Intrinsic Functions)
/Os, /Ot (Favor Small Code, Favor Fast Code)
/Ox (Enable Most Speed Optimizations)
/Oy (Frame/Pointer Omission)
/openmp (Enable OpenMP 2.0 Support)
/P (Preprocess to a File)
/permissive- (Standards conformance)
/Q Options (Low-Level Operations)
/Qfast_transcendentals (Force Fast Transcendentals)
/QIfist (Suppress _ftol)
/Qimprecise_fwaits (Remove fwaits Inside Try Blocks)
/Qpar (Auto-Parallelizer)
/Qpar-report (Auto-Parallelizer Reporting Level)
/Qsafe_fp_loads
/Qspectre
/Qvec-report (Auto-Vectorizer Reporting Level)
/RTC (Run-Time Error Checks)
/sdl (Enable Additional Security Checks)
/showIncludes (List Include Files)
/source-charset (Set Source Character Set)
/std (Specify Language Standard Version)
/Tc, /Tp, /TC, /TP (Specify Source File Type)
/U, /u (Undefine Symbols)
/utf-8 (Set Source and Executable character sets to UTF-8)
/V (Version Number)
/validate-charset (Validate for compatible characters)
/vd (Disable Construction Displacements)
/vmb, /vmg (Representation Method)
/vmm, /vms, /vmv (General Purpose Representation)
/volatile (volatile Keyword Interpretation)
/w, /W0, /W1, /W2, /W3, /W4, /w1, /w2, /w3, /w4, /Wall, /wd, /we, /wo, /Wv,
/WX (Warning Level)
/WL (Enable One-Line Diagnostics)
/Wp64 (Detect 64-Bit Portability Issues)
/X (Ignore Standard Include Paths)
/Y (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)
/Z7, /Zi, /ZI (Debug Information Format)
/Za, /Ze (Disable Language Extensions)
Microsoft Extensions to C and C++
/Zc (Conformance)
/Zc:alignedNew (C++17 over-aligned allocation)
/Zc:auto (Deduce Variable Type)
/Zc:__cplusplus (Enable updated __cplusplus macro)
/Zc:externConstexpr (Enable extern constexpr variables)
/Zc:forScope (Force Conformance in for Loop Scope)
/Zc:implicitNoexcept (Implicit Exception Specifiers)
/Zc:inline (Remove unreferenced COMDAT)
/Zc:noexceptTypes (C++17 noexcept rules)
/Zc:referenceBinding (Enforce reference binding rules)
/Zc:rvalueCast (Enforce type conversion rules)
/Zc:sizedDealloc (Enable Global Sized Deallocation Functions)
/Zc:strictStrings (Disable string literal type conversion)
/Zc:ternary (Enforce conditional operator rules)
/Zc:threadSafeInit (Thread-safe Local Static Initialization)
/Zc:throwingNew (Assume operator new throws)
/Zc:trigraphs (Trigraphs Substitution)
/Zc:twoPhase- (disable two-phase name lookup)
/Zc:wchar_t (wchar_t Is Native Type)
/Zf (Faster PDB generation)
/Zg (Generate Function Prototypes)
/Zl (Omit Default Library Name)
/Zm (Specify Precompiled Header Memory Allocation Limit)
/Zo (Enhance Optimized Debugging)
/Zp (Struct Member Alignment)
/Zs (Syntax Check Only)
/ZW (Windows Runtime Compilation)
Unicode Support in the Compiler and Linker
MSVC linker reference
MSVC Linker Options
Compiler-Controlled LINK Options
LINK Input Files
.Obj Files as Linker Input
.netmodule Files as Linker Input
Choosing the Format of .netmodule Input Files
.Lib Files as Linker Input
.Exp Files as Linker Input
.Def Files as Linker Input
.Pdb Files as Linker Input
.Res Files as Linker Input
.Exe Files as Linker Input
.Txt Files as Linker Input
.Ilk Files as Linker Input
LINK Output
Reserved Words
@ (Specify a Linker Response File)
/ALIGN (Section Alignment)
/ALLOWBIND (Prevent DLL Binding)
/ALLOWISOLATION (Manifest Lookup)
/APPCONTAINER (UWP/Microsoft Store App)
/ASSEMBLYDEBUG (Add DebuggableAttribute)
/ASSEMBLYLINKRESOURCE (Link to .NET Framework Resource)
/ASSEMBLYMODULE (Add a MSIL Module to the Assembly)
/ASSEMBLYRESOURCE (Embed a Managed Resource)
/BASE (Base Address)
/CETCOMPAT (Control-flow Enforcement Technology compatible)
/CGTHREADS (Compiler Threads)
/CLRIMAGETYPE (Specify Type of CLR Image)
/CLRSUPPORTLASTERROR (Preserve Last Error Code for PInvoke Calls)
/CLRTHREADATTRIBUTE (Set CLR Thread Attribute)
/CLRUNMANAGEDCODECHECK (Remove
SuppressUnmanagedCodeSecurityAttribute)
/DEBUG (Generate Debug Info)
/DEBUGTYPE (Debug Info Options)
/DEF (Specify Module-Definition File)
/DEFAULTLIB (Specify Default Library)
/DELAY (Delay Load Import Settings)
/DELAYLOAD (Delay Load Import)
/DELAYSIGN (Partially Sign an Assembly)
/DEPENDENTLOADFLAG (Set default dependent load flags)
/DLL (Build a DLL)
/DRIVER (Windows NT Kernel Mode Driver)
/DYNAMICBASE (Use address space layout randomization)
/ENTRY (Entry-Point Symbol)
/ERRORREPORT (Report Internal Linker Errors)
/EXPORT (Exports a Function)
/FILEALIGN (Align sections in files)
/FIXED (Fixed Base Address)
/FORCE (Force File Output)
/FUNCTIONPADMIN (Create Hotpatchable Image)
/GENPROFILE, /FASTGENPROFILE (Generate Profiling Instrumented Build)
/GUARD (Enable Guard Checks)
/HEAP (Set Heap Size)
/HIGHENTROPYVA (Support 64-Bit ASLR)
/IDLOUT (Name MIDL Output Files)
/IGNORE (Ignore Specific Warnings)
/IGNOREIDL (Don't Process Attributes into MIDL)
/IMPLIB (Name Import Library)
/INCLUDE (Force Symbol References)
/INCREMENTAL (Link Incrementally)
/INTEGRITYCHECK (Require Signature Check)
/KEYCONTAINER (Specify a Key Container to Sign an Assembly)
/KEYFILE (Specify Key or Key Pair to Sign an Assembly)
/LARGEADDRESSAWARE (Handle Large Addresses)
/LIBPATH (Additional Libpath)
/LTCG (Link-time Code Generation)
/MACHINE (Specify Target Platform)
/MANIFEST (Create Side-by-Side Assembly Manifest)
/MANIFESTDEPENDENCY (Specify Manifest Dependencies)
/MANIFESTFILE (Name Manifest File)
/MANIFESTINPUT (Specify Manifest Input)
/MANIFESTUAC (Embeds UAC information in manifest)
/MAP (Generate Mapfile)
/MAPINFO (Include Information in Mapfile)
/MERGE (Combine Sections)
/MIDL (Specify MIDL Command Line Options)
/NATVIS (Add Natvis to PDB)
/NOASSEMBLY (Create a MSIL Module)
/NODEFAULTLIB (Ignore Libraries)
/NOENTRY (No Entry Point)
/NOLOGO (Suppress Startup Banner) (Linker)
/NXCOMPAT (Compatible with Data Execution Prevention)
/OPT (Optimizations)
/ORDER (Put Functions in Order)
/OUT (Output File Name)
/PDB (Use Program Database)
/PDBALTPATH (Use Alternate PDB Path)
/PDBSTRIPPED (Strip Private Symbols)
/PGD (Specify Database for Profile-Guided Optimizations)
/POGOSAFEMODE
/PROFILE (Performance Tools Profiler)
/RELEASE (Set the Checksum)
/SAFESEH (Image has Safe Exception Handlers)
/SECTION (Specify Section Attributes)
/SOURCELINK (Include Sourcelink file in PDB)
/STACK (Stack Allocations)
/STUB (MS-DOS Stub File Name)
/SUBSYSTEM (Specify Subsystem)
/SWAPRUN (Load Linker Output to Swap File)
/TLBID (Specify Resource ID for TypeLib)
/TLBOUT (Name .TLB File)
/TSAWARE (Create Terminal Server Aware Application)
/USEPROFILE
/VERBOSE (Print Progress Messages)
/VERSION (Version Information)
/WHOLEARCHIVE (Include All Library Object Files)
/WINMD (Generate Windows Metadata)
/WINMDFILE (Specify winmd File)
/WINMDKEYFILE (Specify winmd Key File)
/WINMDKEYCONTAINER (Specify Key Container)
/WINMDDELAYSIGN (Partially Sign a winmd)
/WX (Treat Linker Warnings as Errors)
Decorated Names
Module-Definition (.Def) Files
Rules for Module-Definition Statements
EXPORTS
LIBRARY
HEAPSIZE
NAME (C/C++)
SECTIONS (C/C++)
STACKSIZE
STUB
VERSION (C/C++)
Linker Support for Delay-Loaded DLLs
Specifying DLLs to Delay Load
Explicitly Unloading a Delay-Loaded DLL
Binding Imports
Loading All Imports for a Delay-Loaded DLL
Error Handling and Notification
Notification Hooks
Failure Hooks
Exceptions (C/C++)
Dumping Delay-Loaded Imports
Constraints of Delay Loading DLLs
Understanding 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
Developing Your Own Helper Function
Additional MSVC build tools
NMAKE Reference
NMAKE projects in Visual Studio
Running NMAKE
NMAKE Options
Tools.ini and NMAKE
Exit Codes from NMAKE
Contents of a Makefile
Wildcards and NMAKE
Long Filenames in a Makefile
Comments in a Makefile
Special Characters in a Makefile
Sample Makefile
Description Blocks
Targets
Pseudotargets
Multiple Targets
Cumulative Dependencies
Targets in Multiple Description Blocks
Dependency Side Effects
Dependents
Inferred Dependents
Search Paths for Dependents
Commands in a Makefile
Command Modifiers
Filename-Parts Syntax
Inline Files in a Makefile
Specifying an Inline File
Creating Inline File Text
Reusing Inline Files
Multiple Inline Files
Macros and NMAKE
Defining an NMAKE Macro
Special Characters in Macros
Null and Undefined Macros
Where to Define Macros
Precedence in Macro Definitions
Using an NMAKE Macro
Macro Substitution
Special NMAKE Macros
Filename Macros
Recursion Macros
Command Macros and Options Macros
Environment-Variable Macros
Inference Rules
Defining a Rule
Search Paths in Rules
Batch-Mode Rules
Predefined Rules
Inferred Dependents and Rules
Precedence in Inference Rules
Dot Directives
Makefile Preprocessing
Makefile Preprocessing Directives
Expressions in Makefile Preprocessing
Makefile Preprocessing Operators
Executing a Program in Preprocessing
LIB Reference
Overview of LIB
How to: Set LIB.EXE Options in the Visual Studio Development Environment
LIB Input Files
LIB Output Files
Other LIB Output
Structure of a Library
Running LIB
Managing a Library
Extracting a Library Member
Working with Import Libraries and Export Files
Building an Import Library and Export File
Using an Import Library and Export File
EDITBIN Reference
EDITBIN Command Line
EDITBIN Options
/ALLOWISOLATION
/ALLOWBIND
/APPCONTAINER
/BIND
/DYNAMICBASE
/ERRORREPORT (editbin.exe)
/HEAP
/HIGHENTROPYVA
/INTEGRITYCHECK
/LARGEADDRESSAWARE
/NOLOGO (EDITBIN)
/NXCOMPAT
/REBASE
/RELEASE
/SECTION (EDITBIN)
/STACK
/SUBSYSTEM
/SWAPRUN
/TSAWARE
/VERSION
DUMPBIN Reference
DUMPBIN Command Line
DUMPBIN Options
/ALL
/ARCHIVEMEMBERS
/CLRHEADER
/DEPENDENTS
/DIRECTIVES
/DISASM
/ERRORREPORT (dumpbin.exe)
/EXPORTS
/FPO
/HEADERS
/IMPORTS (DUMPBIN)
/LINENUMBERS
/LINKERMEMBER
/LOADCONFIG
/OUT (DUMPBIN)
/PDATA
/PDBPATH
/RANGE
/RAWDATA
/RELOCATIONS
/SECTION (DUMPBIN)
/SUMMARY
/SYMBOLS
/TLS
ERRLOOK Reference
Value Edit Control
Error Message Edit Control
Modules Button
Look Up Button
XDCMake Reference
BSCMAKE Reference
Building Browse Information Files: Overview
Building a .Bsc File
Creating an .Sbr File
How BSCMAKE Builds a .Bsc File
BSCMAKE Command Line
BSCMAKE Command File (Response File)
BSCMAKE Options
BSCMAKE Exit Codes
Compiler Errors C999 to C2499
C/C++ Build Errors
Compiler Fatal Errors C999 through C1999
Fatal Error C999
Fatal Error C1001
Fatal Error C1002
Fatal Error C1003
Fatal Error C1004
Fatal Error C1005
Fatal Error C1007
Fatal Error C1008
Fatal Error C1009
Fatal Error C1010
Fatal Error C1012
Fatal Error C1013
Fatal Error C1014
Fatal Error C1016
Fatal Error C1017
Fatal Error C1018
Fatal Error C1019
Fatal Error C1020
Fatal Error C1021
Fatal Error C1022
Fatal Error C1023
Fatal Error C1026
Fatal Error C1033
Fatal Error C1035
Fatal Error C1037
Fatal Error C1038
Fatal Error C1045
Fatal Error C1046
Fatal Error C1047
Fatal Error C1051
Fatal Error C1052
Fatal Error C1053
Fatal Error C1054
Fatal Error C1055
Fatal Error C1057
Fatal Error C1060
Fatal Error C1061
Fatal Error C1064
Fatal Error C1065
Fatal Error C1067
Fatal Error C1068
Fatal Error C1070
Fatal Error C1071
Fatal Error C1073
Fatal Error C1074
Fatal Error C1075
Fatal Error C1076
Fatal Error C1077
Fatal Error C1079
Fatal Error C1080
Fatal Error C1081
Fatal Error C1082
Fatal Error C1083
Fatal Error C1084
Fatal Error C1085
Fatal Error C1086
Fatal Error C1087
Fatal Error C1088
Fatal Error C1089
Fatal Error C1091
Fatal Error C1092
Fatal Error C1093
Fatal Error C1094
Fatal Error C1098
Fatal Error C1099
Fatal Error C1100
Fatal Error C1103
Fatal Error C1104
Fatal Error C1107
Fatal Error C1108
Fatal Error C1109
Fatal Error C1113
Fatal Error C1120
Fatal Error C1121
Fatal Error C1126
Fatal Error C1128
Fatal Error C1189
Fatal Error C1190
Fatal Error C1191
Fatal Error C1192
Fatal Error C1196
Fatal Error C1197
Fatal Error C1201
Fatal Error C1202
Fatal Error C1205
Fatal Error C1206
Fatal Error C1207
Fatal Error C1208
Fatal Error C1209
Fatal Error C1210
Fatal Error C1211
Fatal Error C1305
Fatal Error C1307
Fatal Error C1308
Fatal Error C1309
Fatal Error C1310
Fatal Error C1311
Fatal Error C1312
Fatal Error C1313
Fatal Error C1350
Fatal Error C1351
Fatal Error C1352
Fatal Error C1353
Fatal Error C1382
Fatal Error C1383
Fatal Error C1506
Fatal Error C1508
Fatal Error C1509
Fatal Error C1510
Fatal Error C1601
Fatal Error C1602
Fatal Error C1603
Fatal Error C1852
Fatal Error C1853
Fatal Error C1854
Fatal Error C1900
Fatal Error C1902
Fatal Error C1903
Fatal Error C1904
Fatal Error C1905
Compiler Errors C2000 through C2099
Compiler Error C2001
Compiler Error C2002
Compiler Error C2003
Compiler Error C2004
Compiler Error C2005
Compiler Error C2006
Compiler Error C2007
Compiler Error C2008
Compiler Error C2009
Compiler Error C2010
Compiler Error C2011
Compiler Error C2012
Compiler Error C2013
Compiler Error C2014
Compiler Error C2015
Compiler Error C2017
Compiler Error C2018
Compiler Error C2019
Compiler Error C2020
Compiler Error C2021
Compiler Error C2022
Compiler Error C2026
Compiler Error C2027
Compiler Error C2028
Compiler Error C2030
Compiler Error C2032
Compiler Error C2033
Compiler Error C2034
Compiler Error C2036
Compiler Error C2039
Compiler Error C2040
Compiler Error C2041
Compiler Error C2042
Compiler Error C2043
Compiler Error C2044
Compiler Error C2045
Compiler Error C2046
Compiler Error C2047
Compiler Error C2048
Compiler Error C2050
Compiler Error C2051
Compiler Error C2052
Compiler Error C2053
Compiler Error C2054
Compiler Error C2055
Compiler Error C2056
Compiler Error C2057
Compiler Error C2058
Compiler Error C2059
Compiler Error C2060
Compiler Error C2061
Compiler Error C2062
Compiler Error C2063
Compiler Error C2064
Compiler Error C2065
Compiler Error C2066
Compiler Error C2067
Compiler Error C2069
Compiler Error C2070
Compiler Error C2071
Compiler Error C2072
Compiler Error C2073
Compiler Error C2074
Compiler Error C2075
Compiler Error C2077
Compiler Error C2078
Compiler Error C2079
Compiler Error C2081
Compiler Error C2082
Compiler Error C2083
Compiler Error C2084
Compiler Error C2085
Compiler Error C2086
Compiler Error C2087
Compiler Error C2088
Compiler Error C2089
Compiler Error C2090
Compiler Error C2091
Compiler Error C2092
Compiler Error C2093
Compiler Error C2094
Compiler Error C2095
Compiler Error C2097
Compiler Error C2099
Compiler Errors C2100 through C2199
Compiler Error C2100
Compiler Error C2101
Compiler Error C2102
Compiler Error C2103
Compiler Error C2104
Compiler Error C2105
Compiler Error C2106
Compiler Error C2107
Compiler Error C2108
Compiler Error C2109
Compiler Error C2110
Compiler Error C2111
Compiler Error C2112
Compiler Error C2113
Compiler Error C2114
Compiler Error C2115
Compiler Error C2116
Compiler Error C2117
Compiler Error C2118
Compiler Error C2120
Compiler Error C2121
Compiler Error C2122
Compiler Error C2124
Compiler Error C2128
Compiler Error C2129
Compiler Error C2130
Compiler Error C2131
Compiler Error C2132
Compiler Error C2133
Compiler Error C2134
Compiler Error C2135
Compiler Error C2137
Compiler Error C2138
Compiler Error C2139
Compiler Error C2140
Compiler Error C2141
Compiler Error C2142
Compiler Error C2143
Compiler Error C2144
Compiler Error C2145
Compiler Error C2146
Compiler Error C2147
Compiler Error C2148
Compiler Error C2149
Compiler Error C2150
Compiler Error C2151
Compiler Error C2152
Compiler Error C2153
Compiler Error C2154
Compiler Error C2155
Compiler Error C2156
Compiler Error C2157
Compiler Error C2158
Compiler Error C2159
Compiler Error C2160
Compiler Error C2161
Compiler Error C2162
Compiler Error C2163
Compiler Error C2164
Compiler Error C2165
Compiler Error C2166
Compiler Error C2167
Compiler Error C2168
Compiler Error C2169
Compiler Error C2170
Compiler Error C2171
Compiler Error C2172
Compiler Error C2173
Compiler Error C2174
Compiler Error C2175
Compiler Error C2177
Compiler Error C2178
Compiler Error C2179
Compiler Error C2180
Compiler Error C2181
Compiler Error C2182
Compiler Error C2183
Compiler Error C2184
Compiler Error C2185
Compiler Error C2186
Compiler Error C2188
Compiler Error C2190
Compiler Error C2191
Compiler Error C2192
Compiler Error C2193
Compiler Error C2194
Compiler Error C2195
Compiler Error C2196
Compiler Error C2197
Compiler Error C2198
Compiler Error C2199
Compiler Errors C2200 through C2299
Compiler Error C2200
Compiler Error C2201
Compiler Error C2203
Compiler Error C2204
Compiler Error C2205
Compiler Error C2206
Compiler Error C2207
Compiler Error C2208
Compiler Error C2212
Compiler Error C2213
Compiler Error C2216
Compiler Error C2217
Compiler Error C2218
Compiler Error C2219
Compiler Error C2220
Compiler Error C2222
Compiler Error C2223
Compiler Error C2224
Compiler Error C2226
Compiler Error C2227
Compiler Error C2228
Compiler Error C2229
Compiler Error C2231
Compiler Error C2232
Compiler Error C2233
Compiler Error C2234
Compiler Error C2236
Compiler Error C2238
Compiler Error C2241
Compiler Error C2242
Compiler Error C2243
Compiler Error C2244
Compiler Error C2245
Compiler Error C2246
Compiler Error C2247
Compiler Error C2248
Compiler Error C2249
Compiler Error C2250
Compiler Error C2251
Compiler Error C2252
Compiler Error C2253
Compiler Error C2254
Compiler Error C2255
Compiler Error C2256
Compiler Error C2258
Compiler Error C2259
Compiler Error C2261
Compiler Error C2262
Compiler Error C2264
Compiler Error C2266
Compiler Error C2267
Compiler Error C2268
Compiler Error C2270
Compiler Error C2271
Compiler Error C2272
Compiler Error C2273
Compiler Error C2274
Compiler Error C2275
Compiler Error C2276
Compiler Error C2277
Compiler Error C2279
Compiler Error C2280
Compiler Error C2283
Compiler Error C2285
Compiler Error C2286
Compiler Error C2287
Compiler Error C2289
Compiler Error C2290
Compiler Error C2292
Compiler Error C2293
Compiler Error C2295
Compiler Error C2296
Compiler Error C2297
Compiler Error C2298
Compiler Error C2299
Compiler Errors C2300 Through C2399
Compiler Error C2300
Compiler Error C2301
Compiler Error C2302
Compiler Error C2307
Compiler Error C2308
Compiler Error C2309
Compiler Error C2310
Compiler Error C2311
Compiler Error C2312
Compiler Error C2313
Compiler Error C2315
Compiler Error C2316
Compiler Error C2317
Compiler Error C2318
Compiler Error C2319
Compiler Error C2320
Compiler Error C2322
Compiler Error C2324
Compiler Error C2325
Compiler Error C2326
Compiler Error C2327
Compiler Error C2332
Compiler Error C2333
Compiler Error C2334
Compiler Error C2337
Compiler Error C2338
Compiler Error C2341
Compiler Error C2344
Compiler Error C2345
Compiler Error C2346
Compiler Error C2348
Compiler Error C2349
Compiler Error C2350
Compiler Error C2351
Compiler Error C2352
Compiler Error C2353
Compiler Error C2355
Compiler Error C2356
Compiler Error C2357
Compiler Error C2360
Compiler Error C2361
Compiler Error C2362
Compiler Error C2364
Compiler Error C2365
Compiler Error C2368
Compiler Error C2369
Compiler Error C2370
Compiler Error C2371
Compiler Error C2372
Compiler Error C2373
Compiler Error C2374
Compiler Error C2375
Compiler Error C2376
Compiler Error C2377
Compiler Error C2378
Compiler Error C2379
Compiler Error C2380
Compiler Error C2381
Compiler Error C2382
Compiler Error C2383
Compiler Error C2384
Compiler Error C2385
Compiler Error C2386
Compiler Error C2387
Compiler Error C2388
Compiler Error C2389
Compiler Error C2390
Compiler Error C2391
Compiler Error C2392
Compiler Error C2393
Compiler Error C2394
Compiler Error C2395
Compiler Error C2396
Compiler Error C2397
Compiler Errors C2400 Through C2499
Compiler Error C2400
Compiler Error C2401
Compiler Error C2402
Compiler Error C2403
Compiler Error C2404
Compiler Error C2405
Compiler Error C2406
Compiler Error C2407
Compiler Error C2408
Compiler Error C2409
Compiler Error C2410
Compiler Error C2411
Compiler Error C2412
Compiler Error C2413
Compiler Error C2414
Compiler Error C2415
Compiler Error C2417
Compiler Error C2418
Compiler Error C2419
Compiler Error C2420
Compiler Error C2421
Compiler Error C2422
Compiler Error C2423
Compiler Error C2424
Compiler Error C2425
Compiler Error C2426
Compiler Error C2427
Compiler Error C2428
Compiler Error C2429
Compiler Error C2430
Compiler Error C2431
Compiler Error C2432
Compiler Error C2433
Compiler Error C2434
Compiler Error C2435
Compiler Error C2436
Compiler Error C2437
Compiler Error C2438
Compiler Error C2439
Compiler Error C2440
Compiler Error C2441
Compiler Error C2443
Compiler Error C2444
Compiler Error C2446
Compiler Error C2447
Compiler Error C2448
Compiler Error C2449
Compiler Error C2450
Compiler Error C2451
Compiler Error C2452
Compiler Error C2457
Compiler Error C2458
Compiler Error C2459
Compiler Error C2460
Compiler Error C2461
Compiler Error C2462
Compiler Error C2464
Compiler Error C2465
Compiler Error C2466
Compiler Error C2467
Compiler Error C2469
Compiler Error C2470
Compiler Error C2471
Compiler Error C2472
Compiler Error C2473
Compiler Error C2474
Compiler Error C2477
Compiler Error C2479
Compiler Error C2480
Compiler Error C2482
Compiler Error C2483
Compiler Error C2485
Compiler Error C2486
Compiler Error C2487
Compiler Error C2488
Compiler Error C2489
Compiler Error C2490
Compiler Error C2491
Compiler Error C2492
Compiler Error C2493
Compiler Error C2494
Compiler Error C2495
Compiler Error C2496
Compiler Error C2498
Compiler Error C2499
Compiler Errors C2500 to C3999
Compiler Errors C2500 Through C2599
Compiler Error C2500
Compiler Error C2502
Compiler Error C2503
Compiler Error C2504
Compiler Error C2505
Compiler Error C2506
Compiler Error C2507
Compiler Error C2509
Compiler Error C2510
Compiler Error C2511
Compiler Error C2512
Compiler Error C2513
Compiler Error C2514
Compiler Error C2516
Compiler Error C2517
Compiler Error C2518
Compiler Error C2521
Compiler Error C2523
Compiler Error C2524
Compiler Error C2526
Compiler Error C2528
Compiler Error C2529
Compiler Error C2530
Compiler Error C2531
Compiler Error C2532
Compiler Error C2533
Compiler Error C2534
Compiler Error C2535
Compiler Error C2537
Compiler Error C2540
Compiler Error C2541
Compiler Error C2542
Compiler Error C2543
Compiler Error C2544
Compiler Error C2545
Compiler Error C2548
Compiler Error C2549
Compiler Error C2550
Compiler Error C2551
Compiler Error C2552
Compiler Error C2553
Compiler Error C2555
Compiler Error C2556
Compiler Error C2557
Compiler Error C2558
Compiler Error C2561
Compiler Error C2562
Compiler Error C2563
Compiler Error C2566
Compiler Error C2567
Compiler Error C2568
Compiler Error C2569
Compiler Error C2570
Compiler Error C2571
Compiler Error C2572
Compiler Error C2573
Compiler Error C2574
Compiler Error C2575
Compiler Error C2577
Compiler Error C2579
Compiler Error C2581
Compiler Error C2582
Compiler Error C2583
Compiler Error C2584
Compiler Error C2585
Compiler Error C2586
Compiler Error C2587
Compiler Error C2588
Compiler Error C2589
Compiler Error C2592
Compiler Error C2593
Compiler Error C2594
Compiler Error C2597
Compiler Error C2598
Compiler Error C2599
Compiler Errors C2600 Through C2699
Compiler Error C2600
Compiler Error C2601
Compiler Error C2602
Compiler Error C2603
Compiler Error C2605
Compiler Error C2611
Compiler Error C2612
Compiler Error C2613
Compiler Error C2614
Compiler Error C2616
Compiler Error C2617
Compiler Error C2619
Compiler Error C2624
Compiler Error C2626
Compiler Error C2627
Compiler Error C2628
Compiler Error C2630
Compiler Error C2632
Compiler Error C2633
Compiler Error C2634
Compiler Error C2635
Compiler Error C2636
Compiler Error C2637
Compiler Error C2638
Compiler Error C2640
Compiler Error C2645
Compiler Error C2646
Compiler Error C2647
Compiler Error C2648
Compiler Error C2649
Compiler Error C2650
Compiler Error C2651
Compiler Error C2652
Compiler Error C2653
Compiler Error C2654
Compiler Error C2655
Compiler Error C2656
Compiler Error C2657
Compiler Error C2658
Compiler Error C2659
Compiler Error C2660
Compiler Error C2661
Compiler Error C2662
Compiler Error C2663
Compiler Error C2664
Compiler Error C2665
Compiler Error C2666
Compiler Error C2667
Compiler Error C2668
Compiler Error C2669
Compiler Error C2670
Compiler Error C2671
Compiler Error C2672
Compiler Error C2673
Compiler Error C2674
Compiler Error C2675
Compiler Error C2676
Compiler Error C2677
Compiler Error C2678
Compiler Error C2679
Compiler Error C2680
Compiler Error C2681
Compiler Error C2682
Compiler Error C2683
Compiler Error C2687
Compiler Error C2688
Compiler Error C2689
Compiler Error C2690
Compiler Error C2691
Compiler Error C2692
Compiler Error C2693
Compiler Error C2694
Compiler Error C2695
Compiler Error C2696
Compiler Error C2698
Compiler Errors C2700 Through C2799
Compiler Error C2700
Compiler Error C2701
Compiler Error C2702
Compiler Error C2703
Compiler Error C2704
Compiler Error C2705
Compiler Error C2706
Compiler Error C2707
Compiler Error C2708
Compiler Error C2709
Compiler Error C2710
Compiler Error C2711
Compiler Error C2712
Compiler Error C2713
Compiler Error C2714
Compiler Error C2715
Compiler Error C2718
Compiler Error C2719
Compiler Error C2720
Compiler Error C2721
Compiler Error C2722
Compiler Error C2723
Compiler Error C2724
Compiler Error C2725
Compiler Error C2726
Compiler Error C2728
Compiler Error C2730
Compiler Error C2731
Compiler Error C2732
Compiler Error C2733
Compiler Error C2734
Compiler Error C2735
Compiler Error C2736
Compiler Error C2738
Compiler Error C2739
Compiler Error C2743
Compiler Error C2745
Compiler Error C2748
Compiler Error C2749
Compiler Error C2750
Compiler Error C2751
Compiler Error C2752
Compiler Error C2753
Compiler Error C2754
Compiler Error C2755
Compiler Error C2756
Compiler Error C2757
Compiler Error C2758
Compiler Error C2760
Compiler Error C2761
Compiler Error C2762
Compiler Error C2764
Compiler Error C2765
Compiler Error C2766
Compiler Error C2767
Compiler Error C2768
Compiler Error C2770
Compiler Error C2771
Compiler Error C2773
Compiler Error C2774
Compiler Error C2775
Compiler Error C2776
Compiler Error C2777
Compiler Error C2778
Compiler Error C2779
Compiler Error C2780
Compiler Error C2781
Compiler Error C2782
Compiler Error C2783
Compiler Error C2784
Compiler Error C2785
Compiler Error C2786
Compiler Error C2787
Compiler Error C2788
Compiler Error C2790
Compiler Error C2791
Compiler Error C2792
Compiler Error C2793
Compiler Error C2794
Compiler Error C2795
Compiler Error C2797
Compiler Error C2798
Compiler Errors C2800 Through C2899
Compiler Error C2800
Compiler Error C2801
Compiler Error C2802
Compiler Error C2803
Compiler Error C2804
Compiler Error C2805
Compiler Error C2806
Compiler Error C2807
Compiler Error C2808
Compiler Error C2809
Compiler Error C2810
Compiler Error C2811
Compiler Error C2812
Compiler Error C2813
Compiler Error C2814
Compiler Error C2815
Compiler Error C2817
Compiler Error C2818
Compiler Error C2819
Compiler Error C2821
Compiler Error C2823
Compiler Error C2824
Compiler Error C2825
Compiler Error C2827
Compiler Error C2828
Compiler Error C2829
Compiler Error C2830
Compiler Error C2831
Compiler Error C2833
Compiler Error C2834
Compiler Error C2835
Compiler Error C2838
Compiler Error C2839
Compiler Error C2842
Compiler Error C2843
Compiler Error C2844
Compiler Error C2845
Compiler Error C2846
Compiler Error C2847
Compiler Error C2849
Compiler Error C2850
Compiler Error C2854
Compiler Error C2855
Compiler Error C2856
Compiler Error C2857
Compiler Error C2858
Compiler Error C2859
Compiler Error C2860
Compiler Error C2861
Compiler Error C2862
Compiler Error C2863
Compiler Error C2864
Compiler Error C2865
Compiler Error C2867
Compiler Error C2868
Compiler Error C2869
Compiler Error C2870
Compiler Error C2871
Compiler Error C2872
Compiler Error C2873
Compiler Error C2874
Compiler Error C2875
Compiler Error C2876
Compiler Error C2877
Compiler Error C2878
Compiler Error C2879
Compiler Error C2881
Compiler Error C2882
Compiler Error C2883
Compiler Error C2884
Compiler Error C2885
Compiler Error C2886
Compiler Error C2888
Compiler Error C2890
Compiler Error C2891
Compiler Error C2892
Compiler Error C2893
Compiler Error C2894
Compiler Error C2896
Compiler Error C2897
Compiler Error C2898
Compiler Errors C2900 Through C2999
Compiler Error C2902
Compiler Error C2903
Compiler Error C2904
Compiler Error C2906
Compiler Error C2908
Compiler Error C2909
Compiler Error C2910
Compiler Error C2911
Compiler Error C2912
Compiler Error C2913
Compiler Error C2914
Compiler Error C2917
Compiler Error C2918
Compiler Error C2919
Compiler Error C2920
Compiler Error C2921
Compiler Error C2923
Compiler Error C2927
Compiler Error C2928
Compiler Error C2929
Compiler Error C2930
Compiler Error C2931
Compiler Error C2932
Compiler Error C2933
Compiler Error C2934
Compiler Error C2935
Compiler Error C2936
Compiler Error C2937
Compiler Error C2939
Compiler Error C2940
Compiler Error C2941
Compiler Error C2942
Compiler Error C2943
Compiler Error C2944
Compiler Error C2945
Compiler Error C2946
Compiler Error C2947
Compiler Error C2948
Compiler Error C2951
Compiler Error C2952
Compiler Error C2953
Compiler Error C2955
Compiler Error C2957
Compiler Error C2958
Compiler Error C2959
Compiler Error C2962
Compiler Error C2969
Compiler Error C2970
Compiler Error C2971
Compiler Error C2973
Compiler Error C2974
Compiler Error C2975
Compiler Error C2976
Compiler Error C2977
Compiler Error C2978
Compiler Error C2979
Compiler Error C2988
Compiler Error C2989
Compiler Error C2990
Compiler Error C2991
Compiler Error C2992
Compiler Error C2993
Compiler Error C2994
Compiler Error C2995
Compiler Error C2996
Compiler Error C2998
Compiler Errors C3000 Through C3099
Compiler Error C3001
Compiler Error C3002
Compiler Error C3003
Compiler Error C3004
Compiler Error C3005
Compiler Error C3006
Compiler Error C3007
Compiler Error C3008
Compiler Error C3009
Compiler Error C3010
Compiler Error C3011
Compiler Error C3012
Compiler Error C3013
Compiler Error C3014
Compiler Error C3015
Compiler Error C3016
Compiler Error C3017
Compiler Error C3018
Compiler Error C3019
Compiler Error C3020
Compiler Error C3021
Compiler Error C3022
Compiler Error C3023
Compiler Error C3024
Compiler Error C3025
Compiler Error C3026
Compiler Error C3027
Compiler Error C3028
Compiler Error C3029
Compiler Error C3030
Compiler Error C3031
Compiler Error C3032
Compiler Error C3033
Compiler Error C3034
Compiler Error C3035
Compiler Error C3036
Compiler Error C3037
Compiler Error C3038
Compiler Error C3039
Compiler Error C3040
Compiler Error C3041
Compiler Error C3042
Compiler Error C3043
Compiler Error C3044
Compiler Error C3045
Compiler Error C3046
Compiler Error C3047
Compiler Error C3048
Compiler Error C3049
Compiler Error C3050
Compiler Error C3052
Compiler Error C3053
Compiler Error C3054
Compiler Error C3055
Compiler Error C3056
Compiler Error C3057
Compiler Error C3058
Compiler Error C3059
Compiler Error C3060
Compiler Error C3062
Compiler Error C3063
Compiler Error C3065
Compiler Error C3066
Compiler Error C3068
Compiler Error C3069
Compiler Error C3070
Compiler Error C3071
Compiler Error C3072
Compiler Error C3073
Compiler Error C3075
Compiler Error C3076
Compiler Error C3077
Compiler Error C3080
Compiler Error C3083
Compiler Error C3084
Compiler Error C3085
Compiler Error C3087
Compiler Error C3094
Compiler Error C3095
Compiler Error C3096
Compiler Error C3097
Compiler Error C3099
Compiler Errors C3100 Through C3199
Compiler Error C3100
Compiler Error C3101
Compiler Error C3103
Compiler Error C3104
Compiler Error C3106
Compiler Error C3110
Compiler Error C3113
Compiler Error C3114
Compiler Error C3115
Compiler Error C3116
Compiler Error C3117
Compiler Error C3118
Compiler Error C3120
Compiler Error C3121
Compiler Error C3126
Compiler Error C3130
Compiler Error C3131
Compiler Error C3132
Compiler Error C3133
Compiler Error C3134
Compiler Error C3135
Compiler Error C3136
Compiler Error C3137
Compiler Error C3138
Compiler Error C3139
Compiler Error C3140
Compiler Error C3141
Compiler Error C3142
Compiler Error C3145
Compiler Error C3149
Compiler Error C3150
Compiler Error C3152
Compiler Error C3153
Compiler Error C3154
Compiler Error C3155
Compiler Error C3156
Compiler Error C3157
Compiler Error C3159
Compiler Error C3160
Compiler Error C3161
Compiler Error C3162
Compiler Error C3163
Compiler Error C3166
Compiler Error C3167
Compiler Error C3168
Compiler Error C3170
Compiler Error C3171
Compiler Error C3172
Compiler Error C3173
Compiler Error C3174
Compiler Error C3175
Compiler Error C3176
Compiler Error C3179
Compiler Error C3180
Compiler Error C3181
Compiler Error C3182
Compiler Error C3183
Compiler Error C3185
Compiler Error C3187
Compiler Error C3189
Compiler Error C3190
Compiler Error C3192
Compiler Error C3194
Compiler Error C3195
Compiler Error C3196
Compiler Error C3197
Compiler Error C3198
Compiler Error C3199
Compiler Errors C3200 Through C3299
Compiler Error C3200
Compiler Error C3201
Compiler Error C3202
Compiler Error C3203
Compiler Error C3204
Compiler Error C3205
Compiler Error C3206
Compiler Error C3207
Compiler Error C3208
Compiler Error C3209
Compiler Error C3210
Compiler Error C3211
Compiler Error C3212
Compiler Error C3213
Compiler Error C3214
Compiler Error C3215
Compiler Error C3216
Compiler Error C3217
Compiler Error C3218
Compiler Error C3219
Compiler Error C3222
Compiler Error C3223
Compiler Error C3224
Compiler Error C3225
Compiler Error C3226
Compiler Error C3227
Compiler Error C3228
Compiler Error C3229
Compiler Error C3230
Compiler Error C3231
Compiler Error C3232
Compiler Error C3233
Compiler Error C3234
Compiler Error C3235
Compiler Error C3236
Compiler Error C3237
Compiler Error C3238
Compiler Error C3239
Compiler Error C3240
Compiler Error C3241
Compiler Error C3242
Compiler Error C3243
Compiler Error C3244
Compiler Error C3246
Compiler Error C3247
Compiler Error C3248
Compiler Error C3251
Compiler Error C3252
Compiler Error C3253
Compiler Error C3254
Compiler Error C3255
Compiler Error C3262
Compiler Error C3264
Compiler Error C3265
Compiler Error C3266
Compiler Error C3268
Compiler Error C3269
Compiler Error C3270
Compiler Error C3271
Compiler Error C3272
Compiler Error C3273
Compiler Error C3274
Compiler Error C3275
Compiler Error C3276
Compiler Error C3277
Compiler Error C3278
Compiler Error C3279
Compiler Error C3280
Compiler Error C3282
Compiler Error C3283
Compiler Error C3284
Compiler Error C3285
Compiler Error C3286
Compiler Error C3287
Compiler Error C3288
Compiler Error C3289
Compiler Error C3290
Compiler Error C3291
Compiler Error C3292
Compiler Error C3293
Compiler Error C3295
Compiler Error C3296
Compiler Error C3297
Compiler Error C3298
Compiler Error C3299
Compiler Errors C3300 Through C3399
Compiler Error C3303
Compiler Error C3309
Compiler Error C3320
Compiler Error C3322
Compiler Error C3333
Compiler Error C3334
Compiler Error C3340
Compiler Error C3342
Compiler Error C3345
Compiler Error C3347
Compiler Error C3350
Compiler Error C3351
Compiler Error C3352
Compiler Error C3353
Compiler Error C3354
Compiler Error C3356
Compiler Error C3358
Compiler Error C3360
Compiler Error C3363
Compiler Error C3364
Compiler Error C3365
Compiler Error C3366
Compiler Error C3367
Compiler Error C3368
Compiler Error C3369
Compiler Error C3370
Compiler Error C3371
Compiler Error C3372
Compiler Error C3373
Compiler Error C3374
Compiler Error C3375
Compiler Error C3379
Compiler Error C3380
Compiler Error C3381
Compiler Error C3382
Compiler Error C3383
Compiler Error C3384
Compiler Error C3385
Compiler Error C3386
Compiler Error C3387
Compiler Error C3388
Compiler Error C3389
Compiler Error C3390
Compiler Error C3391
Compiler Error C3392
Compiler Error C3393
Compiler Error C3394
Compiler Error C3395
Compiler Error C3396
Compiler Error C3397
Compiler Error C3398
Compiler Error C3399
Compiler Errors C3400 Through C3499
Compiler Error C3400
Compiler Error C3408
Compiler Error C3409
Compiler Error C3412
Compiler Error C3413
Compiler Error C3414
Compiler Error C3415
Compiler Error C3417
Compiler Error C3418
Compiler Error C3420
Compiler Error C3421
Compiler Error C3445
Compiler Error C3446
Compiler Error C3450
Compiler Error C3451
Compiler Error C3452
Compiler Error C3453
Compiler Error C3454
Compiler Error C3455
Compiler Error C3456
Compiler Error C3457
Compiler Error C3458
Compiler Error C3459
Compiler Error C3460
Compiler Error C3461
Compiler Error C3462
Compiler Error C3463
Compiler Error C3464
Compiler Error C3465
Compiler Error C3466
Compiler Error C3467
Compiler Error C3468
Compiler Error C3469
Compiler Error C3470
Compiler Error C3480
Compiler Error C3481
Compiler Error C3482
Compiler Error C3483
Compiler Error C3484
Compiler Error C3485
Compiler Error C3487
Compiler Error C3488
Compiler Error C3489
Compiler Error C3490
Compiler Error C3491
Compiler Error C3492
Compiler Error C3493
Compiler Error C3495
Compiler Error C3496
Compiler Error C3498
Compiler Error C3499
Compiler Errors C3500 through C3999
Compiler Error C3500
Compiler Error C3501
Compiler Error C3505
Compiler Error C3506
Compiler Error C3507
Compiler Error C3508
Compiler Error C3509
Compiler Error C3510
Compiler Error C3519
Compiler Error C3530
Compiler Error C3531
Compiler Error C3532
Compiler Error C3533
Compiler Error C3535
Compiler Error C3536
Compiler Error C3537
Compiler Error C3538
Compiler Error C3539
Compiler Error C3540
Compiler Error C3541
Compiler Error C3550
Compiler Error C3551
Compiler Error C3552
Compiler Error C3553
Compiler Error C3554
Compiler Error C3555
Compiler Error C3556
Compiler Error C3603
Compiler Error C3609
Compiler Error C3610
Compiler Error C3611
Compiler Error C3612
Compiler Error C3615
Compiler Error C3618
Compiler Error C3619
Compiler Error C3622
Compiler Error C3623
Compiler Error C3624
Compiler Error C3625
Compiler Error C3626
Compiler Error C3627
Compiler Error C3628
Compiler Error C3630
Compiler Error C3631
Compiler Error C3632
Compiler Error C3633
Compiler Error C3634
Compiler Error C3637
Compiler Error C3638
Compiler Error C3640
Compiler Error C3641
Compiler Error C3642
Compiler Error C3644
Compiler Error C3645
Compiler Error C3646
Compiler Error C3648
Compiler Error C3650
Compiler Error C3651
Compiler Error C3652
Compiler Error C3653
Compiler Error C3654
Compiler Error C3655
Compiler Error C3656
Compiler Error C3657
Compiler Error C3661
Compiler Error C3662
Compiler Error C3665
Compiler Error C3666
Compiler Error C3668
Compiler Error C3669
Compiler Error C3670
Compiler Error C3671
Compiler Error C3672
Compiler Error C3673
Compiler Error C3675
Compiler Error C3697
Compiler Error C3698
Compiler Error C3699
Compiler Error C3701
Compiler Error C3702
Compiler Error C3703
Compiler Error C3704
Compiler Error C3705
Compiler Error C3706
Compiler Error C3707
Compiler Error C3708
Compiler Error C3709
Compiler Error C3710
Compiler Error C3711
Compiler Error C3712
Compiler Error C3713
Compiler Error C3714
Compiler Error C3715
Compiler Error C3717
Compiler Error C3718
Compiler Error C3719
Compiler Error C3721
Compiler Error C3722
Compiler Error C3723
Compiler Error C3724
Compiler Error C3727
Compiler Error C3728
Compiler Error C3731
Compiler Error C3732
Compiler Error C3733
Compiler Error C3734
Compiler Error C3736
Compiler Error C3737
Compiler Error C3738
Compiler Error C3739
Compiler Error C3740
Compiler Error C3741
Compiler Error C3743
Compiler Error C3744
Compiler Error C3745
Compiler Error C3747
Compiler Error C3748
Compiler Error C3749
Compiler Error C3752
Compiler Error C3753
Compiler Error C3754
Compiler Error C3755
Compiler Error C3761
Compiler Error C3762
Compiler Error C3763
Compiler Error C3764
Compiler Error C3765
Compiler Error C3766
Compiler Error C3767
Compiler Error C3768
Compiler Error C3769
Compiler Error C3771
Compiler Error C3772
Compiler Error C3797
Compiler Error C3798
Compiler Error C3799
Compiler Error C3800
Compiler Error C3803
Compiler Error C3804
Compiler Error C3805
Compiler Error C3807
Compiler Error C3808
Compiler Error C3809
Compiler Error C3812
Compiler Error C3813
Compiler Error C3815
Compiler Error C3816
Compiler Error C3817
Compiler Error C3818
Compiler Error C3820
Compiler Error C3821
Compiler Error C3824
Compiler Error C3825
Compiler Error C3828
Compiler Error C3830
Compiler Error C3831
Compiler Error C3832
Compiler Error C3833
Compiler Error C3834
Compiler Error C3836
Compiler Error C3838
Compiler Error C3839
Compiler Error C3842
Compiler Error C3846
Compiler Error C3848
Compiler Error C3849
Compiler Error C3850
Compiler Error C3851
Compiler Error C3852
Compiler Error C3853
Compiler Error C3854
Compiler Error C3855
Compiler Error C3856
Compiler Error C3857
Compiler Error C3858
Compiler Error C3859
Compiler Error C3860
Compiler Error C3861
Compiler Error C3862
Compiler Error C3865
Compiler Error C3866
Compiler Error C3867
Compiler Error C3868
Compiler Error C3869
Compiler Error C3872
Compiler Error C3873
Compiler Error C3874
Compiler Error C3880
Compiler Error C3883
Compiler Error C3886
Compiler Error C3887
Compiler Error C3888
Compiler Error C3890
Compiler Error C3891
Compiler Error C3892
Compiler Error C3893
Compiler Error C3894
Compiler Error C3895
Compiler Error C3896
Compiler Error C3898
Compiler Error C3899
Compiler Error C3900
Compiler Error C3901
Compiler Error C3902
Compiler Error C3903
Compiler Error C3904
Compiler Error C3908
Compiler Error C3909
Compiler Error C3910
Compiler Error C3911
Compiler Error C3912
Compiler Error C3913
Compiler Error C3914
Compiler Error C3915
Compiler Error C3917
Compiler Error C3918
Compiler Error C3919
Compiler Error C3920
Compiler Error C3923
Compiler Warnings
Compiler Warnings by compiler version
Compiler Warnings C4000 Through C4199
Compiler Warning (level 4) C4001
Compiler Warning (level 1) C4002
Compiler Warning (level 1) C4003
Compiler Warning (level 1) C4005
Compiler Warning (level 1) C4006
Compiler Warning (level 2) C4007
Compiler Warning (levels 2 and 3) C4008
Compiler Warning (level 1) C4010
Compiler Warning (level 3) C4013
Compiler Warning (level 1) C4015
Compiler Warning (level 3) C4018
Compiler Warning (level 4) C4019
Compiler Warning (level 1) C4020
Compiler Warning (level 1) C4022
Compiler Warning (level 3) C4023
Compiler Warning (level 1) C4024
Compiler Warning (level 1) C4025
Compiler Warning (level 1) C4026
Compiler Warning (level 1) C4027
Compiler Warning (level 1) C4028
Compiler Warning (level 1) C4029
Compiler Warning (level 1) C4030
Compiler Warning (level 1) C4031
Compiler Warning (level 4) C4032
Compiler Warning (level 1) C4033
Compiler Warning (level 1) C4034
Compiler Warning (level 1) C4036
Compiler Warning (level 1) C4038
Compiler Warning (level 1) C4041
Compiler Warning (level 1) C4042
Compiler Warning (level 1) C4045
Compiler Warning (level 1) C4047
Compiler Warning (level 1) C4048
Compiler Warning (level 1) C4049
Compiler Warning (level 2) C4051
Compiler Warning (level 1) C4052
Compiler Warning (level 4) C4053
Compiler warning (level 1) C4055
Compiler Warning (level 2) C4056
Compiler Warning (level 4) C4057
Compiler Warning (level 4) C4061
Compiler Warning (level 4) C4062
Compiler Warning (level 3) C4066
Compiler Warning (level 1) C4067
Compiler Warning (level 1) C4068
Compiler Warning (level 3) C4073
Compiler Warning (level 1) C4074
Compiler Warning (level 1) C4075
Compiler Warning (level 1) C4076
Compiler Warning (level 1) C4077
Compiler Warning (level 1) C4079
Compiler Warning (level 1) C4080
Compiler Warning (level 1) C4081
Compiler Warning (level 1) C4083
Compiler Warning (level 1) C4085
Compiler Warning (level 1) C4086
Compiler Warning (level 1) C4087
Compiler Warning (level 1) C4088
Compiler Warning (level 1) C4089
Compiler Warning (level 1) C4090
Compiler Warning (level 1) C4091
Compiler Warning (level 4) C4092
Compiler Warning (level 2) C4094
Compiler Warning (level 1) C4096
Compiler Warning (level 1) C4097
Compiler Warning (level 1) C4098
Compiler Warning (level 2) C4099
Compiler Warning (level 4) C4100
Compiler Warning (level 3) C4101
Compiler Warning (level 3) C4102
Compiler Warning (level 1) C4103
Compiler Warning (level 1) C4109
Compiler Warning (levels 1 and 4) C4112
Compiler Warning (level 1) C4113
Compiler Warning (level 1) C4114
Compiler Warning (levels 1 and 4) C4115
Compiler Warning (level 1) C4116
Compiler Warning (level 1) C4117
Compiler Warning (level 1) C4119
Compiler Warning (level 1) C4120
Compiler Warning (level 4) C4121
Compiler Warning (level 1) C4122
Compiler Warning (level 1) C4124
Compiler Warning (level 4) C4125
Compiler Warning (level 4) C4127
Compiler Warning (level 1) C4129
Compiler Warning (level 4) C4130
Compiler Warning (level 4) C4131
Compiler Warning (level 4) C4132
Compiler Warning (level 3) C4133
Compiler Warning (level 1) C4138
Compiler Warning (level 1) C4141
Compiler Warning (level 1) C4142
Compiler Warning (level 1) C4143
Compiler Warning (level 1) C4144
Compiler Warning (level 1) C4145
Compiler Warning (level 2) C4146
Compiler Warning (level 2) C4150
Compiler Warning (level 4) C4152
Compiler Warning (level 1) C4153
Compiler Warning (level 1) C4154
Compiler Warning (level 1) C4155
Compiler Warning (level 2) C4156
Compiler Warning (level 1) C4157
Compiler Warning (level 1) C4158
Compiler Warning (level 3) C4159
Compiler Warning (level 1) C4160
Compiler Warning (level 3) C4161
Compiler Warning (level 1) C4162
Compiler Warning (level 1) C4163
Compiler Warning (level 1) C4164
Compiler Warning (level 1) C4165
Compiler Warning (level 1) C4166
Compiler Warning (level 1) C4167
Compiler Warning (level 1) C4168
Compiler Warning (level 1) C4172
Compiler Warning (level 1) C4174
Compiler Warning (level 1) C4175
Compiler Warning (level 1) C4176
Compiler Warning (level 1) C4177
Compiler Warning (level 1) C4178
Compiler Warning (level 1) C4179
Compiler Warning (level 1) C4180
Compiler Warning (level 1) C4182
Compiler Warning (level 1) C4183
Compiler Warning (level 1) C4185
Compiler Warning (level 1) C4186
Compiler Warning (level 1) C4187
Compiler Warning (level 4) C4189
Compiler Warning (level 1) C4190
Compiler Warning (level 3) C4191
Compiler Warning (level 3) C4192
Compiler Warning (level 3) C4197
Compiler Warnings C4200 Through C4399
Compiler Warning (levels 2 and 4) C4200
Compiler Warning (level 4) C4201
Compiler Warning (level 4) C4202
Compiler Warning (level 4) C4204
Compiler Warning (level 4) C4205
Compiler Warning (level 4) C4206
Compiler Warning (level 4) C4207
Compiler Warning (level 4) C4208
Compiler Warning (level 4) C4210
Compiler Warning (level 4) C4211
Compiler Warning (level 4) C4212
Compiler Warning (level 4) C4213
Compiler Warning (level 4) C4214
Compiler Warning (level 1) C4215
Compiler Warning (level 1) C4216
Compiler Warning (level 1) C4218
Compiler Warning (level 4) C4220
Compiler Warning (level 4) C4221
Compiler Warning (levels 1 and 4) C4223
Compiler Warning (level 1) C4224
Compiler Warning (level 1) C4226
Compiler Warning (level 1) C4227
Compiler Warning (level 1) C4228
Compiler Warning (level 1) C4229
Compiler Warning (level 1) C4230
Compiler Warning (level 4) C4232
Compiler Warning (level 4) C4233
Compiler Warning (level 4) C4234
Compiler Warning (level 4) C4235
Compiler Warning (level 1) C4237
Compiler Warning (level 4) C4238
Compiler Warning (level 4) C4239
Compiler Warning (level 3) C4240
Compiler Warning (level 4) C4242
Compiler Warning (level 3) C4243
Compiler Warning (level 2) C4244
Compiler Warning (levels 3 and 4) C4244
Compiler Warning (level 4) C4245
Compiler Warning (level 2) C4250
Compiler Warning (level 1) C4251
Compiler Warning (level 4) C4254
Compiler Warning (level 4) C4255
Compiler Warning (level 4) C4256
Compiler Warning (level 1) C4258
Compiler Warning (level 4) C4263
Compiler Warning (level 1) C4264
Compiler Warning (level 3) C4265
Compiler Warning (level 4) C4266
Compiler Warning (level 3) C4267
Compiler Warning (level 4) C4268
Compiler Warning (level 1) C4269
Compiler Warning (level 1) C4272
Compiler Warning (level 1) C4273
Compiler Warning (level 1) C4274
Compiler Warning (level 2) C4275
Compiler Warning (level 1) C4276
Compiler Warning (level 3) C4278
Compiler Warning (level 3) C4280
Compiler Warning (level 3) C4281
Compiler Warning (level 3) C4282
Compiler Warning (level 3) C4283
Compiler Warning (level 2) C4285
Compiler Warning (level 1) C4286
Compiler Warning (level 3) C4287
Compiler Warning (level 1) C4288
Compiler Warning (level 4) C4289
Compiler Warning (level 3) C4290
Compiler Warning (level 1) C4291
Compiler Warning (level 1) C4293
Compiler Warning (level 4) C4295
Compiler Warning (level 4) C4296
Compiler Warning (level 1) C4297
Compiler Warning (level 2) C4302
Compiler Warning (level 1) C4305
Compiler Warning (level 3) C4306
Compiler Warning (level 2) C4307
Compiler Warning (level 2) C4308
Compiler Warning (level 2) C4309
Compiler Warning (level 3) C4310
Compiler Warning (level 1) C4311
Compiler Warning (level 1) C4312
Compiler Warning (level 1) C4313
Compiler Warning (level 3) C4316
Compiler Warning (level 1) C4319
Compiler Warning (level 4) C4324
Compiler Warning (level 1) C4325
Compiler Warning (level 1) C4326
Compiler Warning (level 1) C4329
Compiler Warning (level 1) C4333
Compiler Warning (level 3) C4334
Compiler Warning C4335
Compiler Warning (level 4) C4336
Compiler Warning (level 4) C4337
Compiler Warning (level 4) C4339
Compiler Warning (level 1) C4340
Compiler Warning (level 1) C4342
Compiler Warning (level 4) C4343
Compiler Warning (level 1) C4344
Compiler Warning (level 1) C4346
Compiler Warning (level 1) C4348
Compiler Warning (level 1) C4350
Compiler Warning (level 1) C4353
Compiler Warning C4355
Compiler Warning (level 2) C4356
Compiler Warning (level 3) C4357
Compiler Warning (level 1) C4358
Compiler Warning (level 3) C4359
Compiler Warning (level 1) C4364
Compiler Warning (level 4) C4365
Compiler Warning (level 4) C4366
Compiler Warning C4368
Compiler Warning (level 1) C4369
Compiler Warning (level 3) C4371
Compiler Warning (level 3) C4373
Compiler Warning (level 1) C4374
Compiler Warning (level 1) C4375
Compiler Warning (level 1) C4376
Compiler Warning (level 1) C4377
Compiler Warning (level 1) C4378
Compiler Warning (level 1) C4379
Compiler Warning (level 1) C4381
Compiler Warning (level 1) C4382
Compiler Warning (level 1) C4383
Compiler Warning (level 1) C4384
Compiler Warning (level 4) C4389
Compiler Warning (level 3) C4390
Compiler Warning (level 1) C4391
Compiler Warning (level 1) C4392
Compiler Warning (level 1) C4393
Compiler Warning C4394
Compiler Warning (level 1) C4395
Compiler Warning (level 2) C4396
Compiler Warning (level 1) C4397
Compiler Warning (level 3) C4398
Compiler Warning (level 1) C4399
Compiler Warnings C4400 Through C4599
Compiler Warning (level 4) C4400
Compiler Warning (level 1) C4401
Compiler Warning (level 1) C4402
Compiler Warning (level 1) C4403
Compiler Warning (level 3) C4404
Compiler Warning (level 1) C4405
Compiler Warning (level 1) C4406
Compiler Warning (level 1) C4407
Compiler Warning (level 4) C4408
Compiler Warning (level 1) C4409
Compiler Warning (level 1) C4410
Compiler Warning (level 1) C4411
Compiler Warning (level 2) C4412
Compiler Warning (level 3) C4414
Compiler Warning (level 1) C4420
Compiler Warning (level 4) C4429
Compiler Warning C4430
Compiler Warning (level 4) C4431
Compiler Warning (level 4) C4434
Compiler Warning (level 4) C4435
Compiler Warning (level 1) C4436
Compiler Warning (level 4) C4437
Compiler Warning C4439
Compiler Warning (level 1) C4440
Compiler Warning (level 1) C4441
Compiler Warning (level 1) C4445
Compiler warning (level 4) C4456
Compiler warning (level 4) C4457
Compiler warning (level 4) C4458
Compiler Warning (level 4) C4459
Compiler Warning (level 4) C4460
Compiler Warning (level 1) C4461
Compiler Warning (level 1) C4462
Compiler Warning (level 4) C4463
Compiler warning (level 4) C4464
Compiler Warning (level 1) C4470
Compiler Warning (level 4) C4471
Compiler Warning (level 1) C4473
Compiler Warning (level 1) C4477
Compiler Warning (level 4) C4481
Compiler Warning C4484
Compiler Warning C4485
Compiler Warning (level 1) C4486
Compiler Warning (level 4) C4487
Compiler Warning (level 1) C4488
Compiler Warning (level 1) C4489
Compiler Warning (level 1) C4490
Compiler Warning (level 1) C4502
Compiler Warning (level 1) C4503
Compiler Warning (level 4) C4505
Compiler Warning (level 1) C4506
Compiler Warning (level 1) C4508
Compiler Warning (level 4) C4510
Compiler Warning (level 3) C4511
Compiler Warning (level 4) C4512
Compiler Warning (level 4) C4513
Compiler Warning (level 4) C4514
Compiler Warning (level 4) C4515
Compiler Warning (level 4) C4516
Compiler Warning (level 4) C4517
Compiler Warning (level 1) C4518
Compiler Warning (level 3) C4521
Compiler Warning (level 3) C4522
Compiler Warning (level 3) C4523
Compiler Warning (level 1) C4526
Compiler Warning (level 1) C4530
Compiler Warning (level 1) C4532
Compiler Warning (level 1) C4533
Compiler Warning (level 3) C4534
Compiler Warning (level 3) C4535
Compiler Warning (level 4) C4536
Compiler Warning (level 1) C4537
Compiler Warning (level 3) C4538
Compiler Warning (level 1) C4540
Compiler Warning (level 1) C4541
Compiler Warning (level 3) C4543
Compiler Warning (level 1) C4544
Compiler Warning (level 1) C4545
Compiler Warning (level 1) C4546
Compiler Warning (level 1) C4547
Compiler Warning (level 1) C4548
Compiler Warning (level 1) C4549
Compiler Warning (level 1) C4550
Compiler Warning (level 1) C4551
Compiler Warning (level 1) C4552
Compiler Warning (level 1) C4553
Compiler Warning (level 3) C4554
Compiler Warning (level 1) C4555
Compiler Warning (level 1) C4556
Compiler Warning (level 3) C4557
Compiler Warning (level 1) C4558
Compiler Warning (level 4) C4559
Compiler Warning (level 1) C4561
Compiler Warning (level 4) C4564
Compiler Warning (level 4) C4565
Compiler Warning (level 1) C4566
Compiler Warning (level 3) C4570
Compiler Warning (level 4) C4571
Compiler Warning (level 1) C4572
Compiler Warning (level 3) C4580
Compiler Warning (level 1) C4581
Compiler Warning (level 1) C4584
Compiler Warnings C4600 Through C4799
Compiler Warning (level 1) C4600
Compiler Warning (level 1) C4602
Compiler Warning (level 1) C4603
Compiler Warning (level 1) C4606
Compiler Warning (level 3) C4608
Compiler Warning (level 4) C4610
Compiler Warning (level 4) C4611
Compiler Warning (level 1) C4612
Compiler Warning (level 1) C4613
Compiler Warning (level 1) C4615
Compiler Warning (level 1) C4616
Compiler Warning (level 1) C4618
Compiler Warning (level 3) C4619
Compiler Warning (level 1) C4620
Compiler Warning (level 1) C4621
Compiler Warning (level 3) C4622
Compiler Warning (level 4) C4623
Compiler Warning (level 1) C4624
Compiler Warning (level 4) C4625
Compiler Warning (level 4) C4626
Compiler Warning (level 1) C4627
Compiler Warning (level 1) C4628
Compiler Warning (level 4) C4629
Compiler Warning (level 1) C4630
Compiler Warning (level 1) C4631
Compiler Warning (level 1) C4632
Compiler Warning (level 3) C4633
Compiler Warning (level 4) C4634
Compiler Warning (level 3) C4635
Compiler Warning (level 3) C4636
Compiler Warning (level 3) C4637
Compiler Warning (level 3) C4638
Compiler Warning (level 4) C4639
Compiler Warning (level 3) C4640
Compiler Warning (level 3) C4641
Compiler Warning (level 3) C4645
Compiler Warning (level 3) C4646
Compiler Warning (level 1) C4650
Compiler Warning (level 1) C4651
Compiler Warning (level 1) C4652
Compiler Warning (level 2) C4653
Compiler Warning (level 1) C4655
Compiler Warning (level 1) C4656
Compiler Warning (level 1) C4657
Compiler Warning (level 1) C4659
Compiler Warning (level 1) C4661
Compiler Warning (level 1) C4662
Compiler Warning (level 1) C4667
Compiler Warning (level 4) C4668
Compiler Warning (level 1) C4669
Compiler Warning (level 4) C4670
Compiler Warning (level 4) C4672
Compiler Warning (level 4) C4673
Compiler Warning (level 1) C4674
Compiler Warning (level 1) C4677
Compiler Warning (level 1) C4678
Compiler Warning (level 1) C4679
Compiler Warning (level 4) C4680
Compiler Warning (level 4) C4681
Compiler Warning (level 4) C4682
Compiler Warning (level 1) C4683
Compiler Warning (level 1) C4684
Compiler Warning (level 1) C4685
Compiler Warning (level 3) C4686
Compiler Warning C4687
Compiler Warning (level 1) C4688
Compiler Warning (level 4) C4690
Compiler Warning (level 1) C4691
Compiler Warning (level 1) C4692
Compiler Warning C4693
Compiler Warning C4694
Compiler Warning (level 1 and level 4) C4700
Compiler Warning (level 4) C4701
Compiler Warning (level 4) C4702
Compiler Warning (level 4) C4703
Compiler Warning (level 4) C4706
Compiler Warning (level 4) C4709
Compiler Warning (level 4) C4710
Compiler Warning (level 1) C4711
Compiler Warning (level 4) C4714
Compiler Warning (level 1) C4715
Compiler Warning (level 1) C4716
Compiler Warning (level 1) C4717
Compiler Warning (level 4) C4718
Compiler Warning (level 1) C4722
Compiler Warning (level 3) C4723
Compiler Warning (level 3) C4724
Compiler Warning (level 4) C4725
Compiler Warning (level 1) C4727
Compiler Warning (Level 1) C4729
Compiler Warning (Level 1) C4730
Compiler Warning (Level 1) C4731
Compiler Warning (Level 1) C4733
Compiler Warning (Level 3) C4738
Compiler Warning (Level 1) C4739
Compiler Warning (Level 4) C4740
Compiler Warning (Level 1) C4742
Compiler Warning (Level 1) C4743
Compiler Warning (Level 1) C4744
Compiler Warning C4746
Compiler Warning (level 1) C4747
Compiler Warning (level 1) C4750
Compiler Warning (level 4) C4754
Compiler Warning (level 2) C4756
Compiler Warning (level 4) C4764
Compiler Warning (level 1) C4772
Compiler Warning (Level 1) C4788
Compiler Warning (Level 1) C4789
Compiler Warning (level 3) C4792
Compiler Warning (level 1 and 3) C4793
Compiler Warning (level 1) C4794
Compiler Warning (level 1) C4799
Compiler Warnings C4800 Through C5999
Compiler Warning (level 3) C4800
Compiler Warning (level 1) C4803
Compiler Warning (level 1) C4804
Compiler Warning (level 1) C4805
Compiler Warning (level 1) C4806
Compiler Warning (level 1) C4807
Compiler Warning (level 1) C4810
Compiler Warning (level 1) C4811
Compiler Warning (level 1) C4812
Compiler Warning (level 1) C4813
Compiler Warning (level 4) C4816
Compiler Warning (level 1) C4817
Compiler Warning (level 1) C4819
Compiler Warning (level 4) C4820
Compiler Warning (level 1) C4821
Compiler Warning (level 1) C4822
Compiler Warning (level 3) C4823
Compiler Warning (level 1) C4829
Compiler Warning (level 1) C4835
Compiler Warning (level 1) C4838
Compiler Warning (level 3) C4839
Compiler Warning (level 4) C4840
Compiler Warning (level 4) C4866
Compiler Warning C4867
Compiler Warning C4868
Compiler Warning (level 1) C4900
Compiler Warning (level 1) C4905
Compiler Warning (level 1) C4906
Compiler Warning (level 1) C4910
Compiler Warning (level 1) C4912
Compiler Warning (level 4) C4913
Compiler Warning (level 1) C4917
Compiler Warning (level 4) C4918
Compiler Warning (level 1) C4920
Compiler Warning (level 1) C4925
Compiler Warning (level 1) C4926
Compiler Warning (level 1) C4927
Compiler Warning (level 1) C4928
Compiler Warning (level 1) C4929
Compiler Warning (level 1) C4930
Compiler Warning (level 4) C4931
Compiler Warning (level 4) C4932
Compiler Warning (level 1) C4935
Compiler Warning C4936
Compiler Warning (level 4) C4937
Compiler Warning (level 4) C4938
Compiler Warning (level 1) C4939
Compiler Warning (level 1) C4944
Compiler Warning (level 1) C4945
Compiler Warning (level 1) C4946
Compiler Warning (level 1) C4947
Compiler Warning (level 2) C4948
Compiler Warning (level 1 and level 4) C4949
Compiler Warning C4950
Compiler Warning (level 1) C4951
Compiler Warning (level 1) C4952
Compiler Warning (level 1) C4953
Compiler Warning C4956
Compiler Warning C4957
Compiler Warning C4958
Compiler Warning C4959
Compiler Warning (level 4) C4960
Compiler Warning C4961
Compiler Warning C4962
Compiler Warning (level 1) C4964
Compiler Warning (level 1) C4965
Compiler Warning C4972
Compiler Warning (level 4) C4985
Compiler Warning C4986
Compiler Warning (level 3) C4995
Compiler Warning (level 3) C4996
Compiler Warning (level 1) C4997
Compiler Warning (level 1) C4999
Compiler Warning C5038
Compiler Warning C5045
Compiler Warning (level2) C5046
Tool Errors
Vectorizer and Parallelizer Messages
BSCMAKE Errors BK1500 through BK4505
BSCMAKE Error BK1503
BSCMAKE Error BK1504
BSCMAKE Error BK1505
BSCMAKE Error BK1506
BSCMAKE Error BK1507
BSCMAKE Error BK1508
BSCMAKE Error BK1509
BSCMAKE Error BK1510
BSCMAKE Error BK1512
BSCMAKE Error BK1513
BSCMAKE Error BK1514
BSCMAKE Error BK1515
BSCMAKE Error BK1516
BSCMAKE Error BK1517
BSCMAKE Warning BK4502
BSCMAKE Warning BK4503
BSCMAKE Warning BK4504
Expression Evaluator Errors CXX0000 Through CXX0072
Expression Evaluator Error CXX0000
Expression Evaluator Error CXX0001
Expression Evaluator Error CXX0002
Expression Evaluator Error CXX0004
Expression Evaluator Error CXX0005
Expression Evaluator Error CXX0006
Expression Evaluator Error CXX0007
Expression Evaluator Error CXX0008
Expression Evaluator Error CXX0009
Expression Evaluator Error CXX0010
Expression Evaluator Error CXX0011
Expression Evaluator Error CXX0012
Expression Evaluator Error CXX0013
Expression Evaluator Error CXX0014
Expression Evaluator Error CXX0015
Expression Evaluator Error CXX0016
Expression Evaluator Error CXX0017
Expression Evaluator Error CXX0018
Expression Evaluator Error CXX0019
Expression Evaluator Error CXX0020
Expression Evaluator Error CXX0021
Expression Evaluator Error CXX0022
Expression Evaluator Error CXX0023
Expression Evaluator Error CXX0024
Expression Evaluator Error CXX0025
Expression Evaluator Error CXX0026
Expression Evaluator Error CXX0027
Expression Evaluator Error CXX0028
Expression Evaluator Error CXX0029
Expression Evaluator Error CXX0030
Expression Evaluator Error CXX0031
Expression Evaluator Error CXX0032
Expression Evaluator Error CXX0033
Expression Evaluator Error CXX0034
Expression Evaluator Error CXX0036
Expression Evaluator Error CXX0037
Expression Evaluator Error CXX0038
Expression Evaluator Error CXX0039
Expression Evaluator Error CXX0040
Expression Evaluator Error CXX0041
Expression Evaluator Error CXX0043
Expression Evaluator Error CXX0044
Expression Evaluator Error CXX0045
Expression Evaluator Error CXX0046
Expression Evaluator Error CXX0047
Expression Evaluator Error CXX0048
Expression Evaluator Error CXX0049
Expression Evaluator Error CXX0050
Expression Evaluator Error CXX0051
Expression Evaluator Error CXX0052
Expression Evaluator Error CXX0053
Expression Evaluator Error CXX0054
Expression Evaluator Error CXX0055
Expression Evaluator Error CXX0056
Expression Evaluator Error CXX0057
Expression Evaluator Error CXX0058
Expression Evaluator Error CXX0059
Expression Evaluator Error CXX0060
Expression Evaluator Error CXX0061
Expression Evaluator Error CXX0062
Expression Evaluator Error CXX0063
Expression Evaluator Error CXX0064
Expression Evaluator Error CXX0065
Expression Evaluator Error CXX0066
Expression Evaluator Error CXX0067
Expression Evaluator Error CXX0069
Expression Evaluator Error CXX0072
Command-Line Errors D8000 Through D9999
Command-Line Error D8016
Command-Line Error D8021
Command-Line Error D8022
Command-Line Error D8027
Command-Line Error D8036
Command-Line Error D8037
Command-Line Error D8045
Command-Line Warning D9024
Command-Line Warning D9025
Command-Line Warning D9026
Command-Line Warning D9027
Command-Line Warning D9028
Command-Line Warning D9035
Command-Line Warning D9036
Command-Line Warning D9040
Command-Line Warning D9041
Command-Line Warning D9043
Linker Tools Errors and Warnings
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
Name Decoration
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
Global Constants in C++
Function Inlining Problems
Automatic (Function Scope) Variables
Missing Function Body or Variable
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 LNK2038
Linker Tools Error LNK2039
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 LNK4037
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
Profile-Guided Optimization Errors and Warnings
Profile-Guided Optimization Warning PG1039
Profile-Guided Optimization Warning PG1087
Profile-Guided Optimization Error PG0165
Math Errors M6101 through M6205
Math Error M6101
Math Error M6102
Math Error M6107
Math Error M6108
Math Error M6110
Math Error M6111
Math Error M6201
Math Error M6202
Math Error M6203
Math Error M6205
NMAKE Errors U1000 through U4011
NMAKE Fatal Error U1000
NMAKE Fatal Error U1001
NMAKE Fatal Error U1007
NMAKE Fatal Error U1023
NMAKE Fatal Error U1033
NMAKE Fatal Error U1034
NMAKE Fatal Error U1035
NMAKE Fatal Error U1036
NMAKE Fatal Error U1045
NMAKE Fatal Error U1050
NMAKE Fatal Error U1051
NMAKE Fatal Error U1052
NMAKE Fatal Error U1055
NMAKE Fatal Error U1056
NMAKE Fatal Error U1059
NMAKE Fatal Error U1064
NMAKE Fatal Error U1065
NMAKE Fatal Error U1070
NMAKE Fatal Error U1071
NMAKE Fatal Error U1073
NMAKE Fatal Error U1076
NMAKE Fatal Error U1077
NMAKE Fatal Error U1078
NMAKE Fatal Error U1083
NMAKE Fatal Error U1086
NMAKE Fatal Error U1087
NMAKE Fatal Error U1088
NMAKE Fatal Error U1095
NMAKE Fatal Error U1097
NMAKE Fatal Error U1099
NMAKE Fatal Error U1100
NMAKE Warning U4001
NMAKE Warning U4004
NMAKE Warning U4006
NMAKE Warning U4007
NMAKE Warning U4010
NMAKE Warning U4011
C Runtime Errors R6002 through R6035
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 R6026
C Runtime Error R6027
C Runtime Error R6028
C Runtime Error R6030
C Runtime Error R6031
C Runtime Error R6032
C Runtime Error R6033
C Runtime Error R6035
Resource Compiler Errors RC1000 through RC4413
Resource Compiler Fatal Error RC1002
Resource Compiler Fatal Error RC1004
Resource Compiler Fatal Error RC1009
Resource Compiler Fatal Error RC1011
Resource Compiler Fatal Error RC1015
Resource Compiler Fatal Error RC1017
Resource Compiler Fatal Error RC1018
Resource Compiler Fatal Error RC1019
Resource Compiler Fatal Error RC1020
Resource Compiler Fatal Error RC1021
Resource Compiler Fatal Error RC1022
Resource Compiler Fatal Error RC1047
Resource Compiler Fatal Error RC1052
Resource Compiler Fatal Error RC1067
Resource Compiler Fatal Error RC1101
Resource Compiler Fatal Error RC1102
Resource Compiler Fatal Error RC1105
Resource Compiler Fatal Error RC1109
Resource Compiler Fatal Error RC1116
Resource Compiler Fatal Error RC1120
Resource Compiler Fatal Error RC1121
Resource Compiler Fatal Error RC1203
Resource Compiler Fatal Error RC1205
Resource Compiler Fatal Error RC1208
Resource Compiler Error RC2001
Resource Compiler Error RC2007
Resource Compiler Error RC2015
Resource Compiler Error RC2017
Resource Compiler Error RC2101
Resource Compiler Error RC2103
Resource Compiler Error RC2104
Resource Compiler Error RC2107
Resource Compiler Error RC2109
Resource Compiler Error RC2111
Resource Compiler Error RC2112
Resource Compiler Error RC2113
Resource Compiler Error RC2114
Resource Compiler Error RC2116
Resource Compiler Error RC2122
Resource Compiler Error RC2124
Resource Compiler Error RC2127
Resource Compiler Error RC2135
Resource Compiler Error RC2144
Resource Compiler Error RC2147
Resource Compiler Error RC2148
Resource Compiler Error RC2151
Resource Compiler Error RC2152
Resource Compiler Error RC2162
Resource Compiler Error RC2163
Resource Compiler Error RC2164
Resource Compiler Error RC2165
Resource Compiler Error RC2167
Resource Compiler Error RC2169
Resource Compiler Error RC2170
Resource Compiler Error RC2171
Resource Compiler Error RC2175
Resource Compiler Warning RC4002
Resource Compiler Warning RC4005
Resource Compiler Warning RC4093
Resource Compiler Warning RC4214
Resource Compiler Errors RW1004 through RW4004
Resource Compiler Fatal Error RW1004
Resource Compiler Fatal Error RW1009
Resource Compiler Fatal Error RW1016
Resource Compiler Fatal Error RW1022
Resource Compiler Fatal Error RW1023
Resource Compiler Fatal Error RW1025
Resource Compiler Fatal Error RW1030
Resource Compiler Error RW2001
Resource Compiler Error RW2002
Resource Compiler Error RW2003
Resource Compiler Warning RW4001
Resource Compiler Warning RW4003
Resource Compiler Warning RW4004
CVTRES Errors CVT1100 Through CVT4001
CVTRES Fatal Error CVT1100
CVTRES Fatal Error CVT1103
CVTRES Fatal Error CVT1105
CVTRES Warning CVT4001
Project Build Errors and Warnings (PRJxxxx)
Project Build Error PRJ0002
Project Build Error PRJ0003
Project Build Error PRJ0004
Project Build Error PRJ0005
Project Build Error PRJ0006
Project Build Error PRJ0007
Project Build Error PRJ0008
Project Build Error PRJ0009
Project Build Error PRJ0013
Project Build Error PRJ0014
Project Build Error PRJ0015
Project Build Error PRJ0016
Project Build Error PRJ0017
Project Build Warning PRJ0018
Project Build Error PRJ0019
Project Build Error PRJ0020
Project Build Error PRJ0021
Project Build Error PRJ0022
Project Build Error PRJ0023
Project Build Error PRJ0024
Project Build Error PRJ0025
Project Build Error PRJ0026
Project Build Error PRJ0027
Project Build Error PRJ0028
Project Build Warning PRJ0029
Project Build Error PRJ0030
Project Build Error PRJ0031
Project Build Error PRJ0032
Project Build Error PRJ0033
Project Build Error PRJ0034
Project Build Error PRJ0035
Project Build Error PRJ0036
Project Build Error PRJ0040
Project Build Warning PRJ0041
Project Build Warning PRJ0042
Project Build Error PRJ0044
Project Build Error PRJ0046
Project Build Error PRJ0047
Project Build Warning PRJ0049
Project Build Error PRJ0050
XML Documentation for C++
Recommended Tags for C++ Documentation Comments
<c>
<code>
<example>
<exception>
<include>
<list>
<para>
<param>
<paramref>
<permission>
<remarks>
<returns>
<see>
<seealso>
<summary>
<value>
.Xml File Processing
Delimiters for C++ Documentation Tags
C/C++ Building Reference
3/12/2019 • 2 minutes to read • Edit Online

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.

Support File Directories


By default, the primary Visual Studio support files are located in the following directories. The directories under
Microsoft Visual Studio are used by Visual Studio 2017 and later versions, while the directories under MSBuild are
used by Visual Studio 2015 and earlier versions.

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.

For more information, see Target Element (MSBuild).

.props Contains Property Group and user-defined Property XML


elements that specify file and parameter settings that are used
during a build.

May also contain ItemDefinitionGroup and user-defined


Item XML elements that specify additional settings. Items
defined in an item definition group resemble properties, but
cannot be accessed from the command line. Visual Studio
project files frequently use items instead of properties to
represent settings.

For more information, see ItemGroup Element (MSBuild),

ItemDefinitionGroup Element (MSBuild), and Item Element


(MSBuild).
EX TENSION DESCRIPTION

.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.

Most .xml files are in a locale-specific subdirectory. For


example, files for the English-US region are in
$(VCTargetsPath)\1033\.

User targets and properties


To use MSBuild most effectively on the command line, it helps to know which properties and targets are useful and
relevant. Most properties and targets help implement the Visual Studio build system, and consequently are not
relevant to the user. This section describes some worthwhile user-oriented properties and targets.
PlatformToolset property
The PlatformToolset property determines which MSVC toolset is used in the build. By default, the current toolset
is used. When this property is set, the value of the property is concatenated with literal strings to form the path of a
directory that contains the property and target files that are required to build a project for a particular platform.
The platform toolset must be installed to build by using that platform toolset version.
For example, set the PlatformToolset property to v140 to use Visual Studio 2015 tools and libraries to build your
application:
msbuild myProject.vcxproj /p:PlatformToolset=v140

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

BscMake Executes the Microsoft Browse Information Maintenance


Utility tool, bscmake.exe.

Build Builds the project.

This is the default target for a project.

ClCompile Executes the MSVC compiler tool, cl.exe.

Clean Deletes temporary and intermediate build files.

Lib Executes the Microsoft 32-Bit Library Manager tool, lib.exe.

Link Executes the MSVC linker tool, link.exe.

ManifestResourceCompile Extracts a list of resources from a manifest and then executes


the Microsoft Windows Resource Compiler tool, rc.exe.

Midl Executes the Microsoft Interface Definition Language (MIDL)


compiler tool, midl.exe.

Rebuild Cleans and then builds your project.

ResourceCompile Executes the Microsoft Windows Resource Compiler tool,


rc.exe.

XdcMake Executes the XML Documentation tool, xdcmake.exe.

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.

View the current properties and macros


To display the currently available macros, on any property page in the Property Pages dialog, choose the drop-
down arrow at the end of a property row. If Edit is available, choose it, and then in the edit dialog box, choose the
Macros button. The current set of properties and macros visible to Visual Studio is listed along with the current
value for each. For more information, see the Specifying User-Defined Values section of C++ project property
page reference.

List of common macros


This table describes a commonly used subset of the available macros. This list is far from exhaustive. For details on
how MSBuild property definitions are created and used as macros in .props, .targets, and .vcxproj files, see
MSBuild Properties.

MACRO DESCRIPTION

$(Configuration) The name of the current project configuration, for example,


"Debug".

$(DevEnvDir) The installation directory of Visual Studio (defined as drive +


path); includes the trailing backslash '\'.

$(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.

$(FrameworkVersion) The version of the .NET Framework used by Visual Studio.


Combined with $(FrameworkDir), the full path to the
version of the .NET Framework use by Visual Studio.

$(FxCopDir) The path to the fxcop.cmd file. The fxcop.cmd file is not
installed with all Visual C++ editions.

$(IntDir) Path to the directory specified for intermediate files. If this is a


relative path, intermediate files go to this path appended to
the project directory. This path should have a trailing slash.
This resolves to the value for the Intermediate Directory
property. Do not use $(OutDir) to define this property.
MACRO DESCRIPTION

$(OutDir) Path to the output file directory. If this is a relative path,


output files go to this path appended to the project directory.
This path should have a trailing slash. This resolves to the
value for the Output Directory property. Do not use
$(IntDir) to define this property.

$(Platform) The name of current project platform, for example, "Win32".

$(ProjectDir) The directory of the project (defined as drive + path); includes


the trailing backslash '\'.

$(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).

$(ProjectName) The base name of the project.

$(ProjectPath) The absolute path name of the project (defined as drive +


path + base name + file extension).

$(RemoteMachine) Set to the value of the Remote Machine property on the


Debug property page. See Changing Project Settings for a
C/C++ Debug Configuration for more information.

$(RootNameSpace) The namespace, if any, containing the application.

$(SolutionDir) The directory of the solution (defined as drive + path);


includes the trailing backslash '\'. Defined only when building
a solution in the IDE.

$(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.

$(SolutionPath) The absolute path name of the solution (defined as drive +


path + base name + file extension). 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.

$(WebDeployRoot) The absolute path to the location of <localhost>. For


example, c:\inetpub\wwwroot.

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

$(InputDir) (Migrated.) The directory of the input file (defined as drive +


path); includes the trailing backslash '\'. If the project is the
input, then this macro is equivalent to $(ProjectDir).

$(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.

Project and Solution Files

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.

FILE EX TENSION TYPE CONTENTS

.asmx Source Deployment file.

.asp Source Active Server Page file.

.atp Project Application template project file.

.bmp, .dib, .gif, .jpg, .jpe, .png Resource General image files.

.bsc Compiling The browser code file.

.cpp; .c Source Main source code files for your


application.

.cur Resource Cursor bitmap graphic file.

.dbp Project Database project file.


FILE EX TENSION TYPE CONTENTS

.disco Source The dynamic discovery document file.


Handles XML Web service discovery.

.exe, .dll Project Executable or dynamic-link library files.

.h Source A header (include) file.

.htm, .html, .xsp, .asp, .htc, .hta, .xml Resource Common Web files.

.HxC Project Help project file.

.ico Resource Icon bitmap graphic file.

.idb Compiling The state file, containing dependency


information between source files and
class definitions, which can be used by
the compiler during minimal rebuild
and incremental compilation. Use the
/Fd compiler option to specify the name
of the .idb file. See /Gm (Enable Minimal
Rebuild) for more information.

.idl Compiling An interface definition language file. See


Interface Definition (IDL) File in the
Windows SDK for more information.

.ilk Linking Incremental link file. See


/INCREMENTAL for more information.

.map Linking A text file containing linker information.


Use the /Fm compiler option to name
the map file. See /MAP for more
information.

.mfcribbon-ms Resource A resource file that contains the XML


code that defines the buttons, controls,
and attributes in the ribbon. For more
information, see Ribbon Designer
(MFC).

.obj, .o Object files, compiled but not linked.

.pch Debug Precompiled header file.

.rc, .rc2 Resource Resource script files to generate


resources.

.sbr Compiling Source browser intermediate file. The


input file for BSCMAKE.

.sln Solution The solution file.

.suo Solution The solution options file.


FILE EX TENSION TYPE CONTENTS

.txt Resource A text file, usually the "readme" file.

.vap Project A Visual Studio Analyzer project file.

.vbg Solution A compatible project group file.

.vbp, .vip, .vbproj Project The Visual Basic project file.

.vcxitems Project Shared Items project for sharing code


files between multiple C++ projects.
See for more information.
Project Files and Makef iles

.vcxproj Project The Visual Studio project file. See for


Project Files and Makef iles

more information.

.vcxproj.filters Project When Solution Explorer is used to add a


file to a project, the filters file defines
where in the Solution Explorer tree view
the file is added, based on its file name
extension.

.vdproj Project The Visual Studio deployment project


file.

.vmx Project The macro project file.

.vup Project The utility project file.

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

Solname.sln Projname Not displayed in Solution The solution file. It organizes


Explorer all elements of a project or
multiple projects into one
solution.

Projname.suo Projname Not displayed in Solution The solution options file. It


Explorer stores your customizations
for the solution so that
every time you open a
project or file in the solution,
it has the appearance and
behavior you want.

Projname.vcxproj Projname Not displayed in Solution The project file. It stores


Explorer information specific to each
project. (In earlier versions,
this file was named
Projname.vcproj or
Projname.dsp.) For an
example of a Visual C++
project file, see Project Files.

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.sdf Projname Not displayed in Solution The browsing database file.


Explorer It supports browsing and
navigation features such as
Goto Definition, Find All
References, and Class
View. It is generated by
parsing the header files.

Projname.vcxproj.filters Projname Not displayed in Solution The filters file. It specifies


Explorer where to put a file that is
added to the solution. For
example, a .h file is put in the
Header Files node.
SOLUTION EXPLORER
FILENAME DIRECTORY LOCATION LOCATION DESCRIPTION

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.

Projname.idl Projname Source (Project-specific) Contains


the Interface Description
Language (IDL) source code
for a control type library.
This file is used by Visual
C++ to generate a type
library. The generated library
exposes the interface of the
control to other Automation
clients. For more
information, see Interface
Definition (IDL) File in the
Windows SDK.

Readme.txt Projname Project The read me file. It is


generated by the application
wizard and describes the files
in a project.

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 Console Application A project for creating a Windows console application.

Windows Desktop Application A project for creating a Windows desktop (Win32) application.

Dynamic-Link Library A project for creating a dynamic-link library (DLL).

Static Library A project for creating a static library (LIB).

Windows Desktop Wizard A wizard for creating Windows desktop applications and
libraries with additional options.

General
PROJECT TEMPLATE DESCRIPTION

Empty Project An empty project for creating an application, library, or DLL.


You must add any code or resources required.

Makefile Project A project that wraps a Windows makefile in a Visual Studio


project. (To open a makefile as-is in Visual Studio, use Open
Folder.

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

ATL Project A project that uses the Active Template Library.

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.

PROJECT TEMPLATE DESCRIPTION

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.

Windows Universal Apps


If you add the C++ Windows Universal Platform tools component to your Visual Studio installation, these project
templates are added to Visual Studio.
For an overview of Windows Universal apps in C++, see Universal Windows Apps (C++).

PROJECT TEMPLATE DESCRIPTION

Blank App A project for a single-page Universal Windows Platform (UWP)


app that has no predefined controls or layout.

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.

DLL A project for a native dynamic-link library (DLL) that can be


used by a Universal Windows Platform app or runtime
component.
PROJECT TEMPLATE DESCRIPTION

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

Assembly Resource File (.resx) Creates a file containing CLR resources.

Bitmap File (.bmp) Creates a Win32 bitmap file.

C++ File (.cpp) Creates a C++ source file.

Class Diagram (.cd) Creates an empty class diagram.

Code Analysis Rule Set (.ruleset) Creates a settings file for configuring Code Analysis.

Configuration File (app.config) Creates an empty configuration file.

Component Class Adds a Component Class using CLR features.

Cursor File (.cur) Creates a Win32 cursor file.

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.

Header File (.h) Creates a C++ header file.

HTML Page (.htm) Creates a blank HTML file.

Icon File (.ico) Creates a Win32 icon file.

Installer Class Adds a class that inherits from the Installer using CLR features.

MIDL File (.idl) Creates an Interface Definition Language file.

Module-Definition File (.def) Creates a DLL export definition file.

Property Sheet (.props) Creates a Visual C++ property sheet file.

Registration Script (.rgs) Creates an ATL registration script file.


TEMPLATE DESCRIPTION

Report (.rdlc) Creates a report file.

Resource File (.rc) Creates a Win32 resource file.

Resource Template File (.rct) Creates a resource template file.

Ribbon (.mfcribbon-ms) Creates a ribbon file.

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.

Text File (.txt) Adds a blank text file.

User Control Adds a User Control using CLR features.

Windows Form Adds a Windows Form using CLR features.

XML File (.xml) Adds a blank XML file.

XML Schema File (.xsd) Creates a file that is used to define a schema for XML
documents.

XSLT File (.xslt) Creates a file used to transform 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.rc Projname Source Files The resource script file for


the project. The resource
script file contains the
following, depending on the
type of project, and the
support selected for the
project (for example,
toolbars, dialog boxes, or
HTML):

- Default menu definition.


- Accelerator and string
tables.
- Default About dialog box.
- Other dialog boxes.
- Icon file (res\Projname.ico).
- Version information.
- Bitmaps.
- Toolbar.
- HTML files.

The resource file includes the


file Afxres.rc for standard
Microsoft Foundation Class
resources.

Resource.h Projname Header Files The resource header file that


includes definitions for the
resources used by the
project.
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION

Projname.rc2 Projname\res Source Files The script file containing


additional resources used by
the project. You can include
the .rc2 file under the
project's .rc file.

An .rc2 file is useful for


including resources used by
several different projects.
Instead of having to create
the same resources several
times for different projects,
you can put them in an .rc2
file and include the .rc2 file
into the main .rc file.

Projname.def Projname Source Files The module definition file for


a DLL project. For a control,
it provides the name and
description of the control, as
well as the size of the run-
time heap.

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.

ProjnameDoc.ico Projname\res Resource Files The icon file for an MFC


project that includes support
for the document/view
architecture.

Toolbar.bmp Projname\res Resource Files The bitmap file representing


the application or control in
a toolbar or palette. This
bitmap is included in the
project's resource file. The
initial toolbar and status bar
are constructed in the
CMainFrame class.

ribbon.mfcribbon-ms Projname\res Resource Files The resource file that


contains the XML code that
defines the buttons,
controls, and attributes in
the ribbon. For more
information, see Ribbon
Designer (MFC).

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.

FILE NAME FILE DESCRIPTION

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.asmx A text file that references managed classes that encapsulate


the functionality of the XML Web service.

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.vsdisco An XML deployment file containing links to other resources


that describe the XML Web service.

projname.h The main include file for the project, which contains all
declarations, global symbols, and #include directives for
other header files.

projname.sln The solution file used within the development environment to


organize all elements of your project into a single solution.

projname.suo The solution options file used within the development


environment.

projname.vcxproj The project file used within the development environment


that stores the information specific to this project.

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.

FILE NAME DESCRIPTION

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.

Projname.cpp The main program source file. It contains the implementation


of your DLL's exports for an in-process server and the
implementation of WinMain for a local server. For a service,
this additionally implements all the service management
functions.

Resource.h The header file for the resource file.

StdAfx.cpp Includes the files StdAfx.h and Atlimpl.cpp.

StdAfx.h Includes the ATL header files.

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.

FILE NAME DESCRIPTION

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.

For executables, CPrjnameApp::InitInstance does several


things. It registers document templates, which serve as a
connection between documents and views; creates a main
frame window; and creates an empty document (or opens a
document if one is specified as a command-line argument to
the application).

For DLLs and ActiveX (formerly OLE) controls,


CProjNameApp::InitInstance registers the control's object
factory with OLE by calling
COleObjectFactory::RegisterAll and makes a call to
AfxOLEInit . In addition, the member function
CProjNameApp::ExitInstance is used to unload the control
from memory with a call to AfxOleTerm.

This file also registers and unregisters the control in the


Windows registration database by implementing the
DllRegisterServer and DllUnregisterServer functions.

Projnamectrl.h, Projnamectrl.cpp Declare and implement the CProjnameCtrl class.


CProjnameCtrl is derived from COleControl , and skeleton
implementations of some member functions are defined that
initialize, draw, and serialize (load and save) the control.
Message, event, and dispatch maps are also defined.

Projnamedlg.cpp, Projnamedlg.h Created if you choose a dialog-based application. The files


derive and implement the dialog class, named CProjnameDlg
, and include skeleton member functions to initialize a dialog
and perform dialog data exchange (DDX). Your About dialog
class is also placed in these files instead of in Projname.cpp.
FILE NAME DESCRIPTION

Dlgproxy.cpp, Dlgproxy.h In a dialog-based program, the implementation and header


file for the project's Automation proxy class for the main
dialog. This is only used if you have chosen Automation
support.

Projnamedoc.cpp, Projnamedoc.h Derive and implement the document class, named


CProjnameDoc , and include skeleton member functions to
initialize a document, serialize (save and load) a document,
and implement debugging diagnostics.

Projnameset.h/.cpp Created if you create a program that supports a database and


contains the recordset class.

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

The project's view class contains skeleton member functions to


draw the view and implement debugging diagnostics. If you
have enabled support for printing, then message-map entries
are added for print, print setup, and print preview command
messages. These entries call the corresponding member
functions in the base view class.

ProjnamePropPage.h, ProjnamePropPage.cpp Declare and implement the CProjnamePropPage class.


CProjnamePropPage is derived from COlePropertyPage and
a skeleton member function, DoDataExchange , is provided to
implement data exchange and validation.

IPframe.cpp, IPframe.h Created if the Mini-Server or Full-Server option is selected in


the application wizard's Automation Options page (step 3 of
6). The files derive and implement the in-place frame window
class, named CInPlaceFrame, used when the server is in
place activated by a container program.

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

Childfrm.cpp, Childfrm.h Derive the CChildFrame class from CMDIChildWnd. The


CChildFrame class is used for MDI document frame windows.
These files are always created if you select the MDI option.

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

Projname.hhp Projname\hlp HTML Help files The help project file. It


contains the data needed to
compile the help files into an
.hxs file or a .chm file.

Projname.hhk Projname\hlp HTML Help files Contains an index of the


help topics.

Projname.hhc Projname\hlp HTML Help files The contents of the help


project.

Makehtmlhelp.bat Projname Source Files Used by the system to build


the Help project when the
project is compiled.

Afxcore.htm Projname\hlp HTML Help Topics Contains the standard help


topics for standard MFC
commands and screen
objects. Add your own help
topics to this file.

Afxprint.htm Projname\hlp HTML Help Topics Contains the help topics for
the printing commands.

*.jpg; *.gif Projname\hlp\Images Resource Files Contain images for the


different generated help file
topics.

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

Projname.hpj Projname\hlp Source Files The Help project file used by


the Help compiler to create
your program or control's
Help file.

Projname.rtf Projname\hlp Help Files Contains template topics


that you can edit and
information on customizing
your .hpj file.

Projname.cnt Projname\hlp Help Files Provides the structure for


the Contents window in
Windows Help.

Makehelp.bat Projname Source Files Used by the system to build


the Help project when the
project is compiled.

Print.rtf Projname\hlp Help Files Created if your project


includes printing support
(the default). Describes the
printing commands and
dialog boxes.

*.bmp Projname\hlp Resource Files Contain images for the


different generated help file
topics.

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

Projname.hpj Projname\hlp Source files The project file used by the


Help compiler to create your
program or control's Help
file.

Projname.rtf Projname\hlp Project Contains template topics


that you can edit and
information on customizing
your .hpj file.
SOLUTION EXPLORER
FILE NAME DIRECTORY LOCATION LOCATION DESCRIPTION

Makehelp.bat Projname Source Files Used by the system to build


the Help project when the
project is compiled.

Bullet.bmp Projname Resource Files Used by standard Help file


topics to represent bulleted
lists.

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

Macros that contain unbalanced brackets

#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.

Display Browsing Database Errors


The Project > Display Browsing Database Errors menu command displays all the regions that failed to parse in
the Error List. The command is meant to streamline building the initial hint file. However, the parser can't tell if the
cause of the error was a disruptive macro, so you must evaluate each error. Run the Display Browsing Database
Errors command and navigate to each error to load the affected file in the editor. Once the file is loaded, if any
macros are inside the region, they're highlighted. You can invoke the Quick Actions to add them to a hint file. After
a hint file update, the error list is updated automatically. Alternatively, if you're modifying the hint file manually you
can use the Rescan Solution command to trigger an update.

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.

The second syntax form defines a function-like hint. If a


function-like hint occurs in source code, the preprocessor first
replaces each occurrence of parameter in replacement-string
with the corresponding argument in source code, and then
replaces hint-name with replacement-string.

@< A hint-file specific replacement-string that indicates the start


of a set of map elements.

@= A hint-file specific replacement-string that indicates an


intermediate map element. A map can have multiple map
elements.

@> A hint-file specific replacement-string that indicates the end


of a set of map elements.

#undef hint-name The preprocessor directive that deletes an existing hint. The
name of the hint is provided by the hint-name identifier.

// comment A single-line comment.

/* comment */ A multiline comment.

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.

Hint File Directories

Directories and Hint File Contents


This list shows the directories in this project that contain hint files, and the contents of those hint files. Only some
of the many hints in the vcpackages directory hint file are listed:
vcpackages
// vcpackages (partial list)
#define _In_
#define _In_opt_
#define _In_z_
#define _In_opt_z_
#define _In_count_(size)

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:

// vcpackages (partial list)


#define _In_opt_
#define _In_z_
#define _In_opt_z_
#define _In_count_(size)
// Debug...
#define RAISE_EXCEPTION(x) throw (x)
// A1
#define START_NAMESPACE namespace A1Namespace {
// ...Debug
#define END_NAMESPACE }

These notes apply to the preceding list:


The effective hints are from the vcpackages , Debug , A1 , and A2 directories.
The #undef directive in the Debug hint file removed the #define _In_ hint in the vcpackages directory hint
file.
The hint file in the A1 directory redefines START_NAMESPACE .
The #undef hint in the A2 directory removed the hints for OBRACE and CBRACE in the Debug directory hint
file.

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:

<PropertyPageSchema Condition="'$(ConfigurationType)' != 'Utility'"


Include="$(VCTargetsPath)$(LangID)\cl.xml"/>

If you strip cl.xml of all data, you will end up with the following skeleton:

<?xml version="1.0" encoding="utf-8"?>


<Rule>
<Rule.DataSource />
<Rule.Categories>
<Category />
...
</Rule.Categories>
<BoolProperty />
<EnumProperty />
<IntProperty />
<StringProperty />
<StringListProperty />
</Rule>

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:

<Rule Name="CL" PageTemplate="tool" 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.DisplayName>
<sys:String>C/C++</sys:String>
</Rule.DisplayName>

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:

<DataSource Persistence="ProjectFile" ItemType="ClCompile" Label="" HasConfigurationCondition="true" />

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.

.vcxproj file elements


You can inspect the contents of a .vcxproj file by using any text or XML editor. You can view it in Visual Studio by
right-clicking on the project in Solution Explorer, choosing Unload project and then choosing Edit Foo.vcxproj.
The first thing to notice is that the top-level elements appear in a particular order. For example:
Most of the property groups and item definition groups occur after the import for
Microsoft.Cpp.Default.props.
All targets are imported at the end of the file.
There are multiple property groups, each with a unique label, and they occur in a particular order.
The order of elements in the project file is very important, because MSBuild is based on a sequential evaluation
model. If your project file, including all the imported .props and .targets files, consists of multiple definitions of a
property, the last definition overrides the preceding ones. In the following example, the value "xyz” will be set
during compilation because the MSBUild engine encounters it last during its evaluation.

<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.

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>


<ItemGroup Label="ProjectConfigurations" />
<PropertyGroup Label="Globals" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
<PropertyGroup Label="Configuration" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup />
<ItemGroup />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

The following sections describe the purpose of each of these elements and why they are ordered this way:
Project element

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'


>

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

<ItemGroup Label="ProjectConfigurations" />

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

<PropertyGroup Label="Globals" />

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

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />

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

<PropertyGroup Label="Configuration" />

A Configuration property group has an attached configuration condition (such as


Condition=”'$(Configuration)|$(Platform)'=='Debug|Win32'” ) and comes in multiple copies, one per configuration.
This property group hosts the properties that are set for a specific configuration. Configuration properties include
PlatformToolset and also control the inclusion of system property sheets in Microsoft.Cpp.props. For example, if
you define the property <CharacterSet>Unicode</CharacterSet> , then the system property sheet
microsoft.Cpp.unicodesupport.props will be included. If you inspect Microsoft.Cpp.props, you will see the
line:
<Import Condition=”'$(CharacterSet)' == 'Unicode'”
Project=”$(VCTargetsPath)\microsoft.Cpp.unicodesupport.props”/>
.
Microsoft.Cpp.props Import element

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

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

<ImportGroup Label="ExtensionSettings" />

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

<ImportGroup Label="PropertySheets" />

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

<PropertyGroup Label="UserMacros" />

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>

References are specified in an ItemGroup, and they have these limitations:


References do not support conditions.
References metadata do not support conditions.
Microsoft.Cpp.targets Import element

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

Defines (directly or via imports) Visual C++ targets such as build, clean, etc.
ExtensionTargets ImportGroup element

<ImportGroup Label="ExtensionTargets" />

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.

How the IDE uses element labels


In the IDE, when you set the UseOfAtl property in the general property page, it is written to the Configuration
property group in the project file, while the TargetName property in the same property page is written to the
label-less per-configuration property group. Visual Studio looks at the property page's xml file for the information
on where to write each property. For the General property page (assuming you have an English version of Visual
Studio Enterprise Edition), that file is
%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\1033\general.xml . The
property page XML rule file defines the static information about a Rule and all its properties. One such piece of
information is the preferred position of a Rule property in the destination file (the file where its value will be
written). The preferred position is specified by the Label attribute on the project file elements.

Property Sheet layout


The following XML snippet is a minimal layout of a property sheet (.props) file. It is similar to a .vcxproj file, and the
functionality of the .props elements can be inferred from the earlier discussion.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup />
<ItemGroup />
</Project>

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.

<?xml version="1.0" encoding="utf-8"?>


<Project DefaultTargets="Build" ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{96F21549-A7BF-4695-A1B1-B43625B91A14}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SomeProjName</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>true</MinimalRebuild>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SomeProjName.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

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.

You now see a dialog box like this:


Use this dialog to view the current directories. However, if you want to change or add a directory, it is better to
use Property Manager to create a property sheet or modify the default user property sheet. For more
information, see Share or resuse Visual Studio C++ project settings.
As shown above, many of the inherited paths are given as macros. To examine the current value of a macro,
choose the Macros button in the lower right corner of the dialog box. Note that many macros depend on the
configuration type. A macro in a debug build might evaluate to a different path than the same macro in a release
build.
You can search for partial or complete matches in the edit box. The following illustration shows all the macros that
contain the string "WindowsSDK" and it also shows the current path that the macro evaluates to:

Note: The list is populated as you type. Don't press Enter.


For more information about macros and why you should use them instead of hard-coded paths whenever
possible, see Set C++ compiler and build properties in Visual Studio.
For a list of commonly used macros, see Common macros for build commands and properties.
You can define your own macros in two ways:
Set environment variables in a developer command prompt. All environment variables are treated as
MSBuild properties/macros.
Define user macros in a .props file. For more information, see Property page macros.
For more information, see these blog posts: VC++ Directories, Inherited Properties and Property Sheets, and
Visual Studio 2010 C++ Project Upgrade Guide.

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.

Sharing the Settings


You can share project properties with other users or across multiple computers. For more information, see Set
C++ compiler and build properties in Visual Studio.
Command Line Property Pages
3/12/2019 • 2 minutes to read • Edit Online

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++).

General page properties


Ignore Import Library
This property tells the linker not to link any .lib output generated from this build into any dependent project. This
allows the project system to handle .dll files that do not produce a .lib file when built. If a project depends on
another project that produces a DLL, the project system automatically links the .lib file produced by that child
project. This may not be needed by projects that are producing COM DLLs or resource-only DLLs; these DLLs do
not have any meaningful exports. If a DLL has no exports, the linker does not generate a .lib file. If no export .lib
file is present on the disk, and the project system tells the linker to link with this (missing) DLL, the link fails. Use
the Ignore Import Library property to resolve this problem. When set to Yes, the project system ignores the
presence or absence of that .lib file and causes any project that depends on this project to not link with the
nonexistent .lib file.
To programmatically access this property, see IgnoreImportLibrary.
Register Output
Runs regsvr32.exe /s $(TargetPath) on the build output, which is valid only on .dll projects. For .exe projects, this
property is ignored. To register an .exe output, set a postbuild event on the configuration to do the custom
registration that is always required for registered .exe files.
To programmatically access this property, see RegisterOutput.
Per-user Redirection
Registration in Visual Studio has traditionally been done in HKEY_CLASSES_ROOT (HKCR ). With Windows Vista
and later operating systems, to access HKCR you must run Visual Studio in elevated mode. Developers do not
always want to run in elevated mode but still must work with registration. Per-user redirection allows you to
register without having to run in this mode.
Per-user redirection forces any writes to HKCR to be redirected to HKEY_CURRENT_USER (HKCU ). If per-user
redirection is turned off, it can cause Project Build Error PRJ0050 when the program tries to write to HKCR.
Link Library Dependencies
Specifies whether to link the .lib files that are produced by dependent projects. Typically, you want to link in the .lib
files, but this may not be the case for certain DLLs.
You can also specify a .obj file by providing the file name and relative path, for example
"..\..\MyLibProject\MyObjFile.obj". If the source code for the .obj file #includes a precompiled header, for example
pch.h, then the pch.obj file is located in the same folder as MyObjFile.obj, and you must also add pch.obj as an
additional dependency.
Use Library Dependency Inputs
In a large project, when a dependent project produces a .lib file, incremental linking is disabled. If there are many
dependent projects that produce .lib files, building the application can take a long time. When this property is set
to Yes, the project system links in the .obj files for .libs produced by dependent projects, thus enabling incremental
linking.
For information about how to access the General linker property page, see Set C++ compiler and build
properties in Visual Studio.

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

Use this dialog box to specify general 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 General.

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

The resource ID is optional and defaults to CREATEPROCESS_MANIFEST_RESOURCE_ID in winuser.h.


Embed Manifest
Yes specifies that the project system will embed the application manifest file into the assembly.
No specifies that the project system will create the application manifest file as a stand-alone file.
Output Manifest File
Specifies the name of the output manifest file. This property is optional when only one manifest file is operated
upon by the manifest tool.
Manifest Resource File
Specifies the output resources files used to embed the manifest into the project output.
Generate Catalog Files
Uses the /makecdfs option to specify that the manifest tool will generate catalog definition files (.cdf files), which
are used to make catalogs.
Generate Manifest From ManagedAssembly
Generates a manifest from a managed assembly. (-managedassemblyname:file).
Suppress Dependency Element
Used with the -managedassembly option. This tag suppresses the generation of dependency elements in the
final manifest.
Generate Category Tags
Used with the -managedassembly option. This tag causes the category tags to be generated.
Enable DPI Awareness
Specifies whether the application is DPI-aware. By default, the setting is Yes for MFC projects and No otherwise
because only MFC projects have built in DPI awareness. You can override the setting to Yes if you add code to
handle different DPI settings. Your application might appear fuzzy or small if you set it as DPI-aware when it is
not.

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

Use this dialog box to specify advanced 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 Advanced.

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.

Update File Hashes Search Path


Specifies the search path for files that are referenced in <file> elements. This option also uses the
/hashupdate option.

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

Enables settings for the resource compiler.


The Managed Resources property page contains the following properties:
Resource Logical Name
Specifies the logical name of the generated intermediate .resources file. The logical name is the name used
to load the resource. If no logical name is specified, the resource (.resx) file name is used as the logical name.
Output File Name
Specifies the name of the final output file that the resource (.resx) file contributes to.
Default Localized Resources
Specifies whether the given .resx file contributes to the default resources or to a satellite .dll.
For information on how to access the Managed Resources property page, see Set C++ compiler and build
properties in Visual Studio.

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:

#define _WIN32_WINNT 0x0400 //for Windows NT 4.0 or Windows 95 with DCOM


to
#define _WIN32_WINNT 0x0500 //for Windows NT 4.0 or Windows 95 with DCOM

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.

From the command line


You can set compiler (CL.exe) options:
On the command line
In command files
In the CL environment variable
Options specified in the CL environment variable are used every time you invoke CL. If a command file is named in
the CL environment variable or on the command line, the options specified in the command file are used. Unlike
either the command line or the CL environment variable, a command file allows you to use multiple lines of
options and filenames.
Compiler options are processed "left to right," and when a conflict is detected, the last (rightmost) option wins. The
CL environment variable is processed before the command line, so in any conflicts between CL and the command
line, the command line takes precedence.

Additional Compiler Topics


MSVC Compiler Options
Precompiled Header Files
CL Invokes the Linker
For information on choosing the compiler host and target architecture, see Configure C++ projects for 64-bit, x64
targets.

See also
C/C++ Building Reference
Compiler Command-Line Syntax
3/12/2019 • 2 minutes to read • Edit Online

The CL command line uses the following syntax:

CL [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...]

The following table describes input to the CL command.

ENTRY MEANING

option One or more CL options. Note that all options


apply to all specified source files. Options are
specified by either a forward slash (/) or a dash (-). If
an option takes an argument, the option's
description documents whether a space is allowed
between the option and the arguments. Option
names (except for the /HELP option) are case
sensitive. See Order of CL Options for more
information.

file The name of one or more source files, .obj files, or


libraries. CL compiles source files and passes the
names of the .obj files and libraries to the linker. See
CL Filename Syntax for more information.

lib One or more library names. CL passes these names


to the linker.

command-file A file that contains multiple options and filenames.


See CL Command Files for more information.

link-opt One or more MSVC Linker Options. CL passes


these options to the linker.

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

The CL tool uses the following environment variables:


CL and _CL_, if defined. The CL tool prepends the options and arguments defined in the CL environment
variable to the command line arguments, and appends the options and arguments defined in _CL_, before
processing.
INCLUDE, which must point to the \include subdirectory of your Visual C++ installation.
LIBPATH, which specifies directories to search for metadata files referenced with #using. See #using for
more information on LIBPATH.
You can set the CL or _CL_ environment variable using the following syntax:

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:

SET CL=/Zp2 /Ox /I\INCLUDE\MYINCLS \LIB\BINMODE.OBJ

When this environment variable is set, if you enter CL INPUT.C at the command line, this is the effective
command:

CL /Zp2 /Ox /I\INCLUDE\MYINCLS \LIB\BINMODE.OBJ INPUT.C

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:

SET CL=FILE1.C FILE2.C SET _CL_=FILE3.OBJ CL

This has the same effect as the following command line:

CL FILE1.C FILE2.C FILE3.OBJ


See also
Setting Compiler Options
MSVC Compiler Options
CL Command Files
3/12/2019 • 2 minutes to read • Edit Online

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:

/Og /link LIBC.LIB

and you specify the following CL command:

CL /Ob2 @RESP MYAPP.C

the command to CL is as follows:

CL /Ob2 /Og MYAPP.C /link LIBC.LIB

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

/c Compile without linking

/E, /EP, /P Preprocess without compiling or linking

/Zg Generate function prototypes

/Zs Check syntax

For further details about linking, see MSVC Linker Options.

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 MAIN.c MOD1.C MOD2.C MYGRAPH.lib

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.

Find a compiler option


To find a particular compiler option, see one of the following lists:
Compiler Options Listed Alphabetically
Compiler Options Listed by Category

Specify compiler options


The topic for each compiler option discusses how it can be set in the development
environment. For information on specifying options outside the development environment,
see:
MSVC Compiler Command-Line Syntax
CL Command Files
CL Environment Variables

Related build tools


MSVC Linker Options also affect how your program is built.

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

/O1 Creates small code.

/O2 Creates fast code.

/Ob Controls inline expansion.

/Od Disables optimization.

/Og Deprecated. Uses global optimizations.

/Oi Generates intrinsic functions.

/Os Favors small code.

/Ot Favors fast code.

/Ox Uses maximum optimization (/Ob2gity /Gs).

/Oy Omits frame pointer. (x86 only)

/favor Produces code that is optimized for a specified architecture,


or for a range of architectures.

Code generation
OPTION PURPOSE

/arch Use SSE or SSE2 instructions in code generation. (x86 only)

/clr Produces an output file to run on the common language


runtime.

/EH Specifies the model of exception handling.

/fp Specifies floating-point behavior.

/GA Optimizes for Windows applications.


OPTION PURPOSE

/Gd Uses the __cdecl calling convention. (x86 only)

/Ge Deprecated. Activates stack probes.

/GF Enables string pooling.

/Gh Calls hook function _penter .

/GH Calls hook function _pexit .

/GL Enables whole program optimization.

/Gm Deprecated. Enables minimal rebuild.

/GR Enables run-time type information (RTTI).

/Gr Uses the __fastcall calling convention. (x86 only)

/GS Checks buffer security.

/Gs Controls stack probes.

/GT Supports fiber safety for data allocated by using static


thread-local storage.

/guard:cf Adds control flow guard security checks.

/Gv Uses the __vectorcall calling convention. (x86 and x64


only)

/Gw Enables whole-program global data optimization.

/GX Deprecated. Enables synchronous exception handling. Use


/EH instead.

/Gy Enables function-level linking.

/GZ Deprecated. Enables fast checks. (Same as /RTC1)

/Gz Uses the __stdcall calling convention. (x86 only)

/homeparams Forces parameters passed in registers to be written to their


locations on the stack upon function entry. This compiler
option is only for the x64 compilers (native and cross
compile).

/hotpatch Creates a hotpatchable image.

/Qfast_transcendentals Generates fast transcendentals.


OPTION PURPOSE

/QIfist Deprecated. Suppresses the call of the helper function


_ftol when a conversion from a floating-point type to an
integral type is required. (x86 only)

/Qimprecise_fwaits Removes fwait commands inside try blocks.

/Qpar Enables automatic parallelization of loops.

/Qpar-report Enables reporting levels for automatic parallelization.

/Qsafe_fp_loads Uses integer move instructions for floating-point values and


disables certain floating point load optimizations.

/Qspectre Enable mitigations for CVE 2017-5753, for a class of Spectre


attacks.

/Qvec-report Enables reporting levels for automatic vectorization.

/RTC Enables run-time error checking.

/volatile Selects how the volatile keyword is interpreted.

Output files
OPTION PURPOSE

/doc Processes documentation comments to an XML file.

/FA Configures an assembly listing file.

/Fa Creates an assembly listing file.

/Fd Renames program database file.

/Fe Renames the executable file.

/Fi Specifies the preprocessed output file name.

/Fm Creates a mapfile.

/Fo Creates an object file.

/Fp Specifies a precompiled header file name.

/FR, /Fr Name generated .sbr browser files.

Preprocessor
OPTION PURPOSE

/AI Specifies a directory to search to resolve file references


passed to the #using directive.

/C Preserves comments during preprocessing.

/D Defines constants and macros.

/E Copies preprocessor output to standard output.

/EP Copies preprocessor output to standard output.

/FI Preprocesses the specified include file.

/FU Forces the use of a file name, as if it had been passed to the
#using directive.

/Fx Merges injected code with the source file.

/I Searches a directory for include files.

/P Writes preprocessor output to a file.

/U Removes a predefined macro.

/u Removes all predefined macros.

/X Ignores the standard include directory.

Language
OPTION PURPOSE

/constexpr Control constexpr evaluation at compile-time.

/openmp Enables #pragma omp in source code.

/vd Suppresses or enables hidden vtordisp class members.

/vmb Uses best base for pointers to members.

/vmg Uses full generality for pointers to members.

/vmm Declares multiple inheritance.

/vms Declares single inheritance.

/vmv Declares virtual inheritance.

/Z7 Generates C 7.0-compatible debugging information.


OPTION PURPOSE

/Za Disables C89 language extensions.

/Zc Specifies standard behavior under /Ze.

/Ze Deprecated. Enables C89 language extensions.

/Zf Improves PDB generation time in parallel builds.

/ZI Includes debug information in a program database


compatible with Edit and Continue. (x86 only)

/Zi Generates complete debugging information.

/Zl Removes the default library name from the .obj file.

/Zp n Packs structure members.

/Zs Checks syntax only.

/ZW Produces an output file to run on the Windows Runtime.

Linking
OPTION PURPOSE

/F Sets stack size.

/LD Creates a dynamic-link library.

/LDd Creates a debug dynamic-link library.

/link Passes the specified option to LINK.

/LN Creates an MSIL module.

/MD Compiles to create a multithreaded DLL, by using


MSVCRT.lib.

/MDd Compiles to create a debug multithreaded DLL, by using


MSVCRTD.lib.

/MT Compiles to create a multithreaded executable file, by using


LIBCMT.lib.

/MTd Compiles to create a debug multithreaded executable file, by


using LIBCMTD.lib.

Miscellaneous
OPTION PURPOSE

/? Lists the compiler options.

@ Specifies a response file.

/analyze Enables code analysis.

/bigobj Increases the number of addressable sections in an .obj file.

/c Compiles without linking.

/cgthreads Specifies number of cl.exe threads to use for optimization and


code generation.

/errorReport Enables you to provide internal compiler error (ICE)


information directly to the Visual C++ team.

/FC Displays the full path of source code files passed to cl.exe in
diagnostic text.

/FS Forces writes to the program database (PDB) file to be


serialized through MSPDBSRV.EXE.

/H Deprecated. Restricts the length of external (public) names.

/HELP Lists the compiler options.

/J Changes the default char type.

/JMC Supports native C++ Just My Code debugging.

/kernel The compiler and linker will create a binary that can be
executed in the Windows kernel.

/MP Builds multiple source files concurrently.

/nologo Suppresses display of sign-on banner.

/sdl Enables additional security features and warnings.

/showIncludes Displays a list of all include files during compilation.

/Tc Specifies a C source file.

/TC Specifies all source files are C.

/Tp Specifies a C++ source file.

/TP Specifies all source files are C++.

/V Deprecated. Sets the version string.


OPTION PURPOSE

/w Disables all warnings.

/W0, /W1, /W2, /W3, /W4 Sets output warning level.

/w1, /w2, /w3, /w4 Sets warning level for the specified warning.

/Wall Enables all warnings, including warnings that are disabled by


default.

/wd Disables the specified warning.

/we Treats the specified warning as an error.

/WL Enables one-line diagnostics for error and warning messages


when compiling C++ source code from the command line.

/wo Displays the specified warning only once.

/Wv Disables warnings introduced by later versions of the


compiler.

/WX Treats warnings as errors.

/Yc Create .PCH file.

/Yd Deprecated. Places complete debugging information in all


object files. Use /Zi instead.

/Yl Injects a PCH reference when creating a debug library.

/Yu Uses a precompiled header file during build.

/Y- Ignores all other precompiled-header compiler options in the


current build.

/Zm Specifies the precompiled header memory allocation limit.

/await Enable coroutines (resumable functions) extensions.

/source-charset Set source character set.

/execution-charset Set execution character set.

/utf-8 Set source and execution character sets to UTF-8.

/validate-charset Validate UTF-8 files for only compatible characters.

/diagnostics Controls the format of diagnostic messages.

/permissive- Set standard-conformance mode.


OPTION PURPOSE

/std C++ standard version compatibility selector.

Deprecated and removed compiler options


OPTION PURPOSE

/clr:noAssembly Deprecated. Use /LN (Create MSIL Module) instead.

/Fr Deprecated. Creates a browse information file without local


variables.

/Ge Deprecated. Activates stack probes. On by default.

/Gm Deprecated. Enables minimal rebuild.

/GX Deprecated. Enables synchronous exception handling. Use


/EH instead.

/GZ Deprecated. Enables fast checks. Use /RTC1 instead.

/H Deprecated. Restricts the length of external (public) names.

/Og Deprecated. Uses global optimizations.

/QIfist Deprecated. Once used to specify how to convert from a


floating-point type to an integral type.

/V Deprecated. Sets the .obj file version string.

/Wp64 Obsolete. Detects 64-bit portability problems.

/Yd Deprecated. Places complete debugging information in all


object files. Use /Zi instead.

/Zc:forScope- Deprecated. Disables conformance in for loop scope.

/Ze Deprecated. Enables language extensions.

/Zg Removed in Visual C++ 2015. Generates function


prototypes.

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

@ Specifies a response file.

/? Lists the compiler options.

/AI Specifies a directory to search to resolve file references passed


to the #using directive.

/analyze Enable code analysis.

/arch Specifies the architecture for code generation.

/await Enable coroutines (resumable functions) extensions.

/bigobj Increases the number of addressable sections in an .obj file.

/C Preserves comments during preprocessing.

/c Compiles without linking.

/cgthreads Specifies number of cl.exe threads to use for optimization and


code generation.

/clr Produces an output file to run on the common language


runtime.

/constexpr Control constexpr evaluation at compile-time.

/D Defines constants and macros.

/diagnostics Controls the format of diagnostic messages.

/doc Process documentation comments to an XML file.

/E Copies preprocessor output to standard output.

/EH Specifies the model of exception handling.

/EP Copies preprocessor output to standard output.

/errorReport Allows you to provide internal compiler error (ICE) information


directly to the Visual C++ team.
OPTION PURPOSE

/execution-charset Set execution character set.

/F Sets stack size.

/favor Produces code that is optimized for a specific x64 architecture


or for the specifics of micro-architectures in both the AMD64
and Extended Memory 64 Technology (EM64T) architectures.

/FA Creates a listing file.

/Fa Sets the listing file name.

/FC Display full path of source code files passed to cl.exe in


diagnostic text.

/Fd Renames program database file.

/Fe Renames the executable file.

/FI Preprocesses the specified include file.

/Fi Sets the preprocessed output file name.

/Fm Creates a mapfile.

/Fo Creates an object file.

/fp Specify floating-point behavior.

/Fp Specifies a precompiled header file name.

/FR Generates browser files. /Fr is deprecated.

/Fr

/FS Forces writes to the program database (PDB) file to be


serialized through MSPDBSRV.EXE.

/FU Forces the use of a file name as if it had been passed to the
#using directive.

/Fx Merges injected code with source file.

/GA Optimizes code for Windows application.

/Gd Uses the __cdecl calling convention (x86 only).

/Ge Deprecated. Activates stack probes.

/GF Enables string pooling.


OPTION PURPOSE

/GH Calls hook function _pexit .

/Gh Calls hook function _penter .

/GL Enables whole program optimization.

/Gm Enables minimal rebuild.

/GR Enables run-time type information (RTTI).

/Gr Uses the __fastcall calling convention (x86 only).

/GS Buffers security check.

/Gs Controls stack probes.

/GT Supports fiber safety for data allocated using static thread-
local storage.

/guard:cf Adds control flow guard security checks.

/Gv Uses the __vectorcall calling convention. (x86 and x64


only)

/Gw Enables whole-program global data optimization.

/GX Deprecated. Enables synchronous exception handling. Use /EH


instead.

/Gy Enables function-level linking.

/GZ Deprecated. Same as /RTC1.

/Gz Uses the __stdcall calling convention (x86 only).

/H Deprecated. Restricts the length of external (public) names.

/HELP Lists the compiler options.

/homeparams Forces parameters passed in registers to be written to their


locations on the stack upon function entry. This compiler
option is only for the x64 compilers (native and cross compile).

/hotpatch Creates a hotpatchable image.

/I Searches a directory for include files.

/J Changes the default char type.

/JMC Supports native C++ Just My Code debugging.


OPTION PURPOSE

/kernel The compiler and linker will create a binary that can be
executed in the Windows kernel.

/LD Creates a dynamic-link library.

/LDd Creates a debug dynamic-link library.

/link Passes the specified option to LINK.

/LN Creates an MSIL module.

/MD Creates a multithreaded DLL using MSVCRT.lib.

/MDd Creates a debug multithreaded DLL using MSVCRTD.lib.

/MP Compiles multiple source files by using multiple processes.

/MT Creates a multithreaded executable file using LIBCMT.lib.

/MTd Creates a debug multithreaded executable file using


LIBCMTD.lib.

/nologo Suppresses display of sign-on banner.

/O1 Creates small code.

/O2 Creates fast code.

/Ob Controls inline expansion.

/Od Disables optimization.

/Og Deprecated. Uses global optimizations.

/Oi Generates intrinsic functions.

/openmp Enables #pragma omp in source code.

/Os Favors small code.

/Ot Favors fast code.

/Ox Uses maximum optimization (/Ob2gity /Gs).

/Oy Omits frame pointer (x86 only).

/P Writes preprocessor output to a file.

/permissive- Set standard-conformance mode.


OPTION PURPOSE

/Qfast_transcendentals Generates fast transcendentals.

/QIfist Deprecated. Suppresses _ftol when a conversion from a


floating-point type to an integral type is required (x86 only).

/Qimprecise_fwaits Removes fwait commands inside try blocks.

/Qpar (Auto-Parallelizer) Enables automatic parallelization of loops that are marked


with the #pragma loop() directive.

/Qsafe_fp_loads Uses integer move instructions for floating-point values and


disables certain floating point load optimizations.

/Qvec-report (Auto-Vectorizer Reporting Level) Enables reporting levels for automatic vectorization.

/RTC Enables run-time error checking.

/sdl Enables additional security features and warnings.

/showIncludes Displays a list of include files during compilation.

/source-charset Set source character set.

/std C++ standard version compatibility selector.

/Tc Specifies a C source file.

/TC Specifies all source files are C.

/Tp Specifies a C++ source file.

/TP Specifies all source files are C++.

/U Removes a predefined macro.

/u Removes all predefined macros.

/utf-8 Set source and execution character sets to UTF-8.

/V Deprecated. Sets the .obj file version string.

/validate-charset Validate UTF-8 files for only compatible characters.

/vd Suppresses or enables hidden vtordisp class members.

/vmb Uses best base for pointers to members.

/vmg Uses full generality for pointers to members.

/vmm Declares multiple inheritance.


OPTION PURPOSE

/vms Declares single inheritance.

/vmv Declares virtual inheritance.

/volatile Selects how the volatile keyword is interpreted.

/w Disables all warnings.

/W0, /W1, /W2, /W3, /W4 Sets which warning level to output.

/w1, /w2, /w3, /w4 Sets the warning level for the specified warning.

/Wall Enables all warnings, including warnings that are disabled by


default.

/wd Disables the specified warning.

/we Treats the specified warning as an error.

/WL Enables one-line diagnostics for error and warning messages


when compiling C++ source code from the command line.

/wo Displays the specified warning only once.

/Wp64 Obsolete. Detects 64-bit portability problems.

/Wv Displays no warnings introduced after the specified version of


the compiler.

/WX Treats all warnings as errors.

/X Ignores the standard include directory.

/Y- Ignores all other precompiled-header compiler options in the


current build.

/Yc Creates a precompiled header file.

/Yd Deprecated. Places complete debugging information in all


object files. Use /Zi instead.

/Yl Injects a PCH reference when creating a debug library

/Yu Uses a precompiled header file during build.

/Z7 Generates C 7.0-compatible debugging information.

/Za Disables language extensions.

/Zc Specifies standard behavior under /Ze./Za, /Ze (Disable


Language Extensions)
OPTION PURPOSE

/Ze Deprecated. Enables language extensions.

/Zf Improves PDB generation time in parallel builds.

/Zg Removed in Visual C++ 2015. Generates function prototypes.

/ZI Includes debug information in a program database compatible


with Edit and Continue.

/Zi Generates complete debugging information.

/Zl Removes default library name from .obj file (x86 only).

/Zm Specifies the precompiled header memory allocation limit.

/Zp Packs structure members.

/Zs Checks syntax only.

/ZW Produces an output file to run on the Windows Runtime.

See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
@ (Specify a Compiler Response File)
3/12/2019 • 2 minutes to read • Edit Online

Specifies a compiler response file.

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

Enables code analysis and control options.

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

Then use this compiler option: /analyze:plugin EspXEngine.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:

r = f1 * f2 + d; // Different results are possible on SSE/SSE2.

Compare:

t = f1 * f2; // Do f1 * f2, round to the type of t.


r = t + d; // This should produce the same overall result
// whether x87 stack is used or SSE/SSE2 is used.

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

Preserves comments during preprocessing.

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

This sample will produce the following output.

#line 1 "C_compiler_option.cpp"
int i; // a 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. Click the C/C++ folder.
3. Click the Preprocessor property page.
4. Modify the Keep Comments property.
To set this compiler option programmatically
See KeepComments.

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

Prevents the automatic call to LINK.

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.

CL /c FIRST.C SECOND.C THIRD.OBJ

To create an executable file, you must invoke LINK:

LINK firsti.obj second.obj third.obj /OUT:filename.exe

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.

Metadata and Unnamed Classes


Unnamed classes will appear in metadata named as follows: $UnnamedClass$ crc-of-current-file-name $
index $ , where index is a sequential count of the unnamed classes in the compilation. For example, the
following code sample generates an unnamed class in metadata.

// clr_unnamed_class.cpp
// compile by using: /clr /LD
class {} x;

Use ildasm.exe to view metadata.

See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/clr Restrictions
3/12/2019 • 3 minutes to read • Edit Online

Note the following restrictions on the use of /clr:


In a structured exception handler, there are restrictions on using _alloca when compiling with /clr. For
more information, see _alloca.
The use of run-time error checks is not valid with /clr. For more information, see How to: Use Native Run-
Time Checks.
When /clr is used to compile a program that only uses standard C++ syntax, the following guidelines apply
to the use of inline assembly:
Inline assembly code that assumes knowledge of the native stack layout, calling conventions outside
of the current function, or other low -level information about the computer may fail if that knowledge
is applied to the stack frame for a managed function. Functions containing inline assembly code are
generated as unmanaged functions, as if they were placed in a separate module that was compiled
without /clr.
Inline assembly code in functions that pass copy-constructed function parameters is not supported.
The vprintf Functions cannot be called from a program compiled with /clr.
The naked __declspec modifier is ignored under /clr.
The translator function set by _set_se_translator will affect only catches in unmanaged code. See Exception
Handling for more information.
The comparison of function pointers is not permitted under /clr.
The use of functions that are not fully prototyped is not permitted under /clr.
The following compiler options are not supported with /clr:
/EHsc and /EHs (/clr implies /EHa (see /EH (Exception Handling Model))
/fp:strict and /fp:except (see /fp (Specify Floating-Point Behavior))
/Zd
/Gm
/MT
/RTC
/ZI
The combination of the _STATIC_CPPLIB preprocessor definition ( /D_STATIC_CPPLIB ) and the /clr compiler
option is not supported. This is so because the definition would cause your application to link with the static
multithreaded C++ Standard Library, which is not supported. For more information, see the /MD, /MT, /LD
(Use Run-Time Library) topic.
When using /Zi with /clr, there are performance implications. For more information, see /Zi.
Passing a wide character to a .NET Framework output routine without also specifying /Zc:wchar_t or
without casting the character to __wchar_t will cause the output to appear as an unsigned short int . For
example:

Console::WriteLine(L' ') // Will output 32.


Console::WriteLine((__wchar_t)L' ') // Will output a space.

/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

Defines a preprocessing symbol for a source file.

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

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. In the left pane, select Configuration Properties, C/C++, Preprocessor.
3. In the right pane, in the right-hand column of the Preprocessor Definitions property, open the drop-
down menu and choose Edit.
4. In the Preprocessor Definitions dialog box, add (one per line), modify, or delete one or more definitions.
Choose OK to save your changes.
To set this compiler option programmatically
See PreprocessorDefinitions.

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;
}

However, if you compile with:

cl -E test.cpp > test2.cpp

int main in test2.cpp will incorrectly be intmain .


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 Optionsbox.
To set this compiler option programmatically
See GeneratePreprocessedFile.

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;

void fail() { // generates SE and attempts to catch it using catch(...)


try {
int i = 0, j = 1;
j /= i; // This will throw a SE (divide by zero).
printf("%d", j);
}
catch(...) { // catch block will only be executed under /EHa
cout<<"Caught an exception in catch(...)."<<endl;
}
}

int main() {
__try {
fail();
}

// __except will only catch an exception here


__except(EXCEPTION_EXECUTE_HANDLER) {
// if the exception was not caught by the catch(...) inside fail()
cout << "An exception was caught in __except." << endl;
}
}

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

Sets the program stack size in bytes.

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

Creates a listing file containing assembler code.

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.

DEVICE NAME REPRESENTS

AUX Auxiliary device

CON Console

PRN Printer

NUL Null device (no file created)

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:

CL /DDEBUG /Zi /FdPROG.PDB PROG.CPP

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".

CL /Fe"C:\Users\User Name\repos\My Project\bin\PROCESS" *.C

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

Causes the preprocessor to process the specified header file.

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:

CL /DDEBUG /Zi /Yc /FpDPROG.PCH PROG.CPP

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.

CL /YuMYAPP.H /FpMYPCH.PCH PROG.CPP


See also
Output-File (/F ) Options
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
Specifying the Pathname
/FR, /Fr (Create .Sbr File)
3/12/2019 • 2 minutes to read • Edit Online

Creates .sbr files.

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.

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 the C/C++, Browse Information property page.
3. Modify the Browse Information File or Enable Browse Information property.
To set this compiler option programmatically
See BrowseInformation and BrowseInformationFile.

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:

//+++ Start Injected Code


[no_injected_text(true)]; // Suppress injected text, it has
// already been injected
#pragma warning(disable: 4543) // Suppress warnings about skipping
// injected text
#pragma warning(disable: 4199) // Suppress warnings from attribute
// providers
//--- End Injected Code

In an .mrg file, code that was injected because of an attribute will be delimited as follows:

//+++ Start Injected Code


...
//--- End Injected Code

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:fast off off off on

/fp:precise on off off on

/fp:strict on on on off

The default floating point environment


When a process is initialized, the default floating point environment is set. This environment masks all floating
point exceptions, sets the rounding mode to round to nearest ( FE_TONEAREST ), preserves subnormal (denormal)
values, uses the default precision of significand (mantissa) for float, double, and long double values, and
where supported, sets the infinity control to the default affine mode.
Floating-point environment access and modification
The Microsoft Visual C++ runtime provides several functions to access and modify the floating-point
environment. These include _controlfp, _clearfp, and _statusfp and their variants. To ensure correct program
behavior when your code accesses or modifies the floating-point environment, fenv_access must be enabled,
either by the /fp:strict option or by use of the fenv_access pragma, for these functions to have any effect. When
fenv_access is not enabled, access or modification of the floating-point environment may result in unexpected
program behavior: code may not honor requested changes to the floating-point environment; the floating-point
status registers may not report expected or current results; and unexpected floating-point exceptions may occur
or expected floating-point exceptions may not occur.
When your code accesses or modifies the floating-point environment, you must be careful when you combine
code where fenv_access is enabled with code that does not have fenv_access enabled. In code where
fenv_access is not enabled, the compiler assumes that the platform default floating-point environment is in
effect, and that the floating-point status is not accessed or modified. We recommend you save and restore the
local floating-point environment to its default state before control is transferred to a function that does not have
fenv_access enabled. This example demonstrates how the float_control pragma can be set and restored:

#pragma float_control(strict, on, push)


// Code that uses /fp:strict mode
#pragma float_control(pop)

Floating-point rounding modes


Under both /fp:precise and /fp:fast the compiler generates code intended to run in the default floating-point
environment and assumes that the 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. However, some programs need to alter the floating-point environment. For example, this
sample computes error bounds of a floating-point multiplication by altering floating-point rounding modes:
// fp_error_bounds.cpp
#include <iostream>
#include <limits>
using namespace std;

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;

// compute lower error bound.


// set rounding mode to -infinity.
err = _controlfp_s(&control_word, _RC_DOWN, _MCW_RC);
if (err)
{
cout << "_controlfp_s(&control_word, _RC_DOWN, _MCW_RC) failed with error:" << err << endl;
}
cLower = a * b;

// compute upper error bound.


// set rounding mode to +infinity.
err = _controlfp_s(&control_word, _RC_UP, _MCW_RC);
if (err)
{
cout << "_controlfp_s(&control_word, _RC_UP, _MCW_RC) failed with error:" << err << endl;
}
cUpper = a * b;

// restore default rounding mode.


err = _controlfp_s(&control_word, _CW_DEFAULT, _MCW_RC);
if (err)
{
cout << "_controlfp_s(&control_word, _CW_DEFAULT, _MCW_RC) failed with error:" << err << endl;
}
// display error bounds.
cout << "cLower = " << cLower << endl;
cout << "cUpper = " << cUpper << endl;
return 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

Floating-point special values


Under /fp:precise and /fp:strict, expressions that involve special values (NaN, +infinity, -infinity, -0.0) behave
according to the IEEE -754 specifications. Under /fp:fast, the behavior of these special values may be
inconsistent with IEEE -754.
This sample demonstrates the different behavior of special values under /fp:precise, /fp:strict and /fp:fast:

// fp_special_values.cpp
#include <stdio.h>
#include <cmath>

float gf0 = -0.0;

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

Floating-point algebraic transformations


Under /fp:precise and /fp:strict, the compiler does not perform mathematical transformations unless the
transformation is guaranteed to produce a bitwise identical result. The compiler may perform such
transformations under /fp:fast. For example, the expression a * b + a * c in the sample function
algebraic_transformation may be compiled into a * (b + c) under /fp:fast. Such transformations aren’t
performed under /fp:precise or /fp:strict, and the compiler generates a * b + a * c .

float algebraic_transformation (float a, float b, float c)


{
return a * b + a * c;
}
Floating-point explicit casting points
Under /fp:precise and /fp:strict, 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. Typecasts can be used to explicitly round
intermediate computations. Under /fp:fast, the compiler does not generate explicit casts at these points to
guarantee source code precision. This sample demonstrates the behavior under different /fp options:

float casting(float a, float b)


{
return 5.0*((double)(a+b));
}

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:

addss xmm0, xmm1


cvtss2sd xmm0, xmm0
mulsd xmm0, QWORD PTR __real@4014000000000000
cvtsd2ss xmm0, xmm0
ret 0

Under /O2 /fp:fast the generated code is simplified, because all type casts are optimized away:

addss xmm0, xmm1


mulss xmm0, DWORD PTR __real@40a00000
ret 0

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 Floating Point Model property.
To set this compiler option programmatically
See floatingPointModel.

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.

Optimization of floating-point code in C++


An optimizing C++ compiler not only translates source code into machine code, it arranges the machine
instructions in such a way as to improve efficiency and/or reduce size. Unfortunately, many common optimizations
are not necessarily safe when applied to floating-point computations. A good example of this can be seen with the
following summation algorithm, taken from David Goldberg, "What Every Computer Scientist Should Know About
Floating-Point Arithmetic", Computing Surveys, March 1991, pg. 203:

float KahanSum( const float A[], int n )


{
float sum=0, C=0, Y, T;
for (int i=0; i<n; i++)
{
Y = A[i] - C;
T = sum + Y;
C = T - sum - Y;
sum = T;
}
return sum;
}

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

C = T - sum - Y ==> (sum+Y )-sum-Y ==> 0;

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,

Y = A[i] - C ==> Y = A[i]


T = sum + Y ==> T = sum + A[i]
sum = T ==> sum = sum + A[i]

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

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;
}

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:

float Sum( const float A[], int n )


{
float sum=0;
for (int i=0; i<n; i++)
sum = sum + A[i];
return sum;
}

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];

the transformed function now computes the result as

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.

The fp:precise mode for floating-point semantics


The default floating-point semantics mode is fp:precise. When this mode is selected, the compiler strictly adheres
to a set of safety rules when optimizing floating-point operations. These rules permit the compiler to generate
efficient machine code while maintaining the accuracy of floating-point computations. To facilitate the production
of fast programs, the fp:precise model disables floating-point exception semantics (although they can be explicitly
enabled). Microsoft has selected fp:precise as the default floating-point mode because it creates both fast and
accurate programs.
To explicitly request the fp:precise mode using the command-line compiler, use the /fp:precise switch:

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.

FP:PRECISE SEMANTICS EXPLANATION

Rounding semantics Explicit rounding at assignments, typecasts, and function calls.


Intermediate expressions will be evaluated at register
precision.

Algebraic transformations Strict adherence to non-associative, non-distributive floating-


point algebra, unless a transformation is guaranteed to always
produce the same results.

Contractions Permitted by default. For more information, see section The


fp_contract pragma.

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.

Rounding semantics for floating-point expressions under fp:precise


The fp:precise model always performs intermediate computations at the highest practical precision, explicitly
rounding only at certain points in expression evaluation. Rounding to the user-specified precision always occurs in
four places: (a) when an assignment is made, (b) when a typecast is performed, (c) when a floating-point value is
passed as an argument to a function and (d) when a floating-point value is returned from a function. Because
intermediate computations are always performed at register precision, the accuracy of intermediate results is
platform dependant (though precision will always be at least as accurate as the user specified precision).
Consider the assignment expression in the following code. The expression on the right-hand side of the
assignment operator '=' will be computed at register precision, and then explicitly rounded to the type of the left-
hand side of the assignment.

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:

float sumsqr(float a, float b)


{
return a*a + b*b;
}

is computed as

float sumsqr(float a, float b)


{
register tmp3 = a*a;
register tmp4 = b*b;
register tmp5 = tmp3+tmp4;
return (float) tmp5;
}

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);

Architecture -specific rounding under fp:precise


PROCESSOR ROUNDING PRECISION FOR INTERMEDIATE EXPRESSIONS
PROCESSOR ROUNDING PRECISION FOR INTERMEDIATE EXPRESSIONS

x86 Intermediate expressions are computed at the default 53-bit


precision with an extended range provided by a 16-bit
exponent. When these 53:16 values are "spilled" to memory
(as can happen during a function call), the extended exponent
range will be narrowed to 11-bits. That is, spilled values are
cast to the standard double precision format with only an 11-
bit exponent.
A user may switch to extended 64-bit precision for
intermediate rounding by altering the floating-point control
word using _controlfp and by enabling FPU environment
access (see The fenv_access pragma). However, when extended
precision register-values are spilled to memory, the
intermediate results will still be rounded to double precision.
This particular semantic is subject to change.

amd64 FP semantics on amd64 are somewhat different from other


platforms. For performance reasons, intermediate operations
are computed at the widest precision of either operand
instead of at the widest precision available. To force
computations to be computed using a wider precision than
the operands, users need to introduce a cast operation on at
least one operand in a sub-expression.
This particular semantic is subject to change.

Algebraic transformations under fp:precise


When the fp:precise mode is enabled, the compiler will never perform algebraic transformations unless the final
result is provably identical. Many of the familiar algebraic rules for Real number arithmetic do not always hold for
floating-point arithmetic. For example, the following expressions are equivalent for Reals, but not necessarily for
Floats.

FORM DESCRIPTION

(a+b)+c = a+(b+c) Associative rule for addition

(a*b)*c = a*(b*c) Associative rule for multiplication

a*(b+c) = a*b + b*c Distribution of multiplication over addition

(a+b)(a-b) = a*a-b*b Algebraic Factoring

a/b = a*(1/b) Division by multiplicative inverse

a*1.0 = a Multiplicative identity

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;

May be transformed into

const double four = 4.0;


const double tmp0 = 1/4.0;
double a, b;
...
a = b*tmp0;

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

(a+b) == (b+a) Commutative rule for addition

(a*b) == (b*a) Commutative rule for multiplication

1.0*x*y == x*1.0*y == x*y*1.0 == x*y Multiplication by 1.0

x/1.0*y == x*y/1.0 == x*y Division by 1.0

2.0*x == x+x Multiplication by 2.0

Contractions under fp:precise


A key architectural feature of many modern floating-point units is the ability to perform a multiplication followed
by an addition as a single operation with no intermediate round-off error. For example, Intel's Itanium architecture
provides instructions to combine each of these ternary operations, (ab+c), (ab-c) and (c-a*b), into a single floating-
point instruction (fma, fms and fnma respectively). 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. 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.

float dotProduct( float x[], float y[], int n )


{
float p=0.0;
for (int i=0; i<n; i++)
p += x[i]*y[i];
return p;
}

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...

d = (float)a*b + c; // won't be contracted because of explicit rounding

t = a*b; // (this assignment rounds a*b to float)


d = t + c; // won't be contracted because of rounding of a*b

Order of floating-point expression evaluation under fp:precise


Optimizations that preserve the order of floating-point expression evaluation are always safe and are therefore
permitted under the fp:precise mode. Consider the following function which computes the dot product of two n-
dimensional vectors in single precision. The first code block below is the original function as it might be encoded
by a programmer, followed by the same function after a partial loop-unrolling optimization.

//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;
}

//after a partial loop-unrolling


float dotProduct( float x[], float y[], int n )
{
int n4= n/4*4; // or n4=n&(~3);
float p=0;
int i;

for (i=0; i<n4; i+=4)


{
p+=x[i]*y[i];
p+=x[i+1]*y[i+1];
p+=x[i+2]*y[i+2];
p+=x[i+3]*y[i+3];
}

// last n%4 elements


for (; i<n; i++)
p+=x[i]*y[i];

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:

double a, b, c, root0, root1;


...
root0 = (-b + sqrt(b*b-4*a*c))/(2*a);
root1 = (-b - sqrt(b*b-4*a*c))/(2*a);

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.

double a, b, c, root0, root1;


...
register tmp0 = -b;
register tmp1 = sqrt(b*b-4*a*c);
register tmp2 = 2*a;
root0 = (tmp0+tmp1)/tmp2;
root1 = (tmp0-tmp1)/tmp2;

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 -&infin;
cLower = a*b;
_controlfp( _RC_UP, _MCW_RC ); // round to +&infin;
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.

The fp:fast mode for floating-point semantics


When the fp:fast mode is enabled, the compiler relaxes the rules that fp:precise uses when optimizing floating-
point operations. This mode is allows the compiler to further optimize floating-point code for speed at the expense
of floating-point accuracy and correctness. Programs that do not rely on highly accurate floating-point
computations may experience a significant speed improvement by enabling the fp:fast mode.
The fp:fast floating-point mode is enabled using the /fp:fast command-line compiler switch as follows:

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.

FP:FAST SEMANTICS EXPLANATION

Rounding semantics Explicit rounding at assignments, typecasts, and function calls


may be ignored.
Intermediate expressions may be rounded at less than register
precision according to performance requirements.

Algebraic transformations The compiler may transform expressions according real-


number associative, distributive algebra; these transformations
are not guaranteed to be either accurate or correct.

Contractions Always enabled; cannot be disabled by pragma fp_contract

Order of floating-point evaluation The compiler may reorder the evaluation of floating-point
expressions, even when such changes may alter the final
results.

FPU environment access Disabled. Not available

Floating-point exception semantics Disabled. Not available

Rounding semantics for floating-point expressions under fp:fast


Unlike the fp:precise model, the fp:fast model performs intermediate calculations at the most convenient precision.
Rounding at assignments, typecasts and function-calls may not always occur. For instance, the first function below
introduces three single-precision variables ( C , Y and T ). The compiler may choose to enregister these variables,
in effect of type promoting C , Y and T to double-precision.
Original function:

float KahanSum( const float A[], int n )


{
float sum=0, C=0, Y, T;
for (int i=0; i<n; i++)
{
Y = A[i] - C;
T = sum + Y;
C = T - sum - Y;
sum = T;
}
return sum;
}

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.

Original Code Step #1 Step #2

double a, b, c; double a, b, c; double a, b, c;


double x, y, z; double x, y, z; double x, y, z;

y = (a + b); y = (a + b); y = (a + b);


z = y – a – b; z = 0; z = 0;

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

(a + b) + c = a + (b + c) Associative rule for addition


(a * b) * c = a * (b * c) Associative rule for multiplication

a * (b + c) = a * b + b * c Distribution of multiplication over addition

(a + b)(a - b) = a * a - b * b Algebraic Factoring

a / b = a * (1 / b) Division by multiplicative inverse

a * 1.0 = a, a / 1.0 = a Multiplicative identity

a ± 0.0 = a, 0.0 - a = -a Additive identity

a / a = 1.0, a - a = 0.0 Cancellation

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.

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;
}

Under fp:fast, the optimizer may perform a scalar reduction of the dotProduct function effectively transforming
the function as follows:

float dotProduct( float x[], float y[],int n )


{
int n4= n/4*4; // or n4=n&(~3);
float p=0, p2=0, p3=0, p4=0;
int i;

for (i=0; i<n4; i+=4)


{
p+=x[i]*y[i];
p2+=x[i+1]*y[i+1];
p3+=x[i+2]*y[i+2];
p4+=x[i+3]*y[i+3];
}
p+=p2+p3+p4;

// last n%4 elements


for (; i<n; i++)
p+=x[i]*y[i];

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.

The fp:strict mode for floating-point semantics


When the fp:strict mode is enabled, the compiler adheres to all the same rules that fp:precise uses when optimizing
floating-point operations. This mode also enables floating-point exception semantics and sensitivity to the FPU
environment and disables certain optimizations such as contractions. It is the strictest mode of operation.
The fp:strict floating-point mode is enabled using the /fp:strict command-line compiler switch as follows:

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.

FP:STRICT SEMANTICS EXPLANATION

Rounding semantics Explicit rounding at assignments, typecasts, and function calls


Intermediate expressions will be evaluated at register
precision.
Same as fp:precise

Algebraic transformations Strict adherence to non-associative, non-distributive floating-


point algebra, unless a transformation is guaranteed to always
produce the same results.
Same as fp:precise

Contractions Always disabled

Order of floating-point evaluation The compiler will not reorder the evaluation of floating-point
expressions

FPU environment access Always enabled.

Floating-point exception semantics Enabled by default.

Floating-point exception semantics under fp:strict


By default, floating-point exception semantics are enabled under the fp:strict model. To disable these semantics, use
either the /fp:except- switch or introduce a float_control(except, off) pragma.
For more information, see sections Enabling floating-point exception semantics and The float_control Pragma.

The fenv_access pragma


Usage:

#pragma fenv_access( [ on | off ] )

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.

double a, b, cLower, cUpper;


// . . .
_controlfp( _RC_DOWN, _MCW_RC ); // round to -infinity
cLower = a*b;
_controlfp( _RC_UP, _MCW_RC ); // round to +infinity
cUpper = a*b;
_controlfp( _RC_NEAR, _MCW_RC ); // restore rounding mode

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.

The fp_contract pragma


Usage:

#pragma fp_contract( [ on | off ] )

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.

float dotProduct( float x[], float y[], int n )


{
float p=0.0;
for (int i=0; i<n; i++)
p += x[i]*y[i];
return p;
}

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...

d = (float)a*b + c; // won't be contracted because of explicit rounding

t = a*b; // (this assignment rounds a*b to float)


d = t + c; // won't be contracted because of rounding of a*b

The float_control pragma


The /fp:precise, /fp:fast, /fp:strict and /fp:except switches control floating-point semantics on a file-by-file
basis. The float_control pragma provides such control on a function-by-function basis.
Usage:

#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:

float_control(precise) float_control(except) fp_contract fenv_access

/fp:strict on on off on

/fp:strict /fp:except- on off off on

/fp:precise on off on off

/fp:precise /fp:except on on on off

/fp:fast off off on off

For example, the following explicitly enables fp:fast semantics.

#pragma float_control( except, off ) // disable exception semantics


#pragma float_control( precise, off ) // disable precise semantics
#pragma fp_contract(on) // enable contractions
#pragma fenv_access(off) // disable fpu environment sensitivity

NOTE
Exception semantics must be turned off before turning off "precise" semantics.

Enabling floating-point exception semantics


Certain exceptional floating-point conditions, such as dividing by zero, can cause the FPU to signal a hardware
exception. Floating-point exceptions are disabled by default. Floating-point exceptions are enabled by modifying
the FPU control word with the _controlfp function. For example, the following code enables the divide-by-zero
floating-point exception:

_clearfp(); // always call _clearfp before


// enabling/unmasking a FPU exception
_controlfp( _EM_ZERODIVIDE, _MCW_EM );

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:

This line shouldn't be reached when c==0.0


SEH Exception Detected

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:

class float_exception : public std::exception {};

class fe_denormal_operand : public float_exception {};


class fe_divide_by_zero : public float_exception {};
class fe_inexact_result : public float_exception {};
class fe_invalid_operation : public float_exception {};
class fe_overflow : public float_exception {};
class fe_stack_check : public float_exception {};
class fe_underflow : public float_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.

void se_fe_trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )


{
switch (u)
{
case STATUS_FLOAT_DENORMAL_OPERAND: throw fe_denormal_operand();
case STATUS_FLOAT_DIVIDE_BY_ZERO: throw fe_divide_by_zero();
etc...
};
}
// . . .
_set_se_translator(se_fe_trans_func);

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:

char *s = "This is a character buffer";


char *t = "This is a character buffer";

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.

/GF is in effect when /O1 or /O2 is used.


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 the Enable String Pooling property.
To set this compiler option programmatically
See StringPooling.
See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/GH (Enable _pexit Hook Function)
3/12/2019 • 2 minutes to read • Edit Online

Calls the _pexit function at the end of every method or function.

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:

void __declspec(naked) __cdecl _pexit( void );

_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:

void __declspec(naked) __cdecl _penter( void );

This declaration is not available for 64-bit projects.


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.

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();
}

extern "C" void __declspec(naked) __cdecl _penter( void ) {


_asm {
push eax
push ebx
push ecx
push edx
push ebp
push edi
push esi
}

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

Enables whole program optimization.

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

Adds code to check object types at run time.

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; };

Initialize the Security Cookie


The /GS compiler option requires that the security cookie be initialized before any function that uses the cookie is
run. The security cookie must be initialized immediately on entry to an EXE or DLL. This is done automatically if
you use the default VCRuntime entry points: mainCRTStartup, wmainCRTStartup, WinMainCRTStartup,
wWinMainCRTStartup, or _DllMainCRTStartup. If you use an alternate entry point, you must manually initialize
the security cookie by calling __security_init_cookie.

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.

What Is Not Protected


The /GS compiler option does not protect against all buffer overrun security attacks. For example, if you have a
buffer and a vtable in an object, a buffer overrun could corrupt the vtable.
Even if you use /GS, always try to write secure code that has no buffer overruns.
To set this compiler option in Visual Studio
1. In Solution Explorer, right-click the project and then click Properties.
For more information, see Set C++ compiler and build properties in Visual Studio.
2. In the Property Pages dialog box, click the C/C++ folder.
3. Click the Code Generation property page.
4. Modify the Buffer Security Check property.
To set this compiler option programmatically
See BufferSecurityCheck.

Example
This sample overruns a buffer. This causes the application to fail at runtime.

// compile with: /c /W1


#include <cstring>
#include <stdlib.h>
#pragma warning(disable : 4996) // for strcpy use

// Vulnerable function
void vulnerable(const char *str) {
char buffer[10];
strcpy(buffer, str); // overrun buffer !!!

// use a secure CRT function to help prevent buffer overruns


// truncate string to fit a 10 byte buffer
// strncpy_s(buffer, _countof(buffer), str, _TRUNCATE);
}

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

Controls the threshold for stack probes.

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

Enable compiler generation of Control Flow Guard security checks.

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

Package global data in COMDAT sections for optimization.

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.

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 the Enable Function-Level Linking property.
To set this compiler option programmatically
See EnableFunctionLevelLinking.

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

Deprecated. Restricts the length of external names.

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);

int main() { func1(); }

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

Displays a listing of compiler options to standard output.

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

Prepares an image for hot patching.

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

Adds a directory to the list of directories searched for include files.

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.

To set this compiler option in the Visual Studio development environment


1. In Solution Explorer, open the shortcut menu for the project and then choose Properties.
2. In the project Property Pages dialog box, in the left pane under Configuration Properties, expand
C/C++ and then select Command Line.
3. In the Additional Options pane, specify the /J compiler option.
To set this compiler option programmatically
See DefaultCharIsUnsigned.

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

Creates a binary that can be executed in the Windows kernel.

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.

BEHAVIOR TYPE /KERNEL BEHAVIOR

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-.

RTTI Disabled. All instances of the dynamic_cast and typeid


keywords emit a compiler error, unless dynamic_cast is used
statically.

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

class NONPAGESECTION MyNonPagedClass


{
// ...
};

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.

/KERNEL- OBJ, MASM OBJ, MIX OF /KERNEL AND


/KERNEL OBJ OR CV TRESED /KERNEL- OBJS

link /kernel Yes Yes Yes with warning LNK4257

link Yes Yes Yes

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

Passes one or more linker options to the linker.

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

/MD Causes the application to use the multithread-specific and


DLL-specific version of the run-time library. Defines _MT
and _DLL and causes the compiler to place the library
name MSVCRT.lib into the .obj file.

Applications compiled with this option are statically linked


to MSVCRT.lib. This library provides a layer of code that
enables the linker to resolve external references. The actual
working code is contained in MSVCRversionnumber.DLL,
which must be available at run time to applications linked
with MSVCRT.lib.

/MDd Defines _DEBUG , _MT , and _DLL and causes the


application to use the debug multithread-specific and DLL-
specific version of the run-time library. It also causes the
compiler to place the library name MSVCRTD.lib into the
.obj file.

/MT Causes the application to use the multithread, static version


of the run-time library. Defines _MT and causes the
compiler to place the library name LIBCMT.lib into the .obj
file so that the linker will use LIBCMT.lib to resolve external
symbols.

/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

/LD Creates a DLL.

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.

Links the DLL startup code.

Creates an import library (.lib), if an export (.exp) file is not


specified on the command line. You link the import library
to applications that call your DLL.

Interprets /Fe (Name EXE File) as naming a DLL rather than


an .exe file. By default, the program name becomes
basename.dll instead of basename.exe.

Implies /MT unless you explicitly specify /MD.

/LDd Creates a debug DLL. Defines _MT and _DEBUG .

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.

Incompatible Options and Language Features


The /MP option is incompatible with some compiler options and language features. If you use an incompatible
compiler option with the /MP option, the compiler issues warning D9030 and ignores the /MP option. If you use
an incompatible language feature, the compiler issues error C2813 then ends or continues depending on the
current compiler warning level option.

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.

/E, /EP Copies preprocessor output to the standard output (stdout).

/Gm Enables an incremental rebuild.

/showIncludes Writes a list of include files to the standard error (stderr).

/Yc Writes a precompiled 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:

DIAGNOSTIC MESSAGE DESCRIPTION COMPILER BEHAVIOR

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

/O1 (Minimize Size) /Og /Os /Oy /Ob2 /GF /Gy

/O2 (Maximize Speed) /Og /Oi /Ot /Oy /Ob2 /GF /Gy

/O1 and /O2 are mutually exclusive.

NOTE
x86 Specific These options imply the use of the Frame-Pointer Omission (/Oy) 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
/EH (Exception Handling Model)
/Ob (Inline Function Expansion)
3/12/2019 • 2 minutes to read • Edit Online

Controls inline expansion of functions.

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.

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 Configuration Properties, C/C++, and select Optimization.
3. Modify the Inline Function Expansion property.
To set this compiler option programmatically
See InlineFunctionExpansion.

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

Turns off all optimizations in the program and speeds compilation.

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

Minimizes or maximizes the size of EXEs and DLLs.

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:

mov eax, DWORD PTR _x$[ebp]


imul eax, 71 ; 00000047H

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:

mov eax, DWORD PTR _x$[ebp]


mov ecx, eax
shl eax, 3
lea eax, DWORD PTR [eax+eax*8]
sub eax, ecx

END x86 Specific


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 Favor Size or Speed property.
To set this compiler option programmatically
See FavorSizeOrSpeed.

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

Suppresses creation of frame pointers on the call stack.

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

Causes the compiler to process #pragma omp.

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>

volatile DWORD dwStart;


volatile int global = 0;

double test2(int num_steps) {


int i;
global++;
double x, pi, sum = 0.0, step;

step = 1.0 / (double) num_steps;

#pragma omp parallel for reduction(+:sum) private(x)


for (i = 1; i <= num_steps; i++) {
x = (i - 0.5) * step;
sum = sum + 4.0 / (1.0 + x*x);
}

pi = step * sum;
return pi;
}

int main(int argc, char* argv[]) {


double d;
int n = 1000000;

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 func(int default); // Error C2321: 'default' is a keyword, and


// cannot be used in this context

Lookup members in dependent base

template <typename T>


struct B {
void f();
};

template <typename T>


struct D : public B<T> // B is a dependent base because its type
// depends on the type of T.
{
// One possible fix is to uncomment the following line.
// If this is a type, don't forget the 'typename' keyword.
// using B<T>::f;

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();
}

Use of qualified names in member declarations

struct A {
void A::f() { } // error C4596: illegal qualified name in member
// declaration.
// Remove redundant 'A::' to fix.
};

Initialize multiple union members in a member initializer


union U
{
U()
: i(1), j(1) // error C3442: Initializing multiple members of
// union: 'U::i' and 'U::j'.
// Remove all but one of the initializations to fix.
{}
int i;
int j;
};

Hidden friend name lookup rules

// 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

using type = void (*)(S *);


type p = &f; // error C2065: 'f': undeclared identifier.

// 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.
}

Use scoped enums in array bounds

enum class Color {


Red, Green, Blue
};

int data[Color::Blue]; // error C3411: 'Color' is not valid as the size


// of an array as it is not an integer type.
// Cast to type size_t or int to fix.

Use for each in native code

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)
{
// ...
}
}

Use of ATL Attributes


// Example 1
[uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")]
class A {};

// Fix for example 1


class __declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) B {};

// Example 2
[emitidl];
[module(name="Foo")];

[object, local, uuid("9e66a290-4365-11d2-a997-00c04fa37ddb")]


__interface ICustom {
HRESULT Custom([in] longl, [out, retval] long*pLong);
[local] HRESULT CustomLocal([in] longl, [out, retval] long*pLong);
};

[coclass, appobject, uuid("9e66a294-4365-11d2-a997-00c04fa37ddb")]


class CFoo : public ICustom
{};

// Fix for example 2


// First, create the *.idl file. The vc140.idl generated file can be
// used to automatically obtain a *.idl file for the interfaces with
// annotation. Second, add a midl step to your build system to make
// sure that the C++ interface definitions are outputted.
// Last, adjust your existing code to use ATL directly as shown in
// the atl implementation section.

-- IDL FILE--
import "docobj.idl";

[object, local, uuid(9e66a290-4365-11d2-a997-00c04fa37ddb)]


interface ICustom : IUnknown {
HRESULT Custom([in] longl, [out,retval] long*pLong);
[local] HRESULT CustomLocal([in] longl, [out,retval] long*pLong);
};

[ version(1.0), uuid(29079a2c-5f3f-3325-99a1-3ec9c40988bb) ]
library Foo {
importlib("stdole2.tlb");
importlib("olepro32.dll");

[version(1.0), appobject, uuid(9e66a294-4365-11d2-a997-00c04fa37ddb)]


coclass CFoo { interface ICustom; };
}

-- ATL IMPLEMENTATION--
#include <idl.header.h>
#include <atlbase.h>

class ATL_NO_VTABLE CFooImpl : public ICustom,


public ATL::CComObjectRootEx<CComMultiThreadModel>
{
public:BEGIN_COM_MAP(CFooImpl)
COM_INTERFACE_ENTRY(ICustom)
END_COM_MAP()
};

Ambiguous conditional operator arguments


In versions of the compiler before Visual Studio 2017 version 15.3, the compiler accepted arguments to the
conditional operator (or ternary operator) ?: that are considered ambiguous by the Standard. In /permissive-
mode, the compiler now issues one or more diagnostics in cases that compiled without diagnostics in earlier
versions.
Commmon errors that may result from this change include:
error C2593: 'operator ?' is ambiguous
error C2679: binary '?': no operator found which takes a right-hand operand of type 'B' (or there is no
acceptable conversion)
error C2678: binary '?': no operator found which takes a left-hand operand of type 'A' (or there is no
acceptable conversion)
error C2446: ':': no conversion from 'B' to 'A'
A typical code pattern that can cause this issue is when some class C provides both a non-explicit constructor
from another type T and a non-explicit conversion operator to type T. In this case, both the conversion of the
2nd argument to the type of the 3rd and the conversion of the 3rd argument to the type of the 2nd are valid
conversions, which is ambiguous according to the standard.

// Example 1: class that provides conversion to and initialization from some type T
struct A
{
A(int);
operator int() const;
};

extern bool cond;

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.

// Example 2: exception from the above


struct MyString
{
MyString(const char* s = "") noexcept; // from char*
operator const char* () const noexcept; // to char*
};

extern bool cond;

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.

// Example 4: different result types


extern bool cond;
extern int count;
char a = 'A';
const char b = 'B';
decltype(auto) x = cond ? a : b; // char without, const char& with /Zc:ternary
const char (&z)[2] = count > 3 ? "A" : "B"; // const char* without /Zc:ternary

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 templates as required for two-phase name look-up. In Visual
Studio 2017 version 15.3, name dependency analysis is performed. In particular, non-dependent names that are
not declared in the context of a template definition cause a diagnostic message as required by the ISO C++
standards. In Visual Studio 2017 version 15.7, binding of non-dependent names that require argument
dependent look up in the definition context is also done.

// 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

C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\wrl\async.h(483): error C3861:


'TraceDelegateAssigned': identifier not found
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\wrl\async.h(491): error C3861:
'CheckValidStateForDelegateCall': identifier not found
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\wrl\async.h(509): error C3861:
'TraceProgressNotificationStart': identifier not found
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\wrl\async.h(513): error C3861:
'TraceProgressNotificationComplete': identifier not found

Issue in winrt/wrl/implements.h

C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt\wrl\implements.h(2086): error


C2039: 'SetStrongReference': is not a member of 'Microsoft::WRL::Details::WeakReferenceImpl'

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

C:\ProgramFiles(x86)\Windows Kits\10\include\10.0.17134.0\um\tune.h(139): error C3861: 'Release':


identifier not found
C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\tune.h(559): error C3861: 'Release':
identifier not found
C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\tune.h(1240): error C3861: 'Release':
identifier not found
C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\tune.h(1240): note: 'Release':
function declaration must be available as none of the arguments depend on a template parameter

Issue in um/spddkhlp.h

C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\spddkhlp.h(759): error C3861: 'pNode':


identifier not found

Issues in um/refptrco.h

C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\refptrco.h(179): error C2760: syntax


error: unexpected token 'identifier', expected 'type specifier'
C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\refptrco.h(342): error C2760: syntax
error: unexpected token 'identifier', expected 'type specifier'
C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um\refptrco.h(395): error C2760: syntax
error: unexpected token 'identifier', expected 'type specifier'

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:

typedef enum UICCDATASTOREACCESSMODE UICCDATASTOREACCESSMODE; // C4471

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.

virtual /* [id] */ HRESULT STDMETHODCALLTYPE setExpression(


/* [in] */ __RPC__in BSTR propname,
/* [in] */ __RPC__in BSTR expression,
/* [in][defaultvalue] */ __RPC__in BSTR language = L"") = 0; // C2440

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

Generates inline code for transcendental functions.

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>

char get8bits(int value, int position) {


_ASSERT(position < 32);
return (char)(value >> position);
// Try the following line instead:
// return (char)((value >> position) & 0xff);
}

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:

WARNING ENABLED BY /SDL EQUIVALENT COMMAND-LINE SWITCH DESCRIPTION

C4146 /we4146 A unary minus operator was applied to


an unsigned type, resulting in an
unsigned result.

C4308 /we4308 A negative integral constant converted


to unsigned type, resulting in a possibly
meaningless result.

C4532 /we4532 Use of continue , break or goto


keywords in a __finally / finally
block has undefined behavior during
abnormal termination.

C4533 /we4533 Code initializing a variable will not be


executed.

C4700 /we4700 Use of an uninitialized local variable.

C4703 /we4703 Use of a potentially uninitialized local


pointer variable.

C4789 /we4789 Buffer overrun when specific C run-time


(CRT) functions are used.

C4995 /we4995 Use of a function marked with pragma


deprecated.

C4996 /we4996 Use of a function marked as


deprecated.
Runtime checks
When /sdl is enabled, the compiler generates code to perform these checks at run time:
Enables the strict mode of /GS run-time buffer overrun detection, equivalent to compiling with
#pragma strict_gs_check(push, on) .

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:

Note: including file: d:\MyDir\include\stdio.h

Nested include files are indicated by an indentation, one space for each level of nesting, for example:

Note: including file: d:\temp\1.h


Note: including file: d:\temp\2.h

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.

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++, Language.
3. In C++ Language Standard, choose the language standard to support from the dropdown control, then
choose OK or Apply to save your changes.

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.

CL MAIN.C /TcTEST.PRG /TcCOLLATE.PRG 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.

CL TEST1.C TEST2.CXX TEST3.HUH TEST4.O /Tc TEST5.Z /TP


See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/U, /u (Undefine Symbols)
3/12/2019 • 2 minutes to read • Edit Online

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

_CHAR_UNSIGNED Default char type is unsigned. Defined when the /J option is


specified.

_CPPRTTI Defined for code compiled with the /GR option.

_CPPUNWIND Defined for code compiled with the /EHsc option.

_DLL Defined when the /MD option is specified.

_M_IX86 By default, defined to 600 for x86 targets.

_MSC_VER For more information, see Predefined Macros.

_WIN32 Defined for WIN32 applications. Always defined.

_MT Defined when the /MD or /MT option is specified.

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 Undefine Preprocessor Definitions or Undefine All Preprocessor Definitions properties.
To set this compiler option programmatically
See UndefineAllPreprocessorDefinitions or UndefinePreprocessorDefinitions.

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

Deprecated. Embeds a text string in the .obj file.

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

/vmm Specifies the most general representation of a pointer to a


member of a class to be one that uses multiple inheritance.

The corresponding inheritance keyword and argument to


#pragma pointers_to_members is multiple_inheritance.

This representation is larger than that required for single


inheritance.

If the inheritance model of a class definition for which a


pointer to a member is declared is virtual, the compiler
generates an error.

/vms Specifies the most general representation of a pointer to a


member of a class to be one that uses either no inheritance
or single inheritance.

The corresponding inheritance keyword and argument to


#pragma pointers_to_members is single_inheritance.

This is the smallest possible representation of a pointer to a


member of a class.

If the inheritance model of a class definition for which a


pointer to a member is declared is multiple or virtual, the
compiler generates an error.

/vmv Specifies the most general representation of a pointer to a


member of a class to be one that uses virtual inheritance. It
never causes an error and is the default.

The corresponding inheritance keyword and argument to


#pragma pointers_to_members is virtual_inheritance.

This option requires a larger pointer and additional code to


interpret the pointer than the other options.
When you specify one of these inheritance-model options, that model is used for all pointers to class members,
regardless of their inheritance type or whether the pointer is declared before or after the class. Therefore, if you
always use single-inheritance classes, you can reduce code size by compiling with /vms; however, if you want to
use the most general case (at the expense of the largest data representation), compile with /vmv.
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
/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

Specifies how the volatile keyword is to be interpreted.

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

Specifies how the compiler generates warnings for a given compilation.

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

/w Suppresses all compiler warnings.

/W0 Specifies the level of warnings to be generated by the


compiler. Valid warning levels range from 0 to 4:
/W1 /W0 suppresses all warnings. This is equivalent to /w.
/W1 displays level 1 (severe) warnings. /W1 is the default
/W2 setting in the command line compiler.
/W2 displays level 1 and level 2 (significant) warnings.
/W3 /W3 displays level 1, level 2 and level 3 (production
quality) warnings. /W3 is the default setting in the IDE.
/W4 /W4 displays level 1, level 2, and level 3 warnings, and all
level 4 (informational) warnings that are not turned off by
default. We recommend that you use this option to
provide lint-like warnings. For a new project, it may be
best to use /W4 in all compilations; this will ensure the
fewest possible hard-to-find code defects.

/Wall Displays all warnings displayed by /W4 and all other


warnings that /W4 does not include—for example,
warnings that are off by default. For more information,
see Compiler Warnings That Are Off By Default.
OPTION DESCRIPTION

/Wv[:version] Displays only warnings introduced in compiler version


version and earlier. You can use this option to suppress
new warnings in code when you migrate to a newer
version of the compiler, and to maintain your existing
build process while you fix them. The optional parameter
version takes the form nn[.mm[.bbbbb]] where nn is the
major version number, mm is the optional minor version
number, and bbbbb is the optional build number of the
compiler. For example, use /Wv:17 to display warnings
introduced in Visual Studio 2012 (that is, any version of
the compiler that has a major version number of 17) or
earlier, but suppress warnings introduced in Visual Studio
2013 (major version 18) and later. By default, /Wv uses
the current compiler version number, and no warnings are
suppressed. For information about which warnings are
suppressed by compiler version, see Compiler Warnings
by compiler version.

/WX Treats all compiler warnings as errors. For a new project, it


may be best to use /WX in all compilations; resolving all
warnings ensures the fewest possible hard-to-find code
defects.

The linker also has a /WX option. For more information,


see /WX (Treat Linker Warnings as Errors).

/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.

For example, /w34326 causes C4326 to be generated as


a level 3 warning instead of level 1. If you compile by
using both the /w34326 option and the /W2 option,
warning C4326 is not generated.

/wdnnnn Suppresses the compiler warning that is specified by


nnnn.

For example, /wd4326 suppresses compiler warning


C4326.

/wennnn Treats the compiler warning that is specified by nnnn as


an error.

For example, /we4326 causes warning number C4326 to


be treated as an error by the compiler.

/wonnnn Reports the compiler warning that is specified by nnnn


only once.

For example, /wo4326 causes warning C4326 to be


reported only once, the first time it is encountered by the
compiler.

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

Appends additional information to an error or warning message.

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
}

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
/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:

CL /YcETC.H /Z7 F.CPP

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:

CL /YuETC.H /Z7 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 .

On the command line, no space is allowed between /Yu and filename .


When you specify the /Yu option without a file name, your source program must contain a #pragma hdrstop
pragma that specifies the file name of the precompiled header, .pch file. In this case, the compiler will use the
precompiled header (.pch file) named by /Fp (Name .Pch File). The compiler skips to the location of that pragma,
restores the compiled state from the precompiled header file specified by the pragma, and then compiles only
code that follows the pragma. If #pragma hdrstop does not specify a file name, the compiler looks for a file
with a name derived from the base name of the source file with a .pch extension. You can also use the /Fp
option to specify a different .pch file.
If you specify the /Yu option without a file name and fail to specify a hdrstop pragma, an error message is
generated and the compilation is unsuccessful.
If the /Yc filename and /Yu filename options occur on the same command line and both reference the same
file name, /Yc filename takes precedence, precompiling all code up to and including the named file. This feature
simplifies the writing of makefiles.
Because .pch files contain information about the machine environment as well as memory address information
about the program, you should only use a pch file on the machine where it was created.
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. Specify /Yc (Create Precompiled Header File) on a .cpp file in your project.
2. Open the project's Property Pages dialog box. For details, see Set C++ compiler and build properties in
Visual Studio.
3. Click the C/C++ folder.
4. Click the Precompiled Headers property page.
5. Modify the Create/Use PCH Through File property or the Create/Use Precompiled Header
property.
To set this compiler option programmatically
See PrecompiledHeaderThrough and UsePrecompiledHeader.

Examples
If the following code:

#include <afxwin.h> // Include header for class library


#include "resource.h" // Include resource definitions
#include "myapp.h" // Include information specific to this app
...

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:

CL /YuMYAPP.H /FpMYPCH.pch PROG.CPP

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.

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++ > General property page.
3. Modify the Debug Information Format property. Choose OK to save your changes.
To set this compiler option programmatically
See DebugInformationFormat.

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.

The Microsoft C/C++ compiler supports compilation of C code in two ways:


The compiler uses C compilation mode by default when a source file has a .c extension, or when
the /Tc or /TC option is specified. The C compiler is an C89/C90 compiler that, by default, enables
Microsoft extensions to the C language. For more information about specific extensions, see
Microsoft Extensions to C and C++. When both C compilation and the /Za option are specified,
the C compiler conforms strictly to the C89/C90 standard. The compiler treats Microsoft extended
keywords as simple identifiers, disables the other Microsoft extensions, and automatically defines
the __STDC__ predefined macro for C programs.
The compiler can compile C code in C++ compilation mode. This behavior is the default for source
files that don't have a .c extension, and when the /Tp or /TP option is specified. In C++ compilation
mode, the compiler supports those parts of the ISO C99 and C11 standards that have been
incorporated into the C++ standard. Almost all C code is also valid C++ code. A small number of C
keywords and code constructs aren't valid C++ code, or are interpreted differently in C++. The
compiler behaves according to the C++ standard in these cases. In C++ compilation mode, the
/Za option may cause unexpected behavior and isn't recommended.
Other compiler options can affect how the compiler ensures standards conformance. For ways to specify
specific standard C and C++ behavior settings, see the /Zc compiler option. For additional C++ standard
conformance settings, see the /permissive- and /std compiler options.
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. In the navigation pane, choose Configuration Properties > C/C++ > Language.
3. Modify the Disable Language Extensions property.
To set this compiler option programmatically
See DisableLanguageExtensions.

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.

Out of class definition of static const integral (or enum) members


Under the standard (/Za), you must make an out-of-class definition for data members, as shown here:

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:

__declspec(selectany) const int CMyClass::max = 5;

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.

p = ( char * )(( int * )p + 1 );

Non-ANSI casts of a function pointer to a data pointer. For example:


int ( * pfunc ) ();
int *pdata;
pdata = ( int * ) pfunc;

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:

pdata = ( int * ) (uintptr_t) pfunc;

Variable-length argument lists


Both the C++ compiler and C compiler support a function declarator that specifies a variable number of
arguments, followed by a function definition that provides a type instead:

void myfunc( int x, ... );


void myfunc( int x, char * c )
{ }

Single-line comments
The C compiler supports single-line comments, which are introduced by using two forward slash (//) characters:

// This is a single-line comment.

Scope
The C compiler supports the following scope-related features.
Redefinitions of extern items as static:

extern int clip();


static int clip()
{}

Use of benign typedef redefinitions within the same scope:

typedef int INT;


typedef int INT;

Function declarators have file scope:

void func1()
{
extern int func2( double );
}
int main( void )
{
func2( 4 ); // /Ze passes 4 as type double
} // /Za passes 4 as type int

Use of block-scope variables that are initialized by using nonconstant expressions:


int clip( int );
int bar( int );
int main( void )
{
int array[2] = { clip( 2 ), bar( 4 ) };
}
int clip( int x )
{
return x;
}
int bar( int x )
{
return x;
}

Data declarations and definitions


The C compiler supports the following data declaration and definition features.
Mixed character and string constants in an initializer:

char arr[5] = {'a', 'b', "cde"};

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;
}

Unsized arrays as the last field in structures and unions:

struct zero
{
char *c;
int zarray[];
};

Unnamed (anonymous) structures:

struct
{
int i;
char *s;
};

Unnamed (anonymous) unions:

union
{
int i;
float fl;
};
Unnamed members:

struct s
{
unsigned int flag : 1;
unsigned int : 31;
}

Intrinsic floating-point functions


Both the x86 C++ compiler and C compiler support inline generation of the atan , atan2 , cos , exp , log ,
log10 , sin , sqrt , and tan functions when /Oi is specified. For the C compiler, ANSI conformance is lost when
these intrinsics are used, because they do not set the errno variable.

Passing a non-const pointer parameter to a function that expects a


reference to a const pointer parameter
This is an extension to C++. This code will compile with /Ze:

typedef int T;

const T acT = 9; // A constant of type 'T'


const T* pcT = &acT; // A pointer to a constant of type 'T'

void func2 ( const T*& rpcT ) // A reference to a pointer to a constant of type 'T'
{
rpcT = pcT;
}

T* pT; // A pointer to a 'T'

void func ()
{
func2 ( pT ); // Should be an error, but isn't detected
*pT = 7; // Invalidly overwrites the constant 'acT'
}

ISO646.H not enabled


Under /Ze, you have to include iso646.h if you want to use text forms of the following operators:
&& (and)
&= (and_eq)
& (bitand)
| (bitor)
~ (compl)
! (not)
!= (not_eq)
|| (or)
|= (or_eq)
^ (xor)
^= (xor_eq)

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

alignedNew[-] Enable C++17 over-aligned dynamic allocation (on by


default in C++17).

auto[-] Enforce the new Standard C++ meaning for auto (on by
default).

__cplusplus[-] Enable the __cplusplus macro to report the supported


standard (off by default).

externConstexpr[-] Enable external linkage for constexpr variables (off by


default).

forScope[-] Enforce Standard C++ for scoping rules (on by default).

implicitNoexcept[-] Enable implicit noexcept on required functions (on by


default).

inline[-] Remove unreferenced function or data if it is COMDAT or


has internal linkage only (off by default).

noexceptTypes[-] Enforce C++17 noexcept rules (on by default in C++17 or


later).

referenceBinding[-] A UDT temporary will not bind to an non-const lvalue


reference (off by default).
OPTION BEHAVIOR

rvalueCast[-] Enforce Standard C++ explicit type conversion rules (off by


default).

sizedDealloc[-] Enable C++14 global sized deallocation functions (on by


default).

strictStrings[-] Disable string-literal to char* or wchar_t* conversion


(off by default).

ternary[-] Enforce conditional operator rules on operand types (off by


default).

threadSafeInit[-] Enable thread-safe local static initialization (on by default).

throwingNew[-] Assume operator new throws on failure (off by default).

trigraphs[-] Enable trigraphs (obsolete, off by default).

twoPhase- Use non-conforming template parsing behavior (conforming


by default).

wchar_t[-] wchar_t is a native type, not a typedef (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>

// "old" unaligned overloads


void* operator new(std::size_t size) {
auto ptr = malloc(size);
std::cout << "unaligned new(" << size << ") = " << ptr << '\n';
return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size) {


std::cout << "unaligned sized delete(" << ptr << ", " << size << ")\n";
free(ptr);
}

void operator delete(void* ptr) {


std::cout << "unaligned unsized delete(" << ptr << ")\n";
free(ptr);
}

// "new" over-aligned overloads


void* operator new(std::size_t size, std::align_val_t align) {
auto ptr = _aligned_malloc(size, static_cast<std::size_t>(align));
std::cout << "aligned new(" << size << ", " <<
static_cast<std::size_t>(align) << ") = " << ptr << '\n';
return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size, std::align_val_t align) {


std::cout << "aligned sized delete(" << ptr << ", " << size <<
", " << static_cast<std::size_t>(align) << ")\n";
_aligned_free(ptr);
}

void operator delete(void* ptr, std::align_val_t align) {


std::cout << "aligned unsized delete(" << ptr <<
", " << static_cast<std::size_t>(align) << ")\n";
_aligned_free(ptr);
}

struct alignas(256) OverAligned {}; // warning C4324, structure is padded

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.

unaligned new(4) = 009FD0D0


unaligned sized delete(009FD0D0, 4)
aligned new(256, 256) = 009FE800
aligned sized delete(009FE800, 256, 256)

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:

/ZC:__CPLUSPLUS SWITCH /STD:C++ SWITCH __CPLUSPLUS VALUE

Zc:__cplusplus /std:c++14 (default) 201402L

Zc:__cplusplus /std:c++17 201703L

Zc:__cplusplus /std:c++latest 201704L

Zc:__cplusplus- (disabled) Any value 199711L

Not specified Any value 199711L

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

void f() throw(); // equivalent to void f() noexcept;


void f() { } // warning C5043
void g() throw(...); // warning C5040

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>

template <typename T>


struct Thing {
// Construct a Thing by using two rvalue reference parameters
Thing(T&& t1, T&& t2)
: thing1(t1), thing2(t2) {}

T& thing1;
T& thing2;
};

// Create a Thing, using move semantics if possible


template <typename T>
Thing<T> make_thing(T&& t1, T&& t2)
{
return (Thing<T>(std::forward<T>(t1), std::forward<T>(t2)));
}

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.

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:sizedDealloc or /Zc:sizedDealloc- and then
choose OK.

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
}

To fix this code, cast one of the operands explicitly.


Under /Zc:ternary, the compiler rejects conditional operators where one of the arguments is of type void and the
other is not a throw expression. A common use of these is in ASSERT-like macros:

// zcternary3.cpp
// Compile by using: cl /EHsc /W4 /nologo /Zc:ternary /c zcternary3.cpp

void myassert(const char* text, const char* file, int line);


#define ASSERT(ex) (void)((ex) ? 0 : myassert(#ex, __FILE__, __LINE__))
// To fix, define it this way instead:
// #define ASSERT(ex) (void)((ex) ? void() : myassert(#ex, __FILE__, __LINE__))

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
}

This code previously gave this error:


error C2446: ':': no conversion from 'foo::<lambda_f6cd18702c42f6cd636bfee362b37033>' to 'foo::
<lambda_717fca3fc65510deea10bc47e2b06be4>'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot
be called

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:

error C2593: 'operator ?' is ambiguous


note: could be 'built-in C++ operator?(bool (__cdecl *)(int,int), bool (__cdecl *)(int,int))'
note: or 'built-in C++ operator?(bool (__stdcall *)(int,int), bool (__stdcall *)(int,int))'
note: or 'built-in C++ operator?(bool (__fastcall *)(int,int), bool (__fastcall *)(int,int))'
note: or 'built-in C++ operator?(bool (__vectorcall *)(int,int), bool (__vectorcall *)(int,int))'
note: while trying to match the argument list '(foo::<lambda_717fca3fc65510deea10bc47e2b06be4>, foo::
<lambda_f6cd18702c42f6cd636bfee362b37033>)'

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

int main(int argc, char**) {


char a = 'A';
const char b = 'B';
decltype(auto) x = true ? a : b; // char without, const char& with /Zc:ternary
const char(&z)[2] = argc > 3 ? "A" : "B"; // const char* without /Zc:ternary
return x > *z;
}

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:

#pragma comment(linker, "/ThrowingNew")

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.

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:trigraphs or /Zc:trigraphs- and then choose OK.

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:

template <typename T> class Derived : public Base<T> { ... }

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>

void func(void*) { std::puts("The call resolves to void*") ;}

template<typename T> void g(T x)


{
func(0);
}

void func(int) { std::puts("The call resolves to int"); }

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>

void func(long) { std::puts("func(long)"); }

template <typename T> void tfunc(T t) {


func(t);
}

void func(int) { std::puts("func(int)"); }

namespace NS {
struct S {};
void func(S) { std::puts("NS::func(NS::S)"); }
}

int main() {
tfunc(1729);
NS::S s;
tfunc(s);
}

When compiled without /Zc:twoPhase-, this prints

func(long)
NS::func(NS::S)

When compiled with /Zc:twoPhase-, this prints

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

Parse wchar_t as a built-in type according to the C++ standard.

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
}

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 Omit Default Library Names property.
To set this compiler option programmatically
See OmitDefaultLibName.

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.

VALUE OF FACTOR MEMORY ALLOCATION LIMIT

10 7.5 MB

100 75 MB

200 150 MB

1000 750 MB
VALUE OF FACTOR MEMORY ALLOCATION LIMIT

2000 1500 MB

Other Ways to Set the Memory Allocation Limit


To set the /Zm 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, select Configuration Properties > C/C++ > Command Line.
3. Enter the /Zm compiler option in the Additional Options box.
To set the /Zm compiler option programmatically
See AdditionalOptions.

See also
MSVC Compiler Options
MSVC Compiler Command-Line Syntax
/Zo (Enhance Optimized Debugging)
3/12/2019 • 2 minutes to read • Edit Online

Generate enhanced debugging information for optimized code in non-debug builds.

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:

/ZP ARGUMENT EFFECT

1 Packs structures on 1-byte boundaries. Same as /Zp.

2 Packs structures on 2-byte boundaries.

4 Packs structures on 4-byte boundaries.

8 Packs structures on 8-byte boundaries (default).

16 Packs structures on 16-byte boundaries.

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.

Source code files


Unicode characters are supported in identifiers, macros, string and character literals, and in comments. Universal
character names are also supported.
Unicode can be input into a source code file in the following encodings:
UTF -16 little endian with or without byte order mark (BOM )
UTF -16 big endian with or without BOM
UTF -8 with BOM

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.

Linker response files and .DEF files


Response files and DEF files can be either UTF -16 with a BOM, or ANSI.

.asm and .cod dumps


.asm and .cod dumps are in ANSI by default for compatibility with MASM. Use /FAu to output UTF -8. Note that if
you specify /FAs, the intermingled source will just be directly printed and may look garbled, for example if source
code is UTF -8 and you didn't specify /FAsu.

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.

Linker command-line syntax


When you run LINK outside of Visual Studio, you can specify input in one or more ways:
On the command line
Using command files
In environment variables
LINK first processes options specified in the LINK environment variable, followed by options in the
order they are specified on the command line and in command files. If an option is repeated with
different arguments, the last one processed takes precedence.
Options apply to the entire build; no options can be applied to specific input files.
To run LINK.EXE, use the following command syntax:

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 Command Files


You can pass command-line arguments to LINK in the form of a command file. To specify a
command file to the linker, use the following syntax:

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 /dll @objlist.txt @liblist.txt @exports.txt

LINK Environment Variables


The LINK tool uses the following environment variables:
LINK and _LINK_, if defined. The LINK tool prepends the options and arguments defined in
the LINK environment variable and appends the options and arguments defined in the _LINK_
environment variable to the command line arguments before processing.
LIB, if defined. The LINK tools uses the LIB path when searching for an object, library, or other
file specified on the command line or by the /BASE option. It also uses the LIB path to find a
.pdb file named in an object. The LIB variable can contain one or more path specifications,
separated by semicolons. One path must point to the \lib subdirectory of your Visual C++
installation.
PATH, if the tool needs to run CVTRES and cannot find the file in the same directory as LINK
itself. (LINK requires CVTRES to link a .res file.) PATH must point to the \bin subdirectory of
your Visual C++ installation.
TMP, to specify a directory when linking OMF or .res files.
See also
C/C++ Building Reference MSVC Linker Options Module-Definition (.def) Files Linker Support for
Delay-Loaded DLLs
Linker Options
3/12/2019 • 5 minutes to read • Edit Online

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

@ Specifies a response file.

/ALIGN Specifies the alignment of each section.

/ALLOWBIND Specifies that a DLL cannot be bound.

/ALLOWISOLATION Specifies behavior for manifest lookup.

/APPCONTAINER Specifies whether the app must run within an


appcontainer process environment.

/ASSEMBLYDEBUG Adds the DebuggableAttribute to a managed image.

/ASSEMBLYLINKRESOURCE Creates a link to a managed resource.

/ASSEMBLYMODULE Specifies that a Microsoft intermediate language


(MSIL) module should be imported into the assembly.

/ASSEMBLYRESOURCE Embeds a managed resource file in an assembly.

/BASE Sets a base address for the program.

/CGTHREADS Sets number of cl.exe threads to use for optimization


and code generation when link-time code generation
is specified.

/CLRIMAGETYPE Sets the type (IJW, pure, or safe) of a CLR image.


OPTION PURPOSE

/CLRSUPPORTLASTERROR Preserves the last error code of functions that are


called through the P/Invoke mechanism.

/CLRTHREADATTRIBUTE Specifies the threading attribute to apply to the entry


point of your CLR program.

/CLRUNMANAGEDCODECHECK Specifies whether the linker will apply the


SuppressUnmanagedCodeSecurity attribute to linker-
generated PInvoke stubs that call from managed
code into native DLLs.

/DEBUG Creates debugging information.

/DEBUGTYPE Specifies which data to include in debugging


information.

/DEF Passes a module-definition (.def) file to the linker.

/DEFAULTLIB Searches the specified library when external


references are resolved.

/DELAY Controls the delayed loading of DLLs.

/DELAYLOAD Causes the delayed loading of the specified DLL.

/DELAYSIGN Partially signs an assembly.

/DEPENDENTLOADFLAG Sets default flags on dependent DLL loads.

/DLL Builds a DLL.

/DRIVER Creates a kernel mode driver.

/DYNAMICBASE Specifies whether to generate an executable image


that can be randomly rebased at load time by using
the address space layout randomization (ASLR)
feature.

/ENTRY Sets the starting address.

/errorReport Reports internal linker errors to Microsoft.

/EXPORT Exports a function.

/FILEALIGN Aligns sections within the output file on multiples of a


specified value.

/FIXED Creates a program that can be loaded only at its


preferred base address.

/FORCE Forces a link to complete even with unresolved


symbols or symbols defined more than once.
OPTION PURPOSE

/FUNCTIONPADMIN Creates an image that can be hot patched.

/GENPROFILE, /FASTGENPROFILE Both of these options specify generation of a .pgd file


by the linker to support profile-guided optimization
(PGO). /GENPROFILE and /FASTGENPROFILE use
different default parameters.

/GUARD Enables Control Flow Guard protection.

/HEAP Sets the size of the heap, in bytes.

/HIGHENTROPYVA Specifies support for high-entropy 64-bit address


space layout randomization (ASLR).

/IDLOUT Specifies the name of the .idl file and other MIDL
output files.

/IGNORE Suppresses output of specified linker warnings.

/IGNOREIDL Prevents the processing of attribute information into


an .idl file.

/IMPLIB Overrides the default import library name.

/INCLUDE Forces symbol references.

/INCREMENTAL Controls incremental linking.

/INTEGRITYCHECK Specifies that the module requires a signature check


at load time.

/KEYCONTAINER Specifies a key container to sign an assembly.

/KEYFILE Specifies a key or key pair to sign an assembly.

/LARGEADDRESSAWARE Tells the compiler that the application supports


addresses larger than two gigabytes

/LIBPATH Specifies a path to search before the environmental


library path.

/LTCG Specifies link-time code generation.

/MACHINE Specifies the target platform.

/MANIFEST Creates a side-by-side manifest file and optionally


embeds it in the binary.

/MANIFESTDEPENDENCY Specifies a <dependentAssembly> section in the


manifest file.

/MANIFESTFILE Changes the default name of the manifest file.


OPTION PURPOSE

/MANIFESTINPUT Specifies a manifest input file for the linker to process


and embed in the binary. You can use this option
multiple times to specify more than one manifest
input file.

/MANIFESTUAC Specifies whether User Account Control (UAC)


information is embedded in the program manifest.

/MAP Creates a mapfile.

/MAPINFO Includes the specified information in the mapfile.

/MERGE Combines sections.

/MIDL Specifies MIDL command-line options.

/NATVIS Adds debugger visualizers from a Natvis file to the


PDB.

/NOASSEMBLY Suppresses the creation of a .NET Framework


assembly.

/NODEFAULTLIB Ignores all (or the specified) default libraries when


external references are resolved.

/NOENTRY Creates a resource-only DLL.

/NOLOGO Suppresses the startup banner.

/NXCOMPAT Marks an executable as verified to be compatible with


the Windows Data Execution Prevention feature.

/OPT Controls LINK optimizations.

/ORDER Places COMDATs into the image in a predetermined


order.

/OUT Specifies the output file name.

/PDB Creates a program database (PDB) file.

/PDBALTPATH Uses an alternate location to save a PDB file.

/PDBSTRIPPED Creates a program database (PDB) file that has no


private symbols.

/PGD Specifies a .pgd file for profile-guided optimizations.

/POGOSAFEMODE Obsolete Creates a thread-safe PGO instrumented


build.
OPTION PURPOSE

/PROFILE Produces an output file that can be used with the


Performance Tools profiler.

/RELEASE Sets the Checksum in the .exe header.

/SAFESEH Specifies that the image will contain a table of safe


exception handlers.

/SECTION Overrides the attributes of a section.

/SOURCELINK Specifies a SourceLink file to add to the PDB.

/STACK Sets the size of the stack in bytes.

/STUB Attaches an MS-DOS stub program to a Win32


program.

/SUBSYSTEM Tells the operating system how to run the .exe file.

/SWAPRUN Tells the operating system to copy the linker output


to a swap file before it is run.

/TLBID Specifies the resource ID of the linker-generated type


library.

/TLBOUT Specifies the name of the .tlb file and other MIDL
output files.

/TSAWARE Creates an application that is designed specifically to


run under Terminal Server.

/USEPROFILE Uses profile-guided optimization training data to


create an optimized image.

/VERBOSE Prints linker progress messages.

/VERSION Assigns a version number.

/WHOLEARCHIVE Includes every object file from specified static libraries.

/WINMD Enables generation of a Windows Runtime Metadata


file.

/WINMDFILE Specifies the file name for the Windows Runtime


Metadata (winmd) output file that's generated by the
/WINMD linker option.

/WINMDKEYFILE Specifies a key or key pair to sign a Windows Runtime


Metadata file.

/WINMDKEYCONTAINER Specifies a key container to sign a Windows Metadata


file.
OPTION PURPOSE

/WINMDDELAYSIGN Partially signs a Windows Runtime Metadata (.winmd)


file by placing the public key in the winmd file.

/WX Treats linker warnings as errors.

For more information, see Compiler-Controlled LINK Options.

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.

CL SPECIFICATION CL ACTION THAT AFFECTS LINK

Any file name extension other than .c, .cxx, .cpp, or .def Passes a file name as input to LINK

filename.def Passes /DEF:filename.def

/Fnumber Passes /STACK:number

/Fdfilename Passes /PDB:filename

/Fefilename Passes /OUT:filename

/Fmfilename Passes /MAP:filename

/Gy Creates packaged functions (COMDATs); enables function-


level linking

/LD Passes /DLL

/LDd Passes /DLL

/link Passes remainder of command line to LINK

/MD or /MT Places a default library name in the .obj file

/MDd or /MTd Places a default library name in the .obj file. Defines the
symbol _DEBUG

/nologo Passes /NOLOGO

/Zd Passes /DEBUG

/Zi or /Z7 Passes /DEBUG

/Zl Omits default library name from .obj file

For more information, see MSVC Compiler Options.

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).

LINK uses the following types of input files:


.obj files
.netmodule files
.lib files
.exp files
.def files
.pdb files
.res files
.exe files
.txt files
.ilk files

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 {};

ref struct MCPP {


static void Test() {
try {
throw (gcnew V);
}
catch (V ^) {
System::Console::WriteLine("caught non System exception in C++ source code file");
}
}
};

/*
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;

// enable non System exceptions


[assembly:RuntimeCompatibility(WrapNonExceptionThrows=false)]

class MLinkTest {
public static void Main() {
try {
MCPP.Test();
}
catch (RuntimeWrappedException) {
System.Console.WriteLine("caught a wrapped exception in C#");
}
}
}

caught non System exception in C++ source code file

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.

To add .lib files as linker input in the 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 Input property page in the Linker folder.
3. Modify the Additional Dependencies property to add the .lib files.

To programmatically add .lib files as linker input


See AdditionalDependencies.

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

Link output includes .exe files, DLLs, mapfiles, and messages.

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 ("").

APPLOADER1 INITINSTANCE2 PRELOAD

BASE IOPL PRIVATE

CODE LIBRARY1 PROTMODE2

CONFORMING LOADONCALL1 PURE1

DATA LONGNAMES2 READONLY

DESCRIPTION MOVABLE1 READWRITE

DEV386 MOVEABLE1 REALMODE1

DISCARDABLE MULTIPLE RESIDENT

DYNAMIC NAME RESIDENTNAME1

EXECUTE-ONLY NEWFILES2 SECTIONS

EXECUTEONLY NODATA1 SEGMENTS

EXECUTEREAD NOIOPL1 SHARED

EXETYPE NONAME SINGLE

EXPORTS NONCONFORMING1 STACKSIZE

FIXED1 NONDISCARDABLE STUB

FUNCTIONS2 NONE VERSION

HEAPSIZE NONSHARED WINDOWAPI

IMPORTS NOTWINDOWCOMPAT1 WINDOWCOMPAT

IMPURE1 OBJECTS WINDOWS

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

Specifies a linker response file.

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

Specifies behavior for manifest lookup.

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.

/ALLOWISOLATION causes the operating system to do manifest lookups and loads.


/ALLOWISOLATION is the default.
When isolation is disabled for an executable, the Windows loader will not attempt to find an application manifest
for the newly created process. The new process will not have a default activation context, even if there is a manifest
inside the executable or placed in the same directory as the executable with name executable-name.exe.manifest.
For more information, see Manifest Files 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. Select the Configuration Properties > Linker > Manifest File property page.
3. Modify the Allow Isolation property.

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:

[assembly:Debuggable(true, true)]; // same as /ASSEMBLYDEBUG

/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:

[assembly:Debuggable(false, false)]; // same as /ASSEMBLYDEBUG:DISABLE

The default is to not emit the DebuggableAttribute attribute.


DebuggableAttribute can also be added to an assembly directly in source code. For example,

[assembly:Debuggable(true, true)]; // same as /ASSEMBLYDEBUG

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

Specifies the base address for a program.

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:

key address [size] ; comment

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:

main 0x00010000 0x08000000 ; for PROJECT.exe


one 0x28000000 0x00100000 ; for DLLONE.DLL
two 0x28100000 0x00300000 ; for DLLTWO.DLL
If the file that contains these lines is called DLLS.txt, the following example command applies this information:

link dlltwo.obj /dll /base:@dlls.txt,two

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

Set the CLR image type in the linked image.

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:

ACLUI.DLL ACTIVEDS.DLL ADPTIF.DLL ADVAPI32.DLL

ASYCFILT.DLL AUTHZ.DLL AVICAP32.DLL AVIFIL32.DLL

CABINET.DLL CLUSAPI.DLL COMCTL32.DLL COMDLG32.DLL

COMSVCS.DLL CREDUI.DLL CRYPT32.DLL CRYPTNET.DLL

CRYPTUI.DLL D3D8THK.DLL DBGENG.DLL DBGHELP.DLL

DCIMAN32.DLL DNSAPI.DLL DSPROP.DLL DSUIEXT.DLL

GDI32.DLL GLU32.DLL HLINK.DLL ICM32.DLL

IMAGEHLP.DLL IMM32.DLL IPHLPAPI.DLL IPROP.DLL

KERNEL32.DLL KSUSER.DLL LOADPERF.DLL LZ32.DLL

MAPI32.DLL MGMTAPI.DLL MOBSYNC.DLL MPR.DLL

MPRAPI.DLL MQRT.DLL MSACM32.DLL MSCMS.DLL

MSI.DLL MSIMG32.DLL MSRATING.DLL MSTASK.DLL

MSVFW32.DLL MSWSOCK.DLL MTXEX.DLL NDDEAPI.DLL

NETAPI32.DLL NPPTOOLS.DLL NTDSAPI.DLL NTDSBCLI.DLL


NTMSAPI.DLL ODBC32.DLL ODBCBCP.DLL OLE32.DLL

OLEACC.DLL OLEAUT32.DLL OLEDLG.DLL OPENGL32.DLL

PDH.DLL POWRPROF.DLL QOSNAME.DLL QUERY.DLL

RASAPI32.DLL RASDLG.DLL RASSAPI.DLL RESUTILS.DLL

RICHED20.DLL RPCNS4.DLL RPCRT4.DLL RTM.DLL

RTUTILS.DLL SCARDDLG.DLL SECUR32.DLL SENSAPI.DLL

SETUPAPI.DLL SFC.DLL SHELL32.DLL SHFOLDER.DLL

SHLWAPI.DLL SISBKUP.DLL SNMPAPI.DLL SRCLIENT.DLL

STI.DLL TAPI32.DLL TRAFFIC.DLL URL.DLL

URLMON.DLL USER32.DLL USERENV.DLL USP10.DLL

UXTHEME.DLL VDMDBG.DLL VERSION.DLL WINFAX.DLL

WINHTTP.DLL WININET.DLL WINMM.DLL WINSCARD.DLL

WINTRUST.DLL WLDAP32.DLL WOW32.DLL WS2_32.DLL

WSNMP32.DLL WSOCK32.DLL WTSAPI32.DLL XOLEHLP.DLL

NOTE
Preserving the last error is not supported for unmanaged functions that are consumed by CLR code, in the same module.

For more information, see /clr (Common Language Runtime Compilation).


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.

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 comment(lib, "wininet.lib")

double MySqrt(__int64 n);

#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);

hGroup = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL,


0, 0, &groupID, 0);
dwGet = GetLastError();
if (dwGet == 183)
printf_s("GetLastError for system call succeeded (%d).\n",
dwGet);
else
printf_s("GetLastError for system call failed (%d).\n",
dwGet);
}

GetLastError for application call failed (127).


GetLastError for system call succeeded (183).

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

/CLRUNMANAGEDCODECHECK specifies that the linker does not apply


SuppressUnmanagedCodeSecurityAttribute to linker-generated PInvoke calls from managed code into native
DLLs.

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.

/DEBUGTYPE:[CV | PDATA | FIXUP]

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

Specify a default library to search to resolve external references.

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

/DRIVER [:UPONLY |:WDM ]

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.

FUNCTION NAME DEFAULT FOR

mainCRTStartup (or wmainCRTStartup) An application that uses /SUBSYSTEM:CONSOLE; calls main


(or wmain )

WinMainCRTStartup (or wWinMainCRTStartup) An application that uses /SUBSYSTEM:WINDOWS; calls


WinMain (or wWinMain ), which must be defined to use
__stdcall

_DllMainCRTStartup A DLL; calls DllMain if it exists, which must be defined to


use __stdcall

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

/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 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

Exports a function by name or ordinal, or data, from your program.

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:

#pragma comment(linker, "/export:PlainFuncName=_PlainFuncName@4")


BOOL CALLBACK PlainFuncName( Things * lpParams)
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 option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.

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

Prepares an image for hotpatching.

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

LNK4017 keyword statement not supported for the target platform;


ignored

LNK4044 unrecognized option ' option '; ignored

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

LNK4204 ' filename ' is missing debugging information for referencing


module; linking object as if no debug info

LNK4205 ' filename ' is missing current debugging information for


referencing module; 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

LNK4209 debugging information corrupt; recompile module; linking


object as if no debug info

LNK4224 option is no longer supported; ignored

LNK4228 ' option ' invalid for a DLL; ignored

LNK4229 invalid directive / directive found; ignored

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

Use /LTCG to perform whole-program optimization, or to create profile-guided optimization (PGO )


instrumentation, perform training, and create profile-guided optimized builds.

Syntax
/LTCG[:{INCREMENTAL|NOSTATUS|STATUS|OFF}]

These options are deprecated starting in Visual Studio 2015:

/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.

Using /LTCG and /Ogt causes double-alignment optimization.


If /LTCG and /Ogs are specified, double alignment is not performed. If most of the functions in an application
are compiled for speed, with a few functions compiled for size (for example, by using the optimize pragma),
the compiler double-aligns the functions that are optimized for size if they call functions that require double
alignment.
If the compiler can identify all of the call sites of a function, the compiler ignores explicit calling-convention
modifiers on a function and tries to optimize the function's calling convention:
pass parameters in registers
reorder parameters for alignment
remove unused parameters
If a function is called through a function pointer, or if a function is called from outside a module that is
compiled by using /GL, the compiler does not attempt to optimize the function's calling convention.

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.

/LTCG and MSIL Modules


Modules that are compiled by using /GL and /clr can be used as input to the linker when /LTCG is specified.
/LTCG can accept native object files, and mixed native/managed object files (compiled by using /clr).
The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported
in Visual Studio 2017.
/LTCG:PGI does not accept native modules compiled by using /GL and /clr
To set this compiler option in the Visual Studio development environment
1. Open the project Property Pages dialog box. See Set C++ compiler and build properties in Visual
Studio.
2. Select the Configuration Properties > General property page.
3. Modify the Whole Program Optimization property.
You can also apply /LTCG to specific builds by choosing Build > Profile Guided Optimization on the menu
bar, or by choosing one of the Profile Guided Optimization options on the shortcut menu for the project.
To set this compiler option programmatically
See LinkTimeCodeGeneration.

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,

#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Test.Research.SampleAssembly'


version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\"")

which results in the following entry in the manifest file:

<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:

"/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0'


processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\"

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:

"level=[ asInvoker | highestAvailable | requireAdministrator ] uiAccess=[ true | false ]"


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 Enable User Account Control (UAC ), UAC Execution Level, and UAC Bypass UI
Protection properties.
To set this linker option programmatically
1. See EnableUAC, UACExecutionLevel, and UACUIAccess.

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

Specifies a response file for MIDL command line options

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

Controls the optimizations that LINK performs during a build.

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

To set this linker option programmatically


See EnableCOMDATFolding and OptimizeReferences properties.

See also
MSVC linker reference
MSVC Linker Options
/ORDER (Put Functions in Order)
3/12/2019 • 2 minutes to read • Edit Online

Specify the link order for separately packaged (COMDAT) functions.

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.

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 Function Order property to contain the name of your response file.
To set this linker option programmatically
See FunctionOrder.

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.
*/

extern PVOID __safe_se_handler_table[]; /* base of safe handler entry table */


extern BYTE __safe_se_handler_count; /* absolute symbol whose address is
the count of table entries */
typedef struct {
DWORD Size;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD GlobalFlagsClear;
DWORD GlobalFlagsSet;
DWORD CriticalSectionDefaultTimeout;
DWORD DeCommitFreeBlockThreshold;
DWORD DeCommitTotalFreeThreshold;
DWORD LockPrefixTable; // VA
DWORD MaximumAllocationSize;
DWORD VirtualMemoryThreshold;
DWORD ProcessHeapFlags;
DWORD ProcessAffinityMask;
WORD CSDVersion;
WORD Reserved1;
DWORD EditList; // VA
DWORD_PTR *SecurityCookie;
PVOID *SEHandlerTable;
DWORD SEHandlerCount;
} IMAGE_LOAD_CONFIG_DIRECTORY32_2;

const IMAGE_LOAD_CONFIG_DIRECTORY32_2 _load_config_used = {


sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_2),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
&__security_cookie,
__safe_se_handler_table,
(DWORD)(DWORD_PTR) &__safe_se_handler_count
};

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. Enter the option into the Additional Options box.
To set this linker option programmatically
See AdditionalOptions.

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

E Execute The section is executable

R Read Allows read operations on data

W Write Allows write operations on data

S Shared Shares the section among all processes


that load the image

D Discardable Marks the section as discardable

K Cacheable Marks the section as not cacheable

P Pageable Marks the section as not pageable

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:

This program cannot be run in MS-DOS mode.

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.

major and minor


(Optional) Specify the minimum required version of the subsystem. The arguments are decimal numbers in the
range 0 through 65,535. See the Remarks for more information. There are no upper bounds for version
numbers.

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

BOOT_APPLICATION 1.0 1.0

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)

POSIX 1.0 19.90

EFI_APPLICATION, 1.0 1.0


EFI_BOOT_SERVICE_DRIVER, EFI_ROM,
EFI_RUNTIME_DRIVER

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 the SubSystem property.
To set this linker option programmatically
See SubSystem.

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 Displays details about the linking process.

/VERBOSE:ICF Display information about linker activity that results from the
use of /OPT:ICF.

/VERBOSE:INCR Displays information about the incremental link process.

/VERBOSE:LIB Displays progress messages that indicate just the libraries


searched.

The displayed information includes the library search process


and lists each library and object name (with full path), the
symbol being resolved from the library, and a list of objects
that reference the symbol.

/VERBOSE:REF Displays information about linker activity that results from the
use of /OPT:REF.

/VERBOSE:SAFESEH Displays information about modules that are not compatible


with safe exception handling when /SAFESEH is not specified.

/VERBOSE:UNUSEDLIBS Displays information about any library files that are unused
when the image is created.

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 Linker folder.
3. Select the Command Line property page.
4. Add the option to the Additional Options box.
To set this linker option programmatically
See ShowProgress.

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

Enables generation of a Windows Runtime Metadata (.winmd) file.

/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

Specifies a key container to sign a Windows Metadata (.winmd) file.

/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.

Using decorated names


Normally, you don't have to know the decorated name to write code that compiles and links successfully.
Decorated names are an implementation detail internal to the compiler and linker. The tools can usually handle
the name in its undecorated form. However, a decorated name is sometimes required when you specify a function
name to the linker and other tools. For example, to match overloaded C++ functions, members of namespaces,
class constructors, destructors and special member functions, you must specify the decorated name. For details
about the option flags and other situations that require decorated names, see the documentation for the tools and
options that you are using.
If you change the function name, class, calling convention, return type, or any parameter, the decorated name also
changes. In this case, you must get the new decorated name and use it everywhere the decorated name is
specified.
Name decoration is also important when linking to code written in other programming languages or using other
compilers. Different compilers use different name decoration conventions. When your executable links to code
written in another language, special care must be taken to match the exported and imported names and calling
conventions. Assembly language code must use the Visual C++ decorated names and calling conventions to link
to source code written using Visual C++.

Format of a C++ decorated name


A decorated name for a C++ function contains the following information:
The function name.
The class that the function is a member of, if it is a member function. This may include the class that
encloses the class that contains the function, and so on.
The namespace the function belongs to, if it is part of a namespace.
The types of the function parameters.
The calling convention.
The return type of the function.
The function and class names are encoded in the decorated name. The rest of the decorated name is a code that
has internal meaning only for the compiler and the linker. The following are examples of undecorated and
decorated C++ names.
UNDECORATED NAME DECORATED NAME

int a(char){int i=3;return i;}; ?a@@YAHD@Z

void __stdcall b::c(float){}; ?c@b@@AAGXM@Z

Format of a C decorated name


The form of decoration for a C function depends on the calling convention used in its declaration, as shown in the
following table. This is also the decoration format that is used when C++ code is declared to have extern "C"
linkage. The default calling convention is __cdecl . Note that in a 64-bit environment, functions are not decorated.

CALLING CONVENTION DECORATION

__cdecl Leading underscore (_)

__stdcall Leading underscore (_) and a trailing at sign (@) followed by


the number of bytes in the parameter list in decimal

__fastcall Leading and trailing at signs (@) followed by a decimal


number representing the number of bytes in the parameter
list

__vectorcall Two trailing at signs (@@) followed by a decimal number of


bytes in the parameter list

Viewing decorated names


You can get the decorated form of a symbol name after you compile the source file that contains the data, object,
or function definition or prototype. To examine decorated names in your program, you can use one of the
following methods:
To use a listing to view decorated names
1. Generate a listing by compiling the source file that contains the data, object, or function definition or
prototype with the Listing File Type compiler option set to Assembly with Source Code (/FAs).
For example, enter cl /c /FAs example.cpp at a developer command prompt to generate a listing file,
example.asm.
2. In the resulting listing file, find the line that starts with PUBLIC and ends a semicolon followed by the
undecorated data or function name. The symbol between PUBLIC and the semicolon is the decorated
name.
To use DUMPBIN to view decorated names
1. To see the exported symbols in an .obj or .lib file, enter dumpbin /symbols objfile at a developer
command prompt.
2. To find the decorated form of a symbol, look for the undecorated name in parentheses. The decorated
name is on the same line, after a pipe (|) character and before the undecorated name.

Viewing undecorated names


You can use undname.exe to convert a decorated name to its undecorated form. This example shows how it
works:
C:\>undname ?func1@a@@AAEXH@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

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[=internal_name|other_module.exported_name] [@ordinal [NONAME ] ] [ [PRIVATE ] | [DATA ] ]

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

There are four ways to export a definition, listed in recommended order:


1. The __declspec(dllexport) keyword 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 ") . The
following example shows a #pragma comment directive before a function declaration, where
PlainFuncName is the undecorated name, and _PlainFuncName@4 is the decorated name of the function:

#pragma comment(linker, "/export:PlainFuncName=_PlainFuncName@4")


BOOL CALLBACK PlainFuncName( Things * lpParams)

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

Exposes the same functionality as the /HEAP linker option.

/HEAP:reserve[,commit]

See also
Rules for Module-Definition Statements
NAME (C/C++)
3/12/2019 • 2 minutes to read • Edit Online

Specifies a name for the main output file.

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

EXECUTE The section is executable

READ Allows read operations on data

SHARED Shares the section among all processes that load the image

WRITE Allows write operations on data

Separate specifier names with a space. For example:

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:

section [CLASS 'classname'] specifier

The CLASS keyword is supported for compatibility, but is ignored.


An equivalent way to specify section attributes is with the /SECTION option.
See also
Rules for Module-Definition Statements
STACKSIZE
3/12/2019 • 2 minutes to read • Edit Online

Sets the size of the stack in bytes.

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:

// cl t.cpp user32.lib delayimp.lib /link /DELAYLOAD:user32.dll


#include <windows.h>
// uncomment these lines to remove .libs from command line
// #pragma comment(lib, "delayimp")
// #pragma comment(lib, "user32")

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

// link with /link /DELAYLOAD:MyDLL.dll /DELAY:UNLOAD


#include <windows.h>
#include <delayimp.h>
#include "MyDll.h"
#include <stdio.h>

#pragma comment(lib, "delayimp")


#pragma comment(lib, "MyDll")
int main()
{
BOOL TestReturn;
// MyDLL.DLL will load at this point
fnMyDll();

//MyDLL.dll will unload at this point


TestReturn = __FUnloadDelayLoadedDLL2("MyDll.dll");

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;

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}


ExternC
PfnDliHook __pfnDliFailureHook2;

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:

// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}


ExternC
PfnDliHook __pfnDliFailureHook2;

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

Two exception codes can be raised when failures are encountered:


For a LoadLibrary failure
For a GetProcAddress failure
Here is the exception information:

//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)

The exception codes thrown are the standard VcppException(ERROR_SEVERITY_ERROR,


ERROR_MOD_NOT_FOUND ) and VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND )
values. The exception passes a pointer to a DelayLoadInfo structure in the LPDWORD value that can be retrieved
by GetExceptionInformation in the EXCEPTION_RECORD structure, ExceptionInformation[0] field.
Additionally, if the incorrect bits are set in the grAttrs field, the exception ERROR_INVALID_PARAMETER is
thrown. This exception is, for all intents and purposes, fatal.
See Structure and Constant Definitions for more information.

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

There are constraints regarding the delay loading of imports.


Imports of data cannot be supported. A workaround is to explicitly handle the data import yourself using
LoadLibrary (or GetModuleHandle after you know the delay-load helper has loaded the DLL ) and
GetProcAddress .

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.

Multiple Versions of Visual C++


If you have multiple versions of Visual C++ on your computer, make sure the linker matches delayimp.lib. If there
is a mismatch, you will get a linker error reporting either ___delayLoadHelper2@8 or ___delayLoadHelper@8 as an
unresolved external symbol. The former implies a new linker with an old delayimp.lib, and the latter implies an old
linker with a new delayimp.lib.
If you get an unresolved linker error, run dumpbin /linkermember:1 on the delayimp.lib that you expect to contain
the helper function to see which helper function is defined instead. The helper function could also be defined in an
object file; run dumpbin /symbols and look for delayLoadHelper(2) .
If you know you have the Visual C++ 6.0 linker, then:
Run dumpbin on the delay load helper's .lib or .obj file to determine whether it defines
__delayLoadHelper2. If not, the link will fail.
Define __delayLoadHelper in the delay load helper's .lib or .obj file.

User-Defined Helper Function


If you defined your own helper function and are using the current version of Visual C++, do the following:
Rename the helper function to __delayLoadHelper2.
Since the pointers in the delay descriptor (ImgDelayDescr in delayimp.h) have been changed from absolute
addresses (VAs) to relative addresses (RVAs) to work as expected in both 32- and 64-bit programs, you
need to convert these back to pointers. A new function has been introduced: PFromRva, found in
delayhlp.cpp. You can use this function on each of the fields in the descriptor to convert them back to either
32- or 64-bit pointers. The default delay load helper function continues to be a good template to use as an
example.
Load All Imports for a Delay-Loaded DLL
The linker can load all imports from a DLL that you specified to be delay loaded. See Loading All Imports for a
Delay-Loaded DLL for more information.

See also
Understanding the Helper Function
Calling Conventions, Parameters, and Return Type
3/12/2019 • 3 minutes to read • Edit Online

The helper routine's prototype is:

FARPROC WINAPI __delayLoadHelper2(


PCImgDelayDescr pidd,
FARPROC * ppfnIATEntry
);

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.

Expected Return Values


If the function is successful, it returns the address of the imported function.
If the function fails, it raises an exception and returns 0. Three types of exceptions can be raised:
Invalid parameter, which happens if the attributes in pidd aren't specified correctly.
LoadLibrary failed on the specified DLL.
Failure of GetProcAddress .
It's your responsibility to handle these exceptions.

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.

FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)


{
{
switch (dliNotify) {
case dliStartProcessing :

// If you want to return control to the helper, return 0.


// Otherwise, return a pointer to a FARPROC helper function
// that will be used instead, thereby bypassing the rest
// of the helper.

break;

case dliNotePreLoadLibrary :

// If you want to return control to the helper, return 0.


// Otherwise, return your own HMODULE to be used by the
// helper instead of having it call LoadLibrary itself.

break;

case dliNotePreGetProcAddress :

// If you want to return control to the helper, return 0.


// If you choose you may supply your own FARPROC function
// address and bypass the helper's call to GetProcAddress.

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 :

// This notification is called after all processing is done.


// There is no opportunity for modifying the helper's behavior
// at this point except by longjmp()/throw()/RaiseException.
// No return value is processed.

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.
};

typedef struct DelayLoadProc {


BOOL fImportByName;
union {
LPCSTR szProcName;
DWORD dwOrdinal;
};
} DelayLoadProc;

typedef struct DelayLoadInfo {


DWORD cb; // size of structure
PCImgDelayDescr pidd; // raw form of data (everything is there)
FARPROC * ppfn; // points to address of function to load
LPCSTR szDll; // name of dll
DelayLoadProc dlp; // name or ordinal of procedure
HMODULE hmodCur; // the hInstance of the library we have loaded
FARPROC pfnCur; // the actual function that will be called
DWORD dwLastError;// error received (if an error notification)
} DelayLoadInfo, * PDelayLoadInfo;

typedef FARPROC (WINAPI *PfnDliHook)(


unsigned dliNotify,
PDelayLoadInfo pdli
);

typedef struct ImgDelayDescr {


DWORD grAttrs; // attributes
RVA rvaDLLName; // RVA to dll name
RVA rvaHmod; // RVA of module handle
RVA rvaIAT; // RVA of the IAT
RVA rvaINT; // RVA of the INT
RVA rvaBoundIAT; // RVA of the optional bound IAT
RVA rvaUnloadIAT; // RVA of optional copy of original IAT
DWORD dwTimeStamp; // 0 if not bound,
// O.W. date/time stamp of DLL bound to (Old BIND)
} ImgDelayDescr, * PImgDelayDescr;
See also
Understanding the Helper Function
Calculating Necessary Values
3/5/2019 • 2 minutes to read • Edit Online

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 index of the current import


// for all the tables (INT, BIAT, UIAT, and IAT).
__inline unsigned
IndexFromPImgThunkData(PCImgThunkData pitdCur, PCImgThunkData pitdBase) {
return pitdCur - pitdBase;
}

// 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
//

// routine definition; takes a pointer to a name to unload

ExternC
BOOL WINAPI
__FUnloadDelayLoadedDLL2(LPCSTR szDll);

// structure definitions for the list of unload records


typedef struct UnloadInfo * PUnloadInfo;
typedef struct UnloadInfo {
PUnloadInfo puiNext;
PCImgDelayDescr pidd;
} UnloadInfo;

// 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.

Code Your Own


This is fairly simple since you can essentially use the supplied code as a guideline for the new one. Of course, it
must adhere to the calling conventions and if it returns to the linker-generated thunks, it must return a proper
function pointer. Once in your code, you can do pretty much whatever you want in order to satisfy the call or get
out of the call.

Use the Start Processing Notification Hook


It will probably be easiest to simply provide a new pointer to a user-supplied notification hook function that
receives the same values as the default helper on the notification dliStartProcessing. At that point, the hook
function can essentially become the new helper function, as a successful return to the default helper will bypass all
further processing in the default helper.

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.

What do you want to know more about?


Running NMAKE
Contents of a Makefile
Description blocks
Commands in a Makefile
Macros and NMAKE
Inference rules
Dot directives
Makefile preprocessing

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++.

To create a makefile project with the makefile project template


In Visual Studio 2017 and later, the Makefile project template is available when the C++ Desktop Development
workload is installed.
Follow the wizard to specify the commands and environment used by your makefile. You can then use this project
to build your code in Visual Studio.
By default, the makefile project displays no files in Solution Explorer. The makefile project specifies the build
settings, which are reflected in the project's property page.
The output file that you specify in the project has no effect on the name that the build script generates; it declares
only an intention. Your makefile still controls the build process and specifies the build targets.
1. From the Visual Studio start page, type "makefile" in the New Project search box. Or, in the New Project
dialog box, expand Visual C++ > General (Visual Studio 2015) or Other (Visual Studio 2017) and then
select Makefile Project in the Templates pane to open the project wizard.
2. In the Application Settings page, provide the command, output, clean, and rebuild information for debug
and retail builds.
3. Click Finish to close the wizard and open the newly created project in Solution Explorer.
You can view and edit the project's properties in its property page. See Set C++ compiler and build properties in
Visual Studio for information about displaying the property page.

Makefile project wizard


After you create a makefile project, you can view and edit each of the following options in the Nmake page of the
project's property page.
Build command line: Specifies the command line to run when the user selects Build from the Build menu.
Displayed in the Build command line field on the Nmake page of the project's property page.
Output: Specifies the name of the file that will contain the output for the command line. By default, this
option is based on the project name. Displayed in the Output field on the Nmake page of the project's
property page.
Clean commands: Specifies the command line to run when the user selects Clean from the Build menu.
Displayed in the Clean command line field on the Nmake page of the project's property page.
Rebuild command line: Specifies the command line to run when the user selects Rebuild from the Build
menu. Displayed in the Rebuild all command line field on the Nmake page of the project's property page.

How to: Enable IntelliSense for Makefile Projects


IntelliSense fails in makefile projects when certain project settings or compiler options are set up incorrectly.
Follow these steps to configure makefile projects so that IntelliSense works as expected:
1. Open the Property Pages dialog box. For details, see Set C++ compiler and build properties in Visual
Studio.
2. Expand the Configuration Properties node.
3. Select the NMake property page, and then modify properties under IntelliSense as appropriate.
Set the Preprocessor Definitions property to define any preprocessor symbols in your makefile
project. See /D (Preprocessor Definitions), for more information.
Set the Include Search Path property to specify the list of directories that the compiler will search
to resolve file references that are passed to preprocessor directives in your makefile project. See /I
(Additional Include Directories), for more information.
For projects that are built using CL.EXE from a Command Window, set the INCLUDE environment
variable to specify directories that the compiler will search to resolve file references that are passed
to preprocessor directives in your makefile project.
Set the Forced Includes property to specify which header files to process when building your
makefile project. See /FI (Name Forced Include File), for more information.
Set the Assembly Search Path property to specify the list of directories that the compiler will
search to resolve references to .NET assemblies in your project. See /AI (Specify Metadata
Directories), for more information.
Set the Forced Using Assemblies property to specify which .NET assemblies to process when
building your makefile project. See /FU (Name Forced #using File), for more information.
Set the Additional Options property to specify additional compiler switches to be used by
IntelliSense when parsing C++ files.
4. Click OK to close the property pages.
5. Use the Save All command to save the modified project settings.
The next time you open your makefile project in the Visual Studio development environment, run the Clean
Solution command and then the Build Solution command on your makefile project. IntelliSense should work
properly in the IDE.

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.

What do you want to know more about?


NMAKE options
Tools.ini and NMAKE
Exit codes from NMAKE

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

/A Forces build of all evaluated targets, even if not out-of-date


with respect to dependents. Does not force build of unrelated
targets.

/B Forces build even if timestamps are equal. Recommended only


for very fast systems (resolution of two seconds or less).

/C Suppresses default output, including nonfatal NMAKE errors


or warnings, timestamps, and NMAKE copyright message.
Suppresses warnings issued by /K.

/D Displays timestamps of each evaluated target and dependent


and a message when a target does not exist. Useful with /P
for debugging a makefile. Use !CMDSWITCHES to set or clear
/D for part of a makefile.

/E Causes environment variables to override makefile macro


definitions.

/ERRORREPORT[NONE | PROMPT | QUEUE | SEND ] If nmake.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).

/F filename Specifies filename as a makefile. Spaces or tabs can precede


filename. Specify /F once for each makefile. To supply a
makefile from standard input, specify a dash (-) for filename,
and end keyboard input with either F6 or CTRL+Z.

/G Displays the makefiles included with the !INCLUDE directive.


See Makefile Preprocessing Directives for more information.

/HELP, /? Displays a brief summary of NMAKE command-line syntax.

/I Ignores exit codes from all commands. To set or clear /I for


part of a makefile, use !CMDSWITCHES. To ignore exit codes
for part of a makefile, use a dash (-) command modifier or
.IGNORE. Overrides /K if both are specified.

/K Continues building unrelated dependencies, if a command


returns an error. Also issues a warning and returns an exit
code of 1. By default, NMAKE halts if any command returns a
nonzero exit code. Warnings from /K are suppressed by /C; /I
overrides /K if both are specified.
OPTION PURPOSE

/N Displays but does not execute commands; preprocessing


commands are executed. Does not display commands in
recursive NMAKE calls. Useful for debugging makefiles and
checking timestamps. To set or clear /N for part of a makefile,
use !CMDSWITCHES.

/NOLOGO Suppresses the NMAKE copyright message.

/P Displays information (macro definitions, inference rules,


targets, .SUFFIXES list) to standard output, and then runs the
build. If no makefile or command-line target exists, it displays
information only. Use with /D to debug a makefile.

/Q Checks timestamps of targets; does not run the build. Returns


a zero exit code if all targets are up-to-date and a nonzero
exit code if any target is not. Preprocessing commands are
executed. Useful when running NMAKE from a batch file.

/R Clears the .SUFFIXES list and ignores inference rules and


macros that are defined in the Tools.ini file or that are
predefined.

/S Suppresses display of executed commands. To suppress


display in part of a makefile, use the @ command modifier or
.SILENT. To set or clear /S for part of a makefile, use
!CMDSWITCHES.

/T Updates timestamps of command-line targets (or first


makefile target) and executes preprocessing commands but
does not run the build.

/U Must be used in conjunction with /N. Dumps inline NMAKE


files so that the /N output can be used as a batch file.

/X filename Sends NMAKE error output to filename instead of standard


error. Spaces or tabs can precede filename. To send error
output to standard output, specify a dash (-) for filename.
Does not affect output from commands to standard error.

/Y Disables batch-mode inference rules. When this option is


selected, all batch-mode inference rules are treated as regular
inference rules.

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

NMAKE returns the following exit codes:

CODE MEANING

0 No error (possibly a warning)

1 Incomplete build (issued only when /K is used)

2 Program error, possibly due to one of the following:

- A syntax error in the makefile

- An error or exit code from a command

- An interruption by the user

4 System error — out of memory

255 Target is not up-to-date (issued only when /Q is used)

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

Enclose long filenames in double quotation marks, as follows:

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:

# Comment on line by itself


OPTIONS = /MAP # Comment on macro definition line

all.exe : one.obj two.obj # Comment on dependency line


link one.obj two.obj
# Comment in commands block
# copy *.obj \objects # Command turned into comment
copy one.exe \release

.obj.exe: # Comment on inference rule line


link $<

my.exe : my.obj ; link my.obj # Err: cannot comment this


# Error: # must be the first character
.obj.exe: ; link $< # Error: cannot comment this

To specify a literal number sign, precede it with a caret (^), as follows:

DEF = ^#define #Macro for a C preprocessing directive

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

This topic contains a sample makefile.

Sample
Code

# Sample makefile

!include <win32.mak>

all: simple.exe challeng.exe

.c.obj:
$(cc) $(cdebug) $(cflags) $(cvars) $*.c

simple.exe: simple.obj
$(link) $(ldebug) $(conflags) -out:simple.exe simple.obj $(conlibs) lsapi32.lib

challeng.exe: challeng.obj md4c.obj


$(link) $(ldebug) $(conflags) -out:challeng.exe $** $(conlibs) lsapi32.lib

See also
Contents of a Makefile
Description Blocks
3/12/2019 • 2 minutes to read • Edit Online

A description block is a dependency line optionally followed by a commands block:

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.

What do you want to know more about?


Targets
Dependents

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.

What do you want to know more about?


Pseudotargets
Multiple targets
Cumulative dependencies
Targets in multiple description blocks
Dependency side effects

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 leap.exe : jump.obj


echo Building...

...is evaluated as 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

Dependencies are cumulative in a description block if a target is repeated.


For example, this set of rules,

bounce.exe : jump.obj
bounce.exe : up.obj
echo Building bounce.exe...

is evaluated as this:

bounce.exe : jump.obj up.obj


echo Building bounce.exe...

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,

leap.exe bounce.exe : jump.obj


bounce.exe climb.exe : up.obj
echo Building bounce.exe...

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.

target.lib :: one.asm two.asm three.asm


ml one.asm two.asm three.asm
lib target one.obj two.obj three.obj
target.lib :: four.c five.c
cl /c four.c five.c
lib target four.obj five.obj

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:

bounce.exe : jump.obj up.obj


echo Building bounce.exe...

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

Each dependent has an optional search path, specified as follows:

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:

project.obj : project.c project.h ; cl /c project.c

What do you want to know more about?


Command modifiers
Filename-parts syntax
Inline files in a makefile

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

@command Prevents display of the command. Display by commands is


not suppressed. By default, NMAKE echoes all executed
commands. Use /S to suppress display for the entire makefile;
use .SILENT to suppress display for part of the makefile.

-[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.

! command Executes command for each dependent file if command uses


$** (all dependent files in the dependency) or $? (all
dependent files in the dependency with a later timestamp
than the target).

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

No letter Complete name (same as %s)

d Drive

p Path

f File base name

e File extension

For example, if the filename is c:\prog.exe:


%s will be c:\prog.exe
%|F will be c:\prog.exe
%|dF will be c
%|pF will be c:\
%|fF will be prog
%|eF will be exe

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.

What do you want to know more about?


Specifying an inline file
Creating inline file text
Reusing inline files
Multiple inline files

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

Inline files are temporary or permanent.

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

A command can create more than one inline file.

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.

What do you want to know more about?


Defining an NMAKE macro
Using an NMAKE macro
Special NMAKE 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.

What do you want to know more about?


Special characters in macros
Null and undefined macros
Where to define macros
Precedence in macro definitions

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.

What do you want to know more about?


Macro substitution

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

$@ Current target's full name (path, base name, extension), as


currently specified.

$$@ Current target's full name (path, base name, extension), as


currently specified. Valid only as a dependent in a dependency.

$* Current target's path and base name minus file extension.

$** All dependents of the current target.

$? All dependents with a later timestamp than the current target.

$< 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.

MODIFIER RESULTING FILENAME PART

D Drive plus directory

B Base name

F Base name plus extension

R Drive plus directory plus 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

MAKE Command used originally to invoke NMAKE.

The $(MAKE) macro gives the full path to nmake.exe.

MAKEDIR Current directory when NMAKE was invoked.

MAKEFLAGS Options currently in effect. Use as /$(MAKEFLAGS) . Note, /F is


not included.

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.

MICROSOFT PRODUCT COMMAND MACRO DEFINED AS OPTIONS MACRO

Macro Assembler AS ml AFLAGS

Basic Compiler BC bc BFLAGS

C Compiler CC cl CFLAGS

C++ Compiler CPP cl CPPFLAGS

C++ Compiler CXX cl CXXFLAGS

Resource Compiler RC rc RFLAGS

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.

What do you want to know more about?


Defining a rule
Batch-mode rules
Predefined rules
Inferred dependents and rules
Precedence in inference rules

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.

What do you want to know more about?


Search paths in rules

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 output without batch-mode inference rules:


E:\tmp> nmake -f test.mak -a NOBatch=1

Microsoft (R) Program Maintenance Utility Version 7.00.0000


Copyright (C) Microsoft Corp 1988-2001. All rights reserved.
cl -nologo -Fd.\ -c .\foo1.cpp
foo1.cpp
cl -nologo -Fd.\ -c .\foo2.cpp
foo2.cpp
cl -nologo -Fd.\ -c .\foo3.cpp
foo3.cpp
cl -nologo -Fd.\ -c .\foo4.cpp
foo4.cpp

NMAKE produces the following result with the batch-mode inference rules:

E:\tmp> nmake -f test.mak -a

Microsoft (R) Program Maintenance Utility Version 7.00.0000


Copyright (C) Microsoft Corp 1988-2001. All rights reserved.

cl -nologo -Fd.\ -c .\foo1.cpp .\foo2.cpp .\foo3.cpp .\foo4.cpp


foo1.cpp
foo2.cpp
foo3.cpp
foo4.cpp
Generating Code...

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

.asm.exe $(AS) $(AFLAGS) $< ml $< no x86

.asm.obj $(AS) $(AFLAGS) /c ml /c $< yes x86


$<

.asm.exe $(AS) $(AFLAGS) $< ml64 $< no x64

.asm.obj $(AS) $(AFLAGS) /c ml64 /c $< yes x64


$<

.c.exe $(CC) $(CFLAGS) $< cl $< no all

.c.obj $(CC) $(CFLAGS) /c cl /c $< yes all


$<

.cc.exe $(CC) $(CFLAGS) $< cl $< no all

.cc.obj $(CC) $(CFLAGS) /c cl /c $< yes all


$<

.cpp.exe $(CPP) $(CPPFLAGS) cl $< no all


$<

.cpp.obj $(CPP) $(CPPFLAGS) cl /c $< yes all


/c $<

.cxx.exe $(CXX) $(CXXFLAGS) cl $< no all


$<

.cxx.obj $(CXX) $(CXXFLAGS) cl /c $< yes all


/c $<

.rc.res $(RC) $(RFLAGS) /r rc /r $< no all


$<

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

.IGNORE : Ignores nonzero exit codes returned by commands, from the


place it is specified to the end of the makefile. By default,
NMAKE halts if a command returns a nonzero exit code. To
restore error checking, use !CMDSWITCHES. To ignore the
exit code for a single command, use the dash (-) modifier. To
ignore exit codes for an entire file, use /I.

.PRECIOUS : targets Preserves targets on disk if the commands to update them


are halted; has no effect if a command handles an interrupt
by deleting the file. Separate the target names with one or
more spaces or tabs. By default, NMAKE deletes a target if a
build is interrupted by CTRL+C or CTRL+BREAK. Each use of
.PRECIOUS applies to the entire makefile; multiple
specifications are cumulative.

.SILENT : Suppresses display of executed commands, from the place it


is specified to the end of the makefile. By default, NMAKE
displays the commands it invokes. To restore echoing, use
!CMDSWITCHES. To suppress echoing of a single command,
use the @ modifier. To suppress echoing for an entire file, use
/S.

.SUFFIXES : list Lists extensions for inference-rule matching; predefined to


include the following extensions: .exe .obj .asm .c .cpp .cxx .bas
.cbl .for .pas .res .rc .f .f90

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 :

To add additional suffixes to the end of the list, specify

.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.

What do you want to know more about?


Makefile preprocessing directives
Expressions in makefile preprocessing

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.

What do you want to know more about?


Makefile preprocessing operators
Executing a program in preprocessing

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 logical NOT.

~ Unary one’s complement.

- Unary negation.

* Multiplication.

/ Division.

% Modulus (remainder).

+ Addition.
OPERATOR DESCRIPTION

- Subtraction.

<< Bitwise shift left.

>> Bitwise shift right.

<= Less than or equal.

>= Greater than or equal.

< Less than.

> Greater than.

== Equality.

!= Inequality.

& Bitwise AND.

^ Bitwise XOR.

| Bitwise OR.

&& Logical AND.

|| 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

/DEF Create an import library and an export file.

For more information see Building an Import Library and


Export File.

/ERRORREPORT Send information to Microsoft about internal errors with


lib.exe.

For more information see Running LIB.

/EXPORT Exports a function from your program.

For more information see Building an Import Library and


Export File.

/EXTRACT Create an object (.obj) file that contains a copy of a member


of an existing library.

For more information see Extracting a Library Member.

/INCLUDE Adds a symbol to the symbol table.

For more information see Building an Import Library and


Export File.

/LIBPATH Overrides the environment library path.

For more information see Managing a Library.

/LIST Displays information about the output library to standard


output.

For more information see Managing a Library.


OPTION DESCRIPTION

/LTCG Causes the library to be built using link-time code generation.

For more information see Running LIB.

/MACHINE Specifies the target platform for the program.

For more information see Running LIB.

/NAME When building an import library, specifies the name of the


DLL for which the import library is being built.

For more information see Managing a Library.

/NODEFAULTLIB Removes one or more default libraries from the list of libraries
it searches when resolving external references.

For more information see Managing a Library.

/NOLOGO Suppresses display of the LIB copyright message and version


number and prevents echoing of command files.

For more information see Running LIB.

/OUT Overrides the default output filename.

For more information see Managing a Library.

/REMOVE Omits an object from the output library.

For more information see Managing a Library.

/SUBSYSTEM Tells the operating system how to run a program created by


linking to the output library.

For more information see Managing a Library.

/VERBOSE Displays details about the progress of the session, including


names of the .obj files being added.

For more information see Running LIB.

/WX Treat warnings as errors.

For more information see Running LIB.

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

To set LIB.EXE options in the Visual Studio development environment


1. Access the project's Property Page dialog box.
2. With a static library project active, select the Librarian node.
3. Select either the General or Input/Output property page.
4. Modify properties as needed.

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

Extracting a member with /EXTRACT COFF library (.lib)

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

Default (building or modifying a library) COFF library (.lib)

Extracting a member with /EXTRACT Object (.obj) file

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

Various command-line options can be used to control LIB.

LIB Command Line


To run LIB, type the command lib followed by the options and file names for the task you are using LIB to
perform. LIB also accepts command-line input in command files, which are described in the following section. LIB
does not use an environment variable.

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 Command Files


You can pass command-line arguments to LIB in a command file using the following syntax:

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.

Using LIB Options


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 an argument, 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, but identifiers used as arguments are case sensitive. LIB processes options in the order specified on the
command line and in command files. If an option is repeated with different arguments, the last one to be
processed takes precedence.
The following options apply to all modes of LIB:

/ERRORREPORT [NONE | PROMPT | QUEUE | SEND ]


If lib.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).

/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:

LIB [options...] files...

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:

LIB library /EXTRACT:member /OUT:objectfile

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:

LIB /DEF[:deffile] [options] [objfiles] [libraries]

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.

/EXPORT: entryname[= internalname][,@ordinal[, NONAME ]][, DATA ]

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

To run EDITBIN, use the following syntax:

EDITBIN [options] files...

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

/ALLOWBIND Specifies whether a DLL can be bound.

/ALLOWISOLATION Specifies DLL or executable file manifest lookup behavior.

/APPCONTAINER Specifies whether the app must run within an AppContainer


—for example, a UWP app.

/BIND Sets the addresses for the entry points in the specified
objects to speed load time.

/DYNAMICBASE Specifies whether the DLL or executable image can be


randomly rebased at load-time by using address space
layout randomization (ASLR).

/ERRORREPORT Reports internal errors to Microsoft.

/HEAP Sets the size of the executable image’s heap in bytes.

/HIGHENTROPYVA Specifies whether the DLL or executable image supports high


entropy (64-bit) address space layout randomization (ASLR).

/INTEGRITYCHECK Specifies whether to check the digital signature at load time.

/LARGEADDRESSAWARE Specifies whether the object supports addresses that are


larger than two gigabytes.

/NOLOGO Suppresses the EDITBIN startup banner.

/NXCOMPAT Specifies whether the executable image is compatible with


Windows Data Execution Prevention.

/REBASE Sets the base addresses for the specified objects.

/RELEASE Sets the checksum in the header.


OPTION PURPOSE

/SECTION Overrides the attributes of a section.

/STACK Sets the size of the executable image’s stack in bytes.

/SUBSYSTEM Specifies the execution environment.

/SWAPRUN Specifies that the executable image must be copied to the


swap file, and then run from there.

/TSAWARE Specifies that the app is designed to run in a multi-user


environment.

/VERSION Sets the version number in the header.

See also
Additional MSVC Build Tools
EDITBIN Reference
/ALLOWISOLATION
3/12/2019 • 2 minutes to read • Edit Online

Specifies behavior for manifest lookup.

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

Specifies whether a DLL can be bound.

/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

/ERRORREPORT[NONE | PROMPT | QUEUE | SEND ]

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

BASE=address Provides a beginning address for reassigning base addresses


to the files. Specify address in decimal or C-language notation.
If BASE is not specified, the default starting base address is
0x400000. If DOWN is used, BASE must be specified, and
address sets the end of the range of base addresses.

BASEFILE Creates a file named COFFBASE.TXT, which is a text file in the


format expected by LINK's /BASE option.

DOWN Tells EDITBIN to reassign base addresses downward from an


ending address. The files are reassigned in the order specified,
with the first file located in the highest possible address below
the end of the address range. BASE must be used with DOWN
to ensure sufficient address space for basing the files. To
determine the address space needed by the specified files, run
EDITBIN with /REBASE on the files and add 64 KB to the
displayed total size.

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

k cached virtual memory

m link remove

o link info

p paged virtual memory

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

Specifies the execution environment that's required by the executable image.

/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 .

The values of major and minor must be from 0 through 65,535.


The choice of subsystem affects the default starting address for the program. For more information, see /ENTRY
(Entry-Point Symbol), the linker /ENTRY:function option.
For more information, including the minimum and default values for the major and minor version numbers for
each subsystem, see the /SUBSYSTEM linker option.

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

To run DUMPBIN, use the following syntax:

DUMPBIN [options] files...

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

Display CLR -specific information.

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

Print the disassembly of code sections in the DUMPBIN output.

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

/ERRORREPORT[NONE | PROMPT | QUEUE | SEND ]

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.

dumpbin /disasm /range:4219334,0x004061CD t.exe

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

1 The default. Contents are displayed in hexadecimal bytes, and


also as ASCII characters if they have a printed representation.

2 Contents are displayed as hexadecimal 2-byte values.

4 Contents are displayed as hexadecimal 4-byte values.

8 Contents are displayed as hexadecimal 8-byte values.

NONE Raw data is suppressed. This argument is useful to control the


output of /ALL.

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:

Dump of file main.obj


File Type: COFF OBJECT

COFF SYMBOL TABLE


000 00000000 DEBUG notype Filename | .file
main.cpp
002 000B1FDB ABS notype Static | @comp.id
003 00000000 SECT1 notype Static | .drectve
Section length 26, #relocs 0, #linenums 0, checksum 722C964F
005 00000000 SECT2 notype Static | .text
Section length 23, #relocs 1, #linenums 0, checksum 459FF65F, selection 1 (pick no
duplicates)
007 00000000 SECT2 notype () External | _main
008 00000000 UNDEF notype () External | ?MyDump@@YAXXZ (void __cdecl MyDump(void))

String Table Size = 0x10 bytes

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

Displays the IMAGE_TLS_DIRECTORY structure from an executable.

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

/?, /help Display help for xdcmake.exe.

/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.

/nologo Suppress copyright message.

/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.

This section includes the following topics:


Building Browse Information Files: Overview
Building a .bsc file
BSCMAKE command line
BSCMAKE command file
BSCMAKE options
BSCMAKE exit codes

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

To run BSCMAKE, use the following command line syntax:

BSCMAKE [options] sbrfiles

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:

BSCMAKE main.sbr file1.sbr file2.sbr

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

The following is a sample command file:

/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:

BSCMAKE /n /S toolbox.h /o main.bsc file1.sbr file2.sbr file3.sbr

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

4 Fatal error during build

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 C1001 An internal error has occurred in the compiler.

(compiler file 'file', line number)

To work around this problem, try simplifying or changing the


program near the locations listed above. Please choose the
Technical Support command on the Visual C++ Help menu, or
open the Technical Support help file for more information

Fatal Error C1002 compiler is out of heap space in pass 2


ERROR MESSAGE

Fatal Error C1003 error count exceeds number; stopping compilation

Fatal Error C1004 unexpected end-of-file found

Fatal Error C1005 string too big for buffer

Fatal Error C1007 unrecognized flag 'string' in 'option'

Fatal Error C1008 no input file specified

Fatal Error C1009 compiler limit: macros nested too deeply

Fatal Error C1010 unexpected end of file while looking for precompiled header.
Did you forget to add '#include <file>' to your source?

Fatal Error C1012 unmatched parenthesis: missing 'character"

Fatal Error C1013 compiler limit: too many open parentheses

Fatal Error C1014 too many include files: depth = number

Fatal Error C1016 #ifdef/#ifndef expected an identifier

Fatal Error C1017 invalid integer constant expression

Fatal Error C1018 unexpected #elif

Fatal Error C1019 unexpected #else

Fatal Error C1020 unexpected #endif

Fatal Error C1021 invalid preprocessor command 'string'

Fatal Error C1022 expected #endif

Fatal Error C1023 'file': unexpected error with pch, try rebuilding the pch

Fatal Error C1026 parser stack overflow, program too complex

Fatal Error C1033 cannot open program database 'file'

Fatal Error C1034 file: no include path set

Fatal Error C1035 expression too complex; simplify expression

Fatal Error C1036 cannot overwrite earlier program database format, delete 'file'
and recompile

Fatal Error C1037 cannot open object file 'file'


ERROR MESSAGE

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 C1046 compiler limit: structure 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 C1048 unknown option 'string' in 'option'

Fatal Error C1049 invalid numerical argument 'value'

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 C1053 'function': function too large

Fatal Error C1054 compiler limit: initializers nested too deeply

Fatal Error C1055 compiler limit: out of keys

Fatal Error C1057 unexpected end of file in macro expansion

Fatal Error C1060 compiler is out of heap space

Fatal Error C1061 compiler limit: blocks nested too deeply

Fatal Error C1063 compiler limit: compiler stack overflow

Fatal Error C1064 compiler limit: token overflowed internal buffer

Fatal Error C1065 compiler limit: out of tags

Fatal Error C1067 compiler limit: 64K limit on size of a type record has been
exceeded

Fatal Error C1068 cannot open file 'file'

Fatal Error C1069 cannot read compiler command line

Fatal Error C1070 mismatched #if/#endif pair in file 'file'


ERROR MESSAGE

Fatal Error C1071 unexpected end of file found in comment

Fatal Error C1073 Internal error involving incremental compilation(compiler file


'file', line number)

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 C1081 'file': file name too long

Fatal Error C1082 cannot close type file: 'file': message

Fatal Error C1083 cannot open type file: 'file': message

Fatal Error C1084 cannot read type file: 'file': message

Fatal Error C1085 cannot write type file: 'file': message

Fatal Error C1086 cannot seek type file: 'file': message

Fatal Error C1087 cannot tell type file: 'file': message

Fatal Error C1088 cannot flush type file: 'file': message

Fatal Error C1089 cannot truncate type file: 'file': message

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 C1093 API call 'function' failed 'HRESULT' : 'description'

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 C1099 Edit and Continue engine terminating compile

Fatal Error C1100 unable to initialize OLE: error

Fatal Error C1101 cannot create handler for attribute 'identifier'

Fatal Error C1102 unable to initialize: error

Fatal Error C1103 fatal error importing progid: 'message'

Fatal Error C1104 fatal error importing libid: 'message'

Fatal Error C1105 message: error

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 C1108 unable to find DLL: 'file'

Fatal Error C1109 unable to find 'symbol' in DLL 'file'

Fatal Error C1110 too many nested template/generic definitions

Fatal Error C1111 too many template/generic parameters

Fatal Error C1112 compiler limit: 'number ' too many macro arguments, only
number allowed

Fatal Error C1113 #using failed on 'file'

Fatal Error C1114 'file': WinRT does not support #using of a managed assembly

Fatal Error C1120 call to GetProcAddress failed for 'function'

Fatal Error C1121 call to CryptoAPI failed

Fatal Error C1126 automatic allocation exceeds size

Fatal Error C1128 number of sections exceeded object file format limit: compile
with /bigobj

Fatal Error C1189 #error: message

Fatal Error C1190 managed targeted code requires a '/clr' option

Fatal Error C1191 'file' can only be imported at global scope

Fatal Error C1192 #using failed on 'file'

Fatal Error C1193 an error expected in file(line) not reached


ERROR MESSAGE

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 C1211 The TypeForwardedTo Custom Attribute is not supported by


the version of the runtime installed

Fatal Error C1300 error accessing program database file (message)

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 C1305 profile database 'file' is for a different architecture

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 C1308 file: linking assemblies is not supported

Fatal Error C1309 Mismatched versions of C2.DLL and pgodbver.DLL


ERROR MESSAGE

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 C1351 error loading dll 'file': incompatible version

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 C1384 Incorrect setting for PGO_PATH_TRANSLATION when linking


'file'

Fatal Error C1451 Failed to generate debug information when compiling the call
graph for the concurrency::parallel_for_each at: 'callsite'

Fatal Error C1505 unrecoverable parser look-ahead error

Fatal Error C1506 unrecoverable block scoping error

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 C1510 Cannot open language resource clui.dll

Fatal Error C1601 unsupported inline assembly opcode

Fatal Error C1602 unsupported intrinsic

Fatal Error C1603 inline assembly branch target out of range by number bytes

Fatal Error C1852 'file' is not a valid precompiled header file


ERROR MESSAGE

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 C1901 Internal memory management error

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 C1904 bad provider interaction: 'file'

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

INTERNAL COMPILER ERROR (compiler file file, line number)

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

compiler is out of heap space in pass 2


The compiler ran out of dynamic memory space during its second pass, probably due to a program with too many
symbols or complex expressions.
To fix by using the following possible solutions
1. Divide the source file into several smaller files.
2. Break expressions into smaller subexpressions.
3. Remove other programs or drivers that consume memory.
Fatal Error C1003
10/31/2018 • 2 minutes to read • Edit Online

error count exceeds number; stopping compilation


Errors in the program are too numerous to allow recovery. The compiler must terminate.
Fatal Error C1004
10/31/2018 • 2 minutes to read • Edit Online

unexpected end of file found


The compiler reached the end of a source file without resolving a construct. The code may be missing one of the
following elements:
A closing brace
A closing parenthesis
A closing comment marker (*/)
A semicolon
To resolve this error, check for the following:
The default disk drive has insufficient space for temporary files, which require about twice as much space as
the source file.
An #if directive that evaluates to false lacks a closing #endif directive.
A source file does not end with a carriage return and line feed.
The following sample generates C1004:

// 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

string too big for buffer


A string in a compiler intermediate file overflowed a buffer.
You could get this error when the parameter that you pass to either the /Fd or /Yl compiler options is greater than
256 bytes.
Fatal Error C1007
10/31/2018 • 2 minutes to read • Edit Online

unrecognized flag string in option


The command-line option contains an invalid string. Check the CL command line and environment variable for
errors.
Fatal Error C1008
10/31/2018 • 2 minutes to read • Edit Online

no input file specified


The compiler was not given a C or C++ source file to compile. Check the CL command line and environment
variable for filename specifications.
Fatal Error C1009
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : macros nested too deeply


The compiler tried to expand too many macros at the same time. The compiler has a limit of 256 levels of nested
macros. Split nested macros into simpler macros.
Fatal Error C1010
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

unmatched parenthesis : missing character


The parentheses in a preprocessor directive do not match.
Fatal Error C1013
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : too many open parentheses


An expression contains too many levels of parentheses in a single expression. Simplify the expression or break it
into multiple statements.
Prior to Visual C++ 6.0 Service Pack 3, the limit on nested parenthesis in a single expression was 59. Currently, the
limit on nested parenthesis is 256.
Fatal Error C1014
10/31/2018 • 2 minutes to read • Edit Online

too many include files : depth = level


The nesting of #include directives is too deep. Nested directives can include open files. The source file containing
the directive counts as one file.
Fatal Error C1016
10/31/2018 • 2 minutes to read • Edit Online

#ifdef expected an identifier#ifndef expected an identifier


The conditional compilation directive (#ifdef or #ifndef ) has no identifier to evaluate. To resolve the error, specify
an identifier.
The following sample generates C1016:

// 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

invalid integer constant expression


The expression in an #if directive did not exist or did not evaluate to a constant.
Constants defined using #define must have values that evaluate to an integer constant if they are used in an #if ,
#elif , or #else directive.

The following sample generates C1017:

// 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

invalid preprocessor command 'string'


string is not a valid preprocessor directive. To resolve the error, use a valid preprocessor name for string .
The following sample generates C1021:

// 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

'file' : unexpected error with pch, try rebuilding the pch


C1023 could be caused by one of several problems, the solution to which is a rebuild of the precompiled header
file.
C1023 may be caused if you attempt to use a precompiled header file on a machine other than the one on which it
was built.
Fatal Error C1026
10/31/2018 • 2 minutes to read • Edit Online

parser stack overflow, program too complex


The space required to parse the program caused a compiler stack overflow.
Decrease the complexity of expressions by:
Decreasing nesting in for and switch statements. Put more deeply nested statements in separate
functions.
Breaking up long expressions that involve comma operators or function calls.
Fatal Error C1033
10/31/2018 • 2 minutes to read • Edit Online

cannot open program database pdb


This error can be caused by a disk error, a temporary lock created by an anti-virus program, a previous debugger
instance that has not fully shut down, or parallel build mspdbsrv.exe processes that attempt to access the same file,
among other possible causes.
Fatal Error C1035
10/31/2018 • 2 minutes to read • Edit Online

expression too complex; simplify expression


The compiler could not generate code for a complex expression. Split the expression into simpler expressions and
recompile.
Fatal Error C1037
10/31/2018 • 2 minutes to read • Edit Online

cannot open object file filename


The object file specified by /Fo cannot be opened.
To fix by checking the following possible causes
1. Invalid filename.
2. Insufficient memory to open the file.
3. Another process is using the file.
4. A read-only file has the same name.
Fatal Error C1038
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

compiler limit : linkage specifications nested too deeply


Nested externals exceed the compiler limit. Nested externals are allowed with the external linkage type, such as
extern "C++". Reduce the number of nested externals to resolve the error.
Fatal Error C1046
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : structure nested too deeply


The structure, union, or class exceeded the nesting limit, which is 15 levels. Rewrite the definition to reduce the
nesting level. Split the structure, union, or class into two or more parts by using typedef to define one or more of
the nested structures.
Fatal Error C1047
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

'<identifier>' : function too large


The function is too large to compile.
To fix by using the following possible solutions
1. Try compiling without optimizations.
2. Divide the function into smaller functions.
3. Reduce calls to inline functions.
Fatal Error C1054
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : initializers nested too deeply


The code exceeds the nesting limit on initializers (10-15 levels, depending on the combination of types being
initialized).
To fix by using the following possible solutions
1. Simplify the data types being initialized to reduce nesting.
2. Initialize variables in separate statements after the declaration.
Fatal Error C1055
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : out of keys


The source file contains too many symbols. The compiler ran out of hash keys for the symbol table.
To fix by using the following possible solutions
1. Split the source file into smaller files.
2. Eliminate unnecessary header files.
3. Reuse temporary and global variables instead of creating new ones.
Fatal Error C1057
10/31/2018 • 2 minutes to read • Edit Online

unexpected end of file in macro expansion


The compiler reached the end of the source file while gathering macro-invocation arguments, probably due to a
missing right parenthesis in the macro invocation.
Fatal Error C1060
10/31/2018 • 2 minutes to read • Edit Online

compiler is out of heap space


The operating system or run-time library cannot fill a request for memory.
To fix this error try the following possible solutions
1. If the compiler also issues errors C1076 and C3859, use the /Zm compiler option to lower the memory
allocation limit. More heap space is available to your application if you lower the remaining memory
allocation.
If the /Zm option is already set, try removing it. Heap space might be exhausted because the memory
allocation limit specified in the option is too high. The compiler uses a default limit if you remove the /Zm
option.
2. If you are compiling on a 64-bit platform, use the 64-bit compiler toolset. For information, see How to:
Enable a 64-Bit Visual C++ Toolset on the Command Line.
3. On 32-bit Windows, try using the /3GB boot.ini switch.
4. Increase the size of the Windows swap-file.
5. Close other running programs.
6. Eliminate unnecessary include files.
7. Eliminate unnecessary global variables, for example, by allocating memory dynamically instead of declaring
a large array.
8. Eliminate unused declarations.
9. Split the current file into smaller files.
Fatal Error C1061
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : blocks nested too deeply


Nesting of code blocks exceeds the limit of 128 nesting levels. This is a hard limit in the compiler for both C and
C++, in both the 32-bit and 64-bit tool set. The count of nesting levels can be increased by anything that creates a
scope or block. For example, namespaces, using directives, preprocessor expansions, template expansion, exception
handling, loop constructs, and else-if clauses can all increase the nesting level seen by the compiler.
To fix this error you must refactor your code. In any case, deeply nested code is difficult to understand and reason
about. Refactoring your code to have fewer nesting levels may improve code quality and simplify maintenance.
Break deeply nested code into functions that are called from the original context. Limit the number of loops or
chained else-if clauses within a block.
Fatal Error C1064
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : token overflowed internal buffer


An identifier exceeds the length of the internal buffer used for identifiers. Shorten the name.
Fatal Error C1065
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : out of tags


The source file contains more than 65,523 classes, structs, unions, namespaces, or enums.
Split the file into smaller files.
Fatal Error C1067
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

cannot open file 'file'


Ensure that file is not in use by another program.
Fatal Error C1070
10/31/2018 • 2 minutes to read • Edit Online

mismatched #if/#endif pair in file 'filename'


An #if , #ifdef , or #ifndef directive has no corresponding #endif .
The following sample generates C1070:

// 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

unexpected end of file found in comment


The compiler reached the end of the file while scanning a comment.
To fix by checking the following possible causes
1. Missing comment terminator (*/).
2. Missing newline character after a comment on the last line of a source file.
The following sample generates C1071:

// C1071.cpp
int main() {
}

/* this comment is fine */


/* forgot the closing tag // C1071
Fatal Error C1073
10/31/2018 • 2 minutes to read • Edit Online

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

'IDB' is illegal extension for PDB file: filename


The compiler expects program databases to have the .pdb extension.
Fatal Error C1075
10/31/2018 • 2 minutes to read • Edit Online

the left token was unmatched at the end of the file


The compiler expected matching token before it reached the end of file.
This error can be caused by an unmatched bracket, brace, or other paired character.
Fatal Error C1076
3/11/2019 • 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.

To resolve this error:


1. If your precompiled header uses a #pragma hdrstop directive, use the /Zm option to set the compiler
memory limit to the value specified in the C3859 error message. For more information that includes how
to set this value in Visual Studio, see the Remarks section in /Zm (Specify Precompiled Header Memory
Allocation Limit).
2. Consider reducing the number of parallel processes specified by 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.
3. If you are using the 32-bit hosted compilers on a 64-bit operating system, use the 64-bit hosted compilers
instead. For more information, see How to: Enable a 64-Bit Visual C++ Toolset on the Command Line.
4. Eliminate unnecessary include files.
5. Eliminate unnecessary global variables—for example, by allocating memory dynamically instead of
declaring a large array.
6. Eliminate unused declarations.
If C1076 occurs immediately after the build starts, the value specified for /Zm is probably too high for your
program. Reduce the /Zm value.
Fatal Error C1077
10/31/2018 • 2 minutes to read • Edit Online

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

compiler limit : PCH file size limit exceeded


The PCH file exceeds the 4 GB size limit.
Fatal Error C1080
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : command line option exceeded limit of number characters


An argument passed to the compiler exceeds 256 characters.
Fatal Error C1081
10/31/2018 • 2 minutes to read • Edit Online

'symbol': file name too long


The length of a file pathname exceeds _MAX_PATH (defined by STDLIB.h as 260 characters). Shorten the name of
the file.
If you call CL.exe with a short filename, the compiler may need to generate a full pathname. For example,
cl -c myfile.cpp may cause the compiler to generate:

D:\<very-long-directory-path>\myfile.cpp
Fatal Error C1082
10/31/2018 • 2 minutes to read • Edit Online

Cannot close filetype file: 'file': message


If the message says "bad file number", the file may have been closing in the foreground while compiling in the
background.
Fatal Error C1083
3/12/2019 • 8 minutes to read • Edit Online

Cannot open filetype file: 'file': message

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.

The specified file name is wrong


The name of a file may be mistyped. For example,
#include <algorithm.h>

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>

The file is not included in the include search path


The compiler cannot find the file by using the search rules that are indicated by an #include or #import directive.
For example, when a header file name is enclosed by quotation marks,
#include "myincludefile.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.

Third-party library issues and Vcpkg


If you see this error when you are trying to configure a third-party library as part of your build, consider using
Vcpkg, the Visual C++ Package Manager, to install and build the library. Vcpkg supports a large and growing list of
third-party libraries, and sets all the configuration properties and dependencies required for successful builds as
part of your project. For more information, see the related Visual C++ Blog post.

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).

The command line INCLUDE or LIB environment is not set


When the compiler is invoked on the command line, environment variables are often used to specify search paths.
If the search path described by the INCLUDE or LIB environment variable is not set correctly, a C1083 error can
be generated. We strongly recommend using a developer command prompt shortcut to set the basic environment
for command line builds. For more information, see Build C/C++ on the Command Line. For more information
about how to use environment variables, see How to: Use Environment Variables in a Build.

The file may be locked or in use


If you are using another program to edit or access the file, it may have the file locked. Try closing the file in the
other program. Sometimes the other program can be Visual Studio itself, if you are using parallel compilation
options. If turning off the parallel build option makes the error go away, then this is the problem. Other parallel
build systems can also have this issue. Be careful to set file and project dependencies so build order is correct. In
some cases, consider creating an intermediate project to force build dependency order for a common file that may
be built by multiple projects. Sometimes antivirus programs temporarily lock recently changed files for scanning. If
possible, consider excluding your project build directories from the antivirus scanner.

The wrong version of a file name is included


A C1083 error can also indicate that the wrong version of a file is included. For example, a build could include the
wrong version of a file that has an #include directive for a header file that is not intended for that build. For
example, certain files may only apply to x86 builds, or to Debug builds. When the header file is not found, the
compiler generates a C1083 error. The fix for this problem is to use the correct file, not to add the header file or
directory to the build.

The precompiled headers are not yet precompiled


When a project is configured to use precompiled headers, the relevant .pch files have to be created so that files that
use the header contents can be compiled. For example, the stdafx.cpp file is automatically created in the project
directory for new projects. Compile that file first to create the precompiled header files. In the typical build process
design, this is done automatically. For more information, see Creating Precompiled Header Files.

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

Cannot read filetype file: 'file': message


This error is generally the result of a failed internal system API call made by the compiler. The message shown
when this error is encountered is often generated by either _wcserror_s or FormatMessage.
Performing the following steps may help resolve C1084:
Ensure the specified file exists.
Ensure the appropriate permissions are set in order to access the specified file.
Ensure the command-line syntax adheres to the rules outlined under Compiler Command-Line Syntax.
Ensure sure the environment variables TMP and TEMP are properly set, as well as the appropriate
permissions in order to access the directories these environment variables refer to. Also ensure that the
drives referenced by the TMP and TEMP environment variables contain an adequate amount of free space.
If the message says "bad file number", the specified file may have been closing in the foreground while
compiling in the background.
After performing the above diagnostics, perform a clean build.
Fatal Error C1085
10/31/2018 • 2 minutes to read • Edit Online

Cannot write filetype file: 'file': message


To fix by checking the following possible causes
1. Drive is read-only.
2. Drive is full.
3. Sharing violation.
4. If the message says "bad file number", the file may have been closing in the foreground while compiling in
the background.
Fatal Error C1086
10/31/2018 • 2 minutes to read • Edit Online

Cannot seek filetype file: 'file': message


The compiler cannot complete an I/O operation.
Fatal Error C1087
10/31/2018 • 2 minutes to read • Edit Online

Cannot tell filetype file: 'file': message


The compiler cannot complete an I/O operation.
Fatal Error C1088
10/31/2018 • 2 minutes to read • Edit Online

Cannot flush filetype file: 'file': message


The compiler cannot complete an I/O operation.
Fatal Error C1089
10/31/2018 • 2 minutes to read • Edit Online

Cannot truncate filetype file: 'file': message


The compiler cannot shrink a file to zero length.
Fatal Error C1091
10/31/2018 • 2 minutes to read • Edit Online

compiler limit: string exceeds 'length' bytes in length


A string constant exceeded the current limit on the length of strings.
You might want to split the static string into two (or more) variables and use strcpy_s to join the result as part of
the declaration or during run time.
Fatal Error C1092
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

Version mismatch with Edit and Continue engine


The debugger version you are using does not match the compiler used to create the executable. If recompiling does
not fix the problem, you may need to reinstall Visual C++ to make sure you have the proper versions of the
debugger and compiler.
Fatal Error C1099
10/31/2018 • 2 minutes to read • Edit Online

Edit and Continue engine terminating compile


Edit and Continue loaded a precompiled header file in preparation for compiling code changes, but subsequent
actions (such as code changes prior to the precompiled header #include statement or stopping the debugger)
prevented Edit and Continue from finishing the compile with that process. You do not need to take any action to fix
this error.
Fatal Error C1100
10/31/2018 • 2 minutes to read • Edit Online

unable to initialize OLE : system error message


The compiler cannot initialize the Component Object Model (COM ) library. See CoInitialize.
Fatal Error C1103
10/31/2018 • 2 minutes to read • Edit Online

fatal error importing progid: 'message'


The compiler detected a problem importing a type library. For example, you cannot specify a type library with
progid and also specify no_registry .
For more information, see #import Directive.
The following sample will generate C1103:

// 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

fatal error importing libid: 'message'


The compiler detected a problem importing a type library. For example, you cannot specify a type library with libid
and also specify no_registry .
For more information, see #import Directive.
The following sample will generate C1104:

// 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

unable to find DLL: 'dll name'

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

unable to find 'entry point' in DLL 'dll'


An entry point in a delay-loaded DLL required by the compiler could not be found.
Fatal Error C1113
10/31/2018 • 2 minutes to read • Edit Online

#using failed on 'file'


Only a file in the Microsoft Intermediate Language (MSIL ) format can be passed to a #using directive. The /clr
compiler option lets you create an MSIL output file. Other Visual Studio languages also produce MSIL files.
Fatal Error C1120
10/31/2018 • 2 minutes to read • Edit Online

call to GetProcAddress failed for 'function'


This error indicates Visual C++ needs to be reinstalled.
Fatal Error C1121
10/31/2018 • 2 minutes to read • Edit Online

call to CryptoAPI failed


The compiler made a call to the CryptoAPI and the call failed. Reinstall Visual Studio and possibly reinstall the
operating system.
Fatal Error C1126
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : automatic allocation exceeds size


Space allocated for local variables of a function (plus a limited amount of space used by the compiler, such as an
extra 20 bytes for swappable functions) exceeds the limit.
To correct this error, use malloc or new to allocate large amounts of data.
Fatal Error C1128
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

#error : user supplied error message

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

managed targeted code requires a '/clr' option


You are using CLR constructs but you did not specify /clr.
For more information, see /clr (Common Language Runtime Compilation).
The following sample generates C1190:

// C1190.cpp
// compile with: /c
__gc class A {}; // C1190
ref class A {};
Fatal Error C1191
10/31/2018 • 2 minutes to read • Edit Online

'dll' can only be imported at global scope


The instruction to import mscorlib.dll into a program that uses /clr programming cannot appear in a namespace or
function, but must appear at global scope.
The following sample generates C1191:

// 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

#using failed on 'file'


Only a file in the Microsoft Intermediate Language (MSIL ) format can be passed to a #using directive. The /clr
compiler option lets you create an MSIL output file. Other Visual Studio languages also produce MSIL files.
Fatal Error C1196
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

cannot reference 'mscorlib.dll_1' as the program has already referenced 'mscorlib.dll_2'


The compiler is matched to a version of the common language runtime. However, an attempt was made to
reference a version of a common language runtime file from a previous version.
To resolve this error, only reference files from the version of the common language runtime that shipped with the
version of Visual C++ you are compiling with.

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

unable to continue after syntax error in class template definition


An unexpected error occurred while parsing a class template definition.
Fix any other errors and recompile. If that fails, note the circumstances of the error, try to isolate the problem and
create a reproducible test case, then contact Microsoft Product Support Services.
Fatal Error C1202
10/31/2018 • 2 minutes to read • Edit Online

recursive type or function dependency context too complex


A template definition was recursive or exceeded complexity limits.

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

Generics are not supported by the version of the runtime installed


The version of the common language runtime that the compiler is using is not a version of the runtime supported
by the current compiler. For example, the generics feature requires a runtime that is matched to the compiler.
Your path specification may need to be modified.
Fatal Error C1206
10/31/2018 • 2 minutes to read • Edit Online

Per-appdomain data is not supported by the version of the runtime installed


Some features, such as per application domain data, are only supported by the common language runtime that
supports the feature.
C1206 indicates that the latest version of the runtime is not installed on your computer. Install the common
language runtime version that is intended for use with your compiler.
See appdomain for more information.
Fatal Error C1207
10/31/2018 • 2 minutes to read • Edit Online

Managed templates not supported by the version of the runtime installed


C1207 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 C1207 install the common language runtime version that is intended for use with your compiler.
Fatal Error C1208
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

Friend assemblies 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.
To resolve C1209, install the common language runtime that shipped with the compiler you are using.
For more information, see Friend Assemblies (C++).
Fatal Error C1210
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

profile database 'pgd_file' is for a different architecture


A .pgd file that was generated from the /LTCG:PGINSTRUMENT operation for another platform was passed to
/LTCG:PGOPTIMIZE . Profile-guided optimizations are available for x86 and x64 platforms. However, a .pgd file
generated with a /LTCG:PGINSTRUMENT operation for one platform is not valid as input to a
/LTCG:PGOPTIMIZE for a different platform.
To resolve this error, only pass a .pgd file that is created with /LTCG:PGINSTRUMENT to /LTCG:PGOPTIMIZE on
the same platform.
Fatal Error C1307
10/31/2018 • 2 minutes to read • Edit Online

program has been edited since profile data was collected


When using /LTCG:PGOPTIMIZE, the linker detected an input module that was recompiled after
/LTCG:PGINSTRUMENT and that the module was changed to the point where existing profile data is no longer
relevant. For example, if the call graph changed in the recompiled module, the compiler will generate C1307.
To resolve this error, run /LTCG:PGINSTRUMENT, redo all test runs, and run /LTCG:PGOPTIMIZE. If you cannot
run /LTCG:PGINSTRUMENT and redo all test runs, use /LTCG:PGUPDATE instead of /LTCG:PGOPTIMIZE to
create the optimized image.
Fatal Error C1308
10/31/2018 • 2 minutes to read • Edit Online

linking assemblies is not supported


A .netmodule is allowed as input to the linker, but an assembly is not. This error can be generated when an attempt
is made to link an assembly compiled with /clr:safe .
For more information, see .netmodule Files as Linker Input.
The following sample generates C1308:

// 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

Mismatched versions of C2.DLL and PGODB<version>.DLL


The toolset you are using to build and use Profile-Guided Optimizations contains mismatched components. If you
cannot manually resolve this error, reinstall Visual C++.
Fatal Error C1310
10/31/2018 • 2 minutes to read • Edit Online

profile guided optimizations are not available with OpenMP


You will not be able to link with /LTCG:PGI any module that was compiled with /GL.
The following sample generates C1310:

// C1310.cpp
// compile with: /openmp /GL /link /LTCG:PGI
// C1310 expected
int main()
{
int i = 0, j = 10;

#pragma omp parallel


{
#pragma omp for
for (i = 0; i < 0; i++)
--j;
}
}
Fatal Error C1311
10/31/2018 • 2 minutes to read • Edit Online

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.

char c = (char)"Hello, world"; // C1311


char *d = (char*)"Hello, world"; // OK
Fatal Error C1312
10/31/2018 • 2 minutes to read • Edit Online

Too many conditional branches in function. Simplify or refactor source code.


The code is too complex for the compiler to process without running out of stack memory. Simplify your code.
Fatal Error C1313
10/31/2018 • 2 minutes to read • Edit Online

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

error loading dll 'dll': dll not found


The DLL that supports the attempted operation was not found.
This indicates a problem with your installation and you should reinstall the DLL from your product CD.
Fatal Error C1351
10/31/2018 • 2 minutes to read • Edit Online

error loading dll 'dll': incompatible version

The wrong version of a DLL was found.


This indicates a problem with your installation, and you should reinstall Visual Studio.
Fatal Error C1352
10/31/2018 • 2 minutes to read • Edit Online

Invalid or corrupt MSIL in function 'function' from module 'file'


A .netmodule was passed to the compiler, but the compiler detected corruption in the file. Ask the person who
produced the .netmodule to investigate.
The compiler does not check .netmodule files for all types of corruption. It does, however, check that all control
paths in a function contain a return statement.
For more information, see .netmodule Files as Linker Input.
Fatal Error C1353
10/31/2018 • 2 minutes to read • Edit Online

metadata operation failed: runtime not installed or version mismatch


Reinstall your CLR or Visual Studio.
Fatal Error C1382
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

unrecoverable block scoping error


The block was too large to compile.
To fix by checking the following possible causes
1. Mismatched braces
2. Unusually large function or class
Fatal Error C1508
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : 'function' : more than 65535 argument bytes


The formal parameters to the function exceed the limit of 65535 bytes.
Fatal Error C1509
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

Cannot open language resource clui.dll


The compiler can't load the language resource DLL.
There are two common causes for this issue. When using the 32-bit compiler and tools, you may see this error for
large projects that use more than 2GB of memory during a link. A possible solution on 64-bit Windows systems is
to use the 64-bit native or cross compiler and tools to generate your code. This takes advantage of the larger
memory space available to 64-bit apps. If you must use a 32-bit compiler because you are running on a 32-bit
system, in some cases you can increase the amount of memory available to the linker to 3GB. For more
information, see 4-Gigabyte Tuning: BCDEdit and Boot.ini and the BCDEdit /set increaseuserva command.
The other common cause is a broken or incomplete Visual Studio installation. In this case, run the installer again to
repair or reinstall Visual Studio.
Fatal Error C1601
10/31/2018 • 2 minutes to read • Edit Online

unsupported inline assembly opcode


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 C1602
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

inline assembly branch target out of range by 'number' bytes


The computed distance between a JCXZ or JECXZ instruction and its specified target label was greater than 128
bytes. Update your code so that the label is closer to the instruction.
Fatal Error C1852
10/31/2018 • 2 minutes to read • Edit Online

'filename' is not a valid precompiled header file


The file is not a precompiled header.
To fix by checking the following possible causes
1. Invalid file specified with /Yu or #pragma hdrstop.
2. The compiler assumes a file extension of .pch if you do not specify otherwise.
Fatal Error C1853
3/12/2019 • 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

Il mismatch between 'tool1' version 'number1' and 'tool2' version 'number2'

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

program database manager mismatch; please check your installation


A program database file (.pdb) was created using a newer version of mspdbXXX.dll than the one the compiler
found on your system. This error usually indicates that mspdbsrv.exe or mspdbcore.dll are missing or have
different versions than mspdbXXX.dll. (The XXX placeholder in the mspdbXXX.dll file name changes with each
product release. For example, in Visual Studio 2015, the file name is mspdb140.dll.)
Ensure matching versions of mspdbsrv.exe, mspdbcore.dll, and mspdbXXX.dll are installed on your system. Ensure
that mismatched versions have not been copied to the directory that contains the compiler and link tools for your
target platform. For example, you might have copied the files so you could invoke the compiler or link tool from
the command prompt without setting the PATH environment variable accordingly.
Fatal Error C1903
10/31/2018 • 2 minutes to read • Edit Online

unable to recover from previous error(s); stopping compilation


The compiler found too many errors to continue. Fix the errors and recompile.
Fatal Error C1904
10/31/2018 • 2 minutes to read • Edit Online

bad provider interaction: 'file'


This error indicates the failure of an attribute provider.
Note the circumstances of the error, try to isolate the problem and create a reproducible test case, then contact Talk
to Us.
Fatal Error C1905
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 C2001 newline in constant

Compiler Error C2002 invalid wide-character constant

Compiler Error C2003 expected 'defined id'

Compiler Error C2004 expected 'defined(id)'

Compiler Error C2005 #line expected a line number, found 'token'


ERROR MESSAGE

Compiler Error C2006 'directive': expected a filename, found 'token'

Compiler Error C2007 #define syntax

Compiler Error C2008 'character': unexpected in macro definition

Compiler Error C2009 reuse of macro formal 'identifier'

Compiler Error C2010 'character': unexpected in macro formal parameter list

Compiler Error C2011 'identifier': 'type' type redefinition

Compiler Error C2012 missing name following '<'

Compiler Error C2013 missing '>'

Compiler Error C2014 preprocessor command must start as first nonwhite space

Compiler Error C2015 too many characters in constant

Compiler Error C2016 C requires that a struct or union has at least one member

Compiler Error C2017 illegal escape sequence

Compiler Error C2018 unknown character '0xvalue'

Compiler Error C2019 expected preprocessor directive, found 'character'

Compiler Error C2020 'member': 'class' member redefinition

Compiler Error C2021 expected exponent value, not 'character'

Compiler Error C2022 'number': too big for character

Compiler Error C2023 'identifier': Alignment (number1) different from prior


declaration (number2)

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 C2026 string too big, trailing characters truncated

Compiler Error C2027 use of undefined type 'type'

Compiler Error C2028 struct/union member must be inside a struct/union

Compiler Error C2029 left of 'token' specifies undefined class/struct/interface


'identifier'
ERROR MESSAGE

Compiler Error C2030 a destructor with 'protected private' accessibility cannot be a


member of a class declared 'sealed'

Compiler Error C2031 a virtual destructor with 'accessibility' accessibility is not


allowed for this type

Compiler Error C2032 'identifier': function cannot be member of struct/union 'type'

Compiler Error C2033 'identifier': bit field cannot have indirection

Compiler Error C2034 'identifier': type of bit field too small for number of bits

Compiler Error C2035 a non-virtual destructor with 'accessibility' accessibility is not


allowed for this type

Compiler Error C2036 'identifier': unknown size

Compiler Error C2037 left of 'identifier' specifies undefined struct/union 'type'

Compiler Error C2038 the std namespace cannot be inline

Compiler Error C2039 'identifier1': is not a member of 'identifier2'

Compiler Error C2040 'operator': 'identifier1' differs in levels of indirection from


'identifier2'

Compiler Error C2041 illegal digit 'character' for base 'number'

Compiler Error C2042 signed/unsigned keywords mutually exclusive

Compiler Error C2043 illegal break

Compiler Error C2044 illegal continue

Compiler Error C2045 'identifier': label redefined

Compiler Error C2046 illegal case

Compiler Error C2047 illegal default

Compiler Error C2048 more than one default

Compiler Error C2049 'identifier': non-inline namespace cannot be reopened as inline

Compiler Error C2050 switch expression not integral

Compiler Error C2051 case expression not constant

Compiler Error C2052 'type': illegal type for case expression

Compiler Error C2053 'identifier': wide string mismatch


ERROR MESSAGE

Compiler Error C2054 expected '(' to follow 'identifier'

Compiler Error C2055 expected formal parameter list, not a type list

Compiler Error C2056 illegal expression

Compiler Error C2057 expected constant expression

Compiler Error C2058 constant expression is not integral

Compiler Error C2059 syntax error: 'token'

Compiler Error C2060 syntax error: end of file found

Compiler Error C2061 syntax error: identifier 'identifier'

Compiler Error C2062 type 'type' unexpected

Compiler Error C2063 'identifier': not a function

Compiler Error C2064 term does not evaluate to a function taking number
arguments

Compiler Error C2065 'identifier': undeclared identifier

Compiler Error C2066 cast to function type is illegal

Compiler Error C2067 cast to array type is illegal

Compiler Error C2068 illegal use of overloaded function. Missing argument list?

Compiler Error C2069 cast of 'void' term to non-'void'

Compiler Error C2070 'type': illegal sizeof operand

Compiler Error C2071 'identifier': illegal storage class

Compiler Error C2072 'identifier': initialization of a function

Compiler Error C2073 'identifier': elements of partially initialized array must have a
default constructor

Compiler Error C2074 'identifier': 'type' initialization requires a brace-enclosed


initializer list

Compiler Error C2075 'identifier': array initialization requires a brace-enclosed


initializer list

Compiler Error C2076 a brace-enclosed initializer list cannot be used in a new-


expression whose type contains 'type'
ERROR MESSAGE

Compiler Error C2077 non-scalar field initializer 'identifier'

Compiler Error C2078 too many initializers

Compiler Error C2079 'identifier' uses undefined struct/class/union 'type'

Compiler Error C2080 'identifier': the type for 'type' can only be deduced from a
single initializer expression

Compiler Error C2081 'identifier': name in formal parameter list illegal

Compiler Error C2082 redefinition of formal parameter 'identifier'

Compiler Error C2083 struct/union comparison illegal

Compiler Error C2084 function 'identifier' already has a body

Compiler Error C2085 'identifier': not in formal parameter list

Compiler Error C2086 'identifier': redefinition

Compiler Error C2087 'identifier': missing subscript

Compiler Error C2088 'operator': illegal for struct/class/union

Compiler Error C2089 'identifier': 'type' too large

Compiler Error C2090 function returns array

Compiler Error C2091 function returns function

Compiler Error C2092 'identifier' array element type cannot be function

Compiler Error C2093 'identifier1': cannot be initialized using address of automatic


variable 'identifier2'

Compiler Error C2094 label 'identifier' was undefined

Compiler Error C2095 'function': actual parameter has type 'void': parameter number

Compiler Error C2096 'identifier': A data member cannot be initialized with a


parenthesized initializer

Compiler Error C2097 illegal initialization

Compiler Error C2098 unexpected token after data member 'identifier'

Compiler Error C2099 initializer is not a constant


Compiler Error C2001
10/31/2018 • 2 minutes to read • Edit Online

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

invalid wide-character constant


The multibyte-character constant is not valid.
To fix by checking the following possible causes
1. The wide-character constant contains more bytes than expected.
2. The standard header STDDEF.h is not included.
3. Wide characters cannot be concatenated with ordinary string literals.
4. A wide-character constant must be preceded by the character 'L':

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 follow the preprocessor keyword.
Compiler Error C2004
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

#line expected a line number, found 'token'


The #line directive must be followed by a line number.
The following sample generates C2005:

// 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

'directive' expected a filename, found 'token'


Directives such as #include or #import require a filename. To resolve the error, make sure token is a valid filename.
Also, put the filename in double quotes or angle brackets.
The following sample generates C2006:

// 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

'character' : unexpected in macro definition


The character appears immediately following the macro name. To resolve the error, there must be a space after the
macro name.
The following sample generates C2008:

// 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

reuse of macro formal 'identifier'


The formal parameter list of a macro definition uses the identifier more than once. Identifiers in the macro's
parameter list must be unique.

Example
The following sample generates C2009:

// C2009.cpp
#include <stdio.h>

#define macro1(a,a) (a*a) // C2009

int main()
{
printf_s("%d\n", macro1(2));
}

Example
Possible resolution:

// C2009b.cpp
#include <stdio.h>

#define macro2(a) (a*a)


#define macro3(a,b) (a*b)

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

'character' : unexpected in macro formal parameter list


The character is used incorrectly in the formal parameter list of a macro definition. Remove the character to resolve
the error.
The following sample generates C2010:

// 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

'identifier' : 'type' type redefinition


The identifier was already defined as type . Check for redefinitions of the identifier.
You may also get C2011 if you import a header file or type library more than once into the same file. To prevent
multiple inclusions of the types defined in a header file, use include guards or a #pragma once directive in the
header file.
If you need to find the initial declaration of the redefined type, you can use the /P compiler flag to generate the
preprocessed output passed to the compiler. You can use text search tools to find instances of the redefined
identifier in the output file.
The following sample generates C2011 and shows one way to fix it:

// 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

missing name following '<'


An #include directive lacks the required filename.
The following sample generates C2012:

// 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

preprocessor command must start as first nonwhite space


The # sign of a preprocessor directive must be the first character on a line that is not white space.
The following sample generates C2014:

// 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

too many characters in constant


A character constant contains more than two characters. The limit is one character for standard character constants
and two characters for long character constants.
An escape sequence, such as \t, is converted to a single character.

Example
The following sample generates C2015:

// C2015.cpp
// compile with: /c

char test1 = 'error'; // C2015


char test2 = 'e'; // OK

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

int b = 'a'; // 'a' = ascii 0x61


printf_s("%x\n", b);
}
Compiler Error C2017
10/31/2018 • 2 minutes to read • Edit Online

illegal escape sequence


An escape sequence, such as \t, appears outside of a character or string constant.
The following sample generates C2017:

// 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

unknown character 'hexnumber'


The source file contains an unexpected ASCII character, which is identified by its hex number. To resolve the error,
remove the character.
Compiler Error C2019
10/31/2018 • 2 minutes to read • Edit Online

expected preprocessor directive, found 'character'


The character followed a # sign but it is not the first letter of a preprocessor directive.
The following sample generates C2019:

// 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

'member' : 'class' member redefinition


A member inherited from a base class or structure is redefined. Inherited members cannot be redefined unless
declared as virtual in the base class.
Compiler Error C2021
10/31/2018 • 2 minutes to read • Edit Online

expected exponent value, not 'character'


The character used as the exponent of a floating-point constant is not a valid number. Be sure to use an exponent
that is in range.

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

'number' : too big for character


The octal number following a backslash (\) in a character or string constant is too big to represent a character.
Compiler Error C2026
10/31/2018 • 2 minutes to read • Edit Online

string too big, trailing characters truncated


The string was longer than the limit of 16380 single-byte characters.
Prior to adjacent strings being concatenated, a string cannot be longer than 16380 single-byte characters.
A Unicode string of about one half this length would also generate this error.
If you have a string defined as follows, it generates C2026:

char sz[] =
"\
imagine a really, really \
long string here\
";

You could break it up as follows:

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

use of undefined type 'type'


A type cannot be used until it is defined. To resolve the error, be sure the type is fully defined before referencing it.

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

struct/union member must be inside a struct/union


Structure or union members must be declared within the structure or union.
Compiler Error C2030
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

'identifier' : function cannot be member of struct/union 'structorunion'


The structure or union has a member function, which is allowed in C++ but not in C. To resolve the error, either
compile as a C++ program or remove the member function.
The following sample generates C2032:

// 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

'identifier' : bit field cannot have indirection


The bit field was declared as a pointer, which is not allowed.
The following sample generates C2033:

// 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

'identifier' : type of bit field too small for number of bits


The number of bits in the bit-field declaration exceeds the size of the base type.
The following sample generates C2034:

// 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

'identifier' : unknown size


An operation on identifier requires the size of the data object, which cannot be determined.

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

'identifier1' : is not a member of 'identifier2'


The code incorrectly calls or refers to a member of a structure, class, or union.

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){}
};
};

int S::get_Count() { return 0; } // C2039


int S::Count::get() { return 0; } // OK

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 {};

ref struct R : public I {


virtual void f3() {}
};

generic <typename T>


where T : I
void f(T t) {
t->f3(); // C2039
safe_cast<R^>(t)->f3(); // OK
}

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;

void CheckStatus( Object^ stateInfo ) {}

int main() {
ManualResetEvent^ event = gcnew ManualResetEvent( false );
TimerCallback^ timerDelegate = gcnew TimerCallback( &CheckStatus );
Timer^ stateTimer = gcnew Timer( timerDelegate, event, 1000, 250 );

((IDisposable ^)stateTimer)->Dispose(); // C2039

stateTimer->~Timer(); // OK
}
Compiler Error C2040
10/31/2018 • 2 minutes to read • Edit Online

'operator' : 'identifier1' differs in levels of indirection from 'identifier2'


An expression involving the specified operands has incompatible operand types or implicitly converted operand
types. If both operands are arithmetic, or both are nonarithmetic (such as array or pointer), they are used without
change. If one operand is arithmetic and the other is not, the arithmetic operand is converted to the type of the
nonarithmetic operand.
This sample generates C2040 and shows how to fix it.

// 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

illegal digit 'character' for base 'number'


The specified character is not a valid digit for the base (such as octal or hex).
The following sample generates C2041:

// 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

signed/unsigned keywords mutually exclusive


The keywords signed and unsigned are used in a single declaration.
The following sample generates C2042:

// 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

'identifier' : label redefined


The label appears before multiple statements in the same function.
The following sample generates C2045:

// 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

more than one default


A switch statement contains multiple default labels. Delete one of the default labels to resolve the error.
The following sample generates C2048:

// 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

switch expression not integral


The switch expression evaluates to a noninteger value. To resolve the error, use only integral values in switch
statements.
The following sample generates C2050:

// 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

case expression not constant


Case expressions must be integer constants.
The following sample generates C2051:

// 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

'type' : illegal type for case expression


Case expressions must be integer constants.
The following sample generates C2052:

// 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

'identifier' : wide string mismatch


The wide string is assigned to an incompatible type.
The following sample generates C2053:

// C2053.c
int main() {
char array[] = L"Rika"; // C2053
}
Compiler Error C2054
10/31/2018 • 2 minutes to read • Edit Online

expected '(' to follow 'identifier'


The function identifier is used in a context that requires trailing parentheses.
This error can be caused by omitting an equal sign (=) on a complex initialization.
The following sample generates C2054:

// 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

expected formal parameter list, not a type list


A function definition contains a parameter type list instead of a formal parameter list. ANSI C requires formal
parameters to be named unless they are void or an ellipsis ( ... ).
The following sample generates C2055:

// 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

expected constant expression


The context requires a constant expression, an expression whose value is known at compile time.
The compiler must know the size of a type at compile time in order to allocate space for an instance of that type.

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

constant expression is not integral


The context requires an integer constant expression.
Compiler Error C2059
11/9/2018 • 2 minutes to read • Edit Online

syntax error : 'token'


The token caused a syntax error.
The following example generates an error message for the line that declares j .

// 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) {}
};

void func(ag_type arg = {5, 7.0}); // C2059


void func(ag_type arg = ag_type(5, 7.0)); // OK
C2059 can occur for an ill-formed cast.
The following sample generates C2059:

// 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:

template <typename T> struct Allocator {


template <typename U> struct Rebind {
typedef Allocator<U> Other;
};
};

template <typename X, typename AY> struct Container {


typedef typename AY::Rebind<X>::Other AX; // error C2059
};

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:

template <typename T> struct Allocator {


template <typename U> struct Rebind {
typedef Allocator<U> Other;
};
};

template <typename X, typename AY> struct Container {


typedef typename AY::template Rebind<X>::Other AX; // correct
};
Compiler Error C2060
10/31/2018 • 2 minutes to read • Edit Online

syntax error : end of file found


At least one more token was expected.
Compiler Error C2061
10/31/2018 • 2 minutes to read • Edit Online

syntax error : identifier 'identifier'


The compiler found an identifier where it wasn't expected. Make sure that identifier is declared before you use it.
An initializer may be enclosed by parentheses. To avoid this problem, enclose the declarator in parentheses or
make it a typedef .
This error could also be caused when the compiler detects an expression as a class template argument; use
typename to tell the compiler it is a type.
The following sample generates C2061:

// C2061.cpp
// compile with: /c
template < A a > // C2061
// try the following line instead
// template < typename b >
class c{};

C2061 can occur if you pass an instance name to typeid:

// 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

type 'type' unexpected


The compiler did not expect a type name.
The following sample generates C2062:

// 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

'identifier' : not a function


The identifier is used as a function but not declared as a function.
The following sample generates C2063:

// 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

term does not evaluate to a function taking N arguments


A call is made to a function through an expression. The expression does not evaluate to a pointer to a function that
takes the specified number of arguments.
In this example, the code attempts to call non-functions as functions. The following sample generates C2064:

// 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(){}
};

typedef void (C::*pFunc)();

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

'identifier' : undeclared identifier

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.

The identifier is undeclared


If the identifier is a variable or a function name, you must declare it before it can be used. A function declaration
must also include the types of its parameters before the function can be used. If the variable is declared using
auto , the compiler must be able to infer the type from its initializer.

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 .

Example: misspelled identifier


This error commonly occurs when the identifier name is misspelled, or the identifier uses the wrong uppercase and
lowercase letters. The name in the declaration must exactly match the name you use.

// 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;
}

Example: use an unscoped identifier


This error can occur if your identifier is not properly scoped. If you see C2065 when you use cout , this is the
cause. When C++ Standard Library functions and operators are not fully qualified by namespace, or you have not
brought the std namespace into the current scope by using a using directive, the compiler can't find them. To fix
this issue, you must either fully qualify the identifier names, or specify the namespace with the using directive.
This example fails to compile because cout and endl are defined in the std namespace:

// 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.

Example: precompiled header isn't first


This error can occur if you put any preprocessor directives, such as #include, #define, or #pragma, before the
#include of a precompiled header file. If your source file uses a precompiled header file (that is, if it's compiled by
using the /Yu compiler option) then all preprocessor directives before the precompiled header file are ignored.
This example fails to compile because cout and endl are defined in the <iostream> header, which is ignored
because it is included before the precompiled header file. To build this example, create all three files, then compile
stdafx.cpp, then compile C2065_pch.cpp.

// 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.

Example: missing header file


You have not included the header file that declares the identifier. Make sure the file that contains the declaration for
the identifier is included in every source file that uses it.

// 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.

Example: missing closing quote


This error can occur if you are missing a closing quote after a string constant. This is an easy way to confuse the
compiler. Note that the missing closing quote may be several lines before the reported error location.

// 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
}

Example: use iterator outside for loop scope


This error can occur if you declare an iterator variable in a for loop, and then you try to use that iterator variable
outside the scope of the for loop. The compiler enables the /Zc:forScope compiler option by default. See Debug
Iterator Support for more information.
// C2065_iter.cpp
// compile with: cl /EHsc C2065_iter.cpp
#include <iostream>
#include <string>

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
}

Example: preprocessor removed declaration


This error can occur if you refer to a function or variable that is in conditionally compiled code that is not compiled
for your current configuration. This can also occur if you call a function in a header file that is currently not
supported in your build environment. If certain variables or functions are only available when a particular
preprocessor macro is defined, make sure the code that calls those functions can only be compiled when the same
preprocessor macro is defined. This issue is easy to spot in the IDE, because the declaration for the function is
greyed out if the required preprocessor macros are not defined for the current build configuration.
This is an example of code that works when you build in Debug, but not Retail:

// 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
}

Example: C++/CLI type deduction failure


This error can occur when calling a generic function, if the intended type argument cannot be deduced from the
parameters used. For more information, see Generic Functions (C++/CLI).
// C2065_b.cpp
// compile with: cl /clr C2065_b.cpp
generic <typename ItemType>
void G(int i) {}

int main() {
// global generic function call
G<T>(10); // C2065
G<int>(10); // OK - fix with a specific type argument
}

Example: C++/CLI attribute parameters


This error can also be generated as a result of compiler conformance work that was done for Visual C++ 2005:
parameter checking for Visual C++ attributes.

// 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

cast to function type is illegal


In ANSI C, it is not legal to cast between a function pointer and a data pointer.
Compiler Error C2067
10/31/2018 • 2 minutes to read • Edit Online

cast to array type is illegal


An object was cast to an array type.
Compiler Error C2069
10/31/2018 • 2 minutes to read • Edit Online

cast of 'void' term to non-'void'


Type void cannot be cast to any other type.
Compiler Error C2070
10/31/2018 • 2 minutes to read • Edit Online

'type': illegal sizeof operand


The sizeof operator requires an expression or type name.
The following sample generates C2070:

// 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

'identifier' : illegal storage class


identifier was declared with an invalid storage class. This error can be caused when more than one storage class
is specified for an identifier, or when the definition is incompatible with the storage class declaration.
To fix this issue, understand the intended storage class of the identifier—for example, static or extern —and
correct the declaration to match.

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

'identifier' : initialization of a function


A function initializer was specified incorrectly.
Compiler Error C2073
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : elements of partially initialized array must have a default constructor


Too few initializers were specified for an array of user-defined types or constants. If an explicit initializer and its
corresponding constructor are not specified for an array member, a default constructor must be supplied.
The following sample generates C2073:

// 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

'identifier' : 'class-key' initialization needs curly braces


There were no curly braces around the specified class, structure, or union initializer.
Compiler Error C2075
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : array initialization needs curly braces


There were no curly braces around the specified array initializer.
The following sample generates C2075:

// 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

non-scalar field initializer 'identifier'


You tried to initialize a bit field with a nonscalar (struct, union, array, or class). Use an integer or floating-point
value.
Compiler Error C2078
11/9/2018 • 2 minutes to read • Edit Online

too many initializers


The number of initializers exceeds the number of objects to be initialized.
The compiler can deduce the correct assignment of initializers to objects and inner objects when inner braces are
elided from the initializer list. Complete bracing also eliminates ambiguity and results in correct assignment. Partial
bracing can cause C2078 because of ambiguity in the assignment of initializers to objects.
The following sample generates C2078 and shows how to fix it:

// 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

char a[] = {"a", "b"}; // C2078


char *b[] = {"a", "b"}; // OK
char c[] = {'a', 'b'}; // 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

'identifier' uses undefined class/struct/union 'name'


The specified identifier is an undefined class, structure, or union.
This error can be caused by initializing an anonymous union.
The following sample generates C2079:

// 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

'identifier' : name in formal parameter list illegal


The identifier caused a syntax error.
This error can be caused by using the old style for the formal parameter list. You must specify the type of formal
parameters in the formal parameter list.
The following sample generates C2081:

// 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

redefinition of formal parameter 'identifier'


A formal parameter to a function is redeclared within the function body. To resolve the error, remove the
redefinition.
The following sample generates C2082:

// C2082.cpp
void func(int i) {
int i; // C2082
int ii; // OK
}
Compiler Error C2083
10/31/2018 • 2 minutes to read • Edit Online

struct/union comparison illegal


A structure or union is compared directly with another user-defined type. This is not allowed unless a comparison
operator has been defined or a conversion to a scalar type exists.
Compiler Error C2084
10/31/2018 • 2 minutes to read • Edit Online

function 'function' already has a body


The function has already been defined.
In versions of Visual C++ before Visual Studio 2002,
The compiler would accept multiple template specializations that resolved to the same actual type, although
the additional definitions would never be available. The compiler now detects these multiple definitions.
__int32and int were treated as separate types. The compiler now treats __int32 as a synonym for int .
This means that the compiler detects multiple definitions if a function is overloaded on both __int32 and
int and gives an error.

Example
The following sample generates C2084:

// C2084.cpp
void Func(int);
void Func(int) {} // define function
void Func(int) {} // C2084 second definition

To correct this error, remove the duplicate definition:

// C2084b.cpp
// compile with: /c
void Func(int);
void Func(int) {}
Compiler Error C2085
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : not in formal parameter list


The identifier was declared in a function definition but not in the formal parameter list. (ANSI C only)
The following sample generates C2085:

// 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

'identifier' : missing subscript


The definition of an array with multiple subscripts is missing a subscript value for a dimension higher than one.
The following sample generates C2087:

// 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

'operator' : illegal for 'class-key'


The operator was not defined for the structure or union. This error is only valid for C code.
The following sample generates C2088 three times:

// 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

'identifier' : 'class-key' too large


The specified structure or union exceeds the 4GB limit.
Compiler Error C2090
10/31/2018 • 2 minutes to read • Edit Online

function returns array


A function cannot return an array. Return a pointer to an array instead.
The following sample generates C2090:

// 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

function returns function


A function cannot return a function. Return a pointer to a function instead.
Compiler Error C2092
10/31/2018 • 2 minutes to read • Edit Online

'array name' array element type cannot be function


Arrays of functions are not allowed. Use an array of pointers to functions.

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

'variable1' : cannot be initialized using address of automatic variable 'variable2'


When compiling with /Za, the program tried to use the address of an automatic variable as an initializer.
The following sample generates C2093:

// 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

label 'identifier' was undefined


The label used by a goto statement does not exist in the function.

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

'function' : actual parameter has type 'void' : parameter 'number'


The parameter passed to the function is type void , which is not allowed. Use a pointer to void ( void * ) instead.
The number indicates which parameter is void .
Compiler Error C2097
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

initializer is not a constant


This error is issued only by the C compiler and occurs only for non-automatic variables. The compiler initializes
non-automatic variables at the start of the program and the values they are initialized with must be constant.

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 C2100 illegal indirection

Compiler Error C2101 '&' on constant

Compiler Error C2102 '&' requires l-value

Compiler Error C2103 '&' on register variable

Compiler Error C2104 '&' on bit field ignored

Compiler Error C2105 'operator' needs l-value

Compiler Error C2106 'operator': left operand must be l-value


ERROR MESSAGE

Compiler Error C2107 illegal index, indirection not allowed

Compiler Error C2108 subscript is not of integral type

Compiler Error C2109 subscript requires array or pointer type

Compiler Error C2110 '+': cannot add two pointers

Compiler Error C2111 '+': pointer addition requires integral operand

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 C2115 'operator': incompatible types

Compiler Error C2116 function parameter lists differed

Compiler Error C2117 'identifier': array bounds overflow

Compiler Error C2118 negative subscript

Compiler Error C2119 'identifier': the type for 'type' cannot be deduced from an
empty initializer

Compiler Error C2120 'void' illegal with all types

Compiler Error C2121 '#': invalid character: possibly the result of a macro expansion

Compiler Error C2122 'identifier': prototype parameter in name list illegal

Compiler Error C2123 'identifier': alias templates cannot be explicitly or partially


specialized

Compiler Error C2124 divide or mod by zero

Compiler Error C2125 'constexpr' is incompatible with 'token'

Compiler Error C2126 'identifier' cannot be declared with 'constexpr' specifier

Compiler Error C2127 'identifier': illegal initialization of 'constexpr' entity with a non-
constant expression

Compiler Error C2128 'function': alloc_text/same_seg applicable only to functions


with C linkage

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 C2131 expression did not evaluate to a constant

Compiler Error C2132 syntax error: unexpected identifier

Compiler Error C2133 'identifier': unknown size

Compiler Error C2134 'function': call does not result in a constant expression

Compiler Error C2135 'operator': illegal bit field operation

Compiler Error C2136 authoring API contract not allowed

Compiler Error C2137 empty character constant

Compiler Error C2138 illegal to define an enumeration without any members

Compiler Error C2139 'class': an undefined class is not allowed as an argument to


compiler intrinsic type trait 'trait'

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 C2141 array size overflow

Compiler Error C2142 function declarations differ, variable parameters specified only
in one of them

Compiler Error C2143 syntax error: missing 'token1' before 'token2'

Compiler Error C2144 syntax error: 'type' should be preceded by 'token2'

Compiler Error C2145 syntax error: missing 'token' before identifier

Compiler Error C2146 syntax error: missing 'token' before identifier 'identifier'

Compiler Error C2147 syntax error: 'token' is a new keyword

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 C2151 more than one language attribute

Compiler Error C2152 'identifier': pointers to functions with different attributes

Compiler Error C2153 integer literals must have at least one digit
ERROR MESSAGE

Compiler Error C2154 'type': only enumeration type is allowed as an argument to


compiler intrinsic type trait 'trait'

Compiler Error C2155 '?': invalid left operand, expected arithmetic or pointer type

Compiler Error C2156 pragma must be outside function

Compiler Error C2157 'identifier': must be declared before use in pragma list

Compiler Error C2158 'type': #pragma make_public directive is currently supported


for native non-template types only

Compiler Error C2159 more than one storage class specified

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 C2162 expected macro formal parameter

Compiler Error C2163 'function': not available as an intrinsic function

Compiler Error C2164 'function': intrinsic function not declared

Compiler Error C2165 'modifier': cannot modify pointers to data

Compiler Error C2166 l-value specifies const object

Compiler Error C2167 'function': too many actual parameters for intrinsic function

Compiler Error C2168 'function': too few actual parameters for intrinsic function

Compiler Error C2169 'function': intrinsic function, cannot be defined

Compiler Error C2170 'identifier': not declared as a function, cannot be intrinsic

Compiler Error C2171 'operator': illegal on operands of type 'type'

Compiler Error C2172 'function': actual parameter is not a pointer: parameter


number

Compiler Error C2173 'function': actual parameter is not a pointer: parameter


number, parameter list number

Compiler Error C2174 'function': actual parameter has type 'void': parameter
number, parameter list number

Compiler Error C2175 'locale': invalid locale

Compiler Error C2176 a return statement cannot appear in the handler of a function-
try-block associated with a constructor
ERROR MESSAGE

Compiler Error C2177 constant too big

Compiler Error C2178 'identifier' cannot be declared with 'specifier' specifier

Compiler Error C2179 'type': an attribute argument cannot use type parameters

Compiler Error C2180 controlling expression has type 'type'

Compiler Error C2181 illegal else without matching if

Compiler Error C2182 'identifier': illegal use of type 'void'

Compiler Error C2183 syntax error: translation unit is empty

Compiler Error C2184 'type': illegal type for __except expression

Compiler Error C2185 'identifier': illegal based allocation

Compiler Error C2186 'operator': illegal operand of type 'void'

Compiler Error C2187 syntax error: 'token' was unexpected here

Compiler Error C2188 'number': too big for wide character

Compiler Error C2189 'alignas' attribute cannot be applied to a bit-field, a function


parameter, an exception declaration, or a variable declared
with 'register' storage class

Compiler Error C2190 first parameter list longer than second

Compiler Error C2191 second parameter list longer than first

Compiler Error C2192 parameter 'number' declaration different

Compiler Error C2193 'identifier': already in a segment

Compiler Error C2194 'identifier': is a text segment

Compiler Error C2195 'identifier': is a data segment

Compiler Error C2196 case value 'value' already used

Compiler Error C2197 'function': too many arguments for call

Compiler Error C2198 'function': too few arguments for call

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

'&' requires l-value


The address-of operator ( & ) must have an l-value as operand.
Compiler Error C2103
10/31/2018 • 2 minutes to read • Edit Online

'&' on register variable


You cannot take the address of a register.
Compiler Error C2104
10/31/2018 • 2 minutes to read • Edit Online

'&' on bit field ignored


You cannot take the address of a bit field.
The following sample generates C2104:

// 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

'operator' needs l-value


The operator must have an l-value as operand.
The following sample generates C2105:

// C2105.cpp
int main() {
unsigned char * p1 = 0;
unsigned int * p2 = (unsigned int *)p1;
p2++;

unsigned int * p = 0;
p++; // ok

p2 = (unsigned int *)p1;


((unsigned int *)p1)++; // C2105
}

The following sample generates C2105:

// 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

'operator' : left operand must be l-value


The operator must have an l-value as its left operand.
The following sample generates C2106:

// C2106.cpp
int main() {
int a;
1 = a; // C2106
a = 1; // OK
}
Compiler Error C2107
10/31/2018 • 2 minutes to read • Edit Online

illegal index, indirection not allowed


A subscript is applied to an expression that does not evaluate to a pointer.

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

subscript is not of integral type


The array subscript is a noninteger expression.

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

subscript requires array or pointer type


The subscript was used on a variable that was not an array.
The following sample generates C2109:

// 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

'+' : cannot add two pointers


An attempt was made to add two pointer values using the plus ( + ) operator.
The following sample generates C2110:

// 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

'+' : pointer addition requires integral operand


An attempt was made to add a nonintegral value to a pointer using the plus ( + ) operator.
The following sample generates C2111:

// 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

'-' : pointer subtraction requires integral or pointer operand


An attempt was made to subtract pointers that point to different types.
Compiler Error C2113
10/31/2018 • 2 minutes to read • Edit Online

'-' : pointer can only be subtracted from another pointer


The right operand in a subtraction operation was a pointer, but the left operand was not.
Compiler Error C2114
10/31/2018 • 2 minutes to read • Edit Online

'operator' : pointer on left; needs integral value on right


The left operand of operator was a pointer, so the right operand must be an integer value.
Compiler Error C2115
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : incompatible types


An expression contained incompatible types.
Compiler Error C2116
10/31/2018 • 2 minutes to read • Edit Online

function parameter lists differed


The parameters in the default parameter list do not match the formal parameter list.
Compiler Error C2117
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : array bounds overflow


An array has too many initializers:
Array elements and initializers do not match in size and quantity.
No space for the null terminator in a string.
The following sample generates C2117:

// 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

'void' illegal with all types


The void type is used in a declaration with another type.
The following sample generates C2120:

// C2120.cpp
int main() {
void int i; // C2120
int j; // OK
}
Compiler Error C2121
10/31/2018 • 2 minutes to read • Edit Online

'#' : invalid character : possibly the result of a macro expansion


An invalid # character may have been inserted by an incorrect macro that uses the token-pasting operator (##)
instead of the stringizing operator (#).
Compiler Error C2122
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : prototype parameter in name list illegal


The parameter is not a legal type. ANSI C does not support user-defined types.
Compiler Error C2124
10/31/2018 • 2 minutes to read • Edit Online

divide or mod by zero


A constant expression has a zero denominator. To resolve the error, do not divide by zero.
The following sample generates C2124:

// 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

'function' : alloc_text/same_seg applicable only to functions with C linkage


pragma alloc_text can only be used with functions declared to have C linkage.
The following sample generates C2128:

// C2128.cpp
// compile with: /c

// Delete the following line to resolve.


void func();
// #pragma alloc_text("my segment", func) // C2128

extern "C" {
void func();
}

#pragma alloc_text("my segment", func)


void func() {}
Compiler Error C2129
10/31/2018 • 2 minutes to read • Edit Online

static function 'function' declared but not defined


A forward reference is made to a static function that is never defined.
A static function must be defined within file scope. If the function is defined in another file, it must be declared
extern .
Compiler Error C2130
10/31/2018 • 2 minutes to read • Edit Online

#line expected a string containing the filename, found 'token'


The optional file name token following #line linenumber must be a string.
The following sample generates C2130:

// C2130.cpp
int main() {
#line 1000 test // C2130
#line 1000 "test" // OK
}
Compiler Error C2131
3/5/2019 • 2 minutes to read • Edit Online

expression did not evaluate to a constant

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
};

const int test::array_size = 42;

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

syntax error : unexpected identifier


An identifier appears in an unsupported context.
Compiler Error C2133
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : unknown size


An unsized array is declared as a member of a class, structure, union, or enumeration. The /Za (ANSI C ) option
does not allow unsized member arrays.
The following sample generates C2133:

// 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

'function' : call does not result in a constant expression


A function declared as constexpr can only call other functions declared as constexpr.
The following sample generates C2134:

// C2134.cpp
// compile with: /c
int A() {
return 42;
};

constexpr int B() {


return A(); // Error C2134: 'A': call does not result in a constant expression.
}

Possible resolution:

// C2134b.cpp
constexpr int A() { // add constexpr to A, since it meets the requirements of constexpr.
return 42;
};

constexpr int B() {


return A(); // No error
}
Compiler Error C2135
10/31/2018 • 2 minutes to read • Edit Online

'bit operator' : illegal bit field operation


The address-of operator ( & ) cannot be applied to a bit field.
The following sample generates C2135:

// 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

empty character constant


The empty character constant ( ' ' ) is not permitted.
The following sample generates C2137:

// C2137.cpp
int main() {
char c = ''; // C2137
char d = ' '; // OK
}
Compiler Error C2138
10/31/2018 • 2 minutes to read • Edit Online

illegal to define an enumeration without any members


An enumeration must have at least one member when /Za (disable Microsoft extensions) is selected.
Compiler Error C2139
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;

template <class T>


struct is_polymorphic {
static const bool value = __is_polymorphic(T);
};

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 {};

generic <class T>


ref class C {
void f() {
System::Console::WriteLine(__is_polymorphic(T)); // C2140
System::Console::WriteLine(is_polymorphic<T>::value); // C2140

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

array size overflow


An array exceeds the 2GB limit. Reduce the size of the array.

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

function declarations differ, variable parameters specified only in one of them


One declaration of the function contains a variable parameter list. Another declaration does not. ANSI C (/Za) only.
The following sample generates C2142:

// 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

syntax error : missing 'token1' before 'token2'


The compiler expected a specific token (that is, a language element other than white space) and found another
token instead.
Check the C++ Language Reference to determine where code is syntactically incorrect. Because the compiler may
report this error after it encounters the line that causes the problem, check several lines of code that precede the
error.
C2143 can occur in different situations.
It can occur when an operator that can qualify a name ( :: , -> , and . ) must be followed by the keyword
template , as in this example:

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)
;

if (j < 25) // C2143


}

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;

Or when there's an invalid tag in a class declaration:

// C2143e.cpp
class X {
int member;
} x;

class + {}; // C2143 + is an invalid tag name


class ValidName {}; // OK

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

Or there is a missing typename keyword:

// 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();
}

Or if you try to define an explicit instantiation:

// C2143i.cpp
// compile with: /EHsc /c
// template definition
template <class T>
void PrintType(T i, T j) {}

template void PrintType(float i, float j){} // C2143


template void PrintType(float i, float j); // OK

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

syntax error : 'type' should be preceded by 'token'

The compiler expected token and found type instead.


This error may be caused by a missing closing brace, right parenthesis, or semicolon.
C2144 can also occur when attempting to create a macro from a CLR keyword that contains a white space
character.
You may also see C2144 if you are trying to do type forwarding. See Type Forwarding (C++/CLI) for more
information.

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 {

property double MultiDimProp[,,] { // C2144


// try the following line instead
// property double MultiDimProp[int , int, int] {
double get(int, int, int) { return 1; }
void set(int i, int j, int k, double l) {}
}

property double MultiDimProp2[] { // C2144


// try the following line instead
// property double MultiDimProp2[int] {
double get(int) { return 1; }
void set(int i, double l) {}
}
};
Compiler Error C2145
10/31/2018 • 2 minutes to read • Edit Online

syntax error : missing 'token' before identifier


The compiler expected token and found identifier instead.
This error may be caused by a missing semicolon after the last declaration in a block.
Compiler Error C2146
10/31/2018 • 2 minutes to read • Edit Online

syntax error : missing 'token' before identifier 'identifier'


The compiler expected token and found identifier instead. Possible causes:
1. Spelling or capitalization error.
2. Missing type specifier in the declaration of the identifier.
This error may be caused by a typographical error. Error C2065 usually precedes this error.

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();
};

template <typename T>


X<T>::Y func() { } // C2146

// 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

syntax error : 'identifier' is a new keyword


An identifier was used that is now a reserved keyword in the language.
The following sample generates C2147:

// 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

total size of array must not exceed 0x7fffffff bytes


An array exceeds the limit. Reduce the size of the array.

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

'identifier' : named bit field cannot have zero width


Bit fields can have zero width only if unnamed.
The following sample generates C2149:

// 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

more than one language attribute


A function has more than one keyword ( __cdecl , __stdcall , or __fastcall ) specifying a calling convention.
Compiler Error C2152
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : pointers to functions with different attributes


A pointer to a function with one calling convention ( __cdecl , __stdcall , or __fastcall ) is assigned to a pointer
to a function with another calling convention.
Compiler Error C2153
10/31/2018 • 2 minutes to read • Edit Online

hex constants must have at least one hex digit


Hexadecimal constants 0x, 0X, and \x are not valid. At least one hex digit must follow x or X.
The following sample generates C2153:

// 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

'?' : invalid left operand, expected arithmetic or pointer type


An expression on the left hand side of ? cannot be compared to zero. You must use an arithmetic or pointer
expression that can be compared to zero.
Compiler Error C2156
10/31/2018 • 2 minutes to read • Edit Online

pragma must be outside function


A pragma that must be specified at a global level (outside a function body) is within a function.
The following sample generates C2156:

// 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

'function' : must be declared before use in pragma list


The function name is not declared before being referenced in the list of functions for an alloc_text pragma.
The following sample generates C2157:

// 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

template< typename T >


class B {};
#pragma make_public(B) // C2158
#pragma make_public(B<int>) // 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

more than one storage class specified


A declaration contains more than one storage class.
The following sample generates C2159:

// 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

'##' cannot occur at the beginning of a macro definition


A macro definition began with a token-pasting operator (##).
The following sample generates C2160:

// 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

'##' cannot occur at the end of a macro definition


A macro definition ended with a token-pasting operator (##).
The following sample generates C2161:

// 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

expected macro formal parameter


The token following a stringizing operator (#) is not a formal parameter name.

Example
The following sample generates C2162:

// C2162.cpp
// compile with: /c
#include <stdio.h>

#define print(a) printf_s(b) // OK


#define print(a) printf_s(#b) // C2162
Compiler Error C2163
10/31/2018 • 2 minutes to read • Edit Online

'function' : not available as an intrinsic function


An intrinsic or function pragma lists a function not available in intrinsic form. For example, certain intrinsics
are not available when compiling a program that uses /clr programming.
Compiler Error C2164
10/31/2018 • 2 minutes to read • Edit Online

'function' : intrinsic function not declared


An intrinsic pragma uses an undeclared function (only occurs with /Oi). Or, one of the compiler intrinsics was
used without including its header file.
The following sample generates C2164:

// 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

'keyword' : cannot modify pointers to data


The __stdcall , __cdecl , or __fastcall keyword attempts to modify a pointer to data.
The following sample generates C2165:

// C2165.cpp
// compile with: /c
char __cdecl *p; // C2165
char *p; // OK
Compiler Error C2166
10/31/2018 • 2 minutes to read • Edit Online

l-value specifies const object


Code attempts to modify an item declared const .
The following sample generates C2166:

// C2166.cpp
int f();
int main() {
( (const int&) 1 ) = 5; // C2166
}
Compiler Error C2167
10/31/2018 • 2 minutes to read • Edit Online

'function' : too many actual parameters for intrinsic function


A reference to an intrinsic function has too many parameters.
Compiler Error C2168
10/31/2018 • 2 minutes to read • Edit Online

'function' : too few actual parameters for intrinsic function


A reference to an intrinsic function has too few parameters.
Compiler Error C2169
10/31/2018 • 2 minutes to read • Edit Online

'function' : intrinsic function, cannot be defined


A function definition appears for a function already declared intrinsic .
Compiler Error C2170
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : not declared as a function, cannot be intrinsic


To fix by checking the following possible causes
1. Pragma intrinsic is used for an item other than a function.
2. Pragma intrinsic is used for a function with no intrinsic form.
Compiler Error C2171
11/8/2018 • 2 minutes to read • Edit Online

'operator' : illegal on operands of type 'type'


A unary operator is used with an invalid operand type.

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
}

void STF(void (A::*fnc)()) {


TF = fnc;
}

private:
void (A::*TF)();
};
Compiler Error C2172
10/31/2018 • 2 minutes to read • Edit Online

'function' : actual parameter is not a pointer : parameter number


Parameter number is not a pointer. The function expects a pointer.
Compiler Error C2173
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

'locale' : invalid locale


The specified locale is not valid. See Language and Country/Region Strings in the Run-Time Library Reference for
supported locales.
Compiler Error C2177
10/31/2018 • 2 minutes to read • Edit Online

constant too big


A constant value is too large for the variable type it is assigned.
The following sample generates C2177:

// C2177.cpp
int main() {
int a=18446744073709551616; // C2177
int b=18446744073709551615; // OK
}
Compiler Error C2178
10/31/2018 • 2 minutes to read • Edit Online

'identifier' cannot be declared with 'specifier' specifier


A mutable specifier was used in a declaration, but the specifier is not allowed in this context.
The mutable specifier can be applied only to names of class data members, and cannot be applied to names
declared const or static , and cannot be applied to reference members.

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.
};

mutable int x = 4; // C2178


// To fix, remove mutable keyword
Compiler Error C2179
10/31/2018 • 2 minutes to read • Edit Online

'type' : an attribute argument cannot use type parameters


A generic type parameter is resolved at runtime. However, an attribute parameter must be resolved at compile
time. Therefore, you cannot use a generic type parameter as an argument to an attribute.

Example
The following sample generates C2179.

// C2179.cpp
// compile with: /clr
using namespace System;

public ref struct Attr : Attribute {


Attr(Type ^ a) {
x = a;
}

Type ^ x;
};

ref struct G {};

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

controlling expression has type 'type'


The controlling expression in an if , while , for , or do statement is an expression cast to void . To fix this issue,
change the controlling expression to one that produces a bool or a type that can be converted to bool .
The following sample generates C2180:

// 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

illegal else without matching if


Each else must have a matching if .
The following sample generates C2181:

// 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

'identifier' : illegal use of type 'void'


A variable is declared type void .
The following sample generates C2182:

// 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

syntax error: translation unit is empty


Preprocessing produced an empty source file.
Compiler Error C2184
10/31/2018 • 2 minutes to read • Edit Online

'type' : illegal type for __except expression, must be an integral


A type was used in an __except statement, but the type is not allowed.
The following sample generates C2184:

// 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

'identifier' : illegal based allocation


A register variable or automatic (local) variable is declared __based . Only global variables can be declared
__based .
Compiler Error C2186
10/31/2018 • 2 minutes to read • Edit Online

'operator' : illegal operand of type 'void'


The operator has a void operand.
The following sample generates C2186:

// 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

'number' : too big for wide character


The number exceeds the size limit for the wide-character type. Choose a larger type.
Compiler Error C2190
10/31/2018 • 2 minutes to read • Edit Online

first parameter list longer than second


A C function was declared a second time with a shorter parameter list. C does not support overloaded functions.
The following sample generates C2190:

// 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

second parameter list longer than first


A C function was declared a second time with a longer parameter list. C does not support overloaded functions.

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

parameter 'number' declaration different


A C function was declared a second time with a different parameter list. C does not support overloaded functions.
The following sample generates C2192:

// 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

'identifier' : already in a segment


A function was placed in two different segments using alloc_text and code_seg pragmas.
The following sample generates C2193:

// 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

'identifier' : is a text segment


The data_seg pragma uses a segment name used with code_seg .
The following sample generates C2194:

// 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

'identifier' : is a data segment


The code_seg pragma uses a segment name used with the data_seg pragma.
The following sample generates C2195:

// 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

case value 'value' already used.


A switch statement uses the same case value more than once.
The following sample generates C2196:

// 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

'function' : too many arguments for call


The compiler detected too many parameters for a call to the function, or an incorrect function declaration.
The following sample generates C2197:

// 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

'function' : too few arguments for call


The compiler found too few parameters for a call to the function, or an incorrect function declaration.
The following sample generates C2198:

// 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 C2200 'function': function has already been defined

Compiler Error C2201 'identifier': must have external linkage in order to be


exported/imported

Compiler Error C2202 'function': not all control paths return a value

Compiler Error C2203 delete operator cannot specify bounds for an array

Compiler Error C2204 'type': type definition found within parentheses

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 C2207 'member': a member of a class template cannot acquire a


function type

Compiler Error C2208 'type': no members defined using this type

Compiler Error C2209 'identifier': aliases cannot be used in constructor declarations

Compiler Error C2210 'identifier': pack expansions cannot be used as arguments to


non-packed parameters in alias templates

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 C2213 'identifier': illegal argument to __based

Compiler Error C2214 pointers based on 'void' require the use of:>

Compiler Error C2215 'keyword' cannot be used with '/arch:SSE'

Compiler Error C2216 'keyword1' cannot be used with 'keyword2'

Compiler Error C2217 'attribute1' requires 'attribute2'

Compiler Error C2218 'calltype' cannot be used with '/arch:IA32'

Compiler Error C2219 syntax error: type qualifier must be after '*'

Compiler Error C2220 warning treated as error - no 'filetype' file generated

Compiler Error C2221 Obsolete.

Compiler Error C2222 unexpected type 'type': a base-class or member was expected

Compiler Error C2223 left of '->identifier' must point to struct/union

Compiler Error C2224 left of '.identifier' must have struct/union type

Compiler Error C2225 Obsolete.

Compiler Error C2226 syntax error: unexpected type 'type'

Compiler Error C2227 left of '->identifier' must point to class/struct/union/generic


type

Compiler Error C2228 left of '.identifier' must have class/struct/union

Compiler Error C2229 class/struct/union 'type' has an illegal zero-sized array

Compiler Error C2230 could not find module 'name'


ERROR MESSAGE

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 C2234 identifier': arrays of references are illegal

Compiler Error C2235 Obsolete.

Compiler Error C2236 unexpected token 'token'. Did you forget a ';'?

Compiler Error C2237 multiple module declaration

Compiler Error C2238 unexpected token(s) preceding 'token'

Compiler Error C2239 'function': attempting to delete a __declspec(dllexport) function

Compiler Error C2240 Obsolete.

Compiler Error C2241 'identifier': member access is restricted

Compiler Error C2242 typedef name cannot follow class/struct/union

Compiler Error C2243 'conversion_type': conversion from 'type1' to 'type2' exists,


but is inaccessible

Compiler Error C2244 'identifier': unable to match function definition to an existing


declaration

Compiler Error C2245 non-existent member function 'function' specified as friend


(member function signature does not match any overload)

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 C2248 'identifier': cannot access accessibility member declared in


class 'class'

Compiler Error C2249 'identifier': no accessible path to accessibility member


declared in virtual base 'class'

Compiler Error C2250 'identifier': ambiguous inheritance of class::member'

Compiler Error C2251 namespace 'namespace' does not have a member 'identifier' -
Did you mean 'member'?

Compiler Error C2252 an explicit instantiation of a template can only occur at


namespace scope
ERROR MESSAGE

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 C2255 'element': not allowed outside of a class definition

Compiler Error C2256 illegal use of friend specifier on 'function'

Compiler Error C2257 'specifier': specifier not allowed in trailing return type

Compiler Error C2258 illegal pure syntax, must be '= 0'

Compiler Error C2259 'class': cannot instantiate abstract class

Compiler Error C2260 'specifier': invalid InternalsVisibleToAttribute friend assembly


specifier

Compiler Error C2261 'string': assembly reference is invalid and cannot be resolved

Compiler Error C2262 'specifier': InternalsVisibleTo declarations cannot have a


version, culture, or processor architecture specified

Compiler Error C2263 Obsolete.

Compiler Error C2264 'function': error in function definition or declaration; function


not called

Compiler Error C2265 Obsolete.

Compiler Error C2266 'identifier': reference to a non-constant bounded array is


illegal

Compiler Error C2267 'function': static functions with block scope are illegal

Compiler Error C2268 'function' is a compiler predefined library helper. Library


helpers are not supported with /GL; compile object file
'filename' without /GL.

Compiler Error C2269 cannot create a pointer or reference to a qualified function


type (requires pointer-to-member)

Compiler Error C2270 'function': modifiers not allowed on nonmember functions

Compiler Error C2271 'function': new/delete cannot have formal list modifiers

Compiler Error C2272 'function': modifiers not allowed on static member functions

Compiler Error C2273 'type': illegal as right side of '->' operator

Compiler Error C2274 'type': illegal as right side of '.' operator


ERROR MESSAGE

Compiler Error C2275 'type': illegal use of this type as an expression

Compiler Error C2276 'operator': illegal operation on bound member function


expression

Compiler Error C2277 'function': cannot take address of this member function

Compiler Error C2278 Obsolete.

Compiler Error C2279 exception specification cannot appear in a typedef declaration

Compiler Error C2280 'class::function': attempting to reference a deleted function

Compiler Error C2281 'class::function': a function can only be deleted on the first
declaration

Compiler Error C2282 'function1' cannot override 'function2'

Compiler Error C2283 'identifer': pure specifier or abstract override specifier not
allowed on unnamed class/struct

Compiler Error C2284 'function': illegal argument to intrinsic function, parameter


number

Compiler Error C2285 pointers to members representation has already been


determined - pragma ignored

Compiler Error C2286 pointers to members of 'identifier' representation is already


set to inheritance - declaration ignored

Compiler Error C2287 'identifier': inheritance representation: 'inheritiance' is less


general than the required 'inheritance'

Compiler Error C2288 Obsolete.

Compiler Error C2289 same type qualifier used more than once

Compiler Error C2290 C++ 'asm' syntax ignored. Use __asm.

Compiler Error C2291 An anonymous namespace cannot be exported.

Compiler Error C2292 'identifier': best case inheritance representation: inheritance1'


declared but 'inheritance2' required

Compiler Error C2293 'identifier': illegal to have a member variable as a __based


specifier

Compiler Error C2294 cannot export symbol 'identifier' because it has internal
linkage

Compiler Error C2295 escaped 'character': is illegal in macro definition


ERROR MESSAGE

Compiler Error C2296 'operator': illegal, left operand has type 'type'

Compiler Error C2297 'operator': illegal, right operand has type 'type'

Compiler Error C2298 missing call to bound pointer to member function

Compiler Error C2299 'function': behavior change: an explicit specialization cannot be


a copy constructor or copy assignment operator
Compiler Error C2200
10/31/2018 • 2 minutes to read • Edit Online

'function' : function has already been defined


An alloc_text pragma uses a function name already defined.
Compiler Error C2201
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : must have external linkage in order to be exported/imported


The exported identifier is static .
The following sample generates C2286:

// 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

delete operator cannot specify bounds for an array


With the /Za (ANSI) option, the delete operator can delete an entire array but not parts or specific members of
the array.
The following sample generates C2203:

// 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

'type' : type definition found within parentheses


The type is defined as an operand or in prototype scope.
Compiler Error C2205
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : cannot initialize extern variables with block scope


An extern variable cannot be initialized in a function.
Compiler Error C2206
10/31/2018 • 2 minutes to read • Edit Online

'function' : typedef cannot be used for function definition


A typedef is used to define a function type.
The following sample generates C2206:

// 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

'member': a member of a class template cannot acquire a function type


The member of the class template was previously parsed as a non-static data member. It cannot be redefined as a
member function.
Compiler Error C2208
10/31/2018 • 2 minutes to read • Edit Online

'type' : no members defined using this type


An identifier resolving to a type name is in an aggregate declaration, but the compiler cannot declare a member.
The following sample generates C2208:

// C2208.cpp
class C {
C; // C2208
C(){} // OK
};
Compiler Error C2212
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : __based not available for pointers to functions


Pointers to functions cannot be declared __based . If you need code-based data, use the __declspec keyword or
the data_seg pragma.
Compiler Error C2213
10/31/2018 • 2 minutes to read • Edit Online

'modifier' : illegal argument to __based


The argument modifying __based is invalid.
The following sample generates C2213:

// 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

'keyword1' cannot be used with ' keyword2'


Two keywords that are mutually exclusive were used together.

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();
};

public ref struct R : I {


virtual double f() new override { return 0.0; } // C2216
virtual double g() new { return 0.0; } // OK
virtual double h() override { return 0.0; } // OK
};
Compiler Error C2217
10/31/2018 • 2 minutes to read • Edit Online

'attribute1' requires 'attribute2'


The first function attribute requires the second attribute.
To fix by checking the following possible causes
1. Interrupt ( __interrupt ) function declared as near . Interrupt functions must be far .
2. Interrupt function declared with __stdcall , or __fastcall . Interrupt functions must use C calling
conventions.

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);

// wl("{0}, {1}", 0, 1);


wl("{0}, {1}", x);
}
Compiler Error C2218
10/31/2018 • 2 minutes to read • Edit Online

'__vectorcall' cannot be used with '/arch:IA32'


The __vectorcall calling convention is only supported in native code on x86 and x64 processors that include
Streaming SIMD Extensions 2 (SSE2) and above. For more information, see __vectorcall.
To fix this error, change the compiler options to target SSE2, AVX or AVX2 instruction sets. For more information,
see /arch (x86).
Compiler Error C2219
10/31/2018 • 2 minutes to read • Edit Online

syntax error : type qualifier must be after '*'


Type qualifier ( const or volatile ) appears where it is not permitted.
Compiler Error C2220
10/31/2018 • 2 minutes to read • Edit Online

warning treated as error - no object file generated


/WX tells the compiler to treat all warnings as errors. Because an error occurred, no object or executable file was
generated.
This error only appears when the /WX flag is set and a warning occurs during compilation. To fix this error, you
must eliminate every warning in your project.
To fix, use one of the following techniques
Fix the problems that cause warnings in your project.
Compile at a lower warning level—for example, use /W3 instead of /W4.
Use a warning pragma to disable or suppress a specific warning.
Don't use /WX to compile.
Compiler Error C2222
10/31/2018 • 2 minutes to read • Edit Online

unexpected type 'type': a base-class or member was expected


The initializer list can only initialize base classes or members of a type. To fix this error, verify that only base classes
or members of the type are initialized in the initializer list.
Compiler Error C2223
10/31/2018 • 2 minutes to read • Edit Online

left of '->identifier' must point to struct/union


The operand to the left of -> is not a pointer to a class, structure, or union.
This error can be caused by a left operand that is an undefined variable (therefore type int ).
Compiler Error C2224
10/31/2018 • 2 minutes to read • Edit Online

left of '.identifier' must have struct/union type


The operand to the left of the period (.) is not a class, structure, or union.
This error can be caused by a left operand that is an undefined variable (therefore type int ).
Compiler Error C2226
10/31/2018 • 2 minutes to read • Edit Online

syntax error : unexpected type 'type'


A syntax error occurs before or in the type specifier.
Compiler Error C2227
10/31/2018 • 2 minutes to read • Edit Online

left of '->member' must point to class/struct/union/generic type


The operand to the left of -> is not a pointer to a class, structure, or union.
The following sample generates C2227:

// 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

left of '.identifier' must have class/struct/union


The operand to the left of the period (.) is not a class, structure, or union.
The following sample generates C2228:

// 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

s.member = 0; // s is a structure type


ps->member = 0; // ps points to a structure S
}

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();

Right: String * myString = checkedListBox1->CheckedItems->Item[0]->ToString();


Compiler Error C2229
10/31/2018 • 2 minutes to read • Edit Online

type 'identifier' has an illegal zero-sized array


A member of a structure or bit field contains a zero-sized array that is not the last member.
Because you can have a zero sized array as the last member of the struct, you must specify its size when you
allocate the struct.
If the zero sized array is not the last member of the struct, the compiler can't calculate the offset for the remaining
fields.
The following sample generates C2229:

// 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

'.' : left operand points to 'class-key', use '->'


The operand to the left of the member-selection operation (.) is a pointer instead of a class, structure, or union.
The following sample generates C2231:

// 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

'->' : left operand has 'class-key' type, use '.'


The operand to the left of the -> operator is not a pointer. Use the period (.) operator for a class, structure, or
union.
The following sample generates C2232:

// 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

'identifier' : arrays of objects containing zero-size arrays are illegal


Each object in an array must contain at least one element.
The following sample generates C2233:

// 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

'name' : arrays of references are illegal


Because pointers to references are not allowed, arrays of references are not possible.
The following sample generates C2234:

// 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

unexpected token 'identifier'. Did you forget a ';'?


The identifier is already defined as a type and cannot be overridden by a user-defined type.
The following sample generates C2236:

// 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

unexpected token(s) preceding 'token'


An incorrect token was found.
The following sample generates C2238:

// C2238.cpp
// compile with: /c
class v {
virtual: int vvv; // C2238
};
Compiler Error C2241
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : member access is restricted


Code attempts to access a private or protected member.
To fix by using the following possible solutions
1. Change the access level of the member.
2. Declare the member a friend of the accessing function.
Compiler Error C2242
10/31/2018 • 2 minutes to read • Edit Online

typedef name cannot follow class/struct/union


A typedef name appears at the end of a qualified name.
Compiler Error C2243
10/31/2018 • 2 minutes to read • Edit Online

'conversion type' conversion from 'type1' to 'type2' exists, but is inaccessible


Access protection ( protected or private ) prevented conversion from a pointer to a derived class to a pointer to
the base class.
The following sample generates C2243:

// 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

'identifier' : unable to match function definition to an existing declaration


An unusual use of the unary + operator was used in front of a function call that did not have parenthesis.
This error only occurs in C++ projects.
The following sample generates C2244:

// 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) {}

You cannot partially specialize a function template.


// C2244d.cpp
template<class T, class U>
class QRS {
void func(T t, U u);
};

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

'identifier' : illegal static data member in locally defined class


A member of a class, structure, or union with local scope is declared static .
The following sample generates C2246:

// 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 B: private 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

'member' : cannot access 'access_level' member declared in class 'class'


Members of a derived class cannot access private members of a base class. You cannot access private or
protected members of class instances.

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

'member' : no accessible path to access member declared in virtual base 'class'


The member is inherited from a nonpublic virtual base class or structure.

Example
The following sample generates C2249.

// C2249.cpp
class A {
private:
void privFunc( void ) {};
public:
void pubFunc( void ) {};
};

class B : virtual public A {} b;

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

'identifier' : ambiguous inheritance of 'class::member'


The derived class inherits more than one override of a virtual function of a virtual base class. These overrides are
ambiguous in the derived class.
The following sample generates C2286:

// 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;
}

void A::f1() {} // C2251


void A::B::f1() {} // OK
Compiler Error C2252
10/31/2018 • 2 minutes to read • Edit Online

cannot explicitly instantiate template in current scope


The compiler detected a problem with an explicit instantiation of a template. For example, you cannot explicitly
instantiate a template in a function.
The following sample generates C2252:

// 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
};

The following sample generates C2253:

// 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;

void set(int i) abstract; // C2253


// try the following line instead
// virtual void set(int i) abstract;
}
};
Compiler Error C2254
10/31/2018 • 2 minutes to read • Edit Online

'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
};

void func1() {};


void func3() {};
Compiler Error C2255
10/31/2018 • 2 minutes to read • Edit Online

'element' : not allowed outside of a class definition


For example, a nonmember function is declared a friend .
The following sample generates C2255:

// C2255.cpp
// compile with: /c
class A {
private:
void func1();
friend void func2();
};

friend void func1() {} // C2255


void func2(){}
Compiler Error C2256
10/31/2018 • 2 minutes to read • Edit Online

illegal use of friend specifier on 'function'


A destructor or constructor cannot be specified as a friend.
The following sample generates C2256:

// 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

illegal pure syntax, must be '= 0'


A pure virtual function is declared with incorrect syntax.
The following sample generates C2258:

// 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

'class' : cannot instantiate abstract class


Code declares an instance of an abstract class or structure.
You cannot instantiate a class or structure with one or more pure virtual functions. To instantiate objects of a
derived class, the derived class must override each pure virtual function.
For more information, see Implicitly abstract classes.
The following sample generates C2259:

// 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;
};

class MyClass2 : MyClass {


public:
void func(unsigned short*);
};

MyClass2 x; // C2259

// OK
class MyClass3 {
public:
virtual void func(WCHAR*) = 0;
virtual void func2(wchar_t*) = 0;
virtual void func3(unsigned short*) = 0;
};

class MyClass4 : MyClass3 {


public:
void func(WCHAR*) {}
void func2(wchar_t*) {}
void func3(unsigned short*) {}
};

MyClass4 y;

The following sample generates C2259:

// C2259c.cpp
// compile with: /clr
interface class MyInterface {
void MyMethod();
};

ref class MyDerivedClass: public MyInterface {


private:
// Uncomment the following line to resolve.
// public:
void MyMethod(){}
// or the following line
// void MyInterface::MyMethod() {};
};

int main() {
MyDerivedClass^ instance = gcnew MyDerivedClass; // C2259
}
Compiler Error C2261
10/31/2018 • 2 minutes to read • Edit Online

'string' : assembly reference is invalid and cannot be resolved


A value was not valid.
InternalsVisibleToAttribute is used to specify a friend assembly. For example, if a.dll wants to specify b.dll as a
friend assembly, you would specify (in a.dll): InternalsVisibleTo("b"). The runtime then allows b.dll to access
everything in a.dll (except private types).
For more on the correct syntax when specifying friend assemblies, see Friend Assemblies (C++).

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

'attribute_specifiers' : InternalsVisibleTo declarations cannot have a version, culture, or processor architecture


specified
The InternalsVisibleToAttribute attribute was not specified correctly.

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

'function' : error in function definition or declaration; function not called


The function cannot be called due to an incorrect definition or declaration.
The following sample generates C2264:

// 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

'identifier' : reference to a non-constant bounded array is illegal


A reference is declared for an array with a nonconstant bound. The array must have constant bounds.
Compiler Error C2267
10/31/2018 • 2 minutes to read • Edit Online

'function' : static functions with block scope are illegal


A local function is declared static . Static functions must have global scope.
The following sample generates C2267:

// 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);

int __cdecl _except_handler3(void) {


return SHFusionLoadLibrary(0);
}

extern int main(void);

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);

extern int __cdecl _except_handler3(void);


extern void mainCRTStartup(void*);
int g = 2;

#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;
}

int SHFusionLoadLibrary(int lpLibFileName) { // C2268


ENTERCONTEXT(0)
g = lpLibFileName;
LEAVECONTEXT

return lpLibFileName;
}

int main(void) {
g = SHFusionLoadLibrary(10);
return 0;
}
Compiler Error C2270
10/31/2018 • 2 minutes to read • Edit Online

'function' : modifiers not allowed on nonmember functions


A nonmember function is declared with const, volatile, or another memory-model modifier.
The following sample generates C2270:

// 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

'operator' : new/delete cannot have formal list modifiers


The operator ( new or delete ) is declared with a memory-model specifier.
The following sample generates C2271:

// 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

'function' : modifiers not allowed on static member functions


A static member function is declared with a memory-model specifier, such as const or volatile, and such
modifiers are not allowed on static member functions.
The following sample generates C2272:

// 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

'type' : illegal as right side of '->' operator


A type appears as the right operand of a -> operator.
This error can be caused by trying to access a user-defined type conversion. Use the keyword operator between -
> and type .
The following sample generates C2273:

// 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

'type' : illegal as right side of '.' operator


A type appears as the right operand of a member-access (.) operator.
This error can be caused by trying to access a user-defined type conversion. Use the keyword operator between
the period and type .
The following sample generates C2286:

// 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

'identifier' : illegal use of this type as an expression


An expression uses the -> operator with a typedef identifier.
The following sample generates C2275:

// 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

'operator' : illegal operation on bound member function expression


The compiler found a problem with the syntax to create a pointer-to-member.
The following sample generates C2276:

// C2276.cpp
class A {
public:
int func(){return 0;}
} a;

int (*pf)() = &a.func; // C2276


// try the following line instead
// int (A::*pf3)() = &A::func;

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

'identifier' : cannot take address of this member function


You cannot take the address of a member function.
The following sample generates C2277:

// C2277.cpp
class A {
public:
A();
};
(*pctor)() = &A::A; // C2277
Compiler Error C2279
10/31/2018 • 2 minutes to read • Edit Online

exception specification cannot appear in a typedef declaration


Under /Za, exception specifications are not allowed in a typedef declaration.
The following sample generates C2279:

// 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

'declaration': attempting to reference a deleted function


The compiler detected an attempt to reference a deleted function. This error can be caused by a call to a member
function that has been explicitly marked as = deleted in the source code. This error can also be caused by a call to
an implicit special member function of a struct or class that is automatically declared and marked as deleted by
the compiler. For more information about when the compiler automatically generates default or deleted special
member functions, see Special member functions.

Example: Explicitly deleted functions


A call to an explicitly deleted function causes this error. An explicitly deleted member function implies that the
class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid
it.

// 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)
}

Example: Uninitialized data members


An uninitialized reference type data member or const data member causes the compiler to implicitly declare a
deleted default constructor. To fix this issue, initialize the data member when it is declared.

// 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

Example: Reference and const data members


A const or reference type data member causes the compiler to declare a deleted copy assignment operator.
Once initialized, these members can't be assigned to, so a simple copy or move can't work. To fix this issue, we
recommend you change your logic to remove the assignment operations that cause the error.

// 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
}

Example: Movable deletes implicit copy


If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy
constructor, the compiler implicitly declares a copy constructor and defines it as deleted . Similarly, if a class
declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment
operator, the compiler implicitly declares a copy assignment operator and defines it as deleted . To fix this issue,
you must explicitly declare these members.
When you see error C2280 in connection with a unique_ptr , it is almost certainly because you are attempting to
invoke its copy constructor, which is a deleted function. By design, a unique_ptr cannot be copied. Use a move
constructor to transfer ownership instead.

// 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;
};

void copy(base *p)


{
base b{*p}; // C2280
}

Example: Variant and volatile members


Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default
constructors and destructors for anonymous unions. These are now implicitly declared as deleted . Those versions
also allowed non-conforming implicit definition of default copy and move constructors and default copy and
move assignment operators in classes and structs that have volatile member variables. The compiler now
considers these to have non-trivial constructors and assignment operators, and doesn't generate default
implementations. When such a class is a member of a union, or an anonymous union inside of a class, the copy
and move constructors and copy and move assignment operators of the union or class are implicitly defined as
deleted . To fix this issue, you must explicitly declare the required special member functions.

// 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
}

Example: Indirect base members deleted


Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to
call special member functions of indirectly-derived private virtual base classes. The compiler now issues
compiler error C2280 when such a call is made.
In this example, class top indirectly derives from private virtual base . In conforming code, this makes the
members of base inaccessible to top ; an object of type top can't be default constructed or destroyed. To fix this
issue in code that relied on the old compiler behavior, change the intermediate class to use protected virtual
derivation, or change the top class to use direct derivation:

// C2280_indirect.cpp
// compile with: cl /c C2280_indirect.cpp
class base
{
protected:
base();
~base();
};

class middle : private virtual base {};


// Possible fix: Replace line above with:
// class middle : protected virtual base {};
class top : public virtual middle {}; // C4594, C4624
// Another possible fix: use direct derivation:
// class top : public virtual middle, private virtual base {};

void destroy(top *p)


{
delete p; // C2280
}
Compiler Error C2283
10/31/2018 • 2 minutes to read • Edit Online

'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

pointers to members representation has already been determined - pragma ignored


Two different representations exist for class.
Compiler Error C2286
10/31/2018 • 2 minutes to read • Edit Online

pointers to members of 'identifier' representation is already set to 'inheritance' - declaration ignored


Two different pointer-to-members representations exist for class.
For more information, see Inheritance Keywords.

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

same type qualifier used more than once


A type declaration or definition uses a type qualifier ( const , volatile , signed , or unsigned ) more than once,
causing an error under ANSI compatibility (/Za).
The following sample generates C2286:

// 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

C++ asm syntax ignored. Use __asm.


The asm syntax is reserved for future use.
Compiler Error C2292
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

'identifier': illegal to have a member variable as a __based specifier


Specifiers for __based modifier must be nonmember pointers.
The following sample generates C2293:

// 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

escaped 'character' : is illegal in macro definition


A macro definition cannot contain an escape sequence with the specified character.
Compiler Error C2296
10/31/2018 • 2 minutes to read • Edit Online

'operator' : bad left operand


The left operand used with operator is invalid.
For example, the compiler may see a declaration where you intended a function call.
The following sample generates C2296:

// C2296.cpp
struct MyStruct {
struct Help {
Help(float f) : m_f(f) {}
float m_f;
};

MyStruct(const Help &h) : m_f(h.m_f) {}


MyStruct(float f) : m_f(f) {}
MyStruct operator*(const MyStruct &f1) const {
return MyStruct(m_f * f1.m_f);
}

private:
float m_f;
};

int main() {
float f1 = 1.0f;

MyStruct m_MyStruct1 ( MyStruct::Help( f1 ) );


// try the following line instead
// MyStruct m_MyStruct1 = MyStruct::Help( f1 );

MyStruct m_MyStruct2 ( MyStruct::Help( f1 ) );


// try the following line instead
// MyStruct m_MyStruct2 = MyStruct::Help( f1 );

MyStruct m_MyStruct3 = m_MyStruct1 * m_MyStruct2; // C2296


}
Compiler Error C2297
10/31/2018 • 2 minutes to read • Edit Online

'operator' : bad right operand


The right operand used with operator is invalid.
For example, the compiler may see a declaration where you intended a function call.
The following sample generates C2297:

// C2297.cpp
struct MyStruct {
struct Help {
Help(float f) : m_f(f) {}
float m_f;
};

MyStruct(const Help &h) : m_f(h.m_f) {}

MyStruct(float f) : m_f(f) {}

MyStruct operator*(const MyStruct &f1) const {


return MyStruct(m_f * f1.m_f);
}

private:
float m_f;
};

int main() {
float f1 = 1.0f;

MyStruct m_MyStruct1 ( MyStruct::Help( f1 ) );


// try the following line instead
// MyStruct m_MyStruct1 = MyStruct::Help( f1 );

MyStruct m_MyStruct2 ( MyStruct::Help( f1 ) );


// try the following line instead
// MyStruct m_MyStruct2 = MyStruct::Help( f1 );

MyStruct m_MyStruct3 = m_MyStruct1 * m_MyStruct2; // C2297


}
Compiler Error C2298
11/8/2018 • 2 minutes to read • Edit Online

'operation' : illegal operation on pointer to member function expression


A pointer to member-function expression must call the member function.

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)();

// a pointer to member function X::mf


void (X::*pmf)() = &X::mf;

int main() {
int (*pf)();
pf = x.*pmf; // C2298
+(x.*pmf); // C2298

pmf_t pf2 = &X::mf2;


(x.*pf2)(); // uses X::mf2
(x.*pmf)(); // uses X::mf
}

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);

template <> C (const C&); // C2299


C (const C&); // OK
};
Compiler Errors C2300 Through C2399
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 C2300 'class': class does not have a destructor called '~class'

Compiler Error C2301 left of '->~identifier' must point to class/struct/union

Compiler Error C2302 left of '.~identifier' must have class/struct/union type

Compiler Error C2303 Structured exception handling cannot be used in a coroutine

Compiler Error C2304 'keyword' cannot be used inside of a catch block

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 C2308 concatenating mismatched strings

Compiler Error C2309 catch handler expected a parenthesized exception declaration

Compiler Error C2310 catch handlers must specify one type

Compiler Error C2311 'type': is caught by '...' on line number

Compiler Error C2312 'type1': is caught by 'type2' on line number

Compiler Error C2313 'type1': is caught by reference ('type2') on line number

Compiler Error C2314 keyword 'keyword1' is deprecated: use 'keyword2' instead

Compiler Error C2315 'type1': reference is caught by 'type2' on line number

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 C2319 'try/catch' must be followed by a compound statement.


Missing '{'

Compiler Error C2320 expected ':' to follow access specifier 'specifier'

Compiler Error C2321 'identifier' is a keyword, and cannot be used in this context

Compiler Error C2322 'identifier': address of dllimport 'identifier' is not static

Compiler Error C2323 'identifier': non-member operator new or delete functions


may not be declared static or in a namespace other than the
global namespace

Compiler Error C2324 'identifier': unexpected to the right of '::~'

Compiler Error C2325 'type1': unexpected type to the right of '->~': expected 'type2'

Compiler Error C2326 'declarator': function cannot access 'identifier'

Compiler Error C2327 'identifier': is not a type name, static, or enumerator

Compiler Error C2328 'keyword': keyword is not yet supported

Compiler Error C2329 'identifier': __ptr64 not available for pointers to functions
ERROR MESSAGE

Compiler Error C2330 'implementation_key( )' is only valid in a region bounded by


#pragma start_map_region/stop_map_region

Compiler Error C2331 access to 'identifier' now defined to be 'accessibility1',


previously it was defined to be 'accessibility2'

Compiler Error C2332 'typedef': missing tag name

Compiler Error C2333 'function': error in function declaration; skipping function body

Compiler Error C2334 unexpected token(s) preceding 'token'; skipping apparent


function body

Compiler Error C2335 'identifier': a type cannot be introduced in a function


parameter list

Compiler Error C2336 'type': illegal type

Compiler Error C2337 'attribute': attribute not found

Compiler Error C2338 (error message from external provider)

Compiler Error C2339 'identifier': illegal type in embedded-IDL

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 C2342 syntax error: conflicting type qualifiers

Compiler Error C2343 'section': conflicting section attributes

Compiler Error C2344 align(number): alignment must be power of two

Compiler Error C2345 align(number): illegal alignment value

Compiler Error C2346 'function' cannot be compiled as native: 'explanation'

Compiler Error C2347 Obsolete.

Compiler Error C2348 'type': is not a C-style aggregate, cannot be exported in


embedded-IDL

Compiler Error C2349 'function' cannot be compiled as managed: 'explanation'; use


#pragma unmanaged

Compiler Error C2350 'identifier' is not a static member

Compiler Error C2351 obsolete C++ constructor initialization syntax


ERROR MESSAGE

Compiler Error C2352 'identifier': illegal call of non-static member function

Compiler Error C2353 exception specification is not allowed

Compiler Error C2354 Obsolete.

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 C2357 'identifier': must be a function of type 'type'

Compiler Error C2358 'identifier': a static property cannot be defined outside of a


class definition

Compiler Error C2359 Obsolete.

Compiler Error C2360 initialization of 'identifier' is skipped by 'case' label

Compiler Error C2361 initialization of 'identifier' is skipped by 'default' label

Compiler Error C2362 initialization of 'identifier' is skipped by 'goto label'

Compiler Error C2363 compiler intrinsic numeric limit function requires a string literal
argument

Compiler Error C2364 'type': illegal type for custom attribute

Compiler Error C2365 'member1': redefinition; previous definition was 'member2'

Compiler Error C2366 'identifier': redefinition; different implementation_key specifiers

Compiler Error C2367 Obsolete.

Compiler Error C2368 'identifier': redefinition; different allocation specifiers

Compiler Error C2369 'identifier': redefinition; different subscripts

Compiler Error C2370 'identifier': redefinition; different storage class

Compiler Error C2371 'identifier': redefinition; different basic types

Compiler Error C2372 'identifier': redefinition; different types of indirection

Compiler Error C2373 'identifier': redefinition; different type modifiers

Compiler Error C2374 'identifier': redefinition; multiple initialization

Compiler Error C2375 'identifier': redefinition; different linkage


ERROR MESSAGE

Compiler Error C2376 'identifier': redefinition; different based allocation

Compiler Error C2377 'identifier': redefinition; typedef cannot be overloaded with


any other symbol

Compiler Error C2378 'identifier': redefinition; symbol cannot be overloaded with a


typedef

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 C2381 'identifier': redefinition; '__declspec(noreturn)' or '[[noreturn]]'


differs

Compiler Error C2382 'identifier': redefinition; different exception specifications

Compiler Error C2383 'identifier': default-arguments are not allowed on this symbol

Compiler Error C2384 'member': cannot apply thread_local or __declspec(thread) to a


member of a managed/WinRT class

Compiler Error C2385 ambiguous access of 'member'

Compiler Error C2386 'identifier': a symbol with this name already exists in the
current scope

Compiler Error C2387 'identifier': ambiguous base class

Compiler Error C2388 'identifier': a symbol cannot be declared with both


__declspec(appdomain) and __declspec(process)

Compiler Error C2389 'operator': illegal operand 'nullptr'

Compiler Error C2390 'identifier': incorrect storage class 'specifier'

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 C2393 'symbol': per-appdomain symbol cannot be allocated in


segment 'segment'

Compiler Error C2394 'type::operator operator': CLR/WinRT operator not valid. At


least one parameter must be of the following types: 'T^',
'T^%', 'T^&', where T = 'type'

Compiler Error C2395 'type::operator operator': CLR/WinRT operator not valid. At


least one parameter must be of the following types: 'T', 'T%',
'T&', 'T^', 'T^%', 'T^&', where T = 'type'
ERROR MESSAGE

Compiler Error C2396 'type1::operator type2': CLR/WinRT user-defined conversion


function not valid. Must either convert from or convert to:
'T^', 'T^%', 'T^&', where T = 'type1'

Compiler Error C2397 conversion from 'type1' to 'type2' requires a narrowing


conversion

Compiler Error C2398 Element 'number': conversion from 'type1' to 'type2' requires
a narrowing conversion

Compiler Error C2399 Obsolete.


Compiler Error C2300
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : class does not have a destructor called '~identifier'


The class does not have a destructor with the required name.
Compiler Error C2301
10/31/2018 • 2 minutes to read • Edit Online

left of '->~identifier' must point to class/struct/union


The expression to the left of the -> operator does not evaluate to a pointer to a class, structure, or union.
Compiler Error C2302
10/31/2018 • 2 minutes to read • Edit Online

left of '.~identifier' must have class/struct/union type


The expression to the left of the period (.) operator is not a class, structure, or union.
Compiler Error C2307
10/31/2018 • 2 minutes to read • Edit Online

pragma 'pragma' must be outside function if incremental compilation is enabled


You must place the data_seg pragma between functions if you're using incremental compilation.
Compiler Error C2308
10/31/2018 • 2 minutes to read • Edit Online

concatenating mismatched strings


Both wide and non-wide character strings were specified for concatenation. You cannot concatenate a wide
character string and non-wide character string.
Compiler Error C2309
10/31/2018 • 2 minutes to read • Edit Online

catch handler expected a parenthesized exception declaration


A catch handler has no parenthesized type.
The following sample generates C2309:

// 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

catch handlers must specify one type


A catch handler specified no type or multiple types.
The following sample generates C2310:

// 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

'exception' : is caught by '...' on line number


The catch handler for the ellipsis (...) must be the last handler for a throw.
The following sample generates C2311:

// 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

'exception1' : is caught by 'exception2' on line number


Two handlers catch the same exception type.
The following sample generates C2312:

// 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

'type1' : is caught by reference ('type2') on line number


The exception type has two handlers. The type for the second catch is a reference to the type of the first.
The following sample generates C2313:

// 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

'type1' : reference is caught by 'type2' on line number


The exception type is handled by a previous handler. The reference for the second catch has the type of the first.
Compiler Error C2316
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>

extern "C" int printf_s(const char*, ...);

struct B
{
public:
B() {}
// Delete the following line to resolve.
private:
// copy constructor
B(const B&)
{
}
};

void f(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

'try' block starting on line 'number' has no catch handlers


A try block must have at least one catch handler.
The following sample generates C2317:

// 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

no try block associated with this catch handler


A catch handler is defined but not preceded by a try block.
The following sample generates C2318:

// 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

'try/catch' must be followed by a compound statement. Missing '{'


A try or catch block is not found following the try or catch statement. The block must be enclosed in curly
braces.
The following sample generates C2319:

// 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

expected ':' to follow access specifier 'specifier'


The keyword public , protected , or private must be followed by a colon.
Compiler Error C2322
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : address of dllimport 'dllimport' is not static


A nonstatic value is given as the address of a function declared with dllimport .
Compiler Error C2324
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : unexpected to the right of 'name'


A destructor is called using an incorrect identifier.
The following sample generates C2324:

// 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

'type' : unexpected type to the right of 'name'


A call is made to a destructor of incorrect type.
The following sample generates C2325:

// C2325.cpp
// compile with: /c
class A {};
typedef A* pA_t;
void f() {
A** ppa = new A *;
ppa->~A*; // C2325

pA_t *ppa2 = new pA_t;


ppa2->~pA_t(); // OK
}
Compiler Error C2326
10/31/2018 • 2 minutes to read • Edit Online

'declarator' : function cannot access 'name'


The code tries to modify a member variable, which is not possible.

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

'symbol' : is not a type name, static, or enumerator


Code within a nested class attempts to access a member of the enclosing class that is not a type name, a static
member, or an enumerator.
When compiling with /clr, a common cause for C2327 is a property with the same name as the property type.
The following sample generates C2327:

// 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
}
};

The following sample generates C2327:


// C2327d.cpp
// compile with: /clr /c
using namespace System;

namespace NA {
public enum class E : Int32 {
one = 1,
two = 2,
three = 3
};

public ref class A {


private:
E m_e;
public:
property E E {
NA::E get() {
return m_e;
}
// At set, compiler doesn't know whether E is get_E or
// Enum E, therefore fully qualifying Enum E is necessary
void set( E e ) { // C2327
// try the following line instead
// void set(NA::E e) {
m_e = e;
}
}
};
}

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 {};

public ref class Person {


public:
property Address Address {
::Address get() {
return address;
}
void set(Address addr) { // C2327
// try the following line instead
// set(::Address addr) {
address = addr;
}
}
private:
Address address; // C2327
// try the following line instead
// ::Address address;
};
Compiler Error C2332
10/31/2018 • 2 minutes to read • Edit Online

'typedef' : missing tag name


The compiler found an incomplete type definition.
The following sample generates C2332:

// C2332.cpp
// compile with: /c
struct S {
int i;
};

typedef struct * pS; // C2332


typedef struct S* pS; // OK

int get_S_i(pS p) {
return p->i;
}
Compiler Error C2333
10/31/2018 • 2 minutes to read • Edit Online

'function' : error in function declaration; skipping function body


This error occurs after another error, for member functions defined inside their class.
The following sample generates C2333:

// C2333.cpp
struct s1 {
s1(s1) {} // C2333
};
Compiler Error C2334
10/31/2018 • 2 minutes to read • Edit Online

unexpected token(s) preceding ': or {'; skipping apparent function body


The following sample generates C2334. This error occurs after error C2059:

// 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

'attribute name' : attribute not found


You have used an attribute that is not supported in this version of Visual C++.
The following sample generates C2337:

// 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

align(#) : alignment must be power of two


When using the align keyword, the value you pass must be a power of two.
For example, the following code generates C2344 because 3 is not a power of two:

// 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

align(value) : illegal alignment value


You passed a value to the align keyword that is outside the allowable range.
The following code generates C2345

// 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

'function' cannot be compiled as native: reason


The compiler was unable to compile a function to MSIL.
For more information, see managed, unmanaged and /clr (Common Language Runtime Compilation).
To correct this error
1. Remove the code in the function that cannot be compiled to MSIL.
2. Either do not compile the module with /clr, or mark the function as unmanaged with the unmanaged
pragma.

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

'type name' : is not a C -style aggregate, cannot be exported in embedded-IDL


To place a struct in a .idl file with the export attribute, the struct must contain only data.
The following sample generates C2348:

// 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

'function' cannot be compiled as managed: 'reason'; use #pragma unmanaged


For more information see Compiler Warning (level 1 and 3) C4793.
Compiler Error C2350
10/31/2018 • 2 minutes to read • Edit Online

'identifier' is not a static member


Nonstatic members of a class or structure cannot be defined.
Compiler Error C2351
10/31/2018 • 2 minutes to read • Edit Online

obsolete C++ constructor initialization syntax


In a new -style initialization list for a constructor, you must explicitly name each direct base class, even if it is the
only base class.
The following sample generates C2351:

// C2351.cpp
// compile with: /c
class B {
public:
B() : () {} // C2351
B() {} // OK
};
Compiler Error C2352
10/31/2018 • 2 minutes to read • Edit Online

'class::function' : illegal call of non-static member function


A static member function called a nonstatic member function. Or, a nonstatic member function was called from
outside the class as a static function.
The following sample generates C2352 and shows how to fix it:

// 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

exception specification is not allowed


Exception specifications are not allowed on member functions of managed classes.
The following sample generates C2353:

// 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

initialization segment must not change during translation unit


Possible causes:
#pragma init_seg preceded by segment initialization code
#pragma init_seg preceded by another #pragma init_seg

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)

int __cdecl myexit(void (__cdecl *)());


int __cdecl myexit2(void (__cdecl *)());

#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

'identifier' : must be a function of type 'type'


Your code declares a version of the atexit function that does not match the version declared internally by the
compiler. Declare atexit as follows:

int __cdecl atexit(void (__cdecl *)());

For more information, see init_seg.


The following sample generates C2357:

// 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

initialization of 'identifier' is skipped by 'case' label


The initialization of identifier can be skipped in a switch statement. You cannot jump past a declaration with an
initializer unless the declaration is enclosed in a block. (Unless it is declared within a block, the variable is within
scope until the end of the switch statement.)
The following sample generates C2360:

// 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

initialization of 'identifier' is skipped by 'default' label


The initialization of identifier can be skipped in a switch statement. You cannot jump past a declaration with an
initializer unless the declaration is enclosed in a block. (Unless it is declared within a block, the variable is within
scope until the end of the switch statement.)
The following sample generates C2361:

// 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

initialization of 'identifier' is skipped by 'goto label'


When compiling with /Za, jumping to the label prevents the identifier from being initialized.
You cannot jump past a declaration with an initializer unless the declaration is enclosed in a block that is not
entered, or the variable has already been initialized.
The following sample generates C2326:

// 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

'type': illegal type for custom attribute


Named arguments for custom attributes are limited to compile time constants. For example, integral types (int,
char, etc.), System::Type^, and System::Object^.

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

'class member' : redefinition; previous definition was 'class member'


You attempted to redefine a class member.
The following sample generates C2365.

// 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

'identifier' : redefinition; different allocation specifiers


The declaration and definition of the symbol specify different __declspec attributes.
Compiler Error C2369
10/31/2018 • 2 minutes to read • Edit Online

'array' : redefinition; different subscripts


The array is already declared with a different subscript.
The following sample generates C2369:

// 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

'identifier' : redefinition; different storage class


The identifier is already declared with a different storage class.

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

'identifier' : redefinition; different basic types


The identifier is already declared.
The following sample generates C2371:

// 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

'identifier' : redefinition; different types of indirection


The identifier is already defined with a different derived type.
The following sample generates C2326:

// 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

'identifier' : redefinition; different type modifiers


The identifier is already defined with a different type modifier.
The following sample generates C2373:

// 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

extern int i; // C2373


extern const int i; // OK
Compiler Error C2374
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : redefinition; multiple initialization


The identifier is initialized more than once.
The following sample generates C2374:

// 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

'function' : redefinition; different linkage


The function is already declared with a different linkage specifier.
The following sample generates C2375:

// 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

'function' : redefinition; different based allocation


The function is already declared with a different based allocation.
Compiler Error C2377
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : redefinition; typedef cannot be overloaded with any other symbol


A typedef identifier is redefined.
The following sample generates C2377:

// 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

'identifier' : redefinition; symbol cannot be overloaded with a typedef


The identifier was redefined as a typedef .
The following sample generates C2378:

// 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

formal parameter number has different type when promoted


The type of the specified parameter is not compatible, through default promotions, with the type in a previous
declaration. This is an error in ANSI C (/Za) and a warning with Microsoft extensions (/Ze).
The following sample generates C2379:

// 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

'function' : redefinition; __declspec(noreturn) differs


A function was declared and then defined but the definition used the noreturn __declspec modifier. The use of
noreturn constitutes a redefinition of the function; the declaration and definition need to agree on the use of
noreturn .

The following sample generates C2381:

// 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

'function' : redefinition; different exception specifications


Under /Za, this error indicates that a function overload was attempted only on the exception specification.
The following sample generates C2382:

// 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

'symbol' : default-arguments are not allowed on this symbol


The C++ compiler does not allow default arguments on pointers to functions.
This code was accepted by the Visual C++ compiler in versions before Visual Studio 2005, but now gives an error.
For code that works in all versions of Visual C++, do not assign a default value to a pointer-to-function argument.

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

'member' : cannot apply __declspec(thread) to a member of a managed or WinRT class


The thread __declspec modifier cannot be used on a member of a managed or Windows Runtime class.
Static thread local storage in managed code can only be used for statically loaded DLLs—the DLL must be
statically loaded when the process starts. Windows Runtime does not support thread local storage.
The following line generates C2384 and shows how to fix it in C++/CLI code:

// C2384.cpp
// compile with: /clr /c
public ref class B {
public:
__declspec( thread ) static int tls_i = 1; // C2384

// OK - declare with attribute instead


[System::ThreadStaticAttribute]
static int tls_j;
};
Compiler Error C2385
10/31/2018 • 2 minutes to read • Edit Online

ambiguous access of 'member'


The member can derive from more than one object (it is inherited from more than one object). To resolve this error,
Make the member unambiguous by providing a cast.
Rename the ambiguous members in the base classes.

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");
}
};

// Delete the following line to resolve.


struct C : A, B {}

// Uncomment the following 4 lines to resolve.


// struct C : A, B
// {
// using B::x;
// using A::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

'type' : ambiguous base class


The compiler could not unambiguously resolve a function call because the function exists in more than one base
class.
To resolve this error, either remove one of the base classes from the inheritance, or explicitly qualify the function
call.
The following sample generates C2387:

// C2387.cpp
namespace N1 {
struct B {
virtual void f() {
}
};
}

namespace N2 {
struct B {
virtual void f() {
}
};
}

struct D : N1::B, N2::B {


virtual void f() {
B::f(); // C2387
// try the following line instead
// N1::B::f();
}
};

int main() {
D aD;
aD.f();
}
Compiler Error C2388
10/31/2018 • 2 minutes to read • Edit Online

'symbol' : a symbol cannot be declared with both __declspec(appdomain) and __declspec(process)


The appdomain and process __declspec modifiers cannot be used on the same symbol. The storage for a variable
exists per process or per application domain.
For more information, see appdomain and process.
The following sample generates C2388:

// 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

'operator' : illegal operand 'nullptr'


nullptr cannot be an operand.
The following sample generates C2389:

// C2389.cpp
// compile with: /clr
int main() {
throw nullptr; // C2389
}
Compiler Error C2390
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : incorrect storage class 'specifier'


The storage class is not valid for the global-scope identifier. The default storage class is used in place of the invalid
class.
Possible resolutions:
If the identifier is a function, declare it with extern storage.
If the identifier is a formal parameter or local variable, declare it with auto storage.
If the identifier is a global variable, declare it with no storage class (auto storage).

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

'identifier' : 'friend' cannot be used during type definition


The friend declaration includes a complete class declaration. A friend declaration can specify a member
function or an elaborated type specifier, but not a complete class declaration.
The following sample generates C2326:

// 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;
};

public ref struct D: public B{};

public ref struct B1 {


public:
virtual B^ mf() {
B^ pB = gcnew B;
pB->i = 11;
return pB;
}
};

public ref struct D1: public B1 {


public:
virtual D^ mf() override { // C2392
// try the following line instead
// virtual B^ mf() override {
// return type D^ is covariant with B^, not allowed with CLR types
D^ pD = gcnew D;
pD->i = 12;
return pD;
}
};

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

'symbol' : per-appdomain symbol cannot be allocated in segment 'segment'

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

conversion from 'type_1' to 'type_2' requires a narrowing conversion


An implicit narrowing conversion was found when using uniform initialization.
The C language allows implicit narrowing conversions in assignments and initialization, and C++ follows suit, even
though unexpected narrowing is a cause of many code errors. To make code safer, the C++ standard requires a
diagnostic message when a narrowing conversion occurs in an initialization list. In Visual C++, the diagnostic is
Compiler Error C2397 when using the uniform initialization syntax supported beginning in Visual Studio 2015.
The compiler generates Compiler Warning (level 1) C4838 when using the list or aggregate initialization syntax
supported by Visual Studio 2013.
A narrowing conversion can be okay when you know the possible range of converted values can fit in the target. In
this case, you know more than the compiler does. If you make a narrowing conversion intentionally, make your
intentions explicit by using a static cast. Otherwise, this error message almost always indicates you have a bug in
your code. You can fix it by making sure the objects you initialize have types that are large enough to handle the
inputs.
The following sample generates C2397 and shows one way to fix it:

// C2397.cpp -- C++ narrowing conversion diagnostics


// Compile by using: cl /EHsc C2397.cpp
#include <vector>

struct S1 {
int m1;
double m2, m3;
};

void function_C2397(double d1) {


char c1 { 127 }; // OK
char c2 { 513 }; // error C2397

std::vector<S1> vS1;
vS1.push_back({ d1, 2, 3 }); // error C2397

// Possible fix if you know d1 always fits in an int


vS1.push_back({ static_cast<int>(d1), 2, 3 });
}
Compiler Errors C2400 Through C2499
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 C2400 inline assembler syntax error in 'context'; found 'token'

Compiler Error C2401 'identifier': register must be base in 'context'

Compiler Error C2402 'identifier': register must be index in 'context'

Compiler Error C2403 'identifier': register must be base/index in 'context'

Compiler Error C2404 'identifier': illegal register in 'context'

Compiler Error C2405 illegal short forward reference with offset

Compiler Error C2406 'identifier': name undefined in 'context'


ERROR MESSAGE

Compiler Error C2407 illegal 'float' register in 'context'

Compiler Error C2408 illegal type on PTR operator in 'context'

Compiler Error C2409 illegal type used as operator in 'context'

Compiler Error C2410 'identifier': ambiguous member name in 'context'

Compiler Error C2411 'identifier': illegal struct/union member in 'context'

Compiler Error C2412 'label': case-insensitive label redefined

Compiler Error C2413 'identifier': illegal align size

Compiler Error C2414 illegal number of operands

Compiler Error C2415 improper operand type

Compiler Error C2416 attribute 'attribute' cannot be applied in this context

Compiler Error C2417 divide by zero in 'context'

Compiler Error C2418 cannot delete browser file: filename

Compiler Error C2419 mod by zero in 'context'

Compiler Error C2420 'identifier': illegal symbol in context

Compiler Error C2421 PTR operator used with register in 'context'

Compiler Error C2422 illegal segment override in 'context'

Compiler Error C2423 'number': illegal scale

Compiler Error C2424 'token': improper expression in 'context'

Compiler Error C2425 'token': non-constant expression in 'context'

Compiler Error C2426 'token': illegal operator in 'context'

Compiler Error C2427 'class': cannot define class in this scope

Compiler Error C2428 'operation': not allowed on operand of type 'bool'

Compiler Error C2429 'language feature' requires compiler flag 'compiler option'

Compiler Error C2430 more than one index register in 'context'

Compiler Error C2431 illegal index register in 'context'


ERROR MESSAGE

Compiler Error C2432 illegal reference to 16-bit data in 'context'

Compiler Error C2433 'identifier': 'modifier' not permitted on data declarations

Compiler Error C2434 'symbol': a symbol declared with __declspec(process) cannot


be dynamically initialized in /clr:pure mode

Compiler Error C2435 'var': dynamic initialization requires managed CRT, cannot
compile with /clr:safe

Compiler Error C2436 'identifier': member function or nested class in constructor


initializer list

Compiler Error C2437 'identifier': has already been initialized

Compiler Error C2438 'identifier': cannot initialize static class data via constructor

Compiler Error C2439 'identifier': member could not be initialized

Compiler Error C2440 'conversion': cannot convert from 'type_1' to 'type_2'

Compiler Error C2441 'variable': a symbol declared with __declspec(process) must be


const in /clr:pure mode

Compiler Error C2442 'identifier': nested-namespace-definition cannot be inline or


have attributes

Compiler Error C2443 operand size conflict

Compiler Error C2444 'identifier': used ANSI prototype, found 'type', expected '{' or ';'

Compiler Error C2446 'operator': no conversion from 'type_1' to 'type_2'

Compiler Error C2447 '{': missing function header (old-style formal list?)

Compiler Error C2448 'identifier': function-style initializer appears to be a function


definition

Compiler Error C2449 found '{' at file scope (missing function header?)

Compiler Error C2450 switch expression of type 'type' is illegal

Compiler Error C2451 conditional expression of type 'type' is illegal

Compiler Error C2452 'type': invalid source type for safe_cast

Compiler Error C2453 'type': invalid target type for safe_cast

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 C2457 'identifier': predefined macro cannot appear outside of a


function body

Compiler Error C2458 'identifier': redefinition within definition

Compiler Error C2459 'identifier': is being defined; cannot add as an anonymous


member

Compiler Error C2460 'identifier_1': uses 'identifier_2', which is being defined

Compiler Error C2461 'class': constructor syntax missing formal parameters

Compiler Error C2462 'identifier': cannot define a type in a 'new-expression'

Compiler Error C2464 'type': cannot use 'new' to allocate a reference

Compiler Error C2465 cannot define an anonymous type inside parentheses

Compiler Error C2466 cannot allocate an array of constant size 0

Compiler Error C2467 illegal declaration of anonymous 'user_defined_type'

Compiler Error C2468 constructor cannot be 'constexpr' in a class or struct with


virtual base classes

Compiler Error C2469 'new': cannot allocate 'void' objects

Compiler Error C2470 'function': looks like a function definition, but there is no
parameter list; skipping apparent body

Compiler Error C2471 cannot update program database 'filename'

Compiler Error C2472 'function' cannot be generated in managed code: 'message';


compile with /clr to generate a mixed image

Compiler Error C2473 'identifier': looks like a function definition, but there is no
parameter list.

Compiler Error C2474 'identifier': missing an adjacent semicolon, could be either


keyword or identifier.

Compiler Error C2475 'identifier': redefinition; 'constexpr' specifier mismatch

Compiler Error C2477 'member': static data member cannot be initialized via derived
class
ERROR MESSAGE

Compiler Error C2478 declaration is incompatible with 'instance'

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 C2483 'identifier': object with destructor or non-aggregate type


cannot be declared with thread storage duration in
managed/WINRT code

Compiler Error C2485 'identifier': unrecognized extended attribute

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 C2488 'identifier': 'naked' can only be applied to non-member


function definitions

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 C2491 'identifier': definition of dllimport function not allowed

Compiler Error C2492 'variable': data with thread storage duration may not have dll
interface

Compiler Error C2493 illegal form of __based

Compiler Error C2494 'keyword' cannot be called from within a filter expression or
__finally/finally block

Compiler Error C2495 'identifier': '__declspec(noexcept)' can only be applied to


function declarations or definitions

Compiler Error C2496 'identifier': 'selectany' can only be applied to data items with
external linkage

Compiler Error C2497 'identifier': 'implementation_key' can only be applied to


function declarations
ERROR MESSAGE

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

inline assembler syntax error in 'context'; found 'token'


The token caused a syntax error in the specified context.
The following sample generates C2400:

// 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

'identifier' : register must be base in 'context'


The register used in an indirect memory operand must be a base register in this context.
Compiler Error C2402
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : register must be index in 'context'


The register used in an indirect memory operand must be an index register in this context.
Compiler Error C2403
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : register must be base/index in 'context'


The register used in an indirect memory operand must be a base or index register in this context.
Compiler Error C2404
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal register in 'context'


This register is invalid in this context.
Compiler Error C2405
10/31/2018 • 2 minutes to read • Edit Online

illegal short forward reference with offset


Short forward references must refer to a label only. An additional offset cannot be used.
Compiler Error C2406
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : name undefined in 'context'


An undefined identifier is used with the SIZE , LENGTH , or member-selection (.) operator.
Compiler Error C2407
10/31/2018 • 2 minutes to read • Edit Online

illegal 'float' register in 'context'


An NDP register was specified in an invalid context.
Compiler Error C2408
10/31/2018 • 2 minutes to read • Edit Online

illegal type on PTR operator in 'context'


The first parameter of the PTR operator is not a legal type specification.
Compiler Error C2409
10/31/2018 • 2 minutes to read • Edit Online

illegal type used as operator in 'context'


The type is not legal as an operator in this context.
Compiler Error C2410
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : ambiguous member name in 'context'


The identifier is a member of more than one structure or union in this context.
Use a structure or union specifier on the operand that caused the error. A structure or union specifier is an
identifier of type struct or union (a typedef name or a variable of the same type as the structure or union being
referenced). The specifier must be the left operand of the first member-selection operator (.) to use the operand.
Compiler Error C2411
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal struct/union member in 'context'


To fix by checking the following possible causes
1. The identifier is not a member of a visible structure or union in this context.
2. The identifier is not a member of the structure or union specified with the member-selection (.) operator.
Compiler Error C2412
10/31/2018 • 2 minutes to read • Edit Online

'label' : case-insensitive label redefined


The label is defined more than once in the current function. Change the spelling of the label and its references.
Compiler Error C2413
10/31/2018 • 2 minutes to read • Edit Online

'token' : illegal align size


The size used with the ALIGN directive is missing or outside the valid range.
Compiler Error C2414
10/31/2018 • 2 minutes to read • Edit Online

illegal number of operands


To fix by checking the following possible causes
1. The opcode does not support the number of operands used. Check an assembly-language reference manual
to determine the correct number of operands.
2. A newer processor supports the instruction with a different number of operands. Adjust the /arch
(Minimum CPU Architecture) option to use the later processor.
Compiler Error C2415
10/31/2018 • 2 minutes to read • Edit Online

improper operand type


The opcode does not use operands of this type.
To fix by checking the following possible causes
1. The opcode does not support the number of operands used. Check an assembly-language reference manual
to determine the correct number of operands.
2. A newer processor supports the instruction with additional types. Adjust the /arch (Minimum CPU
Architecture) option to use the later processor.
Compiler Error C2417
10/31/2018 • 2 minutes to read • Edit Online

divide by zero in 'context'


The parameter to the right of the division operator is zero in this context.
Compiler Error C2418
10/31/2018 • 2 minutes to read • Edit Online

cannot delete browser file: filename


The compiler could not delete the browser file.
To fix by checking the following possible causes
1. File is read-only.
2. File is in use by another process.
Compiler Error C2419
10/31/2018 • 2 minutes to read • Edit Online

mod by zero in 'context'


The parameter to the right of the MOD operator is zero in this context.
Compiler Error C2420
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal symbol in context


The identifier is invalid in this context.
Compiler Error C2421
10/31/2018 • 2 minutes to read • Edit Online

PTR operator used with register in 'context'


The PTR operator cannot be used with a register operand.
Compiler Error C2422
10/31/2018 • 2 minutes to read • Edit Online

illegal segment override in 'operand'


Inline assembly code incorrectly uses a segment override operator (colon) on an operand. Possible causes include:
The register preceding the operator is not a segment register.
The register preceding the operator is not the only segment register in the operand.
The segment override operator appears within an indirection operator (brackets).
The expression following the segment override operator is not an immediate operand or a memory
operand.
The following sample generates C2422:

// 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

'number' : illegal scale


Inline assembly code uses a number other than 1, 2, 4, or 8 to scale a register.
The following sample generates C2423:

// 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

'token' : improper expression in 'context'


The token forms part of an incorrect expression in this context.
Compiler Error C2425
10/31/2018 • 2 minutes to read • Edit Online

'token' :non-constant expression in 'context'


The token forms part of a non-constant expression in this context.
To fix this issue, replace the token with a constant literal or with a calculation.
The following sample generates C2425:

// 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

'token' : illegal operator in 'context'


The token cannot be used as an operator in this context. Index operators, for example, cannot be nested.
Compiler Error C2427
10/31/2018 • 2 minutes to read • Edit Online

'class' : cannot define class in this scope


An attempt was made to define a nested class, but the nested class is a member of a base class, not the most
containing class.
The following sample generates C2427:

// C2427.cpp
// compile with: /c
template <class T>
struct S {
struct Inner;
};

struct Y : S<int> {};

struct Y::Inner {}; // C2427

// OK
template<typename T>
struct S<T>::Inner {};
Compiler Error C2428
10/31/2018 • 2 minutes to read • Edit Online

'operation' : not allowed on operand of type 'bool'


You cannot apply a decrement operator to objects of type bool .
The following sample generates C2428:

// C2428.cpp
void g(bool fFlag) {
--fFlag; // C2428
fFlag--; // C2428
}
Compiler Error C2429
10/31/2018 • 2 minutes to read • Edit Online

'language feature' requires compiler flag 'compiler option'

The language feature requires a specific compiler option for support.


The error C2429: language feature 'nested-namespace-definition' requires compiler flag '/std:c++17' is
generated if you try to define a compound namespace, a namespace that contains one or more scope-nested
namespace names, starting in Visual Studio 2015 Update 5. (In Visual Studio 2017 version 15.3, the
/std:c++latest switch is required.) Compound namespace definitions are not allowed in C++ prior to C++17. The
compiler supports compound namespace definitions when the /std:c++17 compiler option is specified:

// 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

more than one index register in 'identifier'


More than one register is scaled. The compiler supports scaled indexing, but you can only scale one register.

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

illegal index register in 'identifier'


The ESP register is scaled or used as both index and base register. The SIB encoding for the x86 processor does
not allow either.
The following sample generates C2431:

// 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

illegal reference to 16-bit data in 'identifier'


A 16-bit register is used as an index or base register. The compiler does not support referencing 16-bit data. 16-bit
registers cannot be used as index or base registers when compiling for 32-bit code.
The following sample generates C2432:

// 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

'identifier' : 'modifier' not permitted on data declarations


The friend , virtual , and inline modifiers cannot be used for data declarations.

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

'identifier' : member function or nested class in constructor initializer list


Member functions or local classes in the constructor initializer list cannot be initialized.
The following sample generates C2436:

// 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

'identifier' : already initialized


An object can be initialized only once.
The following sample generates C2437:

// 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

'identifier' : cannot initialize static class data via constructor


A constructor is used to initialize a static member of a class. Static members must be initialized in a definition
outside the class declaration.
The following sample generates C2438:

// 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

'identifier' : member could not be initialized


A class, structure, or union member cannot be initialized.
To fix by checking the following possible causes
1. Trying to initialize an indirect base class or structure.
2. Trying to initialize an inherited member of a class or structure. An inherited member must be initialized by
the constructor of the class or structure.
Compiler Error C2440
11/9/2018 • 6 minutes to read • Edit Online

'conversion' : cannot convert from 'type1' to 'type2'


The compiler cannot cast from type1 to type2 .

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(){;}

typedef void (B::*pf)();

void f2(pf pf) {


(this->*pf)();
void* pp = (void*)pf; // C2440
}

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

struct Derived; // Forward declaration, not 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();

typedef MyStruct (*FC)();

FC fc1 = &get_c1; // C2440, line 15


FC fc2 = &MyStruct::get_C2; // C2440, line 16
FC fc3 = &get_C3;

class CMyClass {
public:
explicit CMyClass( int iBar)
throw() {
}

static CMyClass get_c2();


};

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 &'
}

To correct the error, use direct initialization:

// 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();
};

int i = (const S)0; // error C2440

To correct the error, declare operator int() as const.


Compiler Error C2441
10/31/2018 • 2 minutes to read • Edit Online

'variable' : a symbol declared with __declspec(process) must be const 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.
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

operand size conflict


The instruction requires operands to be the same size.
The following sample generates C2443:

// 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

'identifier' : used ANSI prototype, found 'type', expected '{' or ';'


The function prototype is followed by a type.
This error can be caused by a missing semicolon or curly brace.
Compiler Error C2446
10/31/2018 • 2 minutes to read • Edit Online

'operator' : no conversion from 'type1' to 'type2'


The compiler cannot convert type1 to type2 . The conversion may not make sense because it violates C/C++
semantics.
Compiler Error C2447
10/31/2018 • 2 minutes to read • Edit Online

'{' : missing function header (old-style formal list?)


The compiler encountered an unexpected open brace at global scope. In most cases, this is caused by a badly-
formed function header, a misplaced declaration, or a stray semi-colon. To resolve this issue, verify that the open
brace follows a correctly-formed function header, and is not preceded by a declaration or a stray semi-colon.
This error can also be caused by an old-style C -language formal argument list. To resolve this issue, refactor the
argument list to use modern style—that is, enclosed in parentheses.
The following sample generates C2447:

// C2447.cpp
int c;
{} // C2447
Compiler Error C2448
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : function-style initializer appears to be a function definition


The function definition is incorrect.
This error can be caused by an old-style C -language formal list.
The following sample generates C2448:

// C2448.cpp
void func(c)
int c;
{} // C2448
Compiler Error C2449
10/31/2018 • 2 minutes to read • Edit Online

found '{' at file scope (missing function header?)


An open brace occurs at file scope.
This error can be caused by a semicolon between a function header and the opening brace of the function
definition.
The following sample generates C2499:

// 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

switch expression of type 'type' is illegal


The switch expression evaluates to an invalid type. It must evaluate to an integer type or a class type with
unambiguous conversion to an integer type. If it evaluates to a user-defined type, you must supply a conversion
operator.
The following sample generates C2450:

// 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

conditional expression of type 'type' is illegal


The conditional expression evaluates to an integer type.
The following sample generates C2451:

// 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

'type' : invalid source type for safe_cast


The source type for safe_cast was not valid. For example, all types in a safe_cast operation must be CLR types.
The following sample generates C2452:

// C2452.cpp
// compile with: /clr

struct A {};
struct B : public A {};

ref struct C {};


ref struct D : public C{};

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

'macro': predefined macro cannot appear outside of a function body

You attempted to use a predefined macro, such as __FUNCTION__, in a global space.

Example
The following sample generates C2457 and also shows correct usage:

// C2457.cpp
#include <stdio.h>

__FUNCTION__; // C2457, cannot be global

int main()
{
printf_s("\n%s", __FUNCTION__); // OK
}
Compiler Error C2458
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : redefinition within definition


A class, structure, union, or enumeration is redefined in its own declaration.
The following sample generates C2458:

// C2458.cpp
class C {
enum i { C }; // C2458
};
Compiler Error C2459
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : is being defined; cannot add as an anonymous member


A class, structure, or union is redefined in its own scope by a member of an anonymous union.
The following sample generates C2459:

// 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

'identifier1' : uses 'identifier2', which is being defined


A class or structure ( identifier2 ) is declared as a member of itself ( identifier1 ). Recursive definitions of classes
and structures are not allowed.
The following sample generates C2460:

// C2460.cpp
class C {
C aC; // C2460
};

Instead, use a pointer reference in the class.

// C2460.cpp
class C {
C * aC; // OK
};
Compiler Error C2461
10/31/2018 • 2 minutes to read • Edit Online

'class' : constructor syntax missing formal parameters

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

'identifier' : cannot define a type in a 'new -expression'


You cannot define a type in the operand field of the new operator. Put the type definition in a separate statement.
The following sample generates C2462:

// C2462.cpp
int main() {
new struct S { int i; }; // C2462
}
Compiler Error C2464
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : cannot use 'new' to allocate a reference


A reference identifier was allocated with the new operator. References are not memory objects, so new cannot
return a pointer to them. Use the standard variable declaration syntax to declare a reference.
The following sample generates C2464:

// C2464.cpp
int main() {
new ( int& ir ); // C2464
}
Compiler Error C2465
10/31/2018 • 2 minutes to read • Edit Online

cannot define an anonymous type inside parentheses


An anonymous structure, union, or enumerated type is defined inside a parenthetical expression. This is invalid in
C++ because the definition is meaningless in function scope.
Compiler Error C2466
10/31/2018 • 2 minutes to read • Edit Online

cannot allocate an array of constant size 0


An array is allocated or declared with size zero. The constant expression for the array size must be an integer
greater than zero. An array declaration with a zero subscript is legal only for a class, structure, or union member
and only with Microsoft extensions (/Ze).
The following sample generates C2466:

// 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

illegal declaration of anonymous 'user-defined-type'


A nested user-defined type was declared. This is an error when compiling C source code with the ANSI
compatibility option (/Za) enabled.
The following sample generates C2467:

//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

'operator': cannot allocate 'type' object


An operator was passed an invalid type.
The following sample generates C2469:

// 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

cannot update program database 'file'


The compiler cannot write to the database file.
To fix the problem
Make sure that the disk has enough available space.
Make sure that the file is not read-only.
Make sure that there are no sharing violations.
Compiler Error C2472
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;

p32 = (int * __ptr32)malloc(4);


p64 = p32;
}

See also
/clr (Common Language Runtime Compilation)
Compiler Error C2473
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : looks like a function definition, but there is no parameter list.


The compiler detected what looked like a function, without the parameter list.

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

'keyword' : missing an adjacent semicolon, could be either keyword or identifier.


The compiler expected to find a semicolon, and was unable to determine your intent. Add the semicolon to resolve
this error.

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

'member' : static data member cannot be initialized via derived class


A static data member of a template class was initialized incorrectly. This is a breaking change with versions of the
Visual C++ compiler prior to Visual Studio .NET 2003, in order to conform to the ISO C++ standard.
The following sample generates C2477:

// C2477.cpp
// compile with: /Za /c
template <class T>
struct S {
static int n;
};

struct X {};
struct A: S<X> {};

int A::n = 0; // C2477

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

'identifier' : 'thread' is only valid for data items of static extent


You cannot use the thread attribute with an automatic variable, nonstatic data member, function parameter, or on
function declarations or definitions.
Use the thread attribute for global variables, static data members, and local static variables only.
The following sample generates C2480:

// 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

'identifier' : dynamic initialization of 'thread' data not allowed in managed/WinRT code

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

int j = j; // OK in C++; C error


Thread int tls_i2 = sizeof( tls_i2 ); // Okay in C and C++

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

'identifier' : object with constructor or destructor cannot be declared 'thread'

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

'identifier' : unrecognized extended attribute


The declaration attribute is not valid.
Compiler Error C2486
10/31/2018 • 2 minutes to read • Edit Online

'__LOCAL_SIZE' only allowed in function with the 'naked' attribute


In inline assembly functions, the name __LOCAL_SIZE is reserved for functions declared with the naked attribute.
The following sample generates C2486:

// 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

'identifier' : 'naked' can only be applied to non-member function definitions


The naked attribute was applied to a function declaration.
The following sample generates C2488:

// 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

__declspec( naked ) void func() {} // OK


Compiler Error C2489
10/31/2018 • 2 minutes to read • Edit Online

'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

'keyword' not allowed in function with 'naked' attribute


A function defined as naked cannot use structured exception handling.
The following sample generates C2490:

// 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

'identifier' : definition of dllimport function not allowed


Data, static data members, and functions can be declared as dllimport s but not defined as dllimport s.
To fix this issue, remove the __declspec(dllimport) specifier from the definition of the function.
The following sample generates C2491:

// 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;
};

__declspec(dllexport) __declspec(thread) C c_1; // C2492


__declspec(thread) C c_1; // OK
Compiler Error C2493
10/31/2018 • 2 minutes to read • Edit Online

illegal form of __based


A __based expression must be based on a pointer.
The following sample generates C2493:

// 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

'keyword' cannot be called from within a filter expression or __finally/finally block


You cannot use keyword in a __finally or finally block.
The following sample generates C2494:

// C2494.cpp
#include <malloc.h>

int main() {
__try {}
__except ( _alloca(100), 1 ) {} // C2494
__try {}
__finally {
_alloca(100); // C2494
}
}

C2494 can also occur when using /clr.

// 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

'identifier' : 'nothrow' can only be applied to function declarations or definitions


The nothrow extended attribute can be applied to function declarations or definitions only.
The following sample generates C2495:

// C2495.cpp
// compile with: /c
__declspec(nothrow) class X { // C2495
int m_data;
} x;

__declspec(nothrow) void test(); // OK


Compiler Error C2496
10/31/2018 • 2 minutes to read • Edit Online

'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

extern const __declspec(selectany) int x3 = 3;

__declspec(selectany) int x4;

// dynamic initialization of x5
int f();
__declspec(selectany) int x5 = f();

extern const int x7;


// OK - redeclaration of x7 that is extern
const __declspec(selectany) int x7 = 7;
Compiler Error C2498
10/31/2018 • 2 minutes to read • Edit Online

'function' : 'novtable' can only be applied to class declarations or definitions


This error can be caused by using __declspec(novtable) with a function.

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

'class' : a class cannot be its own base class


You attempted to specify the class that you are defining as a base class.
The following sample generates C2499:

// 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 C2500 'identifier1': 'identifier2' is already a direct base class

Compiler Error C2501 'identifier': '__declspec(specifier)' can only be applied to


structs, unions, classes, or unsigned bit field members

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 C2504 'class': base class undefined

Compiler Error C2505 'symbol': '__declspec(specifier)' can only be applied to


declarations or definitions of global objects or static data
members
ERROR MESSAGE

Compiler Error C2506 'member': '__declspec(specifier)' cannot be applied to this


symbol

Compiler Error C2507 'identifier': too many virtual modifiers on the base class

Compiler Error C2508 'identifier': '__declspec(specifier1)' cannot be combined with


'__declspec(specifier2)'

Compiler Error C2509 'identifier': member function not declared in 'class'

Compiler Error C2510 'identifier': left of '::' must be a class/struct/union

Compiler Error C2511 'identifier': overloaded member function not found in 'class'

Compiler Error C2512 'identifier': no appropriate default constructor available

Compiler Error C2513 '*type': no variable declared before '='

Compiler Error C2514 'class': class has no constructors

Compiler Error C2515 'identifier': 'vtguard' can only be applied to class declarations
or definitions

Compiler Error C2516 'class': is not a legal base class

Compiler Error C2517 'identifier': right of '::' is undefined

Compiler Error C2518 keyword 'keyword' illegal in base class list; ignored

Compiler Error C2519 'identifier': WinRT attributes may only contain public fields

Compiler Error C2520 'class': no non-explicit constructor available for implicit


conversion

Compiler Error C2521 a destructor/finalizer does not take any arguments

Compiler Error C2522 'identifier': Overload identifier cannot be used on 'identifier1'


as it's already specified on 'identifier2'

Compiler Error C2523 'class::~identifier': destructor/finalizer tag mismatch

Compiler Error C2524 'identifier': a destructor/finalizer must have a 'void' parameter


list

Compiler Error C2525 'identifier': The parameter 'identifier1' is named 'identifier2'


on the base function and must be matched in a published
implementation

Compiler Error C2526 'identifier1': C linkage function cannot return C++ class
'identifier2'
ERROR MESSAGE

Compiler Error C2527 'identifier': DefaultOverload cannot be specified on both


'function1' and 'function2'. Remove one specification or
rename the function during implementation

Compiler Error C2528 'identifier': pointer to reference is illegal

Compiler Error C2529 'identifier': reference to reference is illegal

Compiler Error C2530 'identifier': references must be initialized

Compiler Error C2531 'identifier': reference to a bit field illegal

Compiler Error C2532 'identifier': illegal modifier for reference

Compiler Error C2533 'identifier': constructors not allowed a return type

Compiler Error C2534 'identifier': constructor cannot return a value

Compiler Error C2535 'identifier': member function already defined or declared

Compiler Error C2536 Obsolete.

Compiler Error C2537 'specifier': illegal linkage specification

Compiler Error C2538 Obsolete.

Compiler Error C2539 Obsolete.

Compiler Error C2540 non-constant expression as array bound

Compiler Error C2541 'identifier': cannot delete objects that are not pointers

Compiler Error C2542 'identifier': class object has no constructor for initialization

Compiler Error C2543 expected ']' for operator '[]'

Compiler Error C2544 expected ')' for operator '()'

Compiler Error C2545 'operator': unable to find overloaded operator

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 C2547 'identifier': All parameters of a published method must be


explicitly named on the declaration

Compiler Error C2548 'function': missing default parameter for parameter parameter

Compiler Error C2549 user-defined conversion cannot specify a return type


ERROR MESSAGE

Compiler Error C2550 'identifier': constructor initializer lists are only allowed on
constructor definitions

Compiler Error C2551 'void *' type needs explicit cast

Compiler Error C2552 'identifier': non-aggregates cannot be initialized with an


initializer list

Compiler Error C2553 'type derived_class::function': overriding virtual function


return type differs from 'type base_class::function'

Compiler Error C2555 'derived_class::function': overriding virtual function return


type differs and is not covariant from 'base_class::function'

Compiler Error C2556 'type1 class::function': overloaded function differs only by


return type from 'type2 class::function'

Compiler Error C2557 'identifier': private and protected members cannot be


initialized without a constructor

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 C2561 'function': function must return a value

Compiler Error C2562 'function': 'void' function returning a value

Compiler Error C2563 mismatch in formal parameter list

Compiler Error C2564 Obsolete.

Compiler Error C2565 'identifier': ref-qualifier is illegal for constructors/destructors

Compiler Error C2566 overloaded function in conditional expression

Compiler Error C2567 unable to open metadata in 'filename', possible_reason

Compiler Error C2568 'identifier': unable to resolve function overload

Compiler Error C2569 'identifier': enum/union cannot be used as a base class

Compiler Error C2570 'identifier': union cannot have base classes

Compiler Error C2571 'identifier': virtual function cannot be in union 'union'

Compiler Error C2572 'function': redefinition of default argument: parameter number


ERROR MESSAGE

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 C2574 'destructor': cannot be declared static

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 C2577 'identifier': a destructor/finalizer cannot have a return type

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 C2580 'identifier': multiple versions of a defaulted special member


functions are not allowed

Compiler Error C2581 'type': static 'operator =' function is illegal

Compiler Error C2582 'operator operator' function is unavailable in 'type'

Compiler Error C2583 'identifier': 'const/volatile' 'this' pointer is illegal for


constructors/destructors

Compiler Error C2584 'class': direct base 'base_class2' is inaccessible; already a base
of 'base_class1'

Compiler Error C2585 explicit conversion to 'type' is ambiguous

Compiler Error C2586 incorrect user-defined conversion syntax: illegal indirections

Compiler Error C2587 'identifier': illegal use of local variable as default parameter

Compiler Error C2588 '::~identifier': illegal global destructor/finalizer

Compiler Error C2589 'identifier': illegal token on right side of '::'

Compiler Error C2590 'identifier': only a constructor can have a base/member


initializer list

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 C2593 'operator identifier' is ambiguous


ERROR MESSAGE

Compiler Error C2594 'operator': ambiguous conversions from 'type1' to 'type2'

Compiler Error C2595 'identifier' A WinRT attribute type must be sealed

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'

Compiler Error C2597 illegal reference to non-static member 'identifier'

Compiler Error C2598 linkage specification must be at global scope

Compiler Error C2599 'identifier': the forward declaration of a managed/WinRT enum


is not allowed
Compiler Error C2500
10/31/2018 • 2 minutes to read • Edit Online

'identifier1' : 'identifier2' is already a direct base class


A class or structure appears more than once in a list of base classes.
A direct base is one mentioned in the base list. An indirect base is a base class of one of the classes in the base list.
A class cannot be specified as a direct base class more than once. A class can be used as an indirect base class
more than once.
The following sample generates C2500:

// 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

'identifier' : too many access modifiers on the base class


The base class has more than one access modifier. Only one access modifier ( public , private , or protected ) is
allowed.
The following sample generates C2502:

// 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

'class' : base classes cannot contain zero-sized arrays


A base class or structure contains a zero-sized array. An array in a class must have at least one element.
The following sample generates C2503:

// C2503.cpp
// compile with: /c
class A {
public:
int array [];
};

class B : A {}; // C2503

class C {
public:
int array [10];
};

class D : C {};
Compiler Error C2504
10/31/2018 • 2 minutes to read • Edit Online

'class' : base class undefined


The base class is declared but never defined. Possible causes:
1. Missing include file.
2. External base class not declared with extern.
The following sample generates C2504:

// 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

'member' : '__declspec(modifier)' cannot be applied to this symbol


You cannot declare per-process or per-appdomain for static members of a managed class.
See appdomain for more information.

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

'identifier' : too many virtual modifiers on the base class


A class or structure is declared as virtual more than once. Only one virtual modifier can appear for each class
in a list of base classes.
The following sample generates C2507:

// 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

'identifier' : member function not declared in 'class'


The function is not declared in the specified class.

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();
};

int B::vfunc() { return 1; } // C2509


int B::vfunc2() { return 1; } // OK
Compiler Error C2510
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : left of '::' must be a class/struct/union


A class, structure, or union name must appear on the left side of the scope-resolution operator ( :: ) operator.
Compiler Error C2511
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : overloaded member function not found in 'class'


No version of the function is declared with the specified parameters. Possible causes:
1. Wrong parameters passed to function.
2. Parameters passed in wrong order.
3. Incorrect spelling of parameter names.
The following sample generates C2511:

// C2511.cpp
// compile with: /c
class C {
int c_2;
int Func(char *, char *);
};

int C::Func(char *, char *, int i) { // C2511


// try the following line instead
// int C::Func(char *, char *) {
return 0;
}
Compiler Error C2512
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : no appropriate default constructor available

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

'type' : no variable declared before '='


The type specifier appears in declaration with no variable identifier.
The following sample generates C2513:

// 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

'class' : class has no constructors


The class, structure, or union has no constructor with a parameter list that matches the parameters being used to
instantiate it.
A class must be fully declared before it can be instantiated.
The following sample generates C2514:

// 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

'name' : is not a legal base class


The class is derived from a type name defined by a typedef statement.
The following sample generates C2516:

// C2516.cpp
typedef unsigned long ulong;
class C : public ulong {}; // C2516
Compiler Error C2517
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : right of '::' is undefined


The identifier on the right of the scope-resolution operator ( :: ) must be a defined member of the class, structure,
or union on the left. If no class, structure, or union is named, the identifier on the right must be declared with global
scope.
Compiler Error C2518
10/31/2018 • 2 minutes to read • Edit Online

keyword 'keyword' illegal in base class list; ignored


The keywords class and struct should not appear in a base class list.
The following sample generates C2518:

// 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

function does not take any arguments


You attempted to use arguments with a destructor or finalizer.
For more information, see Destructors and finalizers.

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

'class::~identifier' : destructor/finalizer tag mismatch


The name of the destructor must be the class name preceded by a tilde ( ~ ). The constructor and destructor are the
only members that have the same name as the class.
The following sample generates C2523:

// C2523.cpp
// compile with: /c
class A {
~B(); // C2523
~A(); // OK
};
Compiler Error C2524
10/31/2018 • 2 minutes to read • Edit Online

'destructor' : a destructor/finalizer must have a 'void' parameter list


The destructor or finalizer had a parameter list that is not void. Other parameter types are not allowed.

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

'identifier1' : C linkage function cannot return C++ class 'identifier2'


A function defined with C linkage cannot return a user-defined type.
Compiler Error C2528
10/31/2018 • 2 minutes to read • Edit Online

'name' : pointer to reference is illegal


You cannot declare a pointer to a reference. Dereference the variable before declaring a pointer to it.
The following sample generates C2528:

// C2528.cpp
int i;
int &ir = i;
int & (*irptr) = ir; // C2528
Compiler Error C2529
10/31/2018 • 2 minutes to read • Edit Online

'name' : reference to reference is illegal


This error may be fixed by using pointer syntax and declaring a reference to a pointer.
The following sample generates C2529:

// 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

'identifier' : references must be initialized


You must initialize a reference when it was declared, unless it is declared already:
With the keyword extern.
As a member of a class, structure, or union (and it is initialized in the constructor).
As a parameter in a function declaration or definition.
As the return type of a function.
The following sample generates C2530:

// 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

'identifier' : reference to a bit field illegal


References to bit fields are not allowed.
The following sample generates C2531:

// 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

'identifier' : illegal modifier for reference


The reference was changed. References cannot be modified to refer to another object. Use a pointer instead.
Compiler Error C2533
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : constructors not allowed a return type


A constructor cannot have a return type (not even a void return type).
A common source of this error is a missing semicolon between the end of a class definition and the first
constructor implementation. The compiler sees the class as a definition of the return type for the constructor
function, and generates C2533.
The following sample generates C2533, and shows how to fix it:

// C2533.cpp
// compile with: /c
class X {
public:
X();
};

int X::X() {} // C2533 - constructor return type not allowed


X::X() {} // OK - fix by using no return type
Compiler Error C2534
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : constructor cannot return a value


A constructor cannot return a value or have a return type (not even a void return type).
This error may be fixed by removing the return statement from the constructor definition.
The following sample generates C2534:

// C2534.cpp
class A {
public:
int i;
A() { return i; } // C2534
};
Compiler Error C2535
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : member function already defined or declared


This error could be caused by using the same formal parameter list in more than one definition or declaration of an
overloaded function.
If you get C2535 because of the Dispose function, see Destructors and finalizers for more information.
The following sample generates C2535:

// 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

'specifier' : illegal linkage specification


Possible causes:
1. The linkage specifier is not supported. Only the "C" linkage specifier is supported.
2. "C" linkage is specified for more than one function in a set of overloaded functions. This is not allowed.
The following sample generates C2537:

// 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

non-constant expression as array bound


An array must have a constant bound.
The following sample generates C2540:

// C2540.cpp
void func(int n, int pC[]) {
int i = ((int [n])pC)[1]; // C2540
}

void func2(int n, int pC[]) {


int i = (pC)[1]; // OK
}

int main() {
int pC[100];
func(100, pC);
func2(100, pC);
}
Compiler Error C2541
10/31/2018 • 2 minutes to read • Edit Online

'delete' : delete : cannot delete objects that are not pointers


The delete operator was used on an object that is not a pointer.
The following sample generates C2541:

// 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

'identifier' : class object has no constructor for initialization


There is no constructor with a parameter list that matches the initialization.
This error can be caused by incorrect parameters in initialization.
Compiler Error C2543
10/31/2018 • 2 minutes to read • Edit Online

expected ']' for operator '[]'


The subscripting operator is missing a left bracket.
This error can be caused by macro expansion.
Compiler Error C2544
10/31/2018 • 2 minutes to read • Edit Online

expected ')' for operator '()'


The function call operator is missing a left parenthesis.
This error can be caused by macro expansion.
Compiler Error C2545
10/31/2018 • 2 minutes to read • Edit Online

'operator' : unable to find overloaded operator


The operator cannot be used with the operands provided. You must supply an overloaded operator with the
required operands.
This error can be caused if operands have incorrect type.
This error may be fixed if you define a conversion operator or constructor that takes a single parameter.
Compiler Error C2548
10/31/2018 • 2 minutes to read • Edit Online

'class::member' : missing default parameter for parameter parameter


The default parameter list is missing a parameter. If you supply a default parameter anywhere in a parameter list,
you must define default parameters for all subsequent parameters.

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

user-defined conversion cannot specify a return type


The following sample generates C2549:

// C2549.cpp
// compile with: /c
class X {
public:
int operator int() { return value; } // C2549

// try the following line instead


// operator int() { return value; }
private:
int value;
};
Compiler Error C2550
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : constructor initializer lists are only allowed on constructor definitions


A base class initializer list is used on the definition of a function that is not a constructor.
The following sample generates C2550:

// C2550.cpp
// compile with: /c
class C {
public:
C();
};

class D : public C {
public:
D();
void func();
};

void D::func() : C() {} // C2550


D::D() : C() {} // OK
Compiler Error C2551
10/31/2018 • 2 minutes to read • Edit Online

'void *' type needs explicit cast


A void pointer is assigned to a nonvoid pointer by implicit conversion. You must use an explicit cast.
Compiler Error C2552
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : non-aggregates cannot be initialized with initializer list


The aggregate identifier was incorrectly initialized.
Aggregates are defined as:
Arrays
Classes, structures, and unions that do not have:
Constructors
Private or protected members
Base classes
Virtual functions
In addition, Visual C++ does not allow data types in an aggregate that contains constructors.
The following represent the reasons C2552 may fire when an aggregate initialization is attempted on a type:
The type has one or more user-defined constructors.
The type has one ore more non-static, private data members.
The type has one or more virtual functions.
The type has a base class.
The type is a ref class or CLR interface.
The type has a non-fixed dimension array (zero-array) whose elements have destructors.
The following sample generates C2552:
// C2552.cpp
// compile with: /clr
#include <string>
using namespace std;

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

// initialize a CLR immutable value type that has a constructor


System::DateTime dt = {2001, 4, 12, 22, 16, 49, 844}; // C2552

Pair_Correct1 pair2( name, 0.0 );


Pair_Correct1 pair3 = Pair_Correct1( name, 0.0 );
Pair_Correct2 pair4 = { name, 0.0 };
System::DateTime dt2(2001, 4, 12, 22, 16, 49, 844);
}
Compiler Error C2553
10/31/2018 • 2 minutes to read • Edit Online

'base_function': overriding virtual function return type differs from 'override_function'


A function in a derived class attempted to override a virtual function in a base class, but the derived class function
did not have the same return type as the base class function. An override function signature must match the
signature of the function being overridden.
The following sample generates C2553:

// C2553.cpp
// compile with: /clr /c
ref struct C {
virtual void f();
};

ref struct D : C {
virtual int f() override ; // C2553

// try the following line instead


// virtual void f() override;
};
Compiler Error C2555
10/31/2018 • 2 minutes to read • Edit Online

' 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:

Guid[] CheckSources(Guid sourceID, Guid[] carouselIDs);

is

Guid CheckSources(Guid sourceID, Guid carouselIDs[]) [];

The following sample generates C2555:

// 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

'identifier' : overloaded functions only differ by return type


The overloaded functions have different return types but the same parameter list. Each overloaded function must
have a distinct formal parameter list.
The following sample generates C2556:

// 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

'identifier' : private and protected members cannot be initialized without a constructor


Only members and friends can assign a value to a private or protected member. Nonpublic members should be
initialized in the class constructor.
Compiler Error C2558
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : no copy constructor available or copy constructor is declared 'explicit'


A copy constructor initializes an object from another object of the same type. (It makes a copy of the object.) The
compiler generates a default copy constructor if you do not define any constructors.
To fix this error
1. The problem can occur when an attempt is made to copy a class whose copy constructor is private . In
most cases, a class that has a private copy constructor should not be copied. A common programming
technique declares a private copy constructor to prevent the direct use of a class. The class may be useless
by itself or require another class in order to work correctly.
If you determine that it is safe to use a class that has a private copy constructor, derive a new class from
the class that has the private constructor and make a public or protected copy constructor available in
the new class. Use the derived class in place of the original.
2. The problem can occur when an attempt is made to copy a class whose copy constructor is explicit.
Declaring a copy constructor as explicit prevents passing/returning objects of a class to/from functions.
For more information about explicit constructors, see User-Defined Type Conversions.
3. The problem can occur when an attempt is made to copy a class instance declared const by using a copy
constructor that does not take a const reference parameter. Declare your copy constructor with a const
type reference instead of a non-const type reference.
Compiler Error C2561
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : function must return a value


The function was declared as returning a value, but the function definition does not contain a return statement.
This error can be caused by an incorrect function prototype:
1. If the function does not return a value, declare the function with return type void.
2. Check that all possible branches of the function return a value of the type declared in the prototype.
3. C++ functions containing inline assembly routines that store the return value in the AX register may need a
return statement. Copy the value in AX to a temporary variable and return that variable from the function.

The following sample generates C2561:

// 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

'identifier' : 'void' function returning a value


The function is declared as void but returns a value.
This error can be caused by an incorrect function prototype.
This error may be fixed if you specify the return type in the function declaration.
The following sample generates C2562:

// 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

mismatch in formal parameter list


The formal parameter list of a function (or a pointer to a function) does not match those of another function (or
pointer to a member function). As a result, the assignment of functions or pointers cannot be made.
The following sample generates C2563:

// 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

overloaded function in conditional expression


An overloaded function in a conditional expression cannot be evaluated.
Compiler Error C2567
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

'identifier1' : unable to resolve function overload


The compiler cannot determine which overloaded function to call. The actual parameters passed to the function
must be cast to match the formal parameters for one of the overloaded function, but no one match is
unambiguously better than all others.
Compiler Error C2569
10/31/2018 • 2 minutes to read • Edit Online

'EnumOrUnion' : enum/union cannot be used as a base class


If you must derive a type from the specified union or enumeration, change the union or enumeration to a class or
structure.
The following sample generates C2569:

// 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

'identifier' : union cannot have base classes


A union derives from a class, structure, or union. This is not allowed. Declare the derived type as a class or
structure instead.
The following sample generates C2570:

// 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

'function' : virtual function cannot be in union 'union'


A union is declared with a virtual function. You can declare a virtual function only in a class or structure. Possible
resolutions:
1. Change the union to a class or structure.
2. Make the function nonvirtual.
The following sample generates C2571:

// 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

'class::member' : redefinition of default parameter : parameter param


Default parameters cannot be redefined. If you require another value for the parameter, the default parameter
should be left undefined.
The following sample generates C2572:

// C2572.cpp
// compile with: /c
void f(int i = 1); // function declaration

// function definition
void f(int i = 1) {} // C2572

// try the following line instead


// void f(int i) {}
Compiler Error C2573
10/31/2018 • 2 minutes to read • Edit Online

'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

'destructor' : cannot be declared static


Neither destructors nor constructors can be declared static .
The following sample generates C2574:

// 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

'identifier' : only member functions and bases can be virtual


A global function or class is declared virtual . This is not allowed.
The following sample generates C2575:

// 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

'member' : destructor/finalizer cannot have a return type


A destructor or finalizer cannot return a value of void or any other type. Remove the return statement from the
destructor definition.

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

unable to resolve type 'type' (offset). It is expected in file


C2579 always follows C4691. For more information, see Compiler Warning (level 1) C4691.
Compiler Error C2581
10/31/2018 • 2 minutes to read • Edit Online

'type' : static 'operator =' function is illegal


The assignment ( = ) operator is incorrectly declared as static . Assignment operators cannot be static . For
more information, see User-Defined Operators (C++/CLI).

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

'function' function is unavailable in 'type'


An attempt was made to assign to an object that does not have an assignment operator.
The following sample generates C2582:

// 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

'identifier' : 'const/volatile' 'this' pointer is illegal for constructors/destructors


A constructor or destructor is declared const or volatile . This is not allowed.
The following sample generates C2583:

// C2583.cpp
// compile with: /c
class A {
public:
int i;
A() const; // C2583

// try the following line instead


// A();
};
Compiler Error C2584
10/31/2018 • 2 minutes to read • Edit Online

'Class' : direct base 'Base2' is inaccessible; already a base of 'Base1'


Class already derives directly from Base1 . Base2 also derives from Base1 . Class cannot derive from Base2
because that would mean inheriting (indirectly) from Base1 again, which is not legal because Base1 is already a
direct base class.

Example
The following sample generates C2584.

// C2584.cpp
// compile with: /c
struct A1 {
virtual int MyFunction();
};

struct A2 {
virtual int MyFunction();
};

struct B1: public virtual A1, virtual A2 {


virtual int MyFunction();
};

struct B2: public virtual A2, virtual A1 {


virtual int MyFunction();
};

struct C: virtual B1, B2 {


virtual int MyFunction();
};

struct Z : virtual B2, virtual C { // C2584


// try the following line insted
// struct Z : virtual C {
virtual int MyFunction();
};
Compiler Error C2585
10/31/2018 • 2 minutes to read • Edit Online

explicit conversion to 'type' is ambiguous


The type conversion can produce more than one result.
To fix by checking the following possible causes
1. Converting from a class or structure type based on multiple inheritance. If the type inherits the same base
class more than once, the conversion function or operator must use scope resolution ( :: ) to specify which
of the inherited classes to use in the conversion.
2. A conversion operator and a constructor have been defined making the same conversion.
Compiler Error C2586
10/31/2018 • 2 minutes to read • Edit Online

incorrect user-defined conversion syntax : illegal indirections


Indirection of a conversion operator is not allowed.
The following sample generates C2586:

// 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

'identifier' : illegal use of local variable as default parameter


Local variables are not allowed as default parameters.
The following sample generates C2587:

// 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

'::~identifier' : illegal global destructor


The destructor is defined for something other than a class, structure, or union. This is not allowed.
This error can be caused by a missing class, structure, or union name on the left side of the scope resolution ( :: )
operator.
The following sample generates C2588:

// C2588.cpp
~F(); // C2588
Compiler Error C2589
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal token on right side of '::'


If a class, structure, or union name appears to the left of the scope-resolution operator (double colons), the token
on the right must be a class, structure, or union member. Otherwise, any global identifier can appear on the right.
The scope-resolution operator cannot be overloaded.
The following sample generates C2589:

// C2589.cpp
void Test(){}
class A {};
void operator :: (); // C2589

int main() {
::Test();
}
Compiler Error C2592
10/31/2018 • 2 minutes to read • Edit Online

'class': 'base_class_2' is inherited from 'base_class_1' and cannot be re-specified


You can only specify base classes that do not inherit from other base classes. In this case, only base_class_1 is
needed in the specification of class because base_class_1 already inherits base_class_2 .
Compiler Error C2593
10/31/2018 • 2 minutes to read • Edit Online

'operator identifier' is ambiguous


More than one possible operator is defined for an overloaded operator.
This error may be fixed if you use an explicit cast on one or more actual parameters.
The following sample generates C2593:

// 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 :

ar.Write(&f, sizeof( float ));


Compiler Error C2594
10/31/2018 • 2 minutes to read • Edit Online

'operator' : ambiguous conversions from 'type1' to 'type2'


No conversion from type1 to type2 was more direct than any other. We suggest two possible solutions to
converting from type1 to type2. The first option is to define a direct conversion from type1 to type2, and the
second option is to specify a sequence of conversions from type1 to type2.
The following sample generates C2594. The suggested resolution to the error is a sequence of conversions:

// 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

// try the following line instead


// return static_cast<A *>(static_cast<I1 *>(p));
}
Compiler Error C2597
10/31/2018 • 2 minutes to read • Edit Online

illegal reference to non-static member 'identifier'


Possible causes:
1. A nonstatic member is specified in a static member function. To access the nonstatic member, you must pass
in or create a local instance of the class and use a member-access operator ( . or -> ).
2. The specified identifier is not a member of a class, structure, or union. Check identifier spelling.
3. A member access operator refers to a nonmember function.
4. The following sample generates C2597 and shows how to fix it:

// 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
}

// OK - fix by passing an instance of s1


void s1::func2(s1& a) {
a.i = 1;
}
Compiler Error C2598
10/31/2018 • 2 minutes to read • Edit Online

linkage specification must be at global scope


The linkage specifier is declared at local scope.
The following sample generates C2598:

// C2598.cpp
// compile with: /c
void func() {
extern "C" int func2(); // C2598
}

extern "C" int func( int i );


Compiler Error C2599
10/31/2018 • 2 minutes to read • Edit Online

'enum' : forward declaration of enum type is not allowed


The compiler no longer supports forward declaration of a managed enumeration.
Forward declaration of an enum type is not allowed under /Za.
The following sample generates C2599:

// C2599.cpp
// compile with: /clr /c
enum class Status; // C2599

enum class Status2 { stop2, hold2, go2};

ref struct MyStruct {


// Delete the following line to resolve.
Status m_status;

Status2 m_status2; // OK
};

enum class Status { stop, hold, go };


Compiler Errors C2600 Through C2699
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 C2600 'function': cannot define a compiler-generated special member


function (must be declared in the class first)

Compiler Error C2601 'function': local function definitions are illegal

Compiler Error C2602 'class::identifier' is not a member of a base class of 'class'

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 C2605 'identifier': this method is reserved within a managed/WinRT


class

Compiler Error C2606 'class1': cannot re-implement 'member', as it is inherited from


runtime base 'class2'

Compiler Error C2607 static assertion failed

Compiler Error C2608 Obsolete.

Compiler Error C2609 Obsolete.

Compiler Error C2610 'class::member': is not a special member function which can be
defaulted

Compiler Error C2611 'token': illegal following '~' (expected identifier)

Compiler Error C2612 trailing 'character' illegal in base/member initializer list

Compiler Error C2613 trailing 'character' illegal in base class list

Compiler Error C2614 'class': illegal member initialization: 'identifier' is not a base or
member

Compiler Error C2615 Obsolete.

Compiler Error C2616 'conversion': cannot implicitly convert a non-lvalue 'type1' to a


'type2' that is not const

Compiler Error C2617 'function': inconsistent return statement

Compiler Error C2618 Obsolete.

Compiler Error C2619 'identifier': a static data member is not allowed in an


anonymous struct/union

Compiler Error C2620 Obsolete.

Compiler Error C2621 Obsolete.

Compiler Error C2622 Obsolete.

Compiler Error C2623 Obsolete.

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 C2626 'identifier': a private/protected data member is not allowed in


an anonymous struct/union
ERROR MESSAGE

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 C2629 'identifier': an anonymous struct/union cannot declare a


nested type

Compiler Error C2630 'symbol' found in what should be a comma-separated list

Compiler Error C2631 'identifier': a class or enum cannot be defined in an alias


template

Compiler Error C2632 'type1' followed by 'type2' is illegal

Compiler Error C2633 'identifier': 'inline' is the only legal storage class for
constructors

Compiler Error C2634 'class::member': pointer to reference member is illegal

Compiler Error C2635 cannot convert a 'type1*' to a 'type2*'; conversion from a


virtual base class is implied

Compiler Error C2636 'identifier': pointer to reference member is illegal

Compiler Error C2637 'identifier': cannot modify pointers to data members

Compiler Error C2638 'identifier': __based modifier illegal on pointer to member

Compiler Error C2639 Obsolete.

Compiler Error C2640 'identifier': __based modifier illegal on reference

Compiler Error C2641 Obsolete.

Compiler Error C2642 Obsolete.

Compiler Error C2643 Obsolete.

Compiler Error C2644 Obsolete.

Compiler Error C2645 no qualified name for pointer to member (found ':: *')

Compiler Error C2646 an anonymous struct/union at global or namespace scope


must be declared static

Compiler Error C2647 'operator': cannot dereference a 'type1' on a 'type2'

Compiler Error C2648 'identifier': use of member as default parameter requires static
member

Compiler Error C2649 'identifier': is not a 'class/struct/union'


ERROR MESSAGE

Compiler Error C2650 'operator': cannot be a virtual function

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 C2653 'identifier': is not a class or namespace name

Compiler Error C2654 'identifier': attempt to access member outside a member


function

Compiler Error C2655 'identifier': definition or redeclaration illegal in current scope

Compiler Error C2656 'function': function not allowed as a bit field

Compiler Error C2657 'class::*' found at the start of a statement (did you forget to
specify a type?)

Compiler Error C2658 'identifier': redefinition in anonymous struct/union

Compiler Error C2659 'operator': function as left operand

Compiler Error C2660 'function': function does not take number arguments

Compiler Error C2661 'function': no overloaded function takes 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 C2666 'function': number overloads have similar conversions

Compiler Error C2667 'function': none of number overloads have a best conversion

Compiler Error C2668 'function': ambiguous call to overloaded function

Compiler Error C2669 member function not allowed in anonymous union

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 C2672 'function': no matching overloaded function found

Compiler Error C2673 'function': global functions do not have 'this' pointers

Compiler Error C2674 a generic declaration is not allowed in this context

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 C2680 'type': invalid target type for cast

Compiler Error C2681 'type': invalid expression type for cast

Compiler Error C2682 cannot use 'cast' to convert from 'type1' to 'type2'

Compiler Error C2683 'cast': 'type' is not a polymorphic type

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 C2687 'type': exception-declaration cannot be 'void' or denote an


incomplete type or pointer or reference to an incomplete type

Compiler Error C2688 'type::member': covariant returns with multiple or virtual


inheritance not supported for varargs functions

Compiler Error C2689 'function': a friend function cannot be defined within a local
class

Compiler Error C2690 'operator': cannot perform pointer arithmetic on a


managed/WinRT array

Compiler Error C2691 'type': a managed/WinRT array cannot have this element type
ERROR MESSAGE

Compiler Error C2692 'function': fully prototyped functions required in C compiler


with the '/clr' option

Compiler Error C2693 'operator': illegal comparison for references to a


managed/WinRT array

Compiler Error C2694 'override_function': overriding virtual function has less


restrictive exception specification than base class virtual
member function 'base_function'

Compiler Error C2695 'override_function': overriding virtual function differs from


'base_function' only by calling convention

Compiler Error C2696 Cannot create a temporary object of managed/WinRT type


'type'

Compiler Error C2697 Obsolete.

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

'function' : local function definitions are illegal


Code tries to define a function within a function.
Or, there may be an extra brace in your source code before the location of the C2601 error.
The following sample generates C2601:

// C2601.cpp
int main() {
int i = 0;

void funcname(int j) { // C2601


j++;
}
}
Compiler Error C2602
10/31/2018 • 2 minutes to read • Edit Online

'class::Identifier' is not a member of a base class of 'class'


Identifier cannot be accessed because it is not a member inherited from any base class.
The following sample generates C2602:

// 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

'name' : this method is reserved within a managed or WinRT class


Certain names are reserved by the compiler for internal functions. For more information, see Destructors and
finalizers.

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

'token' : illegal following '~' (expected identifier)


The token is not an identifier.
The following sample generates C2611:

// 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

trailing 'char' illegal in base/member initializer list


A character appears after the last base or member in an initializer list.
The following sample generates C2612:

// 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

trailing ',' illegal in base class list


A comma appears after the last base in a base class list.
Compiler Error C2614
10/31/2018 • 2 minutes to read • Edit Online

'class1' : illegal member initialization: 'class2' is not a base or member


Only member or base classes can appear in the initialization list for a class or structure.

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

'function' : inconsistent return statement


The specified function does not have a declared return type, and a previous return statement did not supply a
value.
The following sample generates C2617:

// 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

'identifier': a static data member is not allowed in an anonymous struct or union


A member of an anonymous struct or union is declared static .
The following sample generates C2619, and demonstrates how to fix it by removing the static keyword.

// 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

local classes cannot be used to declare 'extern' variables


A local class or structure cannot be used to declare extern variables.
The following sample generates C2624:

// 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
};
}

To fix this issue, remove any private or protected tags:

// C2626b.cpp
int main() {
union {
public:
int i; // OK, i is public
};
}
Compiler Error C2627
10/31/2018 • 2 minutes to read • Edit Online

'function' : member function not allowed in anonymous union


An anonymous union cannot have member functions.
The following sample generates C2627:

// C2627.cpp
int main() {
union { void f(){} }; // C2627
union X { void f(){} };
}
Compiler Error C2628
10/31/2018 • 2 minutes to read • Edit Online

'type1' followed by 'type2' is illegal (did you forget a ';'?)


A semicolon may be missing.
The following sample generates C2628:

// 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

'symbol' found in what should be a comma-separated list


The symbol appears in a context that requires a comma.
The following sample generates C2630:

// C2630.cpp
// compile with: /c
struct D {
D(int);
};

struct E {
E(int);
};

class C : public D, public E {


C();
};

C::C() : D(0) ; E(0) { } // C2630


C::C() : D(0), E(0) {} // OK
Compiler Error C2632
10/31/2018 • 2 minutes to read • Edit Online

'type1' followed by 'type2' is illegal


This error can be caused if there is missing code between two type specifiers.
The following sample generates C2632:

// 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

'identifier' : 'inline' is the only legal storage class for constructors


A constructor is declared as a storage class other than inline.
The following sample generates C2633:

// 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

'&class::member' : pointer to reference member is illegal


A pointer to a reference member is declared.
The following sample generates C2634:

// 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

'identifier' : pointer to reference member is illegal


A pointer to a reference member was declared.
The following sample generates C2636:

// 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

'identifier' : cannot modify pointers to data members


A pointer to a data member cannot have a calling convention. To resolve, either remove the calling convention or
declare a pointer to member function.
The following sample generates C2637:

// 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

'identifier' : __based modifier illegal on pointer to member


The __based modifier cannot be used for pointers to members.
The following sample generates C2638:

// 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

'identifier' : __based modifier illegal on reference


The __based modifier can be used on pointers only.
The following sample generates C2640:

// 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

no qualified name for pointer to member (found ':: *')


The declaration of a pointer to a member does not specify a class.
The following sample generates C2645:

// 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

an anonymous struct or union at global or namespace scope must be declared static


An anonymous struct or union has global or namespace scope but is not declared static .
The following sample generates C2646 and shows how to fix it:

// 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

'operator': cannot dereference a 'type1' on a 'type2'


The left operand of a pointer-to-member operator ( ->* or .* ) cannot be implicitly converted to a type related
to the right operator.
The following sample generates C2647:

// 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

'identifier' : use of member as default parameter requires static member


A non-static member is used as a default parameter.
The following sample generates C2648:

// 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

'identifier' : is not a 'class-key'


A class, structure, or union declaration uses an incorrect tag.
Compiler Error C2650
10/31/2018 • 2 minutes to read • Edit Online

'operator' : cannot be a virtual function


A newor delete operator is declared virtual . These operators are static member functions and cannot be
virtual .

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

'data type' : left of 'operator' must be a class, struct or union


To use a template parameter as if it is a class, specialize the class template with a class instead of an integral type.
Compiler Error C2652
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal copy constructor: first parameter must not be an 'identifier'


The first parameter in the copy constructor has the same type as the class, structure, or union for which it is
defined. The first parameter can be a reference to the type but not the type itself.
The following sample generates C2651:

// 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

'identifier' : is not a class or namespace name

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);
};

void xx::func1(int m) {} // C2653, xx is not declared


void yy::func1(int m) {} // OK

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

'identifier' : attempt to access member outside a member function


A member is accessed in a declaration. Member data can be accessed only in member functions.
This error can be caused when trying to initialize variables in a declaration. Use a constructor for this purpose.
Compiler Error C2655
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : definition or redeclaration illegal in current scope


An identifier can be redeclared only at global scope.
The following sample generates C2655:

// 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

'function' : function not allowed as a bit field


A function is declared as a member of a bit field.
This error can be caused by a syntax error in a constructor initializer list.
Compiler Error C2657
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

'member': redefinition in anonymous struct/union


Two anonymous structures or unions contained member declarations with the same identifier but with different
types. Under /Za, you will also get this error for members with the same identifier and type.
The following sample generates C2658:

// 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

'operator' : function as left operand


A function was on the left side of the specified operator. The most common reason for this error is that the
compiler has parsed the identifier on the left side of the operator as a function when the developer intended it to
be a variable. For more information, see Wikipedia article Most vexing parse. This example shows a function
declaration and a variable definition that are easily confused:

// 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

string1 = "String 1"; // C2659


string2 = "String 2";
}

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

'function' : function does not take number parameters


The function is called with an incorrect number of parameters.
C2660 can occur if you accidentally call a Windows API function rather than an MFC member function of the same
name. To solve this problem:
Adjust the function call to conform to the format of the member function call.
Use the scope resolution operator ( :: ) to tell the compiler to seek the function name in the global name
space.

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;

void CheckStatus( Object^ stateInfo ) {}

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>

template <class T> class CA {


private:
static T** line;
void* operator new (size_t, int i) {
return 0;
}
void operator delete(void* pMem, int i) {
free(pMem);
}

public:
CA () { new (1) T(); } // C2660
// try the following line instead
// CA () { new (1) CA<int>(); }
};

typedef CA <int> int_CA;

void AAA() {
int_CA list;
}
Compiler Error C2661
10/31/2018 • 2 minutes to read • Edit Online

'function' : no overloaded function takes number parameters


Possible causes:
1. Incorrect actual parameters in function call.
2. Missing function declaration.
The following sample generates C2661:

// 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

'function' : cannot convert 'this' pointer from 'type1' to 'type2'


The compiler could not convert the this pointer from type1 to type2 .
This error can be caused by invoking a non- const member function on a const object. Possible resolutions:
Remove the const from the object declaration.
Add const to the member function.

The following sample generates C2662:

// 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; }
}

void operator=(const M %m) {


M ^ prop = m.Type; // C2662
}
};

ref struct N {
property N^ Type {
N^ get() { return this; }
}

void operator=(N % n) {
N ^ prop = n.Type; // OK
}
};

The following sample generates C2662:


// C2662_c.cpp
// compile with: /c
// C2662 expected
typedef int ISXVD;
typedef unsigned char BYTE;

class LXBASE {
protected:
BYTE *m_rgb;
};

class LXISXVD:LXBASE {
public:
// Delete the following line to resolve.
ISXVD *PMin() { return (ISXVD *)m_rgb; }

ISXVD *PMin2() const { return (ISXVD *)m_rgb; }; // OK


};

void F(const LXISXVD *plxisxvd, int iDim) {


ISXVD isxvd;
// Delete the following line to resolve.
isxvd = plxisxvd->PMin()[iDim];

isxvd = plxisxvd->PMin2()[iDim];
}
Compiler Error C2663
10/31/2018 • 2 minutes to read • Edit Online

'function' : number overloads have no legal conversions for 'this' pointer


The compiler could not convert this to any of the overloaded versions of the member function.
This error can be caused by invoking a non- const member function on a const object. Possible resolutions:
1. Remove the const from the object declaration.
2. Add const to one of the member function overloads.

The following sample generates C2663:

// 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

'function' : cannot convert argument n from 'type1' to 'type2'


This parameter conversion problem might happen if an instance of a class is created and an implicit conversion is
attempted on a constructor marked with the explicit keyword. For more information about explicit conversions,
see User-Defined Type Conversions.
If a temporary object is passed to a function that takes a reference to an object as a parameter, that reference must
be a const reference.
If the function is passed a parameter that is not of the type that the function expects, a temporary object is created
by using the appropriate constructor. This temporary object is then passed to the function. In this case, the
temporary object is used to initialize the reference. In earlier versions of the language, all references could be
initialized by temporary objects.
To fix C2664,
Recheck the prototype for the given function and correct the argument noted in the error message.
Supply an explicit conversion if necessary.
C2664 can also be generated if a class hides a member in one of its base classes.
For more information, see How to: Convert System::String to wchar_t* or char*.

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){}
};

void func( int, A ) {}

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;
}
};

// Simple reference cannot bind to temp var.


void Test(szString &a) {}

// To fix, uncomment the following line.


// void Test(const szString &a) {}

szString::szString(const char * newstr) : slen(0), str(NULL) {


slen=strlen(newstr);
str = new char[slen + 1];
if (str)
strcpy_s(str, (slen + 1), newstr);
}

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>

void func1(LPCSTR &s)


{

void func2(LPSTR &s)


{
func1(s);
}

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>

using namespace std;


#define LEN 90

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));

// To fix, delete the following line.


char* pszNext;

// To fix, uncomment the following line.


// const char* pszNext;

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) ]

interface IMyObj1 : IUnknown {


HRESULT teststr([in, string] wchar_t *wstr);
HRESULT testarr([in, size_is(len)] wchar_t wstr[], [in] int len);
HRESULT testbstr([in] BSTR bstr);
};

[ 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);
}
};

template <class t1>


void test(CTypedImg<t1>& myarg) {
myarg.run();
}

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

'identifier' : number overloads have similar conversions


An overloaded function or operator is ambiguous. Formal parameter lists may be too similar for the compiler to
resolve the ambiguity. To resolve this error, explicitly cast one or more of the actual parameters.
The following sample generates C2666:

// 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;
}

T( const char* str )


{
int iSize = (strlen( str )+ 1);
m_str = new char[ iSize ];
if (m_str)
strcpy_s( m_str, iSize, str );
}

bool operator<( const T& RHS )


{
return m_str < RHS.m_str;
}

operator char*() const


{
return m_str;
}

char* m_str;
};

int main()
{
T str1( "ABCD" );
const char* str2 = "DEFG";

// Error - Ambiguous call to operator<()


// Trying to convert str1 to char* and then call
// operator<( const char*, const char* )?
// OR
// trying to convert str2 to T and then call
// T::operator<( const T& )?

if( str1 < str2 ) // C2666

if ( str1.operator < ( str2 ) ) // Treat str2 as type T


printf_s("str1.operator < ( str2 )\n");

if ( str1.operator char*() < str2 ) // Treat str1 as type char*


printf_s("str1.operator char*() < str2\n");
}

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

'function' : none of number overloads have a best conversion


An overloaded function call is ambiguous and cannot be resolved.
The conversion required to match the actual parameters in the function call to one of the overloaded functions
must be strictly better than the conversions required by all the other overloaded functions.
Compiler Error C2668
10/31/2018 • 2 minutes to read • Edit Online

'function' : ambiguous call to overloaded function


The specified overloaded function call could not be resolved. You may want to explicitly cast one or more of the
actual parameters.
You can also get this error through template use. If, in the same class, you have a regular member function and a
templated member function with the same signature, the templated one must come first. This is a limitation of the
current implementation of Visual C++.

Example
The following sample generates C2668:

// C2668.cpp
struct A {};
struct B : A {};
struct X {};
struct D : B, X {};

void func( X, X ){}


void func( A, B ){}
D d;
int main() {
func( d, d ); // C2668 D has an A, B, and X
func( (X)d, (X)d ); // OK, uses func( X, 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 = "");
};

class AppTestCase : public TestCase {


public:
// Uncomment the following line to resolve.
// using TestCase::AssertEqual;
void AssertEqual(const TypeA expected, const TypeA actual,
std::string conditionExpression = "");
void AssertEqual(const TypeB expected, const TypeB actual,
std::string conditionExpression = "");
};

class MyTestCase : public AppTestCase {


void TestSomething() {
int actual = 0;
AssertEqual(0, actual, "Value");
}
};

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) {}
};

void f(const A&) {}


void f(const B&) {}

int main()
{
f({ 1 }); // error C2668: 'f': ambiguous call to overloaded function
}
Compiler Error C2669
10/31/2018 • 2 minutes to read • Edit Online

member function not allowed in anonymous union


Anonymous unions cannot have member functions.

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

'function' : static member functions do not have 'this' pointers


A static member function tried to access this .
The following sample generates C2671:

// C2671.cpp
struct S {
static S* const func() { return this; } // C2671
};
Compiler Error C2672
10/31/2018 • 2 minutes to read • Edit Online

'function': no matching overloaded function found

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>

template <class T> class S {


// public: // Uncomment this line to fix
typedef typename T type;
};

template <class T, std::enable_if<std::is_integral<typename S<T>::type>::value, T> * = 0>


bool f(T x)
{
return (x == 0);
}

int main()
{
f(10); // C2672: No matching overloaded function found.
}
Compiler Error C2673
10/31/2018 • 2 minutes to read • Edit Online

'function' : global functions do not have 'this' pointers


A global function tried to access this .
The following sample generates C2673:

// C2673.cpp
int main() {
this = 0; // C2673
}
Compiler Error C2674
10/31/2018 • 2 minutes to read • Edit Online

a generic declaration is not allowed in this context


A generic was declared incorrectly. For more information, see Generics.

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;
};

inline Combo& operator+=(Combo& lhs, int rhs) {


lhs.number += rhs;
return lhs;
}

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

'type' : invalid target type for name


A casting operator tried to convert to a type that is not a pointer or reference. The dynamic_cast operator can be
used only for pointers or references.
The following sample generates C2680:

// 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
}

C2680 can also occur when the target is not defined:

// C2680b.cpp
// compile with: /clr /c
// C2680 expected
using namespace System::Collections;

// Delete the following line to resolve.


ref class A; // not defined

// Uncomment the following line to resolve.


// ref class A{};

public ref class B : ArrayList {


property A^ C[int] {
A^ get(int index) {
return dynamic_cast<A^>(this->default::get(index));
}
void set(int index, A^ value) {
this->default::set(index, value);
}
}
};
Compiler Error C2681
10/31/2018 • 2 minutes to read • Edit Online

'type' : invalid expression type for name


A casting operator tried to convert from an invalid type. For example, if you use the dynamic_cast operator to
convert an expression to a pointer type, the source expression must be a pointer.
The following sample generates C2681:

// 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

cannot use casting_operator to convert from 'type1' to 'type2'


A casting operator tried to convert between incompatible types. For example, you cannot use the dynamic_cast
operator to convert a pointer to a reference. The dynamic_cast operator cannot be used to cast away qualifiers. All
qualifiers on the types must match.
You can use the const_cast operator to remove attributes such as const , volatile , or __unaligned .
The following sample generates C2682:

// C2682.cpp
class A { virtual void f(); };
class B: public A {};

void g(A* pa) {


B& rb = dynamic_cast<B&>(pa); // C2682
}

The following sample generates C2682:

// 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

'cast' : 'type' is not a polymorphic type


You cannot use dynamic_cast to convert from a non-polymorphic class (a class with no virtual functions).
You can use static_cast to perform conversions of non-polymorphic types. However, static_cast does not
perform a run-time check.
The following sample generates C2683:

// C2683.cpp
// compile with: /c
class B { };
class D : public B { };

void f(B* pb) {


D* pd1 = dynamic_cast<D*>(pb); // C2683
D* pd1 = static_cast<D*>(pb); // OK
}
Compiler Error C2687
10/31/2018 • 2 minutes to read • Edit Online

'type' : exception-declaration cannot be 'void' or denote an incomplete type or pointer or reference to an


incomplete type
For a type to be part of an exception declaration, it must be defined and not void.
The following sample generates C2687:

// 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

'function' : a friend function cannot be defined within a local class


You can declare but not define a friend function in a local class.
The following sample generates C2689:

// 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

'operator' : cannot perform pointer arithmetic on a managed or WinRT array


Pointer arithmetic is not allowed on a managed or WinRT array. Use array index notation to traverse the array.
Compiler Error C2691
10/31/2018 • 2 minutes to read • Edit Online

'data type' : a managed or WinRTarray cannot have this element type


The type of a managed or WinRT array element can be a value type or a reference type.
The following sample generates C2691:

// 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

'operator' : illegal comparison for references to a managed or WinRT array


You cannot test a managed or WinRT array for any kind of inequality. For example, you can test to see if managed
arrays are equal but you cannot test to see if one array is greater or less than another array.
Compiler Error C2694
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) {
}
};

class Derived : public MyBase {


public:
void f(void) throw(...) {} // C2694
void f2(void) throw(int) {} // OK
};
Compiler Error C2695
10/31/2018 • 2 minutes to read • Edit Online

'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

Cannot create a temporary object of a managed type 'type'


References to const in an unmanaged program cause the compiler to call the constructor and create a temporary
object on the stack. However, a managed class can never be created on the stack.
C2696 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C2698
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 C2701 'function': a function template/generic cannot be a friend of a


local class

Compiler Error C2702 __except may not appear in termination block

Compiler Error C2703 illegal __leave statement

Compiler Error C2704 'function': __va_start intrinsic only allowed in varargs

Compiler Error C2705 'label': illegal jump into 'exception_block' scope


ERROR MESSAGE

Compiler Error C2706 illegal __except without matching __try (missing '}' in __try
block?)

Compiler Error C2707 'identifier': bad context for intrinsic function

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 C2710 'identifier': '__declspec(modifier)' can only be applied to a


function returning a pointer

Compiler Error C2711 'function': this function cannot be compiled as managed,


consider using #pragma unmanaged

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 C2714 alignof(void) is not allowed

Compiler Error C2715 'type': cannot throw or catch this type

Compiler Error C2716 Obsolete.

Compiler Error C2717 Obsolete.

Compiler Error C2718 'type': actual parameter with requested alignment of number
won't be aligned

Compiler Error C2719 'parameter': formal parameter with requested alignment of


number won't be aligned

Compiler Error C2720 'identifier': 'specifier' storage-class specifier illegal on members

Compiler Error C2721 'specifier': storage-class specifier illegal between operator


keyword and type

Compiler Error C2722 '::operator': illegal following operator command; use 'operator
operator'

Compiler Error C2723 'function': 'specifier' specifier illegal on function definition

Compiler Error C2724 'function': 'static' should not be used on member functions
defined at file scope

Compiler Error C2725 'type': unable to throw or catch a managed/WinRT object by


value or reference
ERROR MESSAGE

Compiler Error C2726 'gcnew' may only be used to create an object with
managed/WinRT type

Compiler Error C2727 Obsolete.

Compiler Error C2728 'type': a native array cannot contain this type

Compiler Error C2729 Obsolete.

Compiler Error C2730 'class': cannot be a base class of itself

Compiler Error C2731 'function': function cannot be overloaded

Compiler Error C2732 linkage specification contradicts earlier specification for


'function'

Compiler Error C2733 'function': second C linkage of overloaded function not


allowed

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 C2736 'keyword' keyword is not permitted in cast

Compiler Error C2737 'identifier': 'constexpr' object must be initialized

Compiler Error C2738 'operator type': is ambiguous or is not a member of 'class'

Compiler Error C2739 'number': explicit managed/WinRT array dimensions must be


between 1 and 32

Compiler Error C2740 value of operand 'number' is out of range 'lower_bound -


upper_bound'

Compiler Error C2741 frame size too large

Compiler Error C2742 Obsolete.

Compiler Error C2743 'type': cannot catch a native type with __clrcall destructor or
copy constructor

Compiler Error C2744 'operator' is not a valid CLR/WinRT operator

Compiler Error C2745 'token': this token cannot be converted to an identifier

Compiler Error C2746 Obsolete.

Compiler Error C2747 Obsolete.


ERROR MESSAGE

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 C2751 'parameter': the name of a function parameter cannot be


qualified

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 C2754 'template': a partial specialization cannot have a dependent


non-type template parameter

Compiler Error C2755 'parameter': non-type parameter of a partial specialization


must be a simple identifier

Compiler Error C2756 'template': default template arguments not allowed on a


partial specialization

Compiler Error C2757 'identifier': a symbol with this name already exists and
therefore this name cannot be used as a namespace name

Compiler Error C2758 'member': a member of reference type must be initialized

Compiler Error C2759 in-line assembler reports: error_message

Compiler Error C2760 syntax error: expected 'token1' not 'token2'

Compiler Error C2761 'function': member function redeclaration not allowed

Compiler Error C2762 'template': invalid expression as a template argument for


'parameter'

Compiler Error C2763 'template': invalid use of a string literal as a template


argument for 'parameter'

Compiler Error C2764 'parameter': template parameter not used or deducible in


partial specialization 'specialization'

Compiler Error C2765 'function': an explicit specialization of a function template


cannot have any default arguments

Compiler Error C2766 explicit specialization; 'specialization' has already been defined
ERROR MESSAGE

Compiler Error C2767 managed/WinRT array dimension mismatch: expected number


argument(s) - number provided

Compiler Error C2768 'function': illegal use of explicit template arguments

Compiler Error C2769 you cannot brace initialize a managed/WinRT array in a


base/member initializer list

Compiler Error C2770 invalid explicit template/generic argument(s) for 'template'

Compiler Error C2771 #import only permitted at global or namespace scope

Compiler Error C2772 Obsolete.

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 C2778 improperly formed GUID in __declspec(uuid())

Compiler Error C2779 'declaration': property methods can only be associated with
non-static data members

Compiler Error C2780 'declaration': expects number arguments - number provided

Compiler Error C2781 'declaration': expects at least number argument - number


provided

Compiler Error C2782 'declaration': template/generic parameter 'parameter' is


ambiguous

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 C2786 'type': invalid operand for __uuidof

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 C2789 'identifier': an object of const-qualified type must be initialized

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 C2792 'super': this keyword must be followed by '::'

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 C2795 'super::identifier' is not a member function

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

Compiler Error C2798 'super::identifier' is ambiguous

Compiler Error C2799 'identifier': an object of const-qualified class type without a


user-provided default constructor must be initialized
Compiler Error C2700
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : cannot be thrown (use /W4 for more info)


The object cannot be thrown. Compile with /W4 for more diagnostic information.
Compiler Error C2701
10/31/2018 • 2 minutes to read • Edit Online

'function' : a function template cannot be a friend of a local class


A local class cannot have a template function as a friend function.
The following sample generates C2701:

// 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

__except may not appear in termination block


An exception handler ( __try / __except ) cannot be nested inside a __finally block.
The following sample generates C2702:

// 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

illegal __leave statement


A __leave statement must be inside a __try block.
The following sample generates C2703:

// 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

'identifier' : __va_start intrinsic only allowed in varargs


The __va_start intrinsic is used in a declaration for a function with a fixed number of arguments.
Compiler Error C2705
10/31/2018 • 2 minutes to read • Edit Online

'label' : illegal jump into 'exception handler block' scope


Execution jumps to a label within a try / catch , __try / __except , __try / __finally block. For more
information, see Exception Handling.
The following sample generates C2705:

// C2705.cpp
int main() {
goto trouble;
__try {
trouble: ; // C2705
}
__finally {}

// try the following line instead


// trouble: ;
}
Compiler Error C2706
10/31/2018 • 2 minutes to read • Edit Online

illegal __except without matching __try (missing '}' in __try block?)


The compiler did not find a closing brace for a __try block.
The following sample generates C2706:

// 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

'identifier' : bad context for intrinsic function


Structured exception-handling intrinsics are invalid in certain contexts:
_exception_code() outside an exception filter or __except block
_exception_info() outside an exception filter
_abnormal_termination() outside a __finally block

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 MyFilter(LONG excode)


{
return (excode == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH); // OK
}

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

'identifier' : formal parameter's length in bytes differs from previous declaration


The signature in a call to the specified function differs from the prototype.
Compiler Error C2710
10/31/2018 • 2 minutes to read • Edit Online

'construct' : '__declspec(modifier)' can only be applied to a function returning a pointer


A function whose return value is a pointer is the only construct to which modifier can be applied.
The following sample generates C2710:

// 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

cannot use __try in functions that require object unwinding

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

only one form of exception handling permitted per function


You cannot use structured exception handling ( __try / __except ) and C++ exception handling ( try / catch ) in the
same function.
Compiler Error C2714
10/31/2018 • 2 minutes to read • Edit Online

__alignof(void) is not allowed


An invalid value was passed to an operator.
See __alignof Operator for more information.

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

'type' : cannot throw or catch this type


Value types are not valid arguments when using exception handling in managed code (see Exception Handling for
more information).

// 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();
}

catch(V v) { if ( v.i == 10 ) { // C2715


// try the following line instead
// catch(V^ pv) { if ( pv->i == 10 ) {
Console::WriteLine("caught 10 - looks OK");
}
else {
Console::WriteLine("catch looks bad");
}
}
catch(...) {
Console::WriteLine("catch looks REALLY bad");
}
}
Compiler Error C2718
10/31/2018 • 2 minutes to read • Edit Online

'parameter': actual parameter with __declspec(align('#')) won't be aligned


The align __declspec modifier is not permitted on function parameters.
The following sample generates C2718:

// C2718.cpp
typedef struct __declspec(align(32)) AlignedStruct {
int i;
} AlignedStruct;

void f2(int i, ...);

void f4() {
AlignedStruct as;

f2(0, as); // C2718, actual parameter is aligned


}
Compiler Error C2719
10/31/2018 • 2 minutes to read • Edit Online

'parameter': formal parameter with __declspec(align('#')) won't be aligned


The align __declspec modifier is not permitted on function parameters. Function parameter alignment is
controlled by the calling convention used. For more information, see Calling Conventions.
The following sample generates C2719 and shows how to fix it:

// 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

'identifier' : 'specifier' storage-class specifier illegal on members

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

'specifier' : storage-class specifier illegal between operator keyword and type


User-defined type conversions apply to all storage classes, so you cannot specify a storage class in a type
conversion.
Compiler Error C2722
10/31/2018 • 2 minutes to read • Edit Online

'::operator' : illegal following operator command; use 'operator operator'


An operator statement redefines ::new or ::delete . The new and delete operators are global, so the scope
resolution operator ( :: ) is meaningless. Remove the :: operator.
Compiler Error C2723
10/31/2018 • 2 minutes to read • Edit Online

'function' : 'specifier' specifier illegal on function definition


The specifier cannot appear with a function definition outside of a class declaration. The virtual specifier can be
specified only on a member function declaration within a class declaration.
The following sample generates C2723 and shows how to fix it:

// C2723.cpp
struct X {
virtual void f();
virtual void g();
};

virtual void X::f() {} // C2723

// try the following line instead


void X::g() {}
Compiler Error C2724
10/31/2018 • 2 minutes to read • Edit Online

'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();
};

static void C::func(){}; // C2724


// try the following line instead
// void C::func(){};
Compiler Error C2725
10/31/2018 • 2 minutes to read • Edit Online

'exception' : unable to throw or catch a managed or WinRT object by value or reference


The type of a managed or WinRT exception was not correct.

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

'type' : a native array cannot contain this type


Array creation syntax was used to create an array of managed or WinRT objects. You cannot create an array of
managed or WinRT objects using native array syntax.
For more information, see array.
The following sample generates C2728 and shows how to fix it:

// C2728.cpp
// compile with: /clr

int main() {
int^ arr[5]; // C2728

// try the following line instead


array<int>^arr2;
}
Compiler Error C2730
10/31/2018 • 2 minutes to read • Edit Online

'class' : cannot be a base class of itself


Recursive base classes are invalid. Specify another class as the base class.
Compiler Error C2731
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : function cannot be overloaded


The functions main , WinMain , DllMain , and LibMain cannot be overloaded.
The following sample generates C2731:

// 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

linkage specification contradicts earlier specification for 'function'


The function is already declared with a different linkage specifier.
This error can be caused by include files with different linkage specifiers.
To fix this error, change the extern statements so that the linkages agree. In particular, do not wrap #include
directives in extern "C" blocks.

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

second C linkage of overloaded function 'function' not allowed


More than one overloaded function is declared with C linkage. When using C linkage, only one form of a specified
function can be external. Since overloaded functions have the same undecorated name, they cannot be used with C
programs.
The following sample generates C2733:

// 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

'identifier' : const object must be initialized if not extern


The identifier is declared const but not initialized or extern .
The following sample generates C2734:

// 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

'keyword' keyword is not permitted in formal parameter type specifier


The keyword is invalid in this context.
The following sample generates C2735:

// C2735.cpp
void f(inline int){} // C2735
Compiler Error C2736
10/31/2018 • 2 minutes to read • Edit Online

'keyword' keyword is not permitted in cast


The keyword is invalid in a cast.
The following sample generates C2736:

// 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

'declaration' : is ambiguous or is not a member of 'type'


A function was declared incorrectly.
The following sample generates C2738:

// C2738.cpp
struct A {
template <class T> operator T*();
// template <class T> operator T();
};

template <>
A::operator int() { // C2738

// try the following line instead


// A::operator int*() {

// or use the commented member declaration

return 0;
}
Compiler Error C2739
10/31/2018 • 2 minutes to read • Edit Online

'number' : explicit managed or WinRT array dimensions must be between 1 and 32


An array dimension was not between 1 and 32.
The following sample generates C2739 and shows how to fix it:

// 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

'token' : this token cannot be converted to an identifier


Identifiers must be comprised of legal characters.
The following sample generates C2745:

// 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;

// Delete the following 4 lines to resolve.


try {
throw (1); // C2749
}
catch(int){}

// 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

// try the following line instead


Y1 ^ x2 = gcnew Y1;
}
Compiler Error C2751
10/31/2018 • 2 minutes to read • Edit Online

'parameter' : the name of a function parameter cannot be qualified


You cannot use a qualified name as a function parameter.
The following sample generates C2751:

// C2751.cpp
namespace std {
template<typename T>
class list {};
}

#define list std::list


void f(int &list){} // C2751
Compiler Error C2752
10/31/2018 • 2 minutes to read • Edit Online

'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 {};

template<class T, class U>


struct A<T*, U> {};

template<class T, class U>


struct A<T,U*> {};

// try the following line instead


// template<class T, class U> struct A<T*,U*> {};

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> {};

template<class T, class U, class V, class W, class X>


struct B {};
Compiler Error C2754
10/31/2018 • 2 minutes to read • Edit Online

'specialization' : a partial specialization cannot have a dependent non-type template parameter


An attempt was made to partially specialize a template class that has a dependent non-type template parameter.
This is not allowed.
The following sample generates C2754:

// C2754.cpp
// compile with: /c

template<class T, T t>
struct A {};

template<class T, int N>


struct B {};

template<class T> struct A<T,5> {}; // C2754


template<> struct A<int,5> {}; // OK
template<class T> struct B<T,5> {}; // OK
Compiler Error C2755
10/31/2018 • 2 minutes to read • Edit Online

'param' : non-type parameter of a partial specialization must be a simple identifier


The non-type parameter needs to be a simple identifier, something the compiler can resolve at compile time to a
single identifier or a constant value.
The following sample generates C2755:

// 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

'template type' : default template arguments not allowed on a partial specialization


The template for a partial specialization may not contain a default argument.
The following sample generates C2756 and shows how to fix it:

// C2756.cpp
template <class T>
struct S {};

template <class T=int>


// try the following line instead
// template <class T>
struct S<T*> {}; // C2756
Compiler Error C2757
10/31/2018 • 2 minutes to read • Edit Online

'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>

namespace Nes { // C2757


// try the following line instead
// namespace Nes2 {
public ref class X {};
}
Compiler Error C2758
10/31/2018 • 2 minutes to read • Edit Online

'member': a member of reference type must be initialized


Compiler error C2758 is caused when the constructor does not initialize a member of reference type in an
initializer list. The compiler leaves the member undefined. Reference member variables must initialized when
declared or be given a value in the initialization list of the constructor.
The following sample generates C2758:

// 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

syntax error : expected 'name1' not 'name2'


A casting operator is used with an invalid operator.
The following sample generates C2760:

// C2760.cpp
class B {};
class D : public B {};

void f(B* pb) {


D* pd1 = static_cast<D*>(pb);
D* pd2 = static_cast<D*>=(pb); // C2760
D* pd3 = static_cast<D*=(pb); // C2760
}
Compiler Error C2761
11/9/2018 • 2 minutes to read • Edit Online

'function' : member function redeclaration not allowed


You cannot redeclare a member function. You can define it, but not redeclare it.

Example
The following sample generates C2761.

// C2761.cpp
class a {
int t;
void test();
};

void a::a; // C2761


void a::test; // C2761

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;
};

int C::s; // C2761


int C::t; // OK
Compiler Error C2762
10/31/2018 • 2 minutes to read • Edit Online

'class' : invalid expression as a template argument for 'argument'


When using /Za, the compiler will not convert an integral to a pointer.
The following sample generates C2762:

// 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

'param' : template parameter not used or deducible in partial specialization 'specialization'


A template parameter is not used in a partial specialization. This makes the partial specialization unusable because
the template parameter cannot be deduced.

Example
The following sample generates C2764:

// C2764.cpp
#include <stdio.h>
template <class T1, class T2>
struct S {
int m_i;
};

template <class T1, class T2>


struct S<int, T2*> { // C2764
// try the following line instead
// struct S<T1(*)(T2), T2*> {
char m_c;
};

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) {};

template<> void f<char>(char c = 'a') {} // C2765


// try the following line instead
// template<> void f<char>(char c) {}
Compiler Error C2766
10/31/2018 • 2 minutes to read • Edit Online

explicit specialization; 'specialization' has already been defined


Duplicate explicit specializations are not allowed. For more information, see Explicit Specialization of Function
Templates.
The following sample generates C2766:

// 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

managed or WinRTarray dimension mismatch : expected N argument(s) - M provided


A managed or WinRT array declaration was ill formed. For more information, see array.
The following sample generates C2767 and shows how to fix it:

// 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

'function' : illegal use of explicit template arguments


The compiler was unable to determine if a function definition was supposed to be an explicit specialization of a
function template or if the function definition was supposed to be for a new function.
This error was introduced in Visual Studio .NET 2003, as part of the compiler conformance enhancements.
The following sample generates C2768:

// C2768.cpp
template<typename T>
void f(T) {}

void f<int>(int) {} // C2768

// an explicit specialization
template<>
void f<int>(int) {}

// global nontemplate function overload


void f(int) {}
Compiler Error C2770
10/31/2018 • 2 minutes to read • Edit Online

invalid explicit template_or_generic argument(s) for 'template'


Function template candidates with explicit template or generic arguments resulted in disallowed function types.
The following sample generates C2770:

// C2770.cpp
#include <stdio.h>
template <class T>
int f(typename T::B*); // expects type with member B

struct Err {};

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

#import only permitted at global or namespace scope


The #import directive is not allowed in, for example, a function or structure.
Compiler Error C2773
10/31/2018 • 2 minutes to read • Edit Online

#import and #using available only in C++ compiler


The C compiler does not recognize the #import preprocessor directive. Compile the source as C++. Use /TP if
necessary.
Compiler Error C2774
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : no 'put' method is associated with this property


A data member declared with property has no put function, but an expression tries to set its value.
The following sample generates C2774:

// C2774.cpp
struct A {
__declspec(property(get=GetProp)) int prop;
int GetProp(void);

__declspec(property(get=GetProp2, put=PutProp2)) int prop2;


int GetProp2(void);
void PutProp2(int);
};

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

'identifier' : no 'get' method is associated with this property


A data member declared with the property extended attribute does not have a get function specified, but an
expression tries to retrieve its value.
The following sample generates C2775:

// C2775.cpp
struct A {
__declspec(property(put=PutProp2, get=GetProp2)) int prop2;
int GetProp2(){return 0;}
void PutProp2(int){}

__declspec(property(put=PutProp)) int prop;


int PutProp(void){}

};

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

only one 'get' method can be specified per property


You can only specify one get function in the property extended attribute. This error occurs when multiple get
functions are specified.
The following sample generates C2776:

// 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

only one 'put' method can be specified per property


A property declspec modifier had more than one put property.
The following sample generates C2777:

// 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

improperly formed GUID in __declspec(uuid())


An incorrect GUID is supplied to the uuid extended attribute.
The GUID must be a string of hexadecimal numbers with the following format:

// 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

'declaration' : expects N arguments - M provided


A function template has too few or too many arguments.
The following sample generates C2780 and shows how to fix it:

// 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

'declaration' : expects at least value1 argument - value2 provided


A function template with a variable parameter list has too few arguments.
The following sample generates C2781:

// C2781.cpp
template<typename T>
void f(T, T, ...){}

int main() {
f(1); // C2781

// try the following line instead


f(1,1);
}
Compiler Error C2782
10/31/2018 • 2 minutes to read • Edit Online

'declaration' : template parameter 'identifier' is ambiguous


The compiler cannot determine the type of a template argument.
The following sample generates C2782:

// C2782.cpp
template<typename T>
void f(T, T) {}

int main() {
f(1, 'c'); // C2782
// try the following line instead
// f<int>(1, 'c');
}

C2782 can also occur when using generics:

// 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

'declaration' : could not deduce template argument for 'identifier'


The compiler cannot determine a template argument. Default arguments cannot be used to deduce a template
argument.
The following sample generates C2783:

// 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);
}

C2783 can also occur when using generics:

// 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;
}

ref class MyClass{};

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

// To fix it, try the following line instead


f(x);
}
Compiler Error C2785
10/31/2018 • 2 minutes to read • Edit Online

'declaration1' and 'declaration2' have different return types


The return type of function template specialization differs from the return type of the primary function template.
To correct this error
1. Check all specializations of the function template for consistency.

Example
The following sample generates C2785:

// C2785.cpp
// compile with: /c
template<class T> void f(T);

template<> int f(int); // C2785


template<> void f(int); // OK
Compiler Error C2786
10/31/2018 • 2 minutes to read • Edit Online

'type' : invalid operand for __uuidof


The __uuidof operator takes a user-defined type with a GUID attached or an object of such a user-defined type.
Possible causes:
1. The argument is not a user-defined type.
2. __uuidof cannot extract the GUID from the argument.
The following sample generates C2786:

// 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

'identifier' : no GUID has been associated with this object


The __uuidof operator takes a user-defined type with a GUID attached or an object of such a user-defined type.
This error occurs when the argument is a user-defined type with no GUID.
The following sample generates C2787:

// C2787.cpp
#include <windows.h>
struct F {};

struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) F2;

int main() {
__uuidof(F); // C2787
__uuidof(F2); // OK
}
Compiler Error C2788
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : more than one GUID associated with this object


The __uuidof operator takes a user-defined type with a GUID attached or an object of such a user-defined type.
This error occurs when the argument is an object with multiple GUIDs.
The following sample generates C2788:

// 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 {};

typedef MyClass<A,B> MyBadClass;


typedef MyClass<A,A> MyGoodClass;

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

'super' : this keyword must be followed by '::'


The only token that can follow the keyword __super is :: .
The following sample generates C2792:

// C2792.cpp
struct B {
void mf();
};

struct D : B {
void mf() {
__super.(); // C2792

// try the following line instead


// __super::mf();
}
};
Compiler Error C2793
10/31/2018 • 2 minutes to read • Edit Online

'token' : unexpected token following '::', identifier or keyword 'operator' expected


The only tokens that can follow __super:: are an identifier or the keyword operator .
The following sample generates C2793

// 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

'function' : is not a member of any direct or indirect base class of 'class'


You tried to use super to call a nonexistent member function.
The following sample generates C2794

// 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

'super::function' is not a member function


This error message appears whenever you try to use super to access a member other than a member function.
Compiler Error C2797
11/9/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 &)'
};

This example also generates C2797:

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};
};

If you do not require list initialization:

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 C2800 'operator operator' cannot be overloaded

Compiler Error C2801 'member' must be a non-static member

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 C2809 'operator operator' has no 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 C2813 #import is not supported with /MP

Compiler Error C2814 'member': a native type cannot be nested within a


managed/WinRT type 'class'

Compiler Error C2815 'operator delete': first formal parameter must be 'void *', but
'type' was used

Compiler Error C2816 Obsolete.

Compiler Error C2817 return type for 'operator delete' must be 'void'

Compiler Error C2818 application of overloaded 'operator ->' is recursive through


type 'class'

Compiler Error C2819 type 'class' does not have an overloaded member 'operator -
>'

Compiler Error C2820 Obsolete.

Compiler Error C2821 first formal parameter to 'operator new' must be 'size_t'

Compiler Error C2822 local unwind is not supported on this platform

Compiler Error C2823 a typedef template/generic is illegal

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 C2826 Obsolete.

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 C2831 'operator operator' cannot have default parameters

Compiler Error C2832 'identifier': a reference type cannot be value-initialized

Compiler Error C2833 'operator token' is not a recognized operator or type

Compiler Error C2834 'operator operator' must be globally qualified

Compiler Error C2835 user-defined conversion 'type' takes no formal parameters

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 C2838 'identifier': illegal qualified name in member declaration

Compiler Error C2839 invalid return type 'type' for overloaded 'operator ->'

Compiler Error C2840 instruction word argument not constant

Compiler Error C2841 register argument not constant

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 C2844 'identifier': cannot be a member of interface 'interface'

Compiler Error C2845 'type': pointer arithmetic not allowed on this type

Compiler Error C2846 'interface': an interface cannot have a constructor

Compiler Error C2847 cannot apply sizeof to managed/WinRT type 'class'

Compiler Error C2848 'class': a managed/WinRT type cannot be a member of a union

Compiler Error C2849 'interface': an interface cannot have a destructor

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 C2854 syntax error in #pragma hdrstop

Compiler Error C2855 command-line option 'option' inconsistent with precompiled


header

Compiler Error C2856 #pragma hdrstop cannot be inside an #if block

Compiler Error C2857 '#include' statement specified with the /Ycfilename command-
line option was not found in the source file

Compiler Error C2858 command-line option '/Yc (/Fdfilename)' inconsistent with


precompiled header, which used '/Fdfilename'

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 C2861 'declaration': an interface member function cannot be defined

Compiler Error C2862 'interface': an interface can only have public members

Compiler Error C2863 'interface': an interface cannot have friends

Compiler Error C2864 'identifier': a static data member/template variable with an in-
class initializer must have non-volatile const integral type

Compiler Error C2865 'operator': illegal comparison for object pointer/handle

Compiler Error C2866 Obsolete.

Compiler Error C2867 'identifier': is not a namespace

Compiler Error C2868 'identifier': illegal syntax for using-declaration; expected


qualified-name

Compiler Error C2869 'identifier': has already been defined to be a namespace

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 C2872 'identifier': ambiguous symbol

Compiler Error C2873 'symbol': symbol cannot be used in a using-declaration

Compiler Error C2874 using-declaration causes a multiple declaration of 'identifier'

Compiler Error C2875 using-declaration causes a multiple declaration of


'class::identifier'

Compiler Error C2876 'class::member': not all overloads are accessible

Compiler Error C2877 'member' is not accessible from 'class'

Compiler Error C2878 'identifier': a namespace or class of this name does not exist

Compiler Error C2879 'identifier': only an existing namespace can be given an


alternative name by a namespace alias definition

Compiler Error C2880 __swi or __hvc requires a valid constant as first argument (SWI
number)

Compiler Error C2881 'identifier': is already used as an alias for 'class'

Compiler Error C2882 'identifier': illegal use of namespace identifier in expression

Compiler Error C2883 'function': function declaration conflicts with 'identifier'


introduced by using-declaration

Compiler Error C2884 'identifier': introduced by using-declaration conflicts with local


function 'function'

Compiler Error C2885 'class::identifier': not a valid using-declaration at non-class


scope

Compiler Error C2886 'class::identifier': symbol cannot be used in a member using-


declaration

Compiler Error C2887 __swi or __hvc cannot have more than five arguments (SWI
number, r0 - r3)

Compiler Error C2888 'identifier': symbol cannot be defined within namespace


'namespace'

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

Compiler Error C2893 Failed to specialize function template 'template'

Compiler Error C2894 templates cannot be declared to have 'C' linkage

Compiler Error C2895 'declaration': cannot explicitly instantiate a function template


that has been declared with dllimport

Compiler Error C2896 'function1': cannot use function template/generic 'function2'


as a function argument

Compiler Error C2897 a destructor/finalizer cannot be a function template

Compiler Error C2898 'declaration': member function templates cannot be virtual

Compiler Error C2899 Obsolete.


Compiler Error C2800
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' cannot be overloaded


The following operators cannot be overloaded: class member access ( . ), pointer to member ( .* ), scope
resolution ( :: ), conditional expression ( ? : ), and sizeof .
The following sample generates C2800:

// C2800.cpp
// compile with: /c
class C {
operator:: (); // C2800
};
Compiler Error C2801
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' must be a non-static member


The following operators can be overloaded only as nonstatic members:
Assignment =

Class member access ->

Subscripting []

Function call ()

Possible C2801 causes:


Overloaded operator is not a class, structure, or union member.
Overloaded operator is declared static .
The following sample generates C2801:

// 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

static member 'operator operator' has no formal parameters


An operator declared by a static member function must have at least one parameter.
The following sample generates C2802:

// 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

binary 'operator operator' has too many parameters


The overloaded binary operator member function is declared with more than one parameter. The first operand
parameter of a binary operator member function, whose type is the operator's enclosing type, is implied.

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

binary 'operator operator' has too few parameters


The binary operator has no parameters.
The following sample generates C2805:

// 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

'operator operator' has too many formal parameters


An overloaded operator has too many parameters.
The following sample generates C2806:

// 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

the second formal parameter to postfix 'operator operator' must be 'int'


The second parameter to a postfix operator has the wrong type.
The following sample generates C2807:

// 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

unary 'operator operator' has too many formal parameters


The unary operator has a nonvoid parameter list.
The following sample generates C2808:

// 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

'operator operator' has no formal parameters


The operator lacks required parameters.
The following sample generates C2809:

// 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

'interface' : an interface can only inherit from another interface


An interface may only inherit from another interface and may not inherit from a class or struct.
The following sample generates C2810:

// 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

#import is not supported with /clr:pure and /clr:safe

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

#import is not supported with /MP


C2813 is emitted if in a compiler command you specify the /MP compiler option and two or more files to compile,
and one or more of the files contains the#import preprocessor directive. The #import directive generates C++
classes from the types in the specified type library, and then writes those classes to two header files. The #import
directive is not supported because if multiple compilation units import the same type library, those units conflict
when they try to write the same header files at the same time.
This compiler error and the /MP compiler option are new in Visual Studio 2008.

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

return type for 'operator delete' must be 'void'


An overloaded operator delete function cannot return a value.
Compiler Error C2818
10/31/2018 • 2 minutes to read • Edit Online

application of overloaded 'operator ->' is recursive through type 'type'


A redefinition of the class member access operator contains a recursive return statement. To redefine the ->
operator with recursion, you must move the recursive routine to a separate function called from the operator
override function.
Compiler Error C2819
10/31/2018 • 2 minutes to read • Edit Online

type 'type' does not have an overloaded member 'operator ->'


You need to define operator->() to use this pointer operation.
The following sample generates C2819:

// 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

first formal parameter to 'operator new' must be 'unsigned int'


The first formal parameter of the operator new must be an unsigned int .

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

a typedef template is illegal

Templates are not allowed in typedef definitions.

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

return type for 'operator new' must be 'void *'


With non-based pointers, overloads of operator new must return void * .
The following sample generates C2824:

// 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

var : must be a class or namespace when followed by '::'


An unsuccessful attempt was made to form a qualified name.
For example, make sure that your code does not contain a function declaration where the function name begins
with ::.

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

'operator operator' cannot be globally overridden with unary form


The operator cannot have a unary form outside of an object.
To fix by using the following possible solutions
1. Make the overloaded operator local to an object.
2. Choose an appropriate unary operator to overload.
Compiler Error C2828
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' cannot be globally overridden with binary form


The operator cannot have a binary form outside of an object.
To fix by using the following possible solutions
1. Make the overloaded operator local to an object.
2. Choose an appropriate unary operator to overload.
Compiler Error C2829
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' cannot have a variable parameter list


Only two operators can take variable parameter lists:
Function call ()

new
Compiler Error C2830
10/31/2018 • 2 minutes to read • Edit Online

only placement parameters to 'operator new' can have default values


The standard formal parameters for operator new cannot have default values. Only user-defined placement
parameters can specify defaults.
Compiler Error C2831
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' cannot have default parameters


Only three operators can have default parameters:
new
Assignment =
Left parenthesis (
The following sample generates C2831:

// 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

'operator operator' is not a recognized operator or type


The word operator must be followed by an operator that you want to override or a type you want to convert.
For a list of the operators that you can define in a managed type, see User-defined Operators.
The following sample generates C2833:

// C2833.cpp
// compile with: /c
class A {};

void operator ::* (); // C2833


void operator :: (); // OK
Compiler Error C2834
10/31/2018 • 2 minutes to read • Edit Online

'operator operator' must be globally qualified


The new and delete operators are tied to the class where they reside. Scope resolution cannot be used to select a
version of new or delete from a different class. To implement multiple forms of the new or delete operator,
create a version of the operator with extra formal parameters.
Compiler Error C2835
10/31/2018 • 2 minutes to read • Edit Online

user-defined conversion 'type' takes no formal parameters


User-defined type conversions cannot take formal parameters.
The following sample generates C2835:

// 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

'member' : illegal qualified name in member declaration


A class, structure, or union uses a fully qualified name to redeclare a member of another class, structure, or union.
The following sample generates C2838:

// 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

invalid return type 'type' for overloaded 'operator ->'


The -> operator must return a class, struct, or union, or a reference to one.
Compiler Error C2842
11/8/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;
};

ref struct MyStruct {


static void sf() {}
void f() {}
};

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

void (__clrcall *F5)() = MyStruct::sf; // OK


void (__clrcall *F6)() = & ps->sf; // OK

interior_ptr<int> i = &C::m_i; // C2843


C ^x = gcnew C();
interior_ptr<int> ii = &x->m_i;
}
Compiler Error C2844
10/31/2018 • 2 minutes to read • Edit Online

'member' : cannot be a member of interface 'interface'


An interface class cannot contain a data member unless it is also a property.
Anything other than a property or member function is not allowed in an interface. Furthermore, constructors,
destructors, and operators are not allowed.
The following sample generates C2844:

// 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

'operator' : pointer arithmetic not allowed on this type


You cannot increment the pointer to a managed class.
Compiler Error C2846
10/31/2018 • 2 minutes to read • Edit Online

'constructor' : an interface cannot have a constructor


A Visual C++ interface cannot have a constructor.
The following sample generates C2846:

// 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

cannot apply sizeof to managed or WinRT type 'class'


The sizeof operator gets the value of an object at compile time. The size of a managed or WinRT class, interface, or
value type is dynamic and so cannot be known at compile time.
For example, the following sample generates C2847:

// 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

'destructor' : an interface cannot have a destructor


A Visual C++ interface cannot have a destructor.
The following sample generates C2849:

// 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

'construct' : only allowed at file scope; may not be in a nested construct


Constructs, such as some pragmas, can only appear at global scope.
The following sample generates C2850:

// 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

syntax error in #pragma hdrstop


The #pragma hdrstop gives an invalid filename. The pragma can be followed by an optional filename in
parentheses and quotation marks:
The following sample generates C2854:

// 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

command-line option 'option' inconsistent with precompiled header


The given command-line option differs from the option used to create the precompiled header. Regenerate the
precompiled header with the given command-line option.
Compiler Error C2856
10/31/2018 • 2 minutes to read • Edit Online

#pragma hdrstop cannot be inside an #if block


The hdrstop pragma cannot be placed inside the body of a conditional compilation block.
Move the #pragma hdrstop statement to an area that is not contained in an #if/#endif block.
Compiler Error C2857
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

'void' cannot be an argument type, except for '(void)'


Type void cannot be used as an argument type with other arguments.
The following sample generates C2860:

// 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

'function name' : an interface member function cannot be defined


The compiler encountered the interface keyword or deduced a struct as an interface but then found a member
function definition. An interface cannot contain a definition for a member function.

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);
};

HRESULT IMyInterface::mf(int a) {} // C2861


Compiler Error C2862
10/31/2018 • 2 minutes to read • Edit Online

'interface' : an interface can only have public members


Protected and private members may be accessed only from other member functions. Such members are no use in
an interface, since it may not provide implementations for any of its members.
The following sample will generate C2862:

// 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

'interface' : an interface cannot have friends


Declaring friends on an interface is not allowed.
The following sample generates C2863:

// C2863.cpp
// compile with: /c
#include <unknwn.h>

class CMyClass {
void *f();
};

__interface IMyInterface {
void g();

friend int h(); // 2863


friend interface IMyInterface1; // C2863
friend void *CMyClass::f(); // C2863
};
Compiler Error C2864
10/31/2018 • 2 minutes to read • Edit Online

'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
};

This sample shows how to fix 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
};

// Initialize static volatile, non-const, or non-integral


// data members when defined, not when declared:
int C::b = 3;
volatile int C::c = 3;
volatile const int C::d = 3;
const double C::f = 3.33;
Compiler Error C2865
10/31/2018 • 2 minutes to read • Edit Online

'function' : illegal comparison for handle_or_pointer


You can compare references to Classes and Structs or managed reference types only for equality to see if they refer
to the same object (==) or to different objects (!=).
You cannot compare them for ordering because the .NET runtime might move managed objects at any time,
changing the outcome of the test.
Compiler Error C2867
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : is not a namespace


A using directive is applied to something other than a namespace.
The following sample generates C2867:

// 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

'identifier' : illegal syntax for using-declaration; expected qualified-name

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

'name' : has already been defined to be a namespace


You cannot reuse a name already used as a namespace.
The following sample generates C2869:

// C2869.cpp
// compile with: /c
namespace A { int i; };

class A {}; // C2869, A is already used


Compiler Error C2870
10/31/2018 • 2 minutes to read • Edit Online

'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

'name' : a namespace with this name does not exist


This error will occur when you pass an identifier that is not a namespace to a using directive.

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

'symbol' : ambiguous symbol


The compiler cannot determine which symbol you are referring to. More than one symbol with the specified name
is in scope. See the notes following the error message for the file locations and declarations the compiler found for
the ambiguous symbol. To fix this issue, you can fully qualify the ambiguous symbol by using its namespace, for
example, std::byte or ::byte . You can also use a namespace alias to give an included namespace a convenient
short name for use when disambiguating symbols in your source code.
C2872 can occur if a header file includes a using directive, and a subsequent header file is included that contains a
type that is also in the namespace specified in the using directive. Specify a using directive only after all your
header files are specified with #include .
C2872 can occur in Visual Studio 2013 due to a conflict between the Windows::Foundation::Metadata::Platform
enum type and the C++/CX-defined Platform namespace. To work around this problem, follow these steps:
Remove the "using namespace Windows::Foundation::Metadata" clause from the project files.
Specify the fully qualified name for any type that is included in this namespace.

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

'symbol' : symbol cannot be used in a using-declaration


A using directive is missing a namespace keyword. This causes the compiler to misinterpret the code as a using
declaration rather than a using directive.
Compiler Error C2874
10/31/2018 • 2 minutes to read • Edit Online

using-declaration causes a multiple declaration of 'symbol'


The declaration causes the same item to be defined twice.
The following sample generates C2874:

// 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

using-declaration causes a multiple declaration of 'class::identifier'


The declaration causes the same item to be defined twice.
The following sample generates C2875:

// 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

'class::symbol' : not all overloads are accessible


All overloaded forms of a function in a base class must be accessible to the derived class.
The following sample generates C2876:

// 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

'symbol' is not accessible from 'class'


All members derived from a base class must be accessible in the derived class.
The following sample generates C2877:

// 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

'name' : a namespace or class of this name does not exist


You made reference to a namespace or class that is not defined.
The following sample generates C2878:

// 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

'namespace1' : is already used as an alias for 'namespace2'


You cannot use the same name as an alias for two namespaces.
The following sample generates C2881:

// 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

'name' : illegal use of namespace identifier in expression


You tried to use the name of a namespace in an expression.
The following sample generates C2882:

// C2882.cpp
// compile with: /c
namespace A {
int k;
}

int i = A; // C2882, can't assign A to i


Compiler Error C2883
10/31/2018 • 2 minutes to read • Edit Online

'name' : function declaration conflicts with 'identifier' introduced by using-declaration


You tried to define a function more than once. The first definition was made from a namespace with a using
declaration. The second was a local definition.
The following sample generates C2883:

// 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

'name' : introduced by using-declaration conflicts with local function 'function'


You tried to define a function more than once. The first definition is a local definition. The second is from a
namespace with a using declaration.
The following sample generates C2884:

// 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

'class::identifier' : not a valid using-declaration at non-class scope


You used a using declaration incorrectly.

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;

typedef MyStruct::X1 abc;


abc X13;
X13.i = 9;
}

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

'class::identifier' : symbol cannot be used in a member using-declaration


A using declaration uses a symbol, such as a namespace name. A using declaration is for declaring base class
members.
The following sample generates C2886:

// 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

// OK: B is a base class


using B::i;
};
Compiler Error C2888
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : symbol cannot be defined within namespace 'namespace'


A symbol belonging to namespace A must be defined in a namespace that encloses A.
The following sample generates C2888:

// C2888.cpp
// compile with: /c
namespace M {
namespace N {
void f1();
void f2();
}

void N::f1() {} // OK: namspace M encloses N


}

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

'parameter' : cannot take the address of a template parameter


You can't take the address of a template parameter unless it is an lvalue. Type parameters are not lvalues because
they have no address. Non-type values in template parameter lists that are not lvalues also do not have an address.
This is an example of code that causes Compiler Error C2891, because the value passed as the template parameter
is a compiler-generated copy of the template argument.

template <int i> int* f() { return &i; }

Template parameters that are lvalues, such as reference types, can have their address taken.

template <int& r> int* f() { return &r; }

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

local class shall not have member templates


Templated member functions are not valid in a class that is defined in a function.
The following sample generates C2892:

// C2892.cpp
int main() {
struct local {
template<class T> // C2892
void f() {}
};
}
Compiler Error C2893
10/31/2018 • 2 minutes to read • Edit Online

Failed to specialize function template 'template name'


The compiler failed to specialize a function template. There can be many causes for this error.
In general, the way to resolve a C2893 error is to review the function's signature and make sure you can instantiate
every type.

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

templates cannot be declared to have 'C' linkage


This error can be caused by a template defined inside an extern "C" block.
The following sample generates C2894:

// C2894.cpp
extern "C" {
template<class T> class stack {}; // C2894 fail

template<class T> void f(const T &aT) {} // C2894


}

The following sample generates C2894:

// C2894b.cpp
// compile with: /c
extern "C" template<class T> void f(const T &aT) {} // C2894

template<class T> void f2(const T &aT) {} // OK


Compiler Error C2896
10/31/2018 • 2 minutes to read • Edit Online

'function1' : cannot use function template 'function2' as argument


A function template cannot be an argument to another function template.
The following sample generates C2896:

// 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
}

C2896 can also occur when you use generics:

// 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

a destructor/finalizer cannot be a function template


Destructors or finalizers cannot be overloaded, so declaring a destructor as a template (which would define a set of
destructors) is not allowed.
The following sample generates C2897:

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

'declaration' : member function templates cannot be virtual


The following sample generates C2898:

// 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 C2900 'declarator': member function templates in WinRT classes


must be 'private', 'internal' or 'protected private'

Compiler Error C2901 'identifier': A generic interface or delegate cannot be public

Compiler Error C2902 'token': unexpected token following 'template/generic',


identifier expected

Compiler Error C2903 'identifier': symbol is neither a class template/generic nor a


function template/generic

Compiler Error C2904 'identifier': name already used for a template in the current
scope
ERROR MESSAGE

Compiler Error C2905 Obsolete.

Compiler Error C2906 'template': explicit specialization requires 'template <>'

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 C2909 'identifier': explicit instantiation of function template requires


return type

Compiler Error C2910 'function': cannot be explicitly specialized

Compiler Error C2911 'member': cannot be declared or defined in the current scope

Compiler Error C2912 explicit specialization 'declaration' is not a specialization of a


function template

Compiler Error C2913 explicit specialization; 'declaration' is not a specialization of a


class template

Compiler Error C2914 'identifier': cannot deduce template/generic argument as


function argument is ambiguous

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 C2916 'identifier': [FlagsAttribute] must (only) be specified on a public


enum with an 'unsigned int' underlying type

Compiler Error C2917 'identifier': invalid template-parameter

Compiler Error C2918 'identifier': Indexed properties cannot be used on the


published surface of a WinRT 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 C2921 redefinition: 'type': class template/generic is being redeclared


as 'declaration'

Compiler Error C2922 'interface': A WinRT interface cannot contain static members

Compiler Error C2923 'type': 'identifier' is not a valid template/generic type


argument for parameter 'parameter'

Compiler Error C2924 __declspec(interrupt) routine argument not in R2


ERROR MESSAGE

Compiler Error C2925 __declspec(interrupt) routine cannot use floating-point

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 C2930 'class': template-id/generic-id redefined as an enumerator of


'enum identifier'

Compiler Error C2931 'class1': template-id/generic-id redefined as a member


function of 'class2'

Compiler Error C2932 'type': template-id/generic-id redefined as a data member of


'identifier'

Compiler Error C2933 'type': template-id/generic-id redefined as a typedef member


of 'identifier'

Compiler Error C2934 'type': template-id/generic-id redefined as a nested 'item' of


'identifier'

Compiler Error C2935 'type': template-id/generic-id redefined as a global function

Compiler Error C2936 'type': template-id/generic-id redefined as a global data


variable

Compiler Error C2937 'type': template-id/generic-id redefined as a global typedef

Compiler Error C2938 'identifier' : Failed to specialize alias template

Compiler Error C2939 'type': template-id/generic-id redefined as a local data variable

Compiler Error C2940 'type': template-id/generic-id redefined as a local typedef

Compiler Error C2941 'type': template-id/generic-id redefined as a local 'item'

Compiler Error C2942 'type': template-id/generic-id redefined as a formal argument


of a function

Compiler Error C2943 'type': template-id/generic-id redefined as a type argument of


a template

Compiler Error C2944 'type': template-id/generic-id redefined as a value argument of


a template
ERROR MESSAGE

Compiler Error C2945 explicit instantiation does not refer to a template-class


specialization

Compiler Error C2946 explicit instantiation; 'type' is not a template-class


specialization

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 C2949 thread_local is not supported with /kernel

Compiler Error C2950 Obsolete.

Compiler Error C2951 template/generic declarations are only permitted at global,


namespace, or class scope

Compiler Error C2952 'declaration': template/generic declaration missing


template/generic parameter list

Compiler Error C2953 'type': class template has already been defined

Compiler Error C2954 instruction word argument not in range

Compiler Error C2955 'type': use of class template/generic requires template/generic


argument list

Compiler Error C2956 sized deallocation function 'operator delete(void*, size_t)'


would be chosen as placement deallocation function.

Compiler Error C2957 'token': invalid left delimiter: expected '<'

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 C2960 Obsolete.

Compiler Error C2961 'function': inconsistent explicit instantiations, a previous explicit


instantiation did not specify 'argument'

Compiler Error C2962 syntax error: 'token': expected template-class member


function definition to end with '}'

Compiler Error C2963 Obsolete.

Compiler Error C2964 Obsolete.

Compiler Error C2965 __declspec(specifier) is not supported with /kernel


ERROR MESSAGE

Compiler Error C2966 'identifier1': must have the same __declspec(code_seg(...)) as


its base class 'identifier2'

Compiler Error C2967 'identifier': an overriding virtual function must have the same
__declspec(code_seg(...)) as an overridden virtual function

Compiler Error C2968 'identifier': recursive alias declaration

Compiler Error C2969 syntax error: 'token': expected member function definition to
end with '}'

Compiler Error C2970 'type': template parameter 'parameter': 'argument': an


expression involving objects with internal linkage cannot be
used as a non-type argument

Compiler Error C2971 'type': template parameter 'parameter': 'argument': a variable


with non-static storage duration cannot be used as a non-
type argument

Compiler Error C2972 'type': template parameter 'parameter': the type of non-type
argument is invalid

Compiler Error C2973 'template': invalid template argument 'number'

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 C2976 'type': too few template/generic arguments

Compiler Error C2977 'type': too many template/generic arguments

Compiler Error C2978 syntax error: expected 'keyword1' or 'keyword2'; found type
'type'; non-type parameters are not supported in generics

Compiler Error C2979 explicit specializations 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 C2982 'declaration': different __declspec(code_seg(...)) used: was


'identifier1' now 'identifier2'

Compiler Error C2983 'declaration': all declarations must have an identical


__declspec(code_seg(...))

Compiler Error C2984 Obsolete.

Compiler Error C2985 'argument': the argument to __declspec(code_seg(...)) must be


a text section
ERROR MESSAGE

Compiler Error C2986 'identifier': __declspec(code_seg(...)) can only be applied to a


class or a function

Compiler Error C2987 a declaration cannot have both


__declspec(code_seg('identifier')) and
__declspec(code_seg('value'))

Compiler Error C2988 unrecognizable template declaration/definition

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 C2991 redefinition of template/generic parameter 'parameter'

Compiler Error C2992 'class': invalid or missing template/generic parameter list

Compiler Error C2993 'type': illegal type for non-type template parameter 'identifier'

Compiler Error C2994 unnamed class in template parameter list

Compiler Error C2995 'declaration': function template has already been defined

Compiler Error C2996 'function': recursive function template definition

Compiler Error C2997 'function': array bound cannot be deduced from a default
member initializer

Compiler Error C2998 'declarator': cannot be a template definition

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

'token' : unexpected token following 'template', identifier expected


The token following the keyword template was not an identifier.
The following sample generates C2902:

// 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
}

C2902 can also occur when using generics:

// 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

'identifier' : symbol is neither a class template nor a function template


Code attempts explicit instantiation of something that is not a template.
The following sample generates C2903:

// 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
}

C2903 can also occur when using generics:

// 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

'identifier' : name already used for a template in the current scope


Check the code for duplicate names.
The following sample generates C2904:

// 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

'specialization' : explicit specialization requires 'template <>'


You must use the new syntax for explicit specialization of templates.
The following sample generates C2906:

// 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

explicit specialization; 'template' has already been instantiated


A specialization of the primary template occurs before the explicit specialization.
The following sample generates C2908:

// C2908.cpp
// compile with: /c
template<class T> class X {};

void f() {
X<int> x; //specialization and instantiation
//of X<int>
}

template<> class X<int> {} // C2908, explicit specialization


Compiler Error C2909
10/31/2018 • 2 minutes to read • Edit Online

'identifier': explicit instantiation of function template requires return type


An explicit instantiation of a function template requires explicit specification of its return type. Implicit return type
specification does not work.
The following sample generates C2909:

// 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

'function' : cannot be explicitly specialized


The compiler detected an attempt to explicitly specialize a function twice.
The following sample generates C2910:

// C2910.cpp
// compile with: /c
template <class T>
struct S;

template <> struct S<int> { void f() {} };


template <> void S<int>::f() {} // C2910 delete this specialization

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);
};

template <> struct A<void> {


A(void* p);
};

template <class T>


inline A<T>::A(T* p) {}

template <> A<void>::A(void* p){} // C2910


// try the following line instead
// A<void>::A(void* 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 <> .

The following sample generates C2910:


// C2910c.cpp
// compile with: /c
template <class T> class A {
void f();
};

template <> class A<int> {


void f();
};

template <> void A<int>::f() {} // C2910


// try the following line instead
// void A<int>::f(){} // OK
Compiler Error C2911
10/31/2018 • 2 minutes to read • Edit Online

'member' : cannot be declared or defined in the current scope


Inside a namespace, class, or function, you can only define a member of the same namespace, class, or function or
a member that is enclosed by the same namespace, class, or function.
The following sample generates C2911:

// 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

explicit specialization 'declaration' is not a specialization of a function template


You cannot specialize a non-template function.
The following sample generates C2912:

// 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

// attempted explicit specialization


template <> CF(const char* p) {} // C2912

// try the following line instead


// template <> CF(const char& p) {}
};
Compiler Error C2913
10/31/2018 • 2 minutes to read • Edit Online

explicit specialization; 'declaration' is not a specialization of a class template


You cannot specialize a non-template class.
The following sample generates C2913:

// C2913.cpp
// compile with: /c
class X{};
template <class T> class Y{};

template<> class X<int> {}; // C2913


template<> class Y<int> {};
Compiler Error C2914
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : cannot deduce type argument as function argument is ambiguous


The compiler cannot determine which overloaded functions to use for a generic or template argument.
The following sample generates C2914:

// 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));

void h() { gf(f);} // C2914


// try the following line instead
void h() { gf<int>(f); }
Compiler Error C2917
10/31/2018 • 2 minutes to read • Edit Online

'name' : invalid template-parameter


A template parameter list contains an identifier that was not a template parameter.

Example
The following sample generates C2917.

// C2917.cpp
// compile with: /c
template<class T> class Vector {
void sort();
};

template<class T*> void Vector<T>::sort() {} // C2917


// try the following line instead
// template<class T> void Vector<T>::sort() {}
Compiler Error C2918
10/31/2018 • 2 minutes to read • Edit Online

'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

'type': Operators cannot be used on the published surface of a WinRT type


The Windows Runtime type system does not support operator member functions in the published surface of a
type. This is because not all languages can consume operator member functions. You can create private or internal
operator member functions that can be called from C++ code in the same class or compilation unit.
To fix this issue, remove the operator member function from the public interface, or change it to a named member
function. For example, instead of operator== , name the member function Equals .
Compiler Error C2920
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

C2920 can also occur when using generics:

// 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

redefinition : 'class' : class template or generic is being redeclared as 'type'


A generic or template class has multiple declarations that 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 C2921:

// 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

C2921 can also occur when using generics.

// 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
}

C2923 can also occur when using generics:

// 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

'function' : a function template must be called with at least one argument


You cannot call a template function without arguments. The type of the template arguments determines what
version of the function to generate.
Compiler Error C2928
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();

extern template A<int>::A(); // C2929


Compiler Error C2930
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as an enumerator of 'enum identifier'


You cannot use a generic or template class as a member of an enumeration.
This error can be caused if braces are improperly matched.
The following sample generates C2930:

// C2930.cpp
// compile with: /c
template<class T>
class x{};
enum SomeEnum { x }; // C2930

class y{};
enum SomeEnum { y };

C2930 can also occur when using generics:

// C2930c.cpp
// compile with: /clr /c
generic<class T>
ref struct GC {};
enum SomeEnum { GC }; // C2930

ref struct GC2 {};


enum SomeEnum2 { GC2 };
Compiler Error C2931
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as a member function of 'identifier'


You cannot use a generic or template class as a member function of another class.
This error can be caused if braces are improperly matched.
The following sample generates C2931:

// C2931.cpp
// compile with: /c
template<class T>
struct TC { };
struct MyStruct {
void TC<int>(); // C2931
};

struct TC2 { };
struct MyStruct2 {
void TC2();
};

C2931 can also occur when using generics:

// 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

'class' : type-class-id redefined as a data member of 'identifier'


You cannot use a generic or template class as a data member.
The following sample generates C2932:

// C2932.cpp
// compile with: /c
template<class T>
struct TC {};

struct MyStruct {
int TC<int>; // C2932
int TC; // OK
};

C2932 can also occur when using generics:

// 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

'class' : type-class-id redefined as a typedef member of 'identifier'


You cannot use a generic or template class as a typedef member.
The following sample generates C2933:

// C2933.cpp
// compile with: /c
template<class T> struct TC { };
struct MyStruct {
typedef int TC<int>; // C2933
};

struct TC2 { };
struct MyStruct2 {
typedef int TC2;
};

C2933 can also occur when using generics:

// C2933b.cpp
// compile with: /clr /c
generic<class T> ref struct GC { };
struct MyStruct {
typedef int GC<int>; // C2933
};

ref struct GC2 { };


struct MyStruct2 {
typedef int GC2;
};
Compiler Error C2934
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as a nested 'item' of 'identifier'


You cannot use a generic or template class as a nested item.
Compiler Error C2935
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as a global function


You cannot use a generic or template class as a global function.
This error can be caused if braces are improperly matched.
The following sample generates C2935:

// C2935.cpp
// compile with: /c
template<class T>
struct TC {};
void TC<int>() {} // C2935

// OK
struct TC2 {};
void TC2() {}

C2935 can also occur when using generics:

// 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

'class' : type-class-id redefined as a global data variable


You cannot use a generic or template class as a global data variable.
This error can be caused if braces are improperly matched.
The following sample generates C2936:

// C2936.cpp
// compile with: /c
template<class T> struct TC { };
int TC<int>; // C2936

// OK
struct TC2 { };
int TC2;

C2936 can also occur when using generics:

// 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

'class' : type-class-id redefined as a global typedef


You cannot use a generic or template class as a global typedef .
The following sample generates C2937:

// C2937.cpp
// compile with: /c
template<class T>
struct TC { };
typedef int TC<int>; // C2937
typedef TC<int> c; // OK

C2937 can also occur when using generics:

// 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

'class' : type-class-id redefined as a local data variable


You cannot use a generic or template class as a local data variable.
This error can be caused if braces are improperly matched.
The following sample generates C2939:

// C2939.cpp
template<class T>
struct TC { };
int main() {
int TC<int>; // C2939
int TC; // OK
}

C2939 can also occur when using generics:

// 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

'class' : type-class-id redefined as a local typedef


You cannot use a generic or template class as a local typedef .
The following sample generates C2940:

// C2940.cpp
template<class T>
struct TC {};
int main() {
typedef int TC<int>; // C2940
typedef int TC; // OK
}

C2940 can also occur when using generics:

// 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

'class' : type-class-id redefined as a local 'item'


You cannot use a generic or template class as an item.
Compiler Error C2942
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as a formal argument of a function


You cannot use a generic or template class as a formal argument. You cannot pass an argument directly to the
constructor of a generic or template class.
The following sample generates C2942:

// C2942.cpp
// compile with: /c
template<class T>
struct TC {};
void f(int TC<int>) {} // C2942

// OK
struct TC2 {};
void f(TC2 i) {}

C2942 can also occur when using generics:

// 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

'class' : type-class-id redefined as a type argument of a template


You cannot use a generic or template class, instead of a symbol, as a generic or template type argument.
The following sample generates C2943:

// C2943.cpp
// compile with: /c
template<class T>
class List {};

template<class List<int> > class MyList; // C2943


template<class T > class MyList;
Compiler Error C2944
10/31/2018 • 2 minutes to read • Edit Online

'class' : type-class-id redefined as a value argument of a template


You cannot use a generic or template class, instead of a symbol, as a template value argument.
The following sample generates C2944:

// C2944.cpp
// compile with: /c
template<class T>
class TC { };

template <int TC<int> > struct X1 { }; // C2944

template <class T > struct X2 {};

C2944 can also occur when using generics:

// C2944b.cpp
// compile with: /clr /c
generic<class T>
ref class GC {};

template <int GC<int> > struct X2 { }; // C2944


template <class T> struct X3 {}; // OK
Compiler Error C2945
10/31/2018 • 2 minutes to read • Edit Online

explicit instantiation does not refer to a template-class specialization


You cannot explicitly instantiate something that is not templated.
Compiler Error C2946
10/31/2018 • 2 minutes to read • Edit Online

explicit instantiation; 'class' is not a template-class specialization


You cannot explicitly instantiate a nontemplated class.

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

expecting '>' to terminate construct, found 'syntax'


A generic or template argument list may not have been terminated correctly.
C2947 can also be generated by syntax errors.
The following sample generates C2947:

// 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

explicit instantiation; storage class specifier 'specifier' not permitted on specialization


You cannot use storage-class specifiers (such as extern ) in a specialization of a template class that was previously
explicitly instantiated.
Compiler Error C2951
10/31/2018 • 2 minutes to read • Edit Online

type declarations are only permitted at global, namespace, or class scope


You cannot declare a generic or template class outside global or namespace scope. If you make your generic or
template declarations in an include file, make sure the include file is at global scope.
The following sample generates C2951:

// C2951.cpp
template <class T>
class A {};

int main() {
template <class T> // C2951
class B {};
}

C2951 can also occur when using generics:

// 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

'declaration' : type declaration missing template parameter list


A template declaration was ill formed.
The following sample generates C2952:

// C2952.cpp
// compile with: /c
template <class T>
struct S {
template <class T1>
struct S1 {
void f();
};
};

template <class T> void S<T>::S1<T>::f() {} // C2952

// OK
template <class T>
template <class T1>
void S<T>::S1<T1>::f() {}

C2952 can also occur when using generics:

// C2952b.cpp
// compile with: /clr /c
generic <class T>
ref struct GC {
generic <class T1>
ref struct GC1 {
void f();
};
};

generic <class T> void GC<T>::GC1<T>::f() {} // C2952

// 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

'identifier' : class template has already been defined


Check the source file and include files for other definitions.
The following sample generates C2953:

// 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();
};

void CT::CTFunc() {} // C2955

// OK - this is how to fix it


template <class T>
void CT<T>::CTFunc2() {}

C2955 can also occur when using generics:

// 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.

template <class T> class ListNode;


template <class T> using ListNodeMember = ListNode<T> T::*;
template <class T, ListNodeMember M> class ListHead; // C2955: 'ListNodeMember': use of alias
// template requires template argument list

// correct: template <class T, ListNodeMember<T> M> class ListHead;


Compiler Error C2957
10/31/2018 • 2 minutes to read • Edit Online

'delim' : invalid left delimiter : expected '<'


A generic class was ill formed.
The following sample generates C2957:

// 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

the left delimiter found at 'location' was not matched correctly


A delimiter is not properly matched.
This error can be caused by mismatched parenthesis in a function template declaration.
Compiler Error C2959
10/31/2018 • 2 minutes to read • Edit Online

a generic class or function may not be a member of a template


For more information, see Windows Runtime and Managed Templates and Generics.

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;

template <int i>


class X {};

template <int *pi>


class Y {};

X<si> anX; // C2970 cannot use static variable in templates

// this would also work


const int i = 10;
X<i> anX2;
Compiler Error C2971
10/31/2018 • 2 minutes to read • Edit Online

'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

invalid template argument 'number'


Check the template definition to find the correct types.
Compiler Error C2974
10/31/2018 • 2 minutes to read • Edit Online

invalid type argument 'number', type expected


The generic or template argument does not match the generic or template declaration. A type should appear
within the angle brackets. Check the generic or template definition to find the correct types.
The following sample generates C2974:

// C2974.cpp
// C2974 expected
template <class T>
struct TC {};

template <typename T>


void tf(T){}

int main() {
// Delete the following 2 lines to resolve
TC<1>* tc;
tf<"abc">("abc");

TC<int>* tc;
tf<const char *>("abc");
}

C2974 can also occur when using generics:

// C2974b.cpp
// compile with: /clr
// C2974 expected
using namespace System;
generic <class T>
ref struct GCtype {};

generic <typename T>


void gf(T){}

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

'identifier' : too few type arguments


A generic or template is missing one or more actual arguments. Check the generic or template declaration to find
the correct number of parameters.
This error can be caused by missing template arguments in C++ Standard Library components.
The following sample generates C2976:

// C2976.cpp
template <class T>
struct TC {
T t;
};
int main() {
TC<>* t; // C2976
TC<int>* t2; // OK
}

C2976 can also occur when using generics:

// 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

'identifier' : too many type arguments


A generic or template has too many actual arguments. Check the generic or template declaration to find the correct
number of parameters.
The following sample generates C2977:

// C2977.cpp
// compile with: /c
template<class T, int i>
class MyClass {};

template MyClass< int , 1, 1 >; // C2977


template MyClass< int , 1 >; // OK

C2977 can also occur when using generics:

// C2977b.cpp
// compile with: /clr
// C2977 expected
generic <class T, class U>
void f(){}

generic <class T>


ref struct GC1 {};

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

explicit specializations are not supported in generics


A generic class was declared incorrectly. See Generics for more information.

Example
The following sample generates C2979.

// C2979.cpp
// compile with: /clr /c
generic <>
ref class Utils {}; // C2979 error

generic <class T>


ref class Utils2 {}; // OK
Compiler Error C2988
10/31/2018 • 2 minutes to read • Edit Online

unrecognizable template declaration/definition


The template declaration does not parse correctly. Check delimiters.
Compiler Error C2989
10/31/2018 • 2 minutes to read • Edit Online

'class' : class type has already been declared as a non-class type


The class generic or template redefines a non-template or non-generic class. Check header files for conflicts.
The following sample generates C2989:

// C2989.cpp
// compile with: /c
class C{};

template <class T>


class C{}; // C2989
class C2{};

C2989 can also occur when using generics:

// C2989b.cpp
// compile with: /clr /c
ref class GC1;

generic <typename T> ref class GC1; // C2989


template <typename T> ref class GC2;

generic <typename T> ref class GC2; // C2989


generic <typename T> ref class GCb;
template <typename T> ref class GC2;
generic <typename T> ref class GCc;
Compiler Error C2990
10/31/2018 • 2 minutes to read • Edit Online

'class' : non-class type as already been declared as a class type


The non generic or template class redefines a generic or template class. Check header files for conflicts.
The following sample generates C2990:

// C2990.cpp
// compile with: /c
template <class T>
class C{};
class C{}; // C2990

C2990 can also occur when using generics:

// C2990b.cpp
// compile with: /clr /c
generic <class T>
ref struct GC;

ref struct GC {}; // C2990

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

redefinition of type parameter 'parameter'


There was a type conflict between two generic or template definitions of parameter . When defining multiple
generic or template parameters, you must use equivalent types.
The following sample generates C2991:

// 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 {};

C2991 can also occur when using generics:

// 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

'class' : invalid or missing type parameter list


The class is preceded by a template or generic keyword with missing or invalid parameters.

Example
The following sample generates C2992:

// C2992.cpp
// compile with: /c
template <class T>
struct TC1 {
template <class U>
struct TC2;
};

template <class T> struct TC1<T>::TC2 {}; // C2992

// 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;
};

generic <class T> ref struct GC1<T>::GC2 {}; // C2992

// OK
generic <class T>
generic <class U>
ref struct GC1<T>::GC2 {};
Compiler Error C2993
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : illegal type for non-type template parameter 'parameter'


You cannot declare a template with a structure or union argument. Use pointers to pass structures and unions as
template parameters.
The following sample generates C2993:

// C2993.cpp
// compile with: /c
// C2993 expected
struct MyStruct {
int a;char b;
};

template <class T, struct MyStruct S> // C2993

// try the following line instead


// template <class T, struct MyStruct * S>
class CMyClass {};

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

unnamed class in template parameter list


You cannot use the class keyword as a template argument without specifying a class name.
Compiler Error C2995
10/31/2018 • 2 minutes to read • Edit Online

'function' : function template has already been defined


Make sure that there is only one definition for each member function of a templated class.
The following sample generates C2995:

// C2995.cpp
// compile with: /c
template <class T>
void Test(T x){}

template <class T> void Test(T x){} // C2995


template <class T> void Test2(T x){} // OK
Compiler Error C2996
10/31/2018 • 2 minutes to read • Edit Online

'function' : recursive function template definition


A function definition attempts to instantiate its root templated class. Recursive template instantiations are not
allowed.
Compiler Error C2998
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : cannot be a template definition


The compiler could not process the syntax used in the template definition.
The following sample generates C2998:

// 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 C3000 Obsolete.

Compiler Error C3001 'message': expected an OpenMP directive name

Compiler Error C3002 'name1 name2': multiple OpenMP directive names

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 C3005 'message': unexpected token encountered on OpenMP


'directive' directive
ERROR MESSAGE

Compiler Error C3006 'clause': clause on OpenMP 'directive' directive is missing an


expected argument

Compiler Error C3007 'clause': clause on OpenMP 'directive' directive does not take
an argument

Compiler Error C3008 'argument': argument is missing closing ')' on OpenMP


'directive' directive

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 C3021 'argument': argument is empty on OpenMP 'directive'


directive

Compiler Error C3022 'directive': invalid schedule kind of 'directive' on OpenMP


'directive' directive

Compiler Error C3023 'argument': unexpected token encountered in argument to


OpenMP 'directive' clause

Compiler Error C3024 'schedule(runtime)': chunk_size expression is not allowed

Compiler Error C3025 'clause': integral expression expected

Compiler Error C3026 'clause': constant expression must be positive


ERROR MESSAGE

Compiler Error C3027 'clause': arithmetic or pointer expression expected

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 C3030 'identifier': variable in 'directive' clause/directive cannot have


reference type

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 C3037 'identifier': variable in 'clause' clause must be shared in


enclosing context

Compiler Error C3038 'identifier': variable in 'private' clause cannot be a reduction


variable in enclosing context

Compiler Error C3039 'identifier': index variable in OpenMP 'for' statement cannot
be a reduction variable

Compiler Error C3040 'identifier': type of variable in 'reduction' clause is incompatible


with reduction operator 'operator'

Compiler Error C3041 'identifier': variable in 'copyprivate' clause must be private in


enclosing context

Compiler Error C3042 'copyprivate' and 'nowait' clauses cannot appear together on
OpenMP 'directive' directive

Compiler Error C3043 OpenMP 'critical' directive cannot be nested in 'critical'


directive with same name

Compiler Error C3044 'section': only allowed directly nested under an OpenMP
'sections' directive
ERROR MESSAGE

Compiler Error C3045 Expected a compound statement following OpenMP 'sections'


directive. Missing '{'

Compiler Error C3046 Missing structured block in an OpenMP '#pragma omp


sections' region

Compiler Error C3047 Structured block in an OpenMP 'sections' region must be


preceded by '#pragma omp section'

Compiler Error C3048 Expression following '#pragma omp atomic' has improper form

Compiler Error C3049 'argument': invalid argument in OpenMP 'default' clause

Compiler Error C3050 'class': a ref class cannot inherit from 'identifier'

Compiler Error C3051 Obsolete.

Compiler Error C3052 'identifier': variable doesn't appear in a data-sharing clause


under a default(none) clause

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 C3055 'identifier': symbol cannot be referenced before it is used in


'threadprivate' directive

Compiler Error C3056 'identifier': symbol is not in the same scope with
'threadprivate' directive

Compiler Error C3057 'identifier': dynamic initialization of 'threadprivate' symbols is


not currently supported

Compiler Error C3058 'identifier': symbol not declared as 'threadprivate' before it is


used in the 'copyin' clause

Compiler Error C3059 'identifier': 'threadprivate' symbol cannot be used in the


'clause' clause

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 C3064 'identifier': must be a simple type or resolve to one

Compiler Error C3065 property declaration at non-class scope is not allowed

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 C3072 operator 'operator' cannot be applied to an instance of a ref


class use the unary '%' operator to convert an instance of a ref
class to a handle type

Compiler Error C3073 'identifier': ref class does not have a user-defined copy
constructor

Compiler Error C3074 an array cannot be initialized with a parenthesized initializer

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 C3077 'identifier': a finalizer can only be a member of a reference


type

Compiler Error C3078 array size must be specified in new expressions

Compiler Error C3079 an initializer list cannot be used as the right operand of this
assignment operator

Compiler Error C3080 'finalizer': a finalizer cannot have a storage-class-specifier

Compiler Error C3081 Obsolete.

Compiler Error C3082 Obsolete.

Compiler Error C3083 'identifier': the symbol to the left of a '::' must be a type

Compiler Error C3084 'identifier': a destructor/finalizer cannot be 'keyword'


ERROR MESSAGE

Compiler Error C3085 'identifier': a constructor cannot be 'keyword'

Compiler Error C3086 cannot find 'std::initializer_list': you need to #include


<initializer_list>

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 C3090 'class': attribute class cannot be a template

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'

Compiler Error C3094 'attribute': anonymous usage not allowed

Compiler Error C3095 'attribute': attribute cannot be repeated

Compiler Error C3096 'attribute': attribute is allowed on data members of attribute


classes only

Compiler Error C3097 'attribute': attribute must be scoped with 'assembly:' or


'module:'

Compiler Error C3098 'identifier': attribute has no user-defined constructors

Compiler Error C3099 'keyword': use


[System::AttributeUsageAttribute]/[Windows::Foundation::Met
adata::AttributeUsageAttribute] for managed/WinRT attributes
Compiler Error C3001
10/31/2018 • 2 minutes to read • Edit Online

'error_text' : expected an OpenMP directive name


The omp pragma must be followed by a directive.
The following sample generates C3001:

// C3001.c
// compile with: /openmp
int main()
{
#pragma omp // C3001 missing token
}
Compiler Error C3002
10/31/2018 • 2 minutes to read • Edit Online

'name1 name2' : multiple OpenMP directive names


Multiple directive names are not allowed.
The following sample generates C3002:

// C3002.c
// compile with: /openmp
int main()
{
#pragma omp parallel single // C3002
}
Compiler Error C3003
10/31/2018 • 2 minutes to read • Edit Online

'directive' : OpenMP directive name not allowed after directive clauses


An OpenMP directive name cannot follow an OpenMP directive clause.
The following sample generates C3003:

// 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

'clause' : clause not valid on OpenMP 'directive' directive


An OpenMP clause was used on a directive for which it is not enabled.
The following sample generates C3004:

// C3004.c
// compile with: /openmp
int main()
{
int x, y, z;

// Shared clause not allowed for 'single' directive.


#pragma omp single shared(x, y) // C3004

x = y;
}
Compiler Error C3005
10/31/2018 • 2 minutes to read • Edit Online

'error_text' : unexpected token encountered on OpenMP 'directive' directive


An OpenMP directive was ill formed.
The following sample generates C3005:

// 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

'clause' : clause on OpenMP 'directive' directive is missing an expected argument


An OpenMP directive did not have an expected argument.
The following sample generates C3006:

// 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

'arg' : clause on OpenMP 'directive' directive does not take an argument


An OpenMP directive had an argument, but the directive does not take an argument.
The following sample generates C3007:

// 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

'arg' : argument is missing closing ')' on OpenMP 'directive' directive


An OpenMP directive that takes an argument did not have a closing parenthesis.
The following sample generates C3008:

// 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

'label' : jump into OpenMP structured block not allowed


Code cannot jump into or out of an OpenMP block.
The following sample generates C3009:

// 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

'label' : jump out of OpenMP structured block not allowed


Code cannot jump into or out of an OpenMP block.
The following sample generates C3010:

// 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

inline assembly not allowed directly within a parallel region


An omp parallel region cannot contain inline assembly instructions.
The following sample generates C3011:

// C3011.cpp
// compile with: /openmp
// processor: /x86
int main() {
int n = 0;

#pragma omp parallel


{
_asm mov eax, n // Delete this line to resolve this error.
} // C3011
}
Compiler Error C3012
10/31/2018 • 2 minutes to read • Edit Online

'intrinsic' : intrinsic function not allowed directly within a parallel region

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

'clause' : clause may only appear once on OpenMP 'directive' directive


A clause appeared twice on the same directive. Delete one occurrence of the clause.
The following sample generates C3013:

// C3013.cpp
// compile with: /openmp
int main() {
int a, b, c, x, y, z;

#pragma omp parallel shared(a,b,c) private(x)

#pragma omp for nowait private(x) nowait // C3013


// The previous line generates C3013, with two nowait clauses
// try the following line instead:
// #pragma omp for nowait private(x)
for (a = 0 ; a < 10 ; ++a) {
}
}
Compiler Error C3014
10/31/2018 • 2 minutes to read • Edit Online

expected a for loop following OpenMP 'directive' directive


It is an error for anything other than a for loop to immediately follow a #pragma omp for directive.
The following sample generates C3014:

// C3014.cpp
// compile with: /openmp
int main()
{
int i = 0;

#pragma omp parallel


{
#pragma omp for
for (i = 0; i < 10; ++i) // OK
{
}
}

#pragma omp parallel for


for (i = 0; i < 10; ++i) // OK
{
}

#pragma omp parallel


{
#pragma omp for
{ // C3014
for (i = 0; i < 10; ++i)
{
}
}
}

#pragma omp parallel for


{ // C3014
for (i = 0; i < 10; ++i)
{
}
}

#pragma omp parallel


{
#pragma omp for
i *= 2; // C3014
for (i = 0; i < 10; ++i)
{
}
}

#pragma omp parallel for


i *= 2; // C3014
for (i = 0; i < 10; ++i)
{
}
}
Compiler Error C3015
10/31/2018 • 2 minutes to read • Edit Online

initialization in OpenMP 'for' statement has improper form


A for loop in an OpenMP statement must be fully and explicitly specified.
The following sample generates C3015:

// C3015.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 10;

#pragma omp parallel


{
#pragma omp for
for (; i < 0; i += j) // C3015
// Try the following line instead:
// for (i = 0; i < 0; i++)
--j;
}
}
Compiler Error C3016
10/31/2018 • 2 minutes to read • Edit Online

'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;

#pragma omp for


for (i = 0; i <= 10; ++i) // C3016
{
}
}
}
Compiler Error C3017
10/31/2018 • 2 minutes to read • Edit Online

termination test in OpenMP 'for' statement has improper form


A for loop in an OpenMP statement must be fully and explicitly specified.
The following sample generates C3017:

// C3017.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 10;

#pragma omp parallel


{
#pragma omp for
for (i = 0; i; ++i) // C3017
// Try the following line instead:
// for (i = 0; i < 10; ++i)
;
}
}
Compiler Error C3018
10/31/2018 • 2 minutes to read • Edit Online

'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;

#pragma omp parallel


{
#pragma omp for
for (i = 0; j < 10; ++i) // C3018
// try the following line instead
// for (i = 0; i < 10; ++i)
j *= 2;

#pragma omp for


for (i = 0; i < 10; j = j + i) // C3018
// try the following line instead
// for (i = 0; i < 10; i = j + i)
j *= 2;
}
}
Compiler Error C3019
10/31/2018 • 2 minutes to read • Edit Online

increment in OpenMP 'for' statement has improper form


The increment part of an OpenMP for loop must use the index variable both on the left and right side of the
operator.
The following sample generates C3019:

// C3019.cpp
// compile with: /openmp
int main()
{
int i = 0, j = 1, n = 3;

#pragma omp parallel


{
#pragma omp for
for (i = 0; i < 10; i = j + n) // C3019
// Try the following line instead:
// for (i = 0; i < 10; i++)
j *= 2;
}
}
Compiler Error C3020
10/31/2018 • 2 minutes to read • Edit Online

'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;

#pragma omp parallel


{
#pragma omp for
for (i = 0; i < 10; i += n)
i *= 2; // C3020
// try the following line instead
// n++;
}
}

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;
}
}
}

The following sample demonstrates a possible resolution:


// C3020c.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_b)
for (idx_b = first; idx_b <= last; ++idx_b) {
a[idx_a][idx_b] += 1.0f;
}
}
}
Compiler Error C3021
10/31/2018 • 2 minutes to read • Edit Online

'arg' : argument is empty on OpenMP directive 'directive'


An argument is required for an OpenMP directive.

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;

#pragma omp parallel for schedule(static,) // C3021


for (i = 0; i < 10; ++i) ;

#pragma omp parallel for schedule() // C3021


for (i = 0; i < 10; ++i)
printf_s("Hello world, thread %d, iteration %d\n",
omp_get_thread_num(), i);

#pragma omp parallel reduction() // C3021


;

#pragma omp parallel reduction(+ :) // C3021


;

//
// The following shows correct syntax examples.
//
#pragma omp parallel reduction(+ : x, y)
;

#pragma omp parallel reduction(* : x, y)


;

#pragma omp parallel reduction(- : x, y)


;

#pragma omp parallel reduction(& : x, y)


;

#pragma omp parallel reduction(^ : x, y)


;

#pragma omp parallel reduction(| : x, y)


;

#pragma omp parallel reduction(&& : x, y)


;

#pragma omp parallel reduction(|| : x, y)


;
}
Compiler Error C3022
10/31/2018 • 2 minutes to read • Edit Online

'clause' : invalid schedule kind of 'value' on OpenMP 'directive' directive


An unsupported value was passed to a clause.
The following sample generates C3022:

// C3022.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"

int main() {
int i;

#pragma omp parallel for schedule(10) // C3022


for (i = 0; i < 10; ++i) ;

#pragma omp parallel for schedule(x) // C3022


for (i = 0; i < 10; ++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

'value' : unexpected token encountered in argument to OpenMP 'clause' clause


The values passed to a clause were not valid.
The following sample generates C3023:

// C3023.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"

int main() {
int i;

#pragma omp parallel for schedule(dynamic 10) // C3023


for (i = 0; i < 10; ++i) ;

#pragma omp parallel for schedule(dynamic;10) // C3023


for (i = 0; i < 10; ++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

'schedule(runtime)' : chunk_size expression is not allowed


A value cannot be passed to the run-time parameter of the schedule clause.
The following sample generates C3024:

// C3024.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"

int main() {
int i;

#pragma omp parallel for schedule(runtime, 10) // C3024


for (i = 0; i < 10; ++i) ;

#pragma omp parallel for schedule(runtime) // OK


for (i = 0; i < 10; ++i) ;
}
Compiler Error C3025
10/31/2018 • 2 minutes to read • Edit Online

'clause' : integral expression expected


A clause requires an integer expression but was given a noninteger expression.

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);

puts("Test with float");


#pragma omp parallel for num_threads(f) // C3025
for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);
}
Compiler Error C3026
10/31/2018 • 2 minutes to read • Edit Online

'clause' : constant expression must be positive


A clause was passed an integer value, but the value was not a positive number. The number must be positive.

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;

#pragma omp parallel for num_threads(i1) // C3026


for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);

#pragma omp parallel for num_threads(i1 + 1) // OK


for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);
}
Compiler Error C3027
10/31/2018 • 2 minutes to read • Edit Online

'clause' : arithmetic or pointer expression expected


A clause that requires an arithmetic or pointer expression was passed another kind of expression.

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;

puts("Test with class MyStruct:\n");


#pragma omp parallel for if(m_MyStruct) // C3027
for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);

puts("Test with int:\n");


#pragma omp parallel for if(9) // OK
for (i = 1; i <= 2; ++i)
printf_s("Hello World - thread %d - iteration %d\n",
omp_get_thread_num(), i);
}
Compiler Error C3028
10/31/2018 • 2 minutes to read • Edit Online

'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;

typedef int MyInt;

template <class T, size_t n> class CTempl {


public:
static T public_array[n];
private:
static T private_array[n];
};

template<class T,size_t n> T CTempl<T,n>::public_array[n];


template<class T,size_t n> T CTempl<T,n>::private_array[n];

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
;

#pragma omp parallel reduction(+: x, g_i, MyClass::x_public,


MyClass::x_private)
// OK
;

#pragma omp parallel reduction(+: mbr)


// C3028, member of a class.
;
}

int main() {

#pragma omp parallel reduction(+:main)


// C3028, main is a function.
;

#pragma omp parallel reduction(+: XyzNS)


// C3028, XyzNS is a namespace.
;
}
Compiler Error C3029
10/31/2018 • 2 minutes to read • Edit Online

'symbol' : can only appear once in data-sharing clauses in an OpenMP directive


A symbol was used more than once in one or more clauses in a directive. The symbol can only be used once in the
directive.
The following sample generates C3029:

// C3029.cpp
// compile with: /openmp /link vcomps.lib
#include "omp.h"

int g_i;

int main() {
int i, x;

#pragma omp parallel reduction(+ : x, x) // C3029


;

#pragma omp parallel reduction(+ : x) // OK


;

#pragma omp parallel private(x) reduction(+ : x) // C3029


;

#pragma omp parallel reduction(+ : x) // OK


;
}
Compiler Error C3030
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'reduction' clause/directive cannot have reference type


You can only pass value parameters to certain clauses, such as the reduction clause.
The following sample generates C3030:

// C3030.cpp
// compile with: /openmp /link vcomps.lib
#include "omp.h"

void test(int &r) {


#pragma omp parallel reduction(+ : r) // C3030
;
}

void test2(int r) {
#pragma omp parallel reduction(+ : r) // OK
;
}

int main(int argc, char** argv) {


int& r = *((int*)argv);
int s = *((int*)argv);

#pragma omp parallel reduction(+ : r) // C3030


;

#pragma omp parallel reduction(+ : s) // OK


;
}
Compiler Error C3031
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'reduction' clause must have scalar arithmetic type


A variable of the wrong type was passed to a reduction clause.
The following sample generates C3031:

// C3031.cpp
// compile with: /openmp /link vcomps.lib
#include <stdio.h>
#include "omp.h"

typedef struct {
int n;
} Incomplete;

extern Incomplete inc;


int i = 9;

int main() {
#pragma omp parallel reduction(+: inc) // C3031
;

#pragma omp parallel reduction(+: i) // OK


;
}
Compiler Error C3032
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'clause' clause cannot have incomplete type 'type'


Types passed to certain clauses must be fully visible to the compiler.
The following sample generates C3032:

// 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
;

#pragma omp parallel private(i) // OK


;

}
Compiler Error C3033
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'clause' clause cannot have const-qualified type


Values passed to certain clauses cannot be const variables.
The following sample generates C3033:

// C3033.cpp
// compile with: /openmp /link vcomps.lib
int main() {
const int val = 1;
int val2 = 1;

#pragma omp parallel reduction(+ : val) // C3033


;

#pragma omp parallel reduction(+ : val2) // OK


;
}
Compiler Error C3034
10/31/2018 • 2 minutes to read • Edit Online

OpenMP 'directive1' directive cannot be directly nested within 'directive2' directive


Some directives cannot be nested. To fix this error, you can merge the statements of both directives into the block
of one directive, or you can construct consecutive directives.
The following sample generates C3034:

// C3034.cpp
// compile with: /openmp /link vcomps.lib
int main() {

#pragma omp single


{
#pragma omp single // C3034
{
;
}
}

// Two consecutive single clauses are OK.


#pragma omp single
{
}

#pragma omp single


{
}
}
Compiler Error C3035
10/31/2018 • 2 minutes to read • Edit Online

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;

#pragma omp parallel private(n)


{
#pragma omp ordered // C3035
// Try the following line instead:
// #pragma omp for ordered
for (i = 0 ; i < 10 ; ++i)
;
}
}
Compiler Error C3036
10/31/2018 • 2 minutes to read • Edit Online

'operator' : invalid operator token in OpenMP 'reduction' clause


A reduction clause was not specified correctly.
The following sample generates C3036:

// 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

'var' : variable in 'reduction' clause must be shared in enclosing context


A variable specified in a reduction clause may not be private to each thread in the context.
The following sample generates C3037:

// C3037.cpp
// compile with: /openmp /c
int g_i;

int main() {
int i;

#pragma omp parallel private(g_i)


// try the following line instead
// #pragma omp parallel
{
#pragma omp for reduction(+:g_i) // C3037
for (i = 0 ; i < 10 ; ++i) {
g_i += i;
}
}
}
Compiler Error C3038
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'private' clause cannot be a reduction variable in enclosing context


Variables that appear in the reduction clause of a parallel directive cannot be specified in a private clause on a
work-sharing directive that binds to the parallel construct.
The following sample generates C3038:

// C3038.cpp
// compile with: /openmp /c
int g_i, g_i2;

int main() {
int i;

#pragma omp parallel reduction(+: g_i)


{
#pragma omp for private(g_i) // C3038
// try the following line instead
// #pragma omp for private(g_i2)
for (i = 0; i < 10; ++i)
g_i += i;
}
}
Compiler Error C3039
10/31/2018 • 2 minutes to read • Edit Online

'var' : index variable in OpenMP 'for' statement cannot be a reduction variable


An index variable is implicitly private, so the variable cannot be used in a reduction clause in the enclosing parallel
directive.

Example
The following sample generates C3039:

// C3039.cpp
// compile with: /openmp /c
int g_i;

int main() {
int i;

#pragma omp parallel reduction(+: i)


{
#pragma omp for
for (i = 0; i < 10; ++i) // C3039
g_i += i;
}
}
Compiler Error C3040
10/31/2018 • 2 minutes to read • Edit Online

'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
;

#pragma omp parallel reduction(-:d) // OK


;
}
Compiler Error C3041
10/31/2018 • 2 minutes to read • Edit Online

'var' : variable in 'copyprivate' clause must be private in enclosing context


A variable passed to copyprivate cannot be shared in the enclosing context.
The following sample generates C3041:

// 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;

#pragma omp parallel


{
++n2;

#pragma omp critical(MyTest)


{
++n2;

#pragma omp critical(MyTest) // C3043


// try the following line instead
// #pragma omp critical(MyTest2)
{
++n3;
}
}
}
}
Compiler Error C3044
10/31/2018 • 2 minutes to read • Edit Online

'section' : only allowed directly nested under an OpenMP 'sections' directive


The compiler found a section directive was used incorrectly. For more information, see sections.
The following sample generates C3044:

// C3044.cpp
// compile with: /openmp /c
#include "omp.h"
int main() {
int n2 = 2, n3 = 3;

#pragma omp parallel


{
++n2;

#pragma omp sections


{
++n2;
}

#pragma omp section // C3044


{
++n3;
}
}

#pragma omp parallel


{
++n2;

#pragma omp sections


{
#pragma omp section // OK
{
++n3;
}
}
}
}
Compiler Error C3045
10/31/2018 • 2 minutes to read • Edit Online

Expected a compound statement following OpenMP 'sections' directive. Missing '{'


A code block delimited by braces must follow a sections directive.
The following sample generates C3045:

// C3045.cpp
// compile with: /openmp /c
#include "omp.h"

int main() {
int n2 = 2, n3 = 3;

#pragma omp parallel


{
++n2;

#pragma omp sections


++n2; // C3045

#pragma omp sections // OK


{
++n3;
}
}
}
Compiler Error C3046
10/31/2018 • 2 minutes to read • Edit Online

Missing structured block in an OpenMP '#pragma omp sections' region


A sections directive has an empty code block.
The following sample generates C3046:

// C3046.cpp
// compile with: /openmp /c
#include "omp.h"

int main() {
int n2 = 2, n3 = 3;

#pragma omp parallel


{
++n2;

#pragma omp sections


{
/*
++n2;

#pragma omp section


{
++n3;
}
*/
} // C3046 uncomment code to resolve this C3046
}
}
Compiler Error C3047
10/31/2018 • 2 minutes to read • Edit Online

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;

#pragma omp parallel


{
++n2;

#pragma omp sections


{

#pragma omp section


{
++n3;
}

++n2; // C3047 not enclosed in #pragma omp section


}
}
}
Compiler Error C3048
10/31/2018 • 2 minutes to read • Edit Online

Expression following '#pragma omp atomic' has improper form


An atomic directive was incorrectly specified.
The following sample generates C3048:

// 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

'arg' : invalid argument in OpenMP 'default' clause


An incorrect value was passed to a default clause.
The following sample generates C3049:

// C3049.cpp
// compile with: /openmp /c
int main() {
int n1 = 1;

#pragma omp parallel default(private) // C3049


// try the following line instead
// #pragma omp parallel default(shared)
{
++n1;
}
}
Compiler Error C3050
10/31/2018 • 2 minutes to read • Edit Online

'type1' : a ref class cannot inherit from 'type1'


System::ValueType cannot be a base class for a reference type.
The following sample generates C3050:

// 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

'var' : variable doesn't appear in a data-sharing clause under a default(none) clause


If default(none) is used, any variable used in the structured block must be explicitly specified as either shared or
private.
The following sample generates C3052:

// C3052.cpp
// compile with: /openmp /c
int main() {
int n1 = 1;

#pragma omp parallel default(none) // shared(n1) private(n1)


{
n1 = 0; // C3052 use either a shared or private clause
}
}
Compiler Error C3053
10/31/2018 • 2 minutes to read • Edit Online

'symbol' : 'threadprivate' is only valid for global or static data items


Symbols passed to threadprivate must either be global or static.
The following sample generates C3053:

// 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

'#pragma omp parallel' is currently not supported in a generic class or function


For more information, see Generics and OpenMP.

Example
The following sample generates C3054.

// C3054.cpp
// compile with: /openmp /clr /c
#include <omp.h>

ref struct MyBaseClass {


// Delete the following 7 lines to resolve.
generic <class ItemType>
void Test(ItemType i) { // C3054
#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
}
}

// 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

'symbol' : symbol cannot be referenced before it is used in 'threadprivate' directive


A symbol was referenced and then used in a threadprivate clause, which is not allowed.
The following sample generates C3055:

// 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

'symbol' : symbol is not in the same scope with 'threadprivate' directive


A symbol used in a threadprivate clause must be in the same scope as the threadprivate clause.
The following sample generates C3056:

// 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

'symbol' : dynamic initialization of 'threadprivate' symbols is not currently supported


The initialized value of a symbol used in a threadprivate clause must be known at compile time.
The following sample generates C3057:

// C3057.cpp
// compile with: /openmp /c
extern int f();
int x, y = f();
int a, b;
#pragma omp threadprivate(x, y) // C3057

#pragma omp threadprivate(a, b)

int main() {
// Delete the following 4 lines to resolve.
#pragma omp parallel copyin(x, y)
{
x = y;
}

#pragma omp parallel copyin(a, b)


{
a = b;
}
}

The following sample generates C3057:

// 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

'var' : 'threadprivate' symbol cannot be used in the 'clause' clause


A threadprivate symbol was used in a clause.
The following sample generates C3059:

// 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

'enum': enumerator requires value since the underlying type is 'type'


You can specify an underlying type for an enumeration. However, some types require you to assign values to each
enumerator.
For more information on enums, see enum class.
The following sample generates C3062:

// C3062.cpp
// compile with: /clr

enum class MyEnum : bool { a }; // C3062


enum class MyEnum2 : bool { a = true}; // OK
Compiler Error C3063
10/31/2018 • 2 minutes to read • Edit Online

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)

if ( ( e & mask ) != E() ) // OK


;
}
Compiler Error C3065
10/31/2018 • 2 minutes to read • Edit Online

property declaration at non-class scope is not allowed


The property __declspec modifier was used outside a class. A property can only be declared inside a class.
The following sample generates C3065:

// 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*){}

typedef void (*PF)(const int*, const char*);


typedef void (*PF1)(const int*, volatile char*);

struct A {
operator PF() const {
return func;
}

operator PF1() {
return func;
}

operator PF1() const {


return func;
}

};

int main() {
A a;
int i;
char c;

a(&i, &c); // C3066


a(&i, (const char *) &c); // OK
}

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){}

__declspec(naked) void c() {


b(A()); // C3068
};
Compiler Error C3069
10/31/2018 • 2 minutes to read • Edit Online

'operator': not allowed for enumeration type


An operator is not supported for CLR enumerations. For more information, see How to: Define and consume
enums in C++/CLI.

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

// supported for native enums


F f = f1;
tf = !f;
}
Compiler Error C3070
10/31/2018 • 2 minutes to read • Edit Online

'property': property does not have a 'set' method


A property's set accessor method was not defined. For more information, see property.
The following sample generates C3070:

// C3070.cpp
// compile with: /clr
ref class R {
public:
R(int size) {
m_data = gcnew array<int>(size);
}

property int % MyProp[int] {


int% get(int index) {
return m_data[index];
}
}

property int % MyProp2[int] {


int% get(int index) {
return m_data[index];
}
void set(int index, int % value) {}
}

property const int % MyProp3[int] {


const int% get(int index) {
return m_data[index];
}
void set(int index, const int % value) {}
}

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

operator 'operator' can only be applied to an instance of a ref class or a value-type


A CLR operator cannot be used on a native type. The operator can be used on a ref class or a ref struct (a value
type) but not a native type such as int or an alias for a native type such as System::Int32. These types can't be boxed
from C++ code in a way that refers to the native variable, so the operator cannot be used.
For more information, see Tracking Reference Operator.

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

operator 'operator' cannot be applied to an instance of a ref class


use the unary ' operator ' operator to convert an instance of a ref class to a handle type
A CLR type requires CLR operators, not native (or standard) operators. For more information, see Tracking
Reference Operator.

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

'type' : ref class does not have a user-defined copy constructor


In a /clr (Common Language Runtime Compilation) compilation, the compiler will not generate a copy constructor
for a reference type. In any /clr compilation, you must define your own copy constructor for a reference type if you
expect an instance of the type to be copied.
For more information, see C++ Stack Semantics for Reference Types.

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

'instance' : you cannot embed an instance of a reference type, 'type', in a value-type


A value type cannot contain an instance of a reference type.
For more information, see C++ Stack Semantics for Reference Types.

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

'finalizer' : a finalizer can only be a member of a reference type


You cannot declare a finalizer in a native or value type.
For more information, see Destructors and finalizers in How to: Define and consume classes and structs
(C++/CLI).

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

'finalizer_function' : a finalizer cannot have a storage-class-specifier


For more information, see Destructors and finalizers in How to: Define and consume classes and structs
(C++/CLI).

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

'function': the symbol to the left of a '::' must be a type


A function was called incorrectly.

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

'function': a finalizer/destructor cannot be 'keyword'


A finalizer or destructor was declared incorrectly.
For example, a destructor should not be marked as sealed. The destructor will be inaccessible to derived types. For
more information, see Explicit Overrides and Destructors and finalizers in How to: Define and consume classes and
structs (C++/CLI).

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

'constructor': a constructor cannot be 'keyword'


A constructor was declared incorrectly. See Override Specifiers for more information.

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

'named_argument': call of 'attribute' already initializes this member


A named argument was specified in the same attribute block as an unnamed argument for the same value. Specify
only a named or unnamed argument.

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

'attribute': anonymous usage not allowed


An attribute was not scoped correctly. For more information, see User-Defined Attributes.

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

'attribute': attribute cannot be repeated


Some attributes are declared such that, multiple occurrences of the attribute cannot be applied to a target.
For more information, see User-Defined Attributes.

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

'attribute': attribute is allowed on data members of attribute classes only


An attribute was applied incorrectly.
For more information, see User-Defined Attributes.
Compiler Error C3097
10/31/2018 • 2 minutes to read • Edit Online

'attribute': attribute must be scoped with 'assembly:' or 'module:'


A global attribute was used incorrectly.
For more information, see User-Defined Attributes.

Example
The following sample generates C3097.

// C3097.cpp
// compile with: /clr /c
using namespace System;

[AttributeUsage(AttributeTargets::All, AllowMultiple = true)]


public ref class Attr : public Attribute {
public:
Attr(int t) : m_t(t) {}
int m_t;
};

[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

'keyword': use [System::AttributeUsageAttribute] for managed attributes; use


[Windows::Foundation::Metadata::AttributeUsageAttribute] for WinRT attributes
Use AttributeUsageAttribute to declare /clr attributes. Use
Windows::Foundation::Metadata::AttributeUsageAttribute to declare Windows Runtime attributes.

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 C3100 'identifier': unknown attribute qualifier

Compiler Error C3101 illegal expression for named attribute argument 'identifier'

Compiler Error C3102 Obsolete.

Compiler Error C3103 'identifier': repeated named argument

Compiler Error C3104 illegal attribute argument

Compiler Error C3105 'symbol': cannot be used as an attribute

Compiler Error C3106 'attribute': unnamed arguments must precede named


arguments
ERROR MESSAGE

Compiler Error C3107 'attribute': member functions of native attributes cannot be


defined

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 C3112 'interface': an interface can only be declared at global or


namespace scope

Compiler Error C3113 an 'interface/enum' cannot be a template/generic

Compiler Error C3114 'identifier': not a valid named attribute argument

Compiler Error C3115 'attribute': this attribute is not allowed on 'construct'

Compiler Error C3116 'specifier': invalid storage class for interface method

Compiler Error C3117 'interface': an interface can only have one base class

Compiler Error C3118 'interface': interfaces do not support virtual inheritance

Compiler Error C3119 alignas(void) is not allowed

Compiler Error C3120 'identifier': interface methods cannot take a variable argument
list

Compiler Error C3121 cannot change GUID for class 'class'

Compiler Error C3122 'interface': a WinRT generic interface cannot have GUID

Compiler Error C3123 WinRT generic interface cannot have constraints

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 C3129 'type': __default_vptr_for_base can only be used on locally


defined polymorphic types and bases

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 C3133 Attributes cannot be applied to C++ varargs

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 C3137 'identifier': a property cannot be initialized

Compiler Error C3138 'identifier': a 'attribute' interface must inherit from IDispatch,
or from an interface that inherits from IDispatch

Compiler Error C3139 'type': cannot export a UDT without members

Compiler Error C3140 cannot have multiple 'module' attributes in the same
compilation unit

Compiler Error C3141 'interface': interfaces only support public inheritance

Compiler Error C3142 'property': you cannot take the address of a property

Compiler Error C3143 'argument': attribute argument cannot have multiple values

Compiler Error C3144 'attribute': attribute requires explicit arguments, 'argument' is


unnamed

Compiler Error C3145 'identifier': global or static variable may not have
managed/WinRT type 'type'

Compiler Error C3146 Obsolete.

Compiler Error C3147 Obsolete.

Compiler Error C3148 Obsolete.

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 C3151 Obsolete.

Compiler Error C3152 'function': 'keyword' can only be applied to a class, struct, or
virtual member function

Compiler Error C3153 'interface': you cannot create an instance of an interface

Compiler Error C3154 Expected ',' before ellipsis. Non-comma separated ellipsis not
supported on parameter array functions.

Compiler Error C3155 attributes are not allowed in a property indexer

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 C3161 'interface': nesting class, struct, or interface in an interface is


illegal; nesting interface in a class or struct is illegal

Compiler Error C3162 'type': a reference type which has a destructor cannot be used
as the type of static data member 'member'

Compiler Error C3163 'class': attributes inconsistent with previous declaration

Compiler Error C3164 Obsolete.

Compiler Error C3165 'value': cannot convert to an integral or floating point value

Compiler Error C3166 Obsolete. 'type': a data member of a managed/WinRT class


cannot have type 'pointer_type to interior
managed_pointer_type'

Compiler Error C3167 Unable to initialize .NET Framework: make sure it is installed

Compiler Error C3168 'type': illegal underlying type for enum

Compiler Error C3169 'type': cannot deduce type for 'auto' from 'type'

Compiler Error C3170 cannot have different module identifiers in a project


ERROR MESSAGE

Compiler Error C3171 'module': cannot specify different module attributes in a


project

Compiler Error C3172 'identifier': cannot specify different idl_module attributes in a


project

Compiler Error C3173 version mismatch in idl merge

Compiler Error C3174 module attribute was not specified

Compiler Error C3175 'function': cannot call a method of a managed type from
unmanaged function 'function'

Compiler Error C3176 'type': cannot declare local value type

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 C3179 an unnamed managed/WinRT type is not allowed

Compiler Error C3180 'type': name exceeds meta-data limit of 'number' characters

Compiler Error C3181 'type': invalid operand for operator

Compiler Error C3182 'type': a member using-declaration or access declaration is


illegal within a managed/WinRT type

Compiler Error C3183 cannot define unnamed class, struct or union inside of
managed/WinRT type 'class'

Compiler Error C3184 Obsolete.

Compiler Error C3185 'typeid': used on managed/WinRT type 'type', use 'operator'
instead

Compiler Error C3186 Obsolete.

Compiler Error C3187 'identifier': is only available within the body of a function

Compiler Error C3188 Obsolete.

Compiler Error C3189 'typeid<declarator>': this syntax is no longer supported,


use::typeid instead

Compiler Error C3190 'declarator' with the provided template arguments is not the
explicit instantiation of any member function of 'type'

Compiler Error C3191 Obsolete.


ERROR MESSAGE

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 C3194 'type': a value-type cannot have an assignment operator

Compiler Error C3195 'keyword': is reserved and cannot be used as a member of a


ref class or value type. CLR/WinRT operators must be defined
using the 'operator' keyword

Compiler Error C3196 'identifier': used more than once

Compiler Error C3197 'keyword': can only be used in definitions

Compiler Error C3198 invalid use of floating-point pragmas: fenv_access pragma


operates only in precise mode

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

'target' : unknown attribute qualifier


An invalid attribute target was specified.
For more information, see User-Defined Attributes.

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

illegal expression for named attribute argument 'field'


When initializing a named attribute argument, the value must be a compile time constant.
For more information on attributes, see User-Defined Attributes.

Example
The following sample generates C3101.

// C3101.cpp
// compile with: /clr /c
ref class AAttribute : System::Attribute {
public:
int Field;
};

extern int i;

[assembly:A(Field = i)]; // C3101


[assembly:A(Field = 0)]; // OK
Compiler Error C3103
10/31/2018 • 2 minutes to read • Edit Online

'argument': repeated named argument


An attribute can not repeat named arguments.
For more information, see User-Defined Attributes.

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;
};

[Attr(m_t = 10, m_t = 1)] // C3103


// try the following line instead
// [Attr(m_t = 10)]
ref class A {};
Compiler Error C3104
10/31/2018 • 2 minutes to read • Edit Online

illegal attribute argument


You specified an invalid argument to an attribute.
See Attribute Parameter Types for more information.
This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: when
passing managed arrays to custom attributes, the type of the array is no longer deduced from the aggregate
initialization list. The compiler now requires you to specify the type of the array as well as the initializer list.

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;
};

[ABC( {1,2,3}, param = {2.71, 3.14})] // C3104


// try the following line instead
// [ABC( gcnew array<int> {1,2,3}, param = gcnew array<double>{2.71, 3.14})]
ref struct AStruct{};

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) {}
};

// Delete the following 2 lines to resolve.


[A(func())]
ref class B {};

// OK
[A(0)]
ref class B {};
Compiler Error C3106
10/31/2018 • 2 minutes to read • Edit Online

'attribute': unnamed arguments must precede named arguments


Unnamed arguments must be passed to an attribute before named arguments.
For more information, see User-Defined Attributes.

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

'function_name' : you cannot overload a COM interface method


An interface that is prefaced by an interface attribute, such as:
custom
dispinterface
dual
object
cannot be overloaded. For example:

// 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

an 'structure' cannot be a template/generic


You attempted to make a class template or class generic out of an interface or an enum.
The following sample generates C3113:

// 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

'argument': not a valid named attribute argument


In order for an attribute class data member to be a valid named argument, it must not be marked static , const ,
or literal . If a property, the property must not be static and must have get and set accessors.
For more information, see property and User-Defined Attributes.

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();
}

property int Prop2 {


int get();
void set(int i);
}
};

[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

'attribute': this attribute is not allowed on 'construct'


An attribute was applied to a construct for which it was not intended. See Attributes by Usage for more
information.

Example
The following sample generates C3115.

// C3115.cpp
// compile with: /c
#include <unknwn.h>
[module(name="xx")];

[object, helpstringdll(xx.dll), uuid("00000000-0000-0000-0000-000000000001")] // C3115


// try the following line instead
// [object, uuid("00000000-0000-0000-0000-000000000001")]
__interface IMyI {
HRESULT xx();
};
Compiler Error C3116
10/31/2018 • 2 minutes to read • Edit Online

'storage specifier' : invalid storage class for interface method


You used typedef , register , or static as the storage class for an interface method. These storage classes are
not permitted on interface members.
The following sample generates C3116:

// C3116.cpp
__interface ImyInterface
{
static void myFunc(); // C3116
};
Compiler Error C3117
10/31/2018 • 2 minutes to read • Edit Online

'%$S' : an interface can only have one base class


You declared an interface that inherits from multiple base classes.
The following sample generates C3117:

// 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

'interface' : interfaces do not support virtual inheritance


You tried to virtually inherit from an interface. For example,

// C3118.cpp
__interface I1 {
};

__interface I2 : virtual I1 { // C3118


};

generates this error.


Compiler Error C3120
10/31/2018 • 2 minutes to read • Edit Online

'method_name' : interface methods cannot take a variable argument list


An interface method cannot take a variable argument list. For example, the following interface definition generates
C3120:

// C3120.cpp
__interface A {
int X(int i, ...); // C3120
};

int main(void) { return(0); }


Compiler Error C3121
10/31/2018 • 2 minutes to read • Edit Online

cannot change GUID for class 'class_name'


You attempted to change the class ID with __declspec(uuid).
For example, the following code generates C3121:

// 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

cannot define a union 'union' inside of managed type 'type'


A union cannot be defined inside a managed type.
The following sample generates C3126:

// 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

Internal Compiler Error: failed to write injected code block to PDB


This error occurs if the compiler failed to write an injected code block to the .pdb file. The most common reason for
the failure is lack of disk space.
Compiler Error C3131
10/31/2018 • 2 minutes to read • Edit Online

project must have a 'module' attribute with a 'name' property


The module attribute must have a name parameter.
The following sample generates C3131:

// 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

void h( [ParamArray] array<Char ^> ^ MyArray ); // OK


Compiler Error C3133
10/31/2018 • 2 minutes to read • Edit Online

Attributes cannot be applied to C++ varargs


An attribute was applied incorrectly. Attributes can not be applied to an ellipsis representing variable arguments.
For more information, see User-Defined Attributes.

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

'property' : a property cannot have a 'const' or 'volatile' type


The const and volatile keywords are not permitted on properties.
Compiler Error C3136
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

'property' : a property cannot be initialized


A property cannot be initialized, for example, in a constructor's initialization list.
The following example generates C3137:

// C3137.cpp
// compile with: /clr /c
ref class CMyClass {
public:
property int Size {
int get() {
return 0;
}
void set( int i ) {}
}

CMyClass() : Size( 1 ) { // C3137


// to resolve this C3137, remove the initializer from the
// ctor declaration and perform the assignment as follows
// Size = 1;
}
};
Compiler Error C3138
10/31/2018 • 2 minutes to read • Edit Online

'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);
};

[ object, dual, uuid("34e90a10-6e9a-11d2-97de-0000f805d73b") ]


__interface IMyDualInterface : IMyCustomInterface // C3138 expected
{
HRESULT mf3(void);
};
Compiler Error C3139
10/31/2018 • 2 minutes to read • Edit Online

'struct' : cannot export a UDT without members


You attempted to apply the export attribute to an empty UDT (user-defined type). For example:

// C3139.cpp
#include "unknwn.h"
[emitidl];
[module(name=xx)];

[export] struct MyStruct { // C3139 empty type


};
int main(){}
Compiler Error C3140
10/31/2018 • 2 minutes to read • Edit Online

cannot have multiple 'module' attributes in the same compilation unit


The module attribute can only be defined once per project.
The following sample generates C3140:

// 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

'interface_name' : interfaces only support public inheritance


Interfaces defined with the interface (or __interface) keyword only support public inheritance.
The following sample generates C3141:

// 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

'property_name' : you cannot take the address of a property


The address of a property is not available to the developer.
The following sample generates C3142:

// 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

ref class GlobalObjects {


public:
static G ^ ptr; // OK
static G ^ ptr2 = gcnew G; // OK
};

int main() {
G ^ ptr; // OK
G ^ ptr2 = gcnew G; // OK
}

The following sample generates C3145:

// C3145b.cpp
// compile with: /clr
ref class MyClass {
public:
static int data;
};

interior_ptr<int> p = &(MyClass::data); // C3145

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

'type' : cannot use this type here without a top-level 'char'


A declaration was not specified correctly.
For example, you may have defined a CLR type at global scope and tried to create a variable of the type as part of
the definition. Because global variables of CLR types are not allowed, the compiler will generate C3149.
To resolve this error, declare variables of CLR types inside a function or type definition.
The following sample generates C3149:

// C3149.cpp
// compile with: /clr
using namespace System;
int main() {
// declare an array of value types
array< Int32 ^> IntArray; // C3149
array< Int32>^ IntArray2; // OK
}

The following sample generates C3149:

// 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

'element' : 'attribute' can only be applied to a class, interface, array or pointer


__gc can only be used on a class, interface, or array.
C3150 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3152
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

'interface' : you cannot create an instance of an interface


An interface cannot be instantiated. To use the members of an interface, derive a class from the interface,
implement the interface members, and then use the members.
The following sample generates C3153:

// 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

attributes are not allowed in a property indexer


An indexed property was declared incorrectly. For more information, see How to: Use Properties in C++/CLI.

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

'class' : you cannot have a local definition of a managed or WinRT type


A function cannot contain the definition, or declaration, of a managed or WinRT class, struct, or interface.

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

ParamArray attribute can only be applied to the last parameter


The ParamArrayAttribute attribute was applied to the wrong parameter.
Compiler Error C3159
10/31/2018 • 2 minutes to read • Edit Online

'pointer' : array of pointers to value type cannot be declared


An array of pointers to a value type cannot be declared.
C3159 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3160
10/31/2018 • 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

'construct': attributes inconsistent with previous declaration


The attribute(s) that are applied to a definition conflict with the attribute(s) that are applied to a declaration.
One way to resolve C3163 is to eliminate attributes on the forward declaration. Any attributes on a forward
declaration should be less than the attributes on the definition or, at most, equal to them.
A possible cause of the C3163 error involves the Microsoft source code annotation language (SAL ). The SAL
macros do not expand unless you compile your project by using the /analyze flag. A program that compiles
cleanly without /analyze might throw C3163 if you attempt to recompile it with the /analyze option. For more
information about SAL, see SAL Annotations.

Example
The following sample generates C3163.

// C3163.cpp
// compile with: /clr /c
using namespace System;

[CLSCompliant(true)] void f();


[CLSCompliant(false)] void f() {} // C3163
// try the following line instead
// [CLSCompliant(true)] void f() {}

See Also
SAL Annotations
Compiler Error C3166
10/31/2018 • 2 minutes to read • Edit Online

'pointer' : cannot declare a pointer to an interior __gc pointer as a member of 'type'


The compiler found an invalid pointer declaration (a __nogc pointer to a __gc pointer.).
C3166 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3167
10/31/2018 • 2 minutes to read • Edit Online

Unable to initialize .NET Framework: make sure it is installed


The .NET Framework is not installed on this computer; install the .NET Framework.
Compiler Error C3168
10/31/2018 • 2 minutes to read • Edit Online

'type' : illegal underlying type for enum


The underlying type you specified for the enum type was not valid. The underlying type must be an integral C++
type or a corresponding CLR type.
The following sample generates C3168:

// C3168.cpp
// compile with: /clr /c
ref class G{};

enum class E : G { e }; // C3168


enum class F { f }; // OK
Compiler Error C3170
10/31/2018 • 2 minutes to read • Edit Online

cannot have different module identifiers in a project


module attributes with different names were found in two of the files in a compilation. Only one unique module
attribute can be specified per compilation.
Identical module attributes can be specified in more than one source code file.
For example, if the following module attributes were found:

// 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") ];

the compiler would generate C3170 (note the different names).


Compiler Error C3171
10/31/2018 • 2 minutes to read • Edit Online

'module': cannot specify different module attributes in a project


module attributes with different parameter lists were found in two of the files in a compilation. Only one unique
module attribute can be specified per compilation.

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

'module_name': cannot specify different idl_module attributes in a project


idl_module attributes with the same name but different dllname or version parameters were found in two of the
files in a compilation. Only one unique idl_module attribute can be specified per compilation.
Identical idl_module attributes can be specified in more than one source code file.
For example, if the following idl_module attributes were found:

// 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

version mismatch in idl merge


This error occurs when an object file contains embedded idl that was generated with a previous version of the
compiler. The compiler encodes a version number to ensure that the same compiler used to generate the idl
content that is embedded in the .obj files is also the same compiler used to merge the embedded idl.
Update your Visual C++ installation so that all tools are from the latest released version.
Compiler Error C3174
10/31/2018 • 2 minutes to read • Edit Online

module attribute was not specified


A program that uses Visual C++ attributes did not also use the module attribute, which is required in any program
that uses attributes.
The following sample generates C3174:

// 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() {
}
};

#pragma unmanaged // remove this line to resolve

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

'type' : cannot declare local value type


A class can only be declared as a value type at global scope.

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

an unnamed managed or WinRT type is not allowed


All CLR and WinRT classes and structs must have names.
The following sample generates C3179 and shows how to fix it:

// 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

'type name' : name exceeds meta-data limit of 'limit' characters


The compiler truncated the name for a managed type in metadata. The truncation will make the type unusable with
the #using directive (or the equivalent in another language).
The type-name limit includes any namespace qualifications.
Compiler Error C3181
10/31/2018 • 2 minutes to read • Edit Online

'type' : invalid operand for operator


An invalid parameter was passed to the typeid operator. The parameter must be a managed type.
Note that the compiler uses aliases for native types that map to types in the common language runtime.
The following sample generates C3181:

// 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

'class' : a member using-declaration or access declaration is illegal within a managed or WinRTtype


A using declaration is invalid within all forms of managed classes.
The following sample generates C3182 and shows how to fix it.

// 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

'typeid' used on managed or WinRT type 'type', use 'operator' instead


You cannot apply the typeid operator to a managed or WinRT type; use typeid instead.
The following sample generates C3185 and shows how to fix it:

// 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

'__func__' : is only available within the body of a function

The predefined macro is not available outside the body of a function.


To correct this error, move the macro inside the body of a function.
Compiler Error C3189
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) {
}
};

template A<float>::A(); // C3190


// try the following line instead
// template A<int>::A(int);

struct Y {
template<class T> void f(T);
};

template<class T> void Y::f(T) { }

template void Y::f(int,int); // C3190

template<class OT> class X {


template<class T> void f2(T,OT);
};

template<class OT> template<class T> void X<OT>::f2(T,OT) {}

template void X<float>::f2<int>(int,char); // C3190


// try one of the following lines instead
// template void X<char>::f2(int, char);
// template void X<char>::f2<int>(int,char);
// template void X<char>::f2<>(int,char);
Compiler Error C3192
10/31/2018 • 2 minutes to read • Edit Online

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;

ref class MyClass {


public:
MyClass () {}
MyClass(MyClass%) {}
};

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

'member' : a value-type cannot have an assignment operator


Special member functions that require automatic invocation by the compiler, such as a copy constructor or copy
assignment operator are not supported within a value class.

Example
The following sample generates C3194.

// C3194.cpp
// compile with: /clr /c
value struct MyStruct {
MyStruct& operator= (const MyStruct& i) { return *this; } // C3194
};

ref struct MyStruct2 {


MyStruct2% operator= (const MyStruct2% i) { return *this; } // OK
};
Compiler Error C3195
10/31/2018 • 2 minutes to read • Edit Online

'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

'keyword' : used more than once


A keyword was used more than once.
The following sample generates C3196:

// 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

'keyword' : can only be used in definitions


A keyword was used in a declaration but is only valid in a definition.
The following sample generates C3197:

// C3197.cpp
// compile with: /clr /c
ref struct R abstract; // C3197
ref struct R abstract {}; // OK

public ref class MyObject; // C3197


ref class MyObject; // OK
public ref class MyObject {}; // OK
Compiler Error C3198
10/31/2018 • 2 minutes to read • Edit Online

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 C3203 'identifier': unspecialized class template/generic can't be used


as a template/generic argument for template/generic
parameter 'parameter', expected a real type

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 C3206 'function': invalid template/generic argument for 'template',


missing template/generic argument list on class
template/generic 'type'

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 C3209 'type': generic class must be a managed/WinRT class

Compiler Error C3210 'identifier': access declaration can only be applied to a base
class member

Compiler Error C3211 'function': explicit specialization is using partial specialization


syntax, use template <> instead

Compiler Error C3212 'function': an explicit specialization of a template member must


be a member of an explicit specialization

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 C3215 'constraint1': generic type parameter already constrained by


'constraint2'

Compiler Error C3216 constraint must be a generic parameter, not 'type'

Compiler Error C3217 'parameter': generic parameter cannot be constrained in this


declaration

Compiler Error C3218 'type': type not allowed as a constraint

Compiler Error C3219 'parameter': generic parameter cannot be constrained by


multiple non-interfaces: 'type'

Compiler Error C3220 'interface': interface cannot have progid

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 C3223 'property': you cannot apply 'typeid' to a property


ERROR MESSAGE

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 C3226 A template declaration is not allowed inside a generic


declaration

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 C3232 'parameter': a generic type parameter cannot be used in a


qualified name

Compiler Error C3233 'type': generic type parameter already constrained

Compiler Error C3234 a generic class may not derive from a generic type parameter

Compiler Error C3235 'specialization': explicit or partial specialization of a generic


class is not allowed

Compiler Error C3236 explicit instantiation of a generic is not allowed

Compiler Error C3237 'class': a generic class cannot be a custom attribute

Compiler Error C3238 'type': a type with this name has already been forwarded to
assembly 'assembly'

Compiler Error C3239 'type': pointer to interior/pin pointer is disallowed by the


common language runtime

Compiler Error C3240 'identifier': must be a non-overloaded abstract member


function of 'type'

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 C3245 'function': use of a variable template requires template


argument list

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 C3248 Obsolete. 'function': function declared as 'sealed' cannot be


overridden by 'function'

Compiler Error C3249 illegal statement or sub-expression for 'constexpr' function

Compiler Error C3250 'declaration': declaration is not allowed in 'constexpr' function


body

Compiler Error C3251 cannot invoke base class method on a value type instance

Compiler Error C3252 'function': cannot reduce accessibility of a virtual method in a


managed/WinRT type

Compiler Error C3253 'function': error with explicit override

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 C3257 Obsolete.

Compiler Error C3258 Obsolete.

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 C3263 Obsolete.


ERROR MESSAGE

Compiler Error C3264 'identifier': a class-constructor cannot have a return type

Compiler Error C3265 cannot declare a managed 'managed_construct' in an


unmanaged 'unmanaged_construct'

Compiler Error C3266 'function': a class-constructor must have a 'void' parameter list

Compiler Error C3267 Obsolete.

Compiler Error C3268 'function': a generic function or a member-function of a


generic class cannot have a variable parameter list

Compiler Error C3269 'function': a member-function of a managed/WinRT type


cannot be declared with '...'

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 C3272 'symbol': symbol requires FieldOffset, as it is a member of


struct/class type_name defined with
StructLayout(LayoutKind::Explicit)

Compiler Error C3273 'keyword': not allowed on C++ try block

Compiler Error C3274 finally/__finally without matching try

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 C3277 cannot define an unmanaged enum 'enumeration' inside


managed 'type'

Compiler Error C3278 direct call of interface or pure method 'function' will fail at
runtime

Compiler Error C3279 partial and explicit specializations as well as explicit


instantiations of class templates declared in the cli namespace
are disallowed

Compiler Error C3280 'function': a member-function of a managed type cannot be


compiled as an unmanaged function

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 C3283 'interface': an interface cannot have an instance constructor


ERROR MESSAGE

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 C3288 'type': illegal dereference of a handle type

Compiler Error C3289 'identifier': a trivial property cannot be indexed

Compiler Error C3290 'type': a trivial property cannot have reference type

Compiler Error C3291 'default': cannot be the name of a trivial property

Compiler Error C3292 the cli namespace cannot be reopened

Compiler Error C3293 'identifier': use 'default' to access the default property
(indexer) for class 'class'

Compiler Error C3294 Obsolete.

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
{
};

template<template<typename U> class T1, typename T2>


class Y
{
};

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
{
};

template<template<typename T> class U = X1> // C3201


class X2
{
};

template<template<typename T, typename V> class U = X1> // OK


class X3
{
};
Compiler Error C3202
10/31/2018 • 2 minutes to read • Edit Online

'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
{
};

template<template<typename U> class T1 = Z, typename T2> // C3202


class Y
{
};
Compiler Error C3203
10/31/2018 • 2 minutes to read • Edit Online

'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) {}
};

template< typename T >


struct Y : public X<Y> { // C3203
// try the following line instead
// struct Y : public X<Y<T> > {
void f(Y) {}
};

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 {};

template <class T>


class C1 {};

typedef C1<S1> MyC1; // C3203

// OK
template <template <class> class T>
class C2 {};

typedef C2<S1> MyC1;

template <class T>


class C3 {};

typedef C3<S1<int> > MyC12;

C3203 can also occur when using generics:


// C3203_c.cpp
// compile with: /clr /c
generic <class T>
value struct GS1 {};

generic <class T>


value struct GC1 {};

typedef GC1<GS1> MyGC1; // C3203


typedef GC1<GS1<int> > MyGC2; // OK
Compiler Error C3204
10/31/2018 • 2 minutes to read • Edit Online

'_alloca' cannot be called from within a catch block


This error occurs when you use a call to _alloca from within a catch block.

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

argument list for template parameter 'parameter' is missing


A template parameter is missing.

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;
};

template <class T>


struct B {
typedef int value_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() {}

template <class T>


struct S {};

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() {}

template <class T>


struct S {};

void f1() {
f<S<int> >();
}

C3206 can also occur when using generics:

// C3206c.cpp
// compile with: /clr
generic <class GT1>
void gf() {}

generic <class T>


value struct GS {};

int main() {
gf<GS>(); // C3206
}

Possible resolution:
// C3206d.cpp
// compile with: /clr
generic <class GT1>
void gf() {}

generic <class T>


value struct GS {};

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 {};

template <class T>


void func() { // takes a type
T<int> t;
}

int main() {
func<S>(); // C3206 S is not a type.
}

Possible resolution:

// C3206f.cpp
template <class T>
struct S {};

template <class T>


void func() { // takes a type
T t;
}

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 {};

template<template<class> class TT>


struct X {
static void func() {
TT<int> t1;
TT<char> t2;
}
};

int main() {
X<S>::func();
}
Compiler Error C3207
10/31/2018 • 2 minutes to read • Edit Online

'function' : invalid template argument for 'arg', class template expected


A template function is defined as taking a template template argument. However, a template type argument was
passed.
The following sample generates C3207:

// C3207.cpp
template <template <class T> class TT>
void f(){}

template <class T>


struct S
{
};

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();

template <class T1, class T2>


struct S;

template <class T1>


struct R;

int i = f<S>(); // C3208


// try the following line instead
// int i = f<R>();
Compiler Error C3209
10/31/2018 • 2 minutes to read • Edit Online

'class' : generic class must be a managed or WinRTclass


A generic class must be a managed class or a Windows Runtime class.
The following sample generates C3209 and shows how to fix it:

// C3209.cpp
// compile with: /clr
generic <class T>
class C {}; // C3209

// OK - ref class can be generic


generic <class T>
ref class D {};
Compiler Error C3210
10/31/2018 • 2 minutes to read • Edit Online

'type' : access declaration can only be applied to a base class member


A using declaration was specified incorrectly.

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

'specialization' : an explicit specialization of a template member must be a member of an explicit specialization


An explicit specialization was ill formed.
The following sample generates C3212:

// C3212.cpp
// compile with: /LD
template <class T>
struct S {
template <class T1>
struct S1;
};

template <class T> // C3212


template <>
struct S<T>::S1<int> {};

/*
// 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

base class 'base_type' is less accessible than 'derived_type'


A type that will be visible from an assembly must use publicly visible base classes.
The following sample generates C3213:

// C3213.cpp
// compile with: /clr
private ref struct privateG {
public:
int i;
};

public ref struct publicG {


public:
int i;
};

public ref struct V : public privateG { // C3213


public:
int j;
};

public ref struct W: public publicG { // OK


public:
int j;
};
Compiler Error C3214
10/31/2018 • 2 minutes to read • Edit Online

'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 {};

generic <class T>


where T : A
ref class C {};

ref class X : public 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

'type1' : generic type parameter already constrained by 'type2'


A constraint was specified more than once.
For more information on generics, see Generics.
The following sample generates C3215:

// C3215.cpp
// compile with: /clr
interface struct A {};

generic <class T>


where T : A,A
ref class C {}; // C3215

Possible resolution:

// C3215b.cpp
// compile with: /clr /c
interface struct A {};

generic <class T>


where T : A
ref class C {};
Compiler Error C3216
10/31/2018 • 2 minutes to read • Edit Online

constraint must be a generic parameter, not 'type'


A constraint was ill formed.
The following sample generates C3216:

// C3216.cpp
// compile with: /clr
interface struct A {};

generic <class T>


where F : A // C3216
// Try the following line instead:
// where T : A // C3216
ref class C {};

The following example demonstrates a possible resolution:

// C3216b.cpp
// compile with: /clr /c
interface struct A {};

generic <class T>


where T : A
ref class C {};
Compiler Error C3217
10/31/2018 • 2 minutes to read • Edit Online

'param' : generic parameter cannot be constrained in this declaration


A constraint was ill formed; the constraint generic parameter must agree with the generic class template parameter.
The following sample generates C3217:

// C3217.cpp
// compile with: /clr
interface struct A {};

generic <class T>


ref class C {
generic <class T1>
where T : A // C3217
void f();
};

The following sample demonstrates a possible resolution:

// C3217b.cpp
// compile with: /clr /c
interface struct A {};

generic <class T>


ref class C {
generic <class T1>
where T1 : A
void f();
};
Compiler Error C3218
10/31/2018 • 2 minutes to read • Edit Online

'type' : type not allowed as a constraint


For a type to be a constraint, it must be either a value type or reference to a managed class or interface.

Example
The following sample generates C3218.

// C3218.cpp
// compile with: /clr /c
class A {};
ref class B {};

// Delete the following 3 lines to resolve.


generic <class T>
where T : A // C3218
ref class C {};

// OK
generic <class T>
where T : B
ref class D {};
Compiler Error C3219
10/31/2018 • 2 minutes to read • Edit Online

'param' : generic parameter cannot be constrained by multiple non-interfaces : 'class'


It is not valid to constrain a generic parameter by two or more managed classes.
The following sample generates C3219:

// C3219.cpp
// compile with: /clr
ref class A {};
ref class B {};

generic <class T>


where T : A, B
ref class E {}; // C3219

The following sample demonstrates a possible resolution:

// C3219b.cpp
// compile with: /clr /c
ref class A {};

interface struct C {};

generic <class T>


where T : A
ref class E {};
Compiler Error C3222
10/31/2018 • 2 minutes to read • Edit Online

'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

'property' : you cannot apply 'typeid' to a property


You cannot apply typeid to a property.

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

'type' : no overloaded generic class takes 'number' generic type arguments


The compiler failed to find an appropriate overload.
The following sample generates C3224:

// 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 {};

ref class B {};

generic <class T>


ref class C {};

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

A template declaration is not allowed inside a generic declaration


Use a generic declaration inside a generic class.
The following sample generates C3226:

// C3226.cpp
// compile with: /clr
generic <class T>
ref class C {
template <class T1> // C3226
ref struct S1 {};
};

The following sample demonstrates a possible resolution:

// 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

'parameter' : cannot use 'keyword' to allocate a generic type


In order to instantiate a type, an appropriate constructor is required. However, the compiler is not able to ensure
that an appropriate constructor is available.
You can use templates instead of generics to resolve this error, or you can use one of several methods to create an
instance of the type.

Example
The following sample generates C3227.

// C3227.cpp
// compile with: /clr /c
generic<class T> interface class ICreate {
static T Create();
};

generic <class T>


where T : ICreate<T>
ref class C {
void f() {
T t = new T; // C3227

// 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 {};

value class B {};

generic <class T>


void Test() {}

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

'type' : indirections on a generic type parameter are not allowed


You cannot use generic parameters with * , ^ , or & .

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);

generic <class U>


ref class C {
void f1(U x) {
f(x); // C3230
}
};
Compiler Error C3231
10/31/2018 • 2 minutes to read • Edit Online

'arg' : template type argument cannot use a generic type parameter


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 C3231:

// C3231.cpp
// compile with: /clr /LD
template <class T> class A;

generic <class T>


ref class C {
void f() {
A<T> a; // C3231
}
};
Compiler Error C3232
10/31/2018 • 2 minutes to read • Edit Online

'param' : a generic type parameter cannot be used in a qualified name


A generic type parameter was used incorrectly.
The following sample generates C3232:

// 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

'type' : generic type parameter already constrained


It is not valid to constrain a generic parameter in more than one where clause.
The following sample generates C3233:

// C3233.cpp
// compile with: /clr /LD

interface struct C {};


interface struct D {};

generic <class T>


where T : C
where T : D
ref class E {}; // C3233
Compiler Error C3234
10/31/2018 • 2 minutes to read • Edit Online

a generic class may not derive from a generic type parameter


A generic class cannot inherit from a generic type parameter.

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

'specialization' : explicit or partial specialization of a generic class is not allowed


Generic classes cannot be used for explicit or partial specializations.

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

explicit instantiation of a generic is not allowed


The compiler does not allow explicit instantiation of generic classes.
The following sample generates C3236:

// C3236.cpp
// compile with: /clr
generic<class T>
public ref class X {};

generic ref class X<int>; // C3236

The following sample demonstrates a possible resolution:

// 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

'generic_class' : a generic class cannot be a custom attribute


Generic classes cannot be user-defined attributes.

Example
The following sample generates C3237.

// C3237.cpp
// compile with: /clr /c
// C3237 expected
using namespace System;

generic <class T>


// Delete the following line to resolve.
[attribute(AttributeTargets::All, AllowMultiple=true)]
public ref class GR {};
Compiler Error C3238
10/31/2018 • 2 minutes to read • Edit Online

'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

'type' : pointer to interior/pin pointer is disallowed by the common language runtime


The compiler encountered an invalid type.
The following sample generates C3229:

// 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

'function' : must be a non-overloaded abstract member function of 'type'


A base type contained a function that was defined. Function must be virtual.

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;
};

template <class T>


struct A3 : T {
void T::f() {}
};

template <class T>


struct A4 : T {
void T::f() {}
};

A3<A1> x; // C3240
A3<I> x2;
A4<A2> x3;
Compiler Error C3241
10/31/2018 • 2 minutes to read • Edit Online

'method' : this method was not introduced by 'interface'


When you explicitly override a function, the function signature must exactly match the declaration for the function
that you are overriding.
The following sample generates C3241:

// C3241.cpp
#pragma warning(disable:4199)

__interface IX12A {
void mf();
};

__interface IX12B {
void mf(int);
};

class CX12 : public IX12A, public IX12B { // C3241


void IX12A::mf(int);
};
Compiler Error C3242
10/31/2018 • 2 minutes to read • Edit Online

'function' : you can only explicitly override virtual functions


You tried to explicitly override a nonvirtual method.
Compiler Error C3243
10/31/2018 • 2 minutes to read • Edit Online

none of the overload functions were introduced by 'interface'


You tried to explicitly override a member that does not exist in the specified interface.
The following sample generates C3243:

// C3243.cpp
#pragma warning(disable:4199)
__interface IX14A {
void g();
};

__interface IX14B {
void f();
void f(int);
};

class CX14 : public IX14A, public IX14B {


public:
void IX14A::g();
void IX14B::f();
void IX14B::f(int);
};

void CX14::IX14A::f() // C3243 occurs here


{
}
Compiler Error C3244
10/31/2018 • 2 minutes to read • Edit Online

'method' : this method was introduced by 'interface' not by 'interface'


You tried to explicitly override a member that does not exist in the specified interface but does exist in another base
class.
The following sample generates C3244:

// C3244.cpp
#pragma warning(disable:4199)

__interface IX15A {
void f();
};

__interface IX15B {
void g();
};

class CX15 : public IX15A, public IX15B {


public:
void IX15A::f();
void IX15B::g();
};

void CX15::IX15A::g() // C3244 occurs here


{
}
Compiler Error C3246
10/31/2018 • 2 minutes to read • Edit Online

'class' : cannot inherit from 'type' as it has been declared as 'sealed'


A class that is marked as sealed cannot be the base class for any other classes.
The following sample generates C3246:

// C3246_2.cpp
// compile with: /clr /LD
ref class X sealed {};

ref class Y : public X {}; // C3246


Compiler Error C3247
10/31/2018 • 2 minutes to read • Edit Online

'class1' : a coclass cannot inherit from another coclass 'class2'


A class marked with the coclass attribute cannot inherit from another class marked with the coclass attribute.
The following sample generates C3247:

// 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

'function1': function declared as '__sealed' cannot be overridden by 'function2'


A derived class tried to override a __sealed virtual method.
C3248 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3251
10/31/2018 • 2 minutes to read • Edit Online

cannot invoke base class method on a value type instance


The following error occurs because GetClass is a member of Microsoft.Runtime.Object , not of
Microsoft.Runtime.Integer4 .
Compiler Error C3252
10/31/2018 • 2 minutes to read • Edit Online

'method' : cannot reduce accessibility of a virtual method in a managed or WinRT type


A class that implements a virtual method from a base class or any method from an interface cannot reduce the
access of that method.
Note that all methods in an interface are public.
The following sample generates C3252 and shows how to fix it:

// C3252.cpp
// compile with: /clr /c
ref class A {
public:
virtual void f1() {}
};

ref class B : public A {


// To fix, uncomment the following line:
// public:
virtual void f1() override sealed {} // C3252, make this method public
};
Compiler Error C3253
10/31/2018 • 2 minutes to read • Edit Online

'function' : error with explicit override


An explicit override was specified incorrectly. For example, you cannot specify an implementation for an override
that you also specify as pure. For more information, see Explicit Overrides.
The following sample generates C3253:

// C3253.cpp
// compile with: /clr
public interface struct I {
void a();
void b();
void c();
};

public ref struct R : I {


virtual void a() = 0, I::a {} // C3253
virtual void b() = I::a {} // OK
virtual void c() = 0; // OK
};
Compiler Error C3254
10/31/2018 • 2 minutes to read • Edit Online

'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

ref class MyClass {


public:
int m_i;
};

// returns a multidimensional managed array of a reference type


array<MyClass^, 2>^ Test0() {
int i, j;
array< MyClass^, 2 >^ local = new array< MyClass^, 2 >
(ARRAY_SIZE, ARRAY_SIZE);

for (i = 0 ; i < ARRAY_SIZE ; i++)


for (j = 0 ; j < ARRAY_SIZE ; j++) {
local[i][j] = new MyClass; // C3262
// try the following line instead
// local[i,j] = new MyClass;
local[i,j] -> m_i = i;
}

return local;
}

int main() {
int i, j;

array< MyClass^, 2 >^ MyClass0;


MyClass0 = Test0();
}
Compiler Error C3264
10/31/2018 • 2 minutes to read • Edit Online

'class' : a class-constructor cannot have a return type


Class constructors cannot have return types.
The following sample generates C3264:

// C3264_2.cpp
// compile with: /clr

ref class X {
public:
static int X() { // C3264
}

/* use the code below to resolve the error


static X() {
}
*/
};
int main() {
}
Compiler Error C3265
10/31/2018 • 2 minutes to read • Edit Online

cannot declare a managed 'managed construct' in an unmanaged 'unmanaged construct'


You cannot include a managed object in an unmanaged context.
The following sample reproduces C3265:

// 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

'class' : a class-constructor must have a 'void' parameter list


Class-constructors in a class using /clr programming cannot take parameters.
The following sample generates C3266:

// 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) {}

generic <class ItemType2>


ref struct MyStruct { void Test(...){} }; // C3268
// try the following line instead
// ref struct MyStruct { void Test2(){} }; // OK
Compiler Error C3269
10/31/2018 • 2 minutes to read • Edit Online

'function' : a member-function of a managed or WinRTtype cannot be declared with '...'


Managed and WinRT class member functions cannot declare variable-length parameter lists.
The following sample generates C3269 and shows how to fix it:

// 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

'member': invalid value 'value' for the FieldOffset attribute


A negative number was passed to the FieldOffset attribute.
The following sample generates C3271:

// 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

'symbol' : symbol requires FieldOffset, as it is a member of type typename defined with


StructLayout(LayoutKind::Explicit)
When StructLayout(LayoutKind::Explicit) is in effect, fields must be marked with FieldOffset .
The following sample generates C3272:

// 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

__finally cannot be used on an exception block in unmanaged code.


The following sample generates C3273:

// 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

__finally/finally without matching try


A __finally or finally statement was found without a matching try . To resolve this, either delete the __finally
statement or add a try statement for the __finally .
The following sample generates C3274:

// 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");
}

// Uncomment the following 3 lines to resolve.


// try {
// throw gcnew ApplicationException();
// }

finally {
Console::WriteLine(L"In finally");
}
Console::WriteLine(L"**FAIL**");
}
Compiler Error C3275
10/31/2018 • 2 minutes to read • Edit Online

'enum member' : cannot use this symbol without qualifier


When using managed code and when two or more enumerations contain an identifier with the same name, you
must explicitly qualify references to the identifier.
C3275 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3276
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

cannot define an unmanaged enum 'enum' inside managed 'type'


An enumeration was defined incorrectly inside a managed type.
The following sample generates C3277:

// 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

direct call of interface or pure method 'method' will fail at runtime

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();
};

public ref class C: public I


{
public:
void vmf()
{
Console::WriteLine( "In C::vmf()" );
I::vmf(); // C3278
}

};

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

'class' : a member-function of a managed type cannot be compiled as an unmanaged function


Managed class member functions cannot be compiled as unmanaged functions.
The following sample generates C3280:

// C3280_2.cpp
// compile with: /clr
ref struct A {
void func();
};

#pragma managed(push,off)

void A::func() // C3280


{
}

#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

ref struct GC0 {


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

'type' : an interface cannot have an instance constructor


A CLR interface cannot have an instance constructor. A static constructor is allowed.
The following sample generates C3283:

// 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();
};

public interface class B {


generic<typename T>
where T : IGettable
virtual int mf(T t);
};

public ref class D : public B {


public:
generic<typename T>
// Uncomment the following line to resolve.
// where T : IGettable
virtual int mf(T t) {
return 4;
}
};
Compiler Error C3285
10/31/2018 • 2 minutes to read • Edit Online

for each statement cannot operate on variables of type 'type'


The for each statement repeats a group of embedded statements for each element in an array or an object
collection.
See for each, in for more information.

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

'specifier': an iteration variable cannot have any storage-class specifiers

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 T {};

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

'type' : illegal dereference of a handle type


The compiler detected an illegal dereference of a handle type. You can dereference a handle type and assign it to a
reference. For more information, see Tracking Reference Operator.

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

'property' : a trivial property cannot be indexed


A property was declared incorrectly. Accessors must be defined for an indexed property. See property for more
information.

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

'type' : a trivial property cannot have reference type


A property was declared incorrectly. When you declare a trivial property, the compiler creates a variable that the
property will update, and it is not possible to have a tracking reference variable in a class.
See property and Tracking Reference Operator for more information.

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

'default' : cannot be the name of a trivial property


A trivial property cannot be named default . See property for more information.

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

the cli namespace cannot be reopened


The cli namespace cannot be declared in your code. For more information, see Platform, default, and cli
Namespaces.

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

'#pragma pragma' can only be used at global or namespace scope


Some pragmas cannot be used in a function. See Pragma Directives and the __Pragma Keyword for more
information.

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

'property' : a property with this name already exists


The compiler encountered more than one property with the same name. Each property in a type must have a
unique name.
For more information, see property.

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); }

property String^ MyProp[int] { void set(int, String^); } // C3296


};
Compiler Error C3297
10/31/2018 • 2 minutes to read • Edit Online

'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();
};

public ref struct S : R {


generic<class T>
where T : R // C3299
virtual void f() override;
};
Compiler Errors C3300 Through C3399
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 C3300 'symbol': improper format for IDL 'value'

Compiler Error C3301 'coclass': coclass cannot be a 'symbol' interface

Compiler Error C3302 'identifier': identifier has more than number characters

Compiler Error C3303 'attribute': attribute can only be used on 'type'

Compiler Error C3304 Obsolete.

Compiler Error C3305 Obsolete.

Compiler Error C3306 'template': unnamed class template/generic is not allowed


ERROR MESSAGE

Compiler Error C3307 'module': unable to create IDL module

Compiler Error C3308 ' function': direct call through imported class is not supported

Compiler Error C3309 'macro/keyword': module name cannot be a macro or a


keyword

Compiler Error C3310 'identifier': module name conflict

Compiler Error C3311 module attribute must be defined at global scope

Compiler Error C3312 no callable 'identifier' function found for type 'type'

Compiler Error C3313 'identifier': variable cannot have the type 'type'

Compiler Error C3314 'symbol': not a supported IDL module type

Compiler Error C3315 ' function': must be a member function

Compiler Error C3316 'type': an array of unknown size cannot be used in a range-
based for statement

Compiler Error C3317 'identifier': an overload function cannot be used as the


expression in a range-based for statement

Compiler Error C3318 'type': an array cannot have an element type that contains
'auto'

Compiler Error C3319 Obsolete.

Compiler Error C3320 'type': type cannot have the same name as the module 'name'
property

Compiler Error C3321 an initializer list is unexpected in this context

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 C3325 'attribute': attribute has too many arguments

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 C3329 syntax error: expected 'token1' not 'token2'

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 C3332 'property': grammar inconsistent, property 'property' is both


required and has a default

Compiler Error C3333 'library': cannot #import corrupt type library

Compiler Error C3334 cannot #import corrupt type library

Compiler Error C3335 'identifier': There can be at most one default interface for a
coclass 'class'

Compiler Error C3336 This operation must be performed at class scope

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 C3339 template template parameter requires either 'class' or


'typename' after the parameter list

Compiler Error C3340 'identifier': interface cannot be both 'restricted' and 'default' in
coclass 'class'

Compiler Error C3341 'interface': a defaultvtable interface must be either 'dual' or


'custom'

Compiler Error C3342 'identifier': ambiguous attribute

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 C3345 'name': invalid identifier for module name

Compiler Error C3346 exported declaration at non-namespace scope

Compiler Error C3347 'argument': required argument is not specified in attribute


asttribute

Compiler Error C3348 exported templates are not part of the current C++ standards

Compiler Error C3349 'class::member': multicast attribute has already been


implemented by provider provider
ERROR MESSAGE

Compiler Error C3350 ' function': a delegate constructor expects number


argument(s)

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 C3355 'class::member': multicast attribute listens to provider


'provider1', but is implemented by provider 'provider2'

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 C3358 'symbol': symbol not found

Compiler Error C3359 'specialization': cannot specialize template

Compiler Error C3360 'string': cannot create name

Compiler Error C3361 there is no context in which to action

Compiler Error C3362 'class::member': multicast attribute has not been implemented

Compiler Error C3363 'identifier': 'typeid' can only be applied to a type

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 C3368 'declarator': invalid calling convention for IDL

Compiler Error C3369 'module': idl_module already defined


ERROR MESSAGE

Compiler Error C3370 'module': idl_module not yet defined

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 C3373 attribute 'attribute' takes no arguments except on a coclass

Compiler Error C3374 can't take address of ' function' unless creating delegate
instance

Compiler Error C3375 'function': ambiguous delegate function

Compiler Error C3376 'template': only static data member templates are allowed

Compiler Error C3377 'decltype(auto)' is not allowed in a new-expression

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 C3382 'sizeof' is not supported with /clr:safe

Compiler Error C3383 'operator new' is not supported with /clr:safe

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 C3386 'type': __declspec(dllexport)/__declspec(dllimport) cannot be


applied to a managed/WinRT type

Compiler Error C3387 'member': __declspec(dllexport)/__declspec(dllimport) cannot


be applied to a member of a managed/WinRT type

Compiler Error C3388 'token': not allowed as a constraint, assuming 'value' to


continue parsing

Compiler Error C3389 __declspec(specifier) cannot be used with /clr:pure or /clr:safe


ERROR MESSAGE

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 C3395 ' function': __declspec(dllexport) cannot be applied to a


function with the __clrcall calling convention

Compiler Error C3396 'class.member': custom attribute not found in 'namespace'

Compiler Error C3397 Aggregate initialization is not allowed in default arguments

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

'attribute': attribute can only be used on 'usage'


An attempt was made to use an attribute where it is not valid.
Compiler Error C3309
10/31/2018 • 2 minutes to read • Edit Online

'macro_name': module name cannot be a macro or a keyword


The value that you pass to the name property of the module attribute cannot be a symbol for the preprocessor to
expand; it must be a string literal.
The following sample generates C3309:

// 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")];

[export] struct xx { // C3320


// Try the following line instead
// [export] struct yy {
int i;
};
Compiler Error C3322
10/31/2018 • 2 minutes to read • Edit Online

'property': is not a valid property for attribute 'attribute'


An invalid or unrecognized property (or parameter) was passed to an attribute. Check the documentation for the
attribute.
Compiler Error C3333
10/31/2018 • 2 minutes to read • Edit Online

'type library': cannot #import corrupt type library


The type library specified in the #import statement is unreadable by the compiler. You may want to either
regenerate the type library, if possible, or request a new type library from your supplier. You may want to use the
OLE Viewer, supplied with Visual C++, to view the type library file to see what is the matter with it.
Compiler Error C3334
10/31/2018 • 2 minutes to read • Edit Online

cannot #import corrupt type library


The library file in a #import statement is corrupt and can't be consumed by the compiler. Corruption can come
from bad generation of the module, disk corruption, or if the binary file was somehow edited and modified.
For more information, see #import Directive.
Compiler Error C3340
10/31/2018 • 2 minutes to read • Edit Online

'interface': interface cannot be both 'restricted' and 'default' in coclass 'class'


The restricted attribute and the default attribute are mutually exclusive.
The following sample generates C3340:

// 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

'attribute': ambiguous attribute


The compiler found more than one definition of an attribute.
An attribute was defined more than once.
For more information, see User-Defined Attributes.

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 {};

[X] // C3342 could refer to X or XAttribute


// try the following line instead
// [XAttribute]
public ref class Class4 {};
Compiler Error C3345
10/31/2018 • 2 minutes to read • Edit Online

'identifier': invalid identifier for module name


The identifier for a module contains one or more unacceptable characters. An identifier is valid if the first character
is an alphabetical, underscore, or high ANSI (0x80-FF ) character, and any subsequent character is an alphanumeric,
underscore, or high ANSI character.
To correct this error
1. Ensure that identifier does not contain blanks or other unacceptable characters.

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

'arg': required argument is not specified in attribute idl_module


A required argument was not passed to the idl_module attribute.
The following sample generates C3347:

// 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

'delegate' : a delegate constructor expects number argument(s)


When you create an instance of a delegate, you must pass two arguments, an instance of the type containing the
delegate function, and the function.
The following sample generates C3350:

// C3350.cpp
// compile with: /clr
delegate void SumDelegate();

public ref class X {


public:
void F() {}
static void F2() {}
};

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;
}

static int mf2(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;
}

// Uncomment the following line to resolve.


// int mf(int, 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 )();

delegate VoidPfn func(); // C3354


// try the following line instead
// delegate void func();
Compiler Error C3356
10/31/2018 • 2 minutes to read • Edit Online

'attribute': cannot call a multicast attribute with a fully qualified name


An attribute that is processed by more than one process, for example, the compiler and ATL provider, was specified
incorrectly.
Compiler Error C3358
10/31/2018 • 2 minutes to read • Edit Online

'symbol': symbol not found


The required symbol was not found.
The following sample generates C3358:

// 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

'string': cannot create name


The value that was passed to the uuid attribute was not valid.
The following sample generates C3360:

// 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

'type' : 'typeid' can only be applied to a type


The typeid operator was used incorrectly.

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

delegate int D( int, int );

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

// try the following line instead


// System::Delegate^ pD = gcnew D(pC, &C::mf);
}
Compiler Error C3365
10/31/2018 • 2 minutes to read • Edit Online

operator 'operator' : differing operands of type 'type1' and 'type2'


An attempt was made to compose delegates with different types. See How to: Define and Use Delegates
(C++/CLI) for more information about delegates.

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
};

int X::i = 5; // C3366


Compiler Error C3367
10/31/2018 • 2 minutes to read • Edit Online

'static_member_function' : cannot use static function to create an unbound delegate


When you call an unbound delegate, you must pass an instance of an object. Since a static member function is
called through the class name, you can only instantiate an unbound delegate with an instance member function.
For more information about unbound delegates, see How to: Define and Use Delegates (C++/CLI).

Example
The following sample generates C3367.

// C3367.cpp
// compile with: /clr
ref struct R {
void b() {}
static void f() {}
};

delegate void Del(R^);

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

'function declaration' : invalid calling convention for IDL


You can only use the __stdcall or __cdecl calling conventions in an .idl file.
The following sample generates C3368:

// 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

'module name': idl_module already defined


The idl_module usage where you define the DLL can only occur once in a program.
The following sample generates C3369:

// 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

'idl_module name': idl_module not yet defined


Before you can use idl_module to specify an entry point in a DLL, you must first use idl_module to specify the DLL
name.
The following sample generates C3370:

// 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

'idl_module': only the 'name' property is allowed here


idl_module usage directly on a function declaration cannot have any parameters other than name.
The following sample generates C3371:

// 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

must specify at least 1 interface for attribute 'source' on a coclass


For certain attributes, you must pass an interface name as a parameter.
The following sample generates C3372:

// 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

attribute 'attribute' takes no arguments except on a coclass


Some attributes can be applied to more than one C++ construct, but arguments to the attribute may only be
allowed on some constructs.
The following sample generates C3373:

// 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

can't take address of 'function' unless creating delegate instance


The address of a function was taken in a context other than the creation of a delegate instance.
The following sample generates C3374:

// 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

'function' : ambiguous delegate function


A delegate instantiation could have been to a static member function, or as an unbound delegate to an instance
function, so the compiler issued this error.
For more information, see delegate (C++ Component Extensions).

Example
The following sample generates C3375.

// C3375.cpp
// compile with: /clr
ref struct R {
static void f(R^) {}
void f() {}
};

delegate void Del(R^);

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;

public ref class A {


public:
static int i = 9;

public ref class BA { // C3379


// try the following line instead
// ref class BA {
public:
static int ii = 8;
};
};

int main() {

A^ myA = gcnew A;
Console::WriteLine(myA->i);

A::BA^ myBA = gcnew A::BA;


Console::WriteLine(myBA->ii);
}
Compiler Error C3380
10/31/2018 • 2 minutes to read • Edit Online

'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

'sizeof' is not supported with /clr:safe


The output file of a /clr:safe compilation is a file that is verifiably type safe, and sizeof is not supported because
the return value of the sizeof operator is size_t, whose size varies depending on the operating system.
For more information, see,
sizeof Operator
/clr (Common Language Runtime Compilation)
Common Visual C++ 64-bit Migration Issues

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

'operator new' is not supported with /clr:safe


The output file of a /clr:safe compilation is a file that is verifiably type safe, and pointers are not supported.
For more information, see,
/clr (Common Language Runtime Compilation)
Common Visual C++ 64-bit Migration Issues

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;

struct SomeStruct1 {};

public ref struct Wrap {


[ DllImport("somedll.dll", CharSet=CharSet::Unicode) ]
static SomeStruct1 f1([In, Out] SomeStruct1 *pS); // C3385
};
Compiler Error C3386
10/31/2018 • 2 minutes to read • Edit Online

'type' : __declspec(dllexport)/__declspec(dllimport) cannot be applied to a managed or WinRTtype


The dllimport and dllexport __declspec modifiers are not valid on a managed or Windows Runtime type.
The following sample generates C3386 and shows how to fix it:

// 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

'member' : __declspec(dllexport)/__declspec(dllimport) cannot be applied to a member of a managed or WinRT


type
The dllimport and dllexport __declspec modifiers are not valid on members of a managed or Windows Runtime
type.
The following sample generates C3387 and shows how to fix it:

// 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

'type' : not allowed as a constraint, assuming 'ref class' to continue parsing


A constraint was specified on a generic type, but the constraint was not specified correctly. See Constraints on
Generic Type Parameters (C++/CLI) for more information.

Example
The following sample generates C3388.

// C3388.cpp
// compile with: /clr /c
interface class AA {};

generic <class T>


where T : interface class // C3388
ref class C {};

// OK
generic <class T>
where T : AA
ref class D {};
Compiler Error C3389
10/31/2018 • 2 minutes to read • Edit Online

__declspec(keyword) cannot be used 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.
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>

ref class R { R(int) {} };


ref class N { N() {} };

value class V {};

ref class N2 { public: N2() {} };


ref class R2 { public: R2() {} };

int main () {
GR<R^, V, N^>^ gr1; // C3392
GR<R^, V, N2^>^ gr1a; // OK

GR<R^, N^, N^>^ gr3; // C3392


GR<R^, V, N2^>^ gr3a; // OK

GR<R^, V, R^>^ gr4; // C3392


GR<R^, V, R2^>^ gr4a; // OK
}
Compiler Error C3393
10/31/2018 • 2 minutes to read • Edit Online

syntax error in constraint clause: 'identifier' is not a type


The identifier passed to a constraint, which must be a type, was not a type. For more information, see Constraints
on Generic Type Parameters (C++/CLI).

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

syntax error in constraint clause: found 'identifier' expected a type


A constraint was ill formed. For more information, see Constraints on Generic Type Parameters (C++/CLI).

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

__declspec(dllexport) void __clrcall Test(){} // C3395


void __clrcall Test2(){} // OK
__declspec(dllexport) void Test3(){} // OK
Compiler Error C3396
10/31/2018 • 2 minutes to read • Edit Online

'attribute' : custom attribute not found in 'namespace'


C3396 indicates that you are not using an up-to-date common language runtime. Reinstall your CLR to resolve.
Compiler Error C3397
10/31/2018 • 2 minutes to read • Edit Online

Aggregate initialization is not allowed in default arguments


An array was declared incorrectly. See Arrays for more information.

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

'type' : cannot provide arguments when creating an instance of a generic parameter


When you specify the gcnew() constraint, you specify that the constraint type will have a parameterless
constructor. Therefore, it is an error to attempt to instantiate that type and pass a parameter.
See Constraints on Generic Type Parameters (C++/CLI) for more information.

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 C3400 circular constraint dependency involving 'constraint1' and


'constraint2'

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 C3403 thread_local cannot be used with /clr:pure or /clr:safe

Compiler Error C3404 'construct': unexpected syntax error

Compiler Error C3405 'function': cannot resolve overload without complete


descriptor
ERROR MESSAGE

Compiler Error C3406 'keyword': cannot be used in an elaborated type specifier

Compiler Error C3407 'type' cannot be used in this context

Compiler Error C3408 'attribute': attribute is not allowed on template definitions

Compiler Error C3409 empty attribute block is not allowed

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 C3412 'specialization': cannot specialize template in current scope

Compiler Error C3413 'template': invalid explicit instantiation

Compiler Error C3414 'function': imported member function can't be defined

Compiler Error C3415 multiple 'section' sections found with different attributes
('0xvalue')

Compiler Error C3416 Obsolete.

Compiler Error C3417 'declarator': value types cannot contain user-defined special
member functions

Compiler Error C3418 access specifier 'specifier' is not supported

Compiler Error C3419 Obsolete.

Compiler Error C3420 'function': a finalizer cannot be virtual

Compiler Error C3421 'function': you cannot call the finalizer for this class as it is
either inaccessible or it does not exist

Compiler Error C3422 'declaration': mismatched types 'type' and 'type'

Compiler Error C3423 Obsolete.

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 C3426 cannot throw object of incomplete type 'type'

Compiler Error C3427 'context': 'keyword' cannot be used with


layout_version(number)
ERROR MESSAGE

Compiler Error C3428 'context': 'keyword' can only be applied to class declarations or
definitions

Compiler Error C3429 'context': 'keyword' cannot be applied to a union

Compiler Error C3430 a scoped enumeration must have a name

Compiler Error C3431 'identifier': type1 cannot be redeclared as type2

Compiler Error C3432 'identifier': a forward declaration of an unscoped enumeration


must have an underlying type

Compiler Error C3433 'identifier': all declarations of an enumeration must have the
same underlying type, was 'type1' now 'type2'

Compiler Error C3434 'context': enumerator value 'number' cannot be represented as


'type', value is 'number'

Compiler Error C3435 character set 'name' is not supported

Compiler Error C3436 #pragma setlocale is not supported when /source-charset,


/execution-charset, or /utf-8 has been specified

Compiler Error C3437 #pragma execution_character_set is not supported when


/source-charset, /execution-charset, or /utf-8 has been
specified

Compiler Error C3438 'context': 'value' cannot be applied to a managed/WinRT class

Compiler Error C3439 layout_version(number): invalid version number

Compiler Error C3440 'declaration': layout_version(number) incompatible with a


prior declaration

Compiler Error C3441 'declaration': 'keyword' cannot be applied after the class has
been defined

Compiler Error C3442 Initializing multiple members of union: 'member1' and


'member2'

Compiler Error C3443 The default member initializer for 'class' is recursive

Compiler Error C3444 Empty aggregate class 'class' must be initialized with '{}'

Compiler Error C3445 copy-list-initialization of 'type' cannot use an explicit


constructor

Compiler Error C3446 'class': a default member initializer is not allowed for a member
of a value class

Compiler Error C3447 Obsolete.


ERROR MESSAGE

Compiler Error C3448 Obsolete.

Compiler Error C3449 Obsolete.

Compiler Error C3450 'type': not an attribute; cannot specify


[System::AttributeUsageAttribute]/[Windows::Foundation::Met
adata::AttributeUsageAttribute]

Compiler Error C3451 'attribute': cannot apply unmanaged attribute to 'type'

Compiler Error C3452 list argument member not constant

Compiler Error C3453 'attribute': attribute not applied because qualifier 'qualifier'
did not match

Compiler Error C3454 [attribute] not allowed on class declaration

Compiler Error C3455 'attribute': none of the attribute constructors matched the
arguments

Compiler Error C3456 [source_annotation_attribute] not allowed on managed/WinRT


class declaration

Compiler Error C3457 'attribute': attribute does not support unnamed arguments

Compiler Error C3458 '[attribute]': attribute '[attribute]' already specified for


'identifier'

Compiler Error C3459 '[attribute]': attribute allowed only on class indexer (default
indexed property)

Compiler Error C3460 'type': only a user-defined type can be forwarded

Compiler Error C3461 'type': only a managed/WinRT type can be forwarded

Compiler Error C3462 'type': only an imported type can be forwarded

Compiler Error C3463 'type': type not allowed in attribute 'implements'

Compiler Error C3464 'type' a nested type cannot be forwarded

Compiler Error C3465 to use type 'type' you must reference the assembly 'assembly'

Compiler Error C3466 'type': a specialization of a generic class cannot be forwarded

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 C3469 'type': a generic class cannot be forwarded


ERROR MESSAGE

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 C3473 no output pathname or module name specified.

Compiler Error C3474 could not open output file 'filename'

Compiler Error C3475 syntax error in input file 'filename'

Compiler Error C3476 could not open file 'filename' for input

Compiler Error C3477 a lambda cannot appear in an unevaluated context

Compiler Error C3478 'identifier': an array cannot be captured by copy

Compiler Error C3479 SAL annotations on lambdas are not supported

Compiler Error C3480 'variable': a lambda capture variable must be from an


enclosing function scope

Compiler Error C3481 'identifier': lambda capture variable not found

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 C3485 a lambda definition cannot have any cv-qualifiers

Compiler Error C3486 Obsolete.

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 C3490 'identifier' cannot be modified because it is being accessed


through a const object
ERROR MESSAGE

Compiler Error C3491 'identifier': a by copy capture cannot be modified in a non-


mutable lambda

Compiler Error C3492 'identifier': you cannot capture a member of an anonymous


union

Compiler Error C3493 'identifier' cannot be implicitly captured because no default


capture mode has been specified

Compiler Error C3494 'this' cannot be explicitly captured because an enclosing


capture mode does not allow it

Compiler Error C3495 'identifier': identifier in capture must be a variable with


automatic storage duration declared in the reaching scope of
the lambda

Compiler Error C3496 'this' is always captured by value: '&' ignored

Compiler Error C3497 you cannot construct an instance of a lambda

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

circular constraint dependency involving 'constraint_1' and 'constraint_2'


The compiler detected circular constraints.
For more information, see Constraints on Generic Type Parameters (C++/CLI).

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

'attribute': attribute is not allowed on template definitions


Attributes cannot be applied to template definitions.

Example
The following sample generates C3408.

// C3408.cpp
// compile with: /c
template <class T> struct PTS {
enum {
IsPointer = 0,
IsPointerToDataMember = 0
};
};

template <class T>


[coclass] // C3408
struct PTS<T*> {
enum {
IsPointer = 1,
IsPointerToDataMember = 0
};
};

template
<class T, class U>
struct PTS<T U::*> {
enum {
IsPointer = 1,
IsPointerToDataMember = 1
};
};

struct S{};

extern "C" int printf(const char*,...);

int main() {
S s, *pS;
int S::*ptm;

printf("PTS<S>::IsPointer == %d PTS<S>::IsPointerToDataMember == %d\n", PTS<S>::IsPointer, PTS<S>::


IsPointerToDataMember);
printf("PTS<S*>::IsPointer == %d PTS<S*>::IsPointerToDataMember == %d\n", PTS<S*>::IsPointer, PTS<S*>::
IsPointerToDataMember);
printf("PTS<int S::*>::IsPointer == %d PTS<int S::*>::IsPointerToDataMember == %d\n", PTS<int
S::*>::IsPointer, PTS<int S::*>:: IsPointerToDataMember);
}
Compiler Error C3409
11/8/2018 • 2 minutes to read • Edit Online

empty attribute block is not allowed

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

'template' : cannot specialize template in current scope


A template cannot be specialized at class scope, only in global or namespace scope.

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

'name' : invalid explicit instantiation


The compiler detected an ill-formed explicit instantiation.
The following sample generates C3413:

// 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

'member' : imported member function can't be defined


A member was defined in code that is also defined in a referenced assembly.
The following sample generates C3414:

// C3414a2.cpp
// compile with: /clr /LD
public ref class MyClass {
public:
void Test(){}
};

and then:

// C3414b2.cpp
// compile with: /clr
#using <C3414a2.dll>

void MyClass::Test() { // C3414


}

System::Object::Object() { // C3414
}
Compiler Error C3415
10/31/2018 • 2 minutes to read • Edit Online

multiple 'section_name' sections found with different attributes ('value')


Conflicting values were specified in section pragmas.
value is the current setting for the section, as specified in ntimage.h. For example:

// Section contains extended relocations.


#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
// Section can be discarded.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
// Section is not cachable.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
// Section is not pageable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
// Section is shareable.
#define IMAGE_SCN_MEM_SHARED 0x10000000
// Section is executable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
// Section is readable.
#define IMAGE_SCN_MEM_READ 0x40000000
// Section is writeable.
#define IMAGE_SCN_MEM_WRITE 0x80000000

The following sample generates C3415:

// C3415.cpp
#pragma section("mysec1",write)
#pragma section("mysec1",read) // C3415
Compiler Error C3417
10/31/2018 • 2 minutes to read • Edit Online

'member' : value types cannot contain user-defined special member functions


Value types cannot contain functions such as a default instance constructor, destructor, or copy constructor.
The following sample generates C3517:

// 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

access specifier 'specifier' is not supported


A CLR access specifier was specified incorrectly. For more information, see Type visibility and Member visibility in
How to: Define and Consume Classes and Structs (C++/CLI).

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

'finalizer' : a finalizer cannot be virtual


A finalizer can only be called non-virtually from its enclosing type. Therefore, it is an error to declare a virtual
finalizer.
For more information, see Destructors and finalizers in How to: Define and consume classes and structs
(C++/CLI).

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

copy-list-initialization of 'type' cannot use an explicit constructor

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
}

To correct the error, use direct initialization instead:

// 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
};

To correct the error, remove the initializer:

// C3446b.cpp
value struct V
{
int i;
int j;
};
Compiler Error C3450
10/31/2018 • 2 minutes to read • Edit Online

'type': not an attribute; cannot specify [System::AttributeUsageAttribute] or


[Windows::Foundation::Metadata::AttributeUsageAttribute]
A user-defined managed attribute must inherit from AttributeCollection. A Windows Runtime attribute must be
defined in the Windows::Foundation::Metadata namespace.
For more information, see User-Defined Attributes.

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;

public ref class MyClass {};

class MyClass2 {};

[attribute(AttributeTargets::All)]
ref struct AtClass {
AtClass(Type ^) {}
};

[attribute(AttributeTargets::All)]
ref struct AtClass2 {
AtClass2() {}
};

// Apply the AtClass and AtClass2 attributes to class B


[AtClass(MyClass::typeid), AtClass2]
[AttributeUsage(AttributeTargets::All)]
// Delete the following line to resolve.
ref class B {};
// Uncomment the following line to resolve.
// ref class B : Attribute {};
Compiler Error C3451
10/31/2018 • 2 minutes to read • Edit Online

'attribute': cannot apply unmanaged attribute to 'type'


A C++ attribute cannot be applied to a CLR type. See C++ Attributes Reference for more information.
For more information, see User-Defined Attributes.
This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: the uuid
attribute is no longer allowed on a user-defined attribute using CLR programming. Use GuidAttribute instead.

Example
The following sample generates C3451.

// C3451.cpp
// compile with: /clr /c
using namespace System;
[ attribute(AttributeTargets::All) ]
public ref struct MyAttr {};

[ MyAttr, helpstring("test") ] // C3451


// try the following line instead
// [ MyAttr ]
public ref struct ABC {};
Compiler Error C3452
10/31/2018 • 2 minutes to read • Edit Online

list argument member not constant


An argument was passed to an attribute that expected a constant, a value that can be evaluated at compile time.

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

[attribute] not allowed on class declaration


A class must be defined for it to be an attribute.
For more information, see attribute.

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

'attribute': none of the attribute constructors matched the arguments


An invalid value was used to declare an attribute. See attribute for more information.

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

[source_annotation_attribute] not allowed on managed or WinRT class declaration


source_annotation_attribute is used to define custom attributes to be used by code analysis.
These custom attributes are only useful if there is a corresponding plugin that understands the attribute.
Compiler Error C3457
10/31/2018 • 2 minutes to read • Edit Online

'attribute': attribute does not support unnamed arguments


Source annotation attributes, unlike CLR custom attribute or compiler attributes, only support named arguments.

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

'attribute1': attribute 'attribute2' already specified for 'construct'


Two attributes that are mutually exclusive were specified for the same construct.

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

'attribute': attribute allowed only on class indexer (default indexed property)


An attribute that is designed to be applied to a class indexer property was used incorrectly.
For more information, see How to: Use Properties in C++/CLI.

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

'type': only a user-defined type can be forwarded


For more information, see Type Forwarding (C++/CLI).

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

'type': only a managed type can be forwarded


Type forwarding can only occur on CLR types. See Classes and Structs for more information.
For more information, see Type Forwarding (C++/CLI).

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

'type': only an imported type can be forwarded


The TypeForwardedTo attribute must be applied to a type in referenced metadata.
For more information, see Type Forwarding (C++/CLI).

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

'type': type not allowed in attribute 'implements'


An invalid type was passed to the implements attribute. For example, you can pass an interface to implements , but
you cannot pass a pointer to an interface.

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;

[ coclass, uuid("00000000-0000-0000-0000-000000000002"), implements(interfaces=PX) ] // C3463


// try the following line instead
// [ coclass, uuid("00000000-0000-0000-0000-000000000002"), implements(interfaces=X) ]
class CMyClass : public X {};
Compiler Error C3464
10/31/2018 • 2 minutes to read • Edit Online

'type' a nested type cannot be forwarded


Type forwarding does not work on nested types.
For more information, see Type Forwarding (C++/CLI).

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

to use type 'type' you must reference the assembly 'assembly'


Type forwarding will work for a client application until you recompile the client. When you recompile, you will need
a reference for every assembly containing the definition of a type used in your client application.
For more information, see Type Forwarding (C++/CLI).

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

'type' : a specialization of a generic class cannot be forwarded


You cannot use type forwarding on a specialization of a generic class.
For more information, see Type Forwarding (C++/CLI).

Example
The following sample creates a component.

// C3466.cpp
// compile with: /clr /LD
generic<typename T>
public ref class GR {};

public ref class GR2 {};

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

'type' : this type has already been forwarded


The compiler found more than one forward type declaration for the same type. Only one declaration per type is
allowed.
For more information, see Type Forwarding (C++/CLI).

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

'type' : you can only forward a type to an assembly:


' file ' is not an assembly
Only types in an assembly can be forwarded.
For more information, see Type Forwarding (C++/CLI).

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

'type' : a generic class cannot be forwarded


You cannot use type forwarding on a generic class.
For more information, see Type Forwarding (C++/CLI).

Example
The following sample creates a component.

// C3469.cpp
// compile with: /clr /LD
generic<typename T>
public ref class GR {};

public ref class GR2 {};

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 operator[](String^ s) { return Convert::ToInt32(s); } // C3470


};

int main() {
R ^ r = gcnew R;
// return r[9] + r["32"] - 42;
}
Compiler Error C3480
10/31/2018 • 2 minutes to read • Edit Online

'var': a lambda capture variable must be from an enclosing function scope


The lambda capture variable is not from an enclosing function scope.
To correct this error
Remove the variable from the capture list of the lambda expression.

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

'var': lambda capture variable not found


The compiler could not find the definition of a variable that you passed to the capture list of a lambda expression.
To correct this error
Remove the variable from the capture list of the lambda expression.

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

'var' is already part of the lambda capture list


You passed the same variable to the capture list of a lambda expression more than one time.
To correct this error
Remove all additional instances of the variable from the capture list.

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

expected '->' before the return type


You must provide -> before the return type of a lambda expression.
To correct this error
Provide -> before the return type.

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

a lambda definition cannot have any cv-qualifiers


You cannot use a const or volatile qualifier as part of the definition of a lambda expression.
To correct this error
Remove the const or volatile qualifier from the definition of your lambda expression.

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

int* test(int* pi) {


// To fix the error, uncomment the trailing return type below
auto odd_pointer = [=]() /* -> int* */ {
if (*pi % 2)
return pi;
return nullptr; // C3487 - nullptr is not an int* type
};
return odd_pointer();
}

See Also
Lambda Expressions
Compiler Error C3488
10/31/2018 • 2 minutes to read • Edit Online

'var' is not allowed when the default capture mode is by-reference


When you specify that the default capture mode for a lambda expression is by-reference, you cannot pass a
variable by reference to the capture clause of that expression.
To correct this error
Do not explicitly pass the variable to the capture clause, or
Do not specify by-reference as the default capture mode, or
Specify by-value as the default capture mode, or
Pass the variable by value to the capture clause. (This might change the behavior of the lambda expression.)

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

'var' is required when the default capture mode is by-value


When you specify that the default capture mode for a lambda expression is by-value, you cannot pass a variable by
value to the capture clause of that expression.
To correct this error
Do not explicitly pass the variable to the capture clause, or
Do not specify by-value as the default capture mode, or
Specify by-reference as the default capture mode, or
Pass the variable by reference to the capture clause. (This might change the behavior of the lambda
expression.)

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

'var' cannot be modified because it is being accessed through a const object


A lambda expression that is declared in a const method cannot modify non-mutable member data.
To correct this error
Remove the const modifier from your method declaration.

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

'var': a by-value capture cannot be modified in a non-mutable lambda


A non-mutable lambda expression cannot modify the value of a variable that is captured by value.
To correct this error
Declare your lambda expression with the mutable keyword, or
Pass the variable by reference to the capture list of the lambda expression.

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

'var': you cannot capture a member of an anonymous union


You cannot capture a member of an unnamed union.
To correct this error
Give the union a name and pass the complete union structure to the capture list of the lambda expression.

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

'var': a lambda capture must have automatic storage duration


You cannot capture a variable that does not have automatic storage duration, such as a variable that is marked
static or extern .

To correct this error


Do not pass a static or extern variable to the capture list of the lambda expression.

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

'this' is always captured by value: '&' ignored


You cannot capture the this pointer by reference.
To correct this error
Capture the this pointer by value.

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

'var': you cannot capture a variable that has a managed or WinRTtype


You cannot capture a variable that has a managed type or a Windows Runtime type in a lambda.
To correct this error
Pass the managed or Windows Runtime variable to the parameter list of the lambda expression.

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 C3500 invalid ProgID 'progid'

Compiler Error C3501 there is no typelib registered for ProgID 'progid'

Compiler Error C3502 cannot obtain LIBID for ProgID 'progid'

Compiler Error C3503 character '0xvalue' is not allowed in a raw string literal

Compiler Error C3504 cannot create GUID from string 'string'

Compiler Error C3505 cannot load type library 'library'

Compiler Error C3506 there is no typelib registered for LIBID 'library'


ERROR MESSAGE

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 C3508 'type': is not a valid Automation type

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 C3510 cannot locate dependent type library library

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 C3515 if an argument for a class template partial specialization is a


pack expansion it shall be the last argument

Compiler Error C3516 unexpected end-of-file found while processing the raw string
literal; delimiter sequence 'string' was not matched

Compiler Error C3517 'identifier' an alias-declaration cannot have a type that


contains 'auto'

Compiler Error C3518 'identifier': in a direct-list-initialization context the type for


'type' can only be deduced from a single initializer expression

Compiler Error C3519 'parameter': invalid parameter to embedded_idl attribute

Compiler Error C3520 'identifier': parameter pack must be expanded in this context

Compiler Error C3521 'identifier' is not a parameter pack

Compiler Error C3522 'type': parameter pack cannot be expanded in this context

Compiler Error C3523 'sizeof...' requires as its argument an unexpanded parameter


pack

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 C3526 '...' cannot be applied to 'this'


ERROR MESSAGE

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 C3534 Obsolete.

Compiler Error C3535 cannot deduce type for 'type1' from 'type2'

Compiler Error C3536 'identifier': cannot be used before it is initialized

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 C3539 a template-argument cannot be a type that contains '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 C3543 'type': does not contain a parameter pack

Compiler Error C3544 'parameter': parameter pack expects a type template


argument

Compiler Error C3545 'parameter': parameter pack expects a non-type template


argument

Compiler Error C3546 '...': there are no parameter packs available to expand

Compiler Error C3547 template parameter 'parameter' cannot be used because it


follows a template parameter pack and cannot be deduced
from the function parameters of 'function'
ERROR MESSAGE

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 C3550 only plain 'decltype(auto)' is allowed in this context

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 C3552 expected 'decltype(auto)'

Compiler Error C3553 decltype expects an expression not a type

Compiler Error C3554 'type' cannot be combined with any other type-specifier

Compiler Error C3555 incorrect argument to 'decltype'

Compiler Error C3556 'expression': incorrect argument to 'decltype'

Compiler Error C3557 Obsolete.

Compiler Error C3558 Obsolete.

Compiler Error C3559 recursive call to 'function': recursion is detected when


compiling the call graph for the concurrency::parallel_for_each
at: 'function'

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 C3573 The number of instances of concurrency::graphics::sampler


passed to concurrency::parallel_for_each cannot exceed
number

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 C3576 'type': concurrency::details::_Parallel_for_each argument


#number has unsupported type

Compiler Error C3577 concurrency::parallel_for_each kernel argument is illegal:


cannot resolve call to member 'void operator()(type)
restrict(amp)'

Compiler Error C3578 The size of the function object passed to


concurrency::parallel_for_each cannot exceed number bytes

Compiler Error C3579 The number of read-only instances of concurrency::array and


concurrency::graphics::texture passed to
concurrency::parallel_for_each cannot exceed number

Compiler Error C3580 The number of writable instances of concurrency::array and


concurrency::graphics::texture passed to
concurrency::parallel_for_each cannot exceed number

Compiler Error C3581 'type': unsupported type in amp restricted code

Compiler Error C3582 Obsolete.

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 C3584 unsupported usage of tile_static on 'identifier'


ERROR MESSAGE

Compiler Error C3585 'identifier' has unsupported storage class in amp restricted
code

Compiler Error C3586 'identifier': using global or static variables is unsupported in


amp restricted code

Compiler Error C3587 dynamic_cast is unsupported in amp restricted code

Compiler Error C3588 casting from 'type1' to 'type2' is unsupported in amp


restricted code

Compiler Error C3589 'string': unsupported usage of string literals in amp restricted
code

Compiler Error C3590 'token': by-reference capture or 'this' capture is unsupported if


the lambda is amp restricted

Compiler Error C3591 typeid operator is unsupported in amp restricted code

Compiler Error C3592 Inline native assembly ('__asm') is unsupported in amp


restricted code

Compiler Error C3593 'goto' is unsupported 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 C3596 'parameter' ('type'): variable captured by lambda has


unsupported type in amp restricted code

Compiler Error C3597 'parameter': 'identifier' is not allowed to be captured by value


if the lambda is amp restricted

Compiler Error C3598 label statement is unsupported in amp restricted code

Compiler Error C3599 'operator': cannot perform pointer arithmetic on pointer to


bool 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 C3603 'symbol': type 'type' not yet supported


ERROR MESSAGE

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 C3606 Obsolete.

Compiler Error C3607 Obsolete.

Compiler Error C3608 Obsolete.

Compiler Error C3609 'identifier': a 'sealed/final' function must be virtual

Compiler Error C3610 'identifier': value type must be 'boxed' before method
'method' can be called

Compiler Error C3611 'identifier': a sealed function cannot have a pure-specifier

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 C3615 constexpr function 'function' cannot result in a constant


expression

Compiler Error C3616 Obsolete.

Compiler Error C3617 Obsolete.

Compiler Error C3618 'declaration': a method marked DllImport cannot be defined

Compiler Error C3619 a template cannot be declared within a managed/WinRT type

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 C3622 type': a class declared as 'keyword' cannot be instantiated

Compiler Error C3623 'identifier': bit fields are not supported in managed/WinRT
types

Compiler Error C3624 'type': use of this type requires a reference to


assembly/module 'identifier'
ERROR MESSAGE

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 C3627 Only a value type can be boxed

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 C3630 error when processing the token 'token'

Compiler Error C3631 'event': cannot overload managed/WinRT events

Compiler Error C3632 'event': illegal style of event for construct

Compiler Error C3633 cannot define 'identifier' as a member of managed 'class'

Compiler Error C3634 'member': cannot define an abstract method of a


managed/WinRT class

Compiler Error C3635 'identifier': cannot be applied to a managed/WinRT class (use


'identifier' instead)

Compiler Error C3636 'identifier': cannot be applied to this type

Compiler Error C3637 'function': a friend function definition cannot be a


specialization of a function template/generic

Compiler Error C3638 'operator': the standard boxing and unboxing conversion
operators cannot be redefined

Compiler Error C3639 Obsolete.

Compiler Error C3640 'member': a referenced or virtual member function of a local


class must be defined

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 C3643 Obsolete.

Compiler Error C3644 'function': cannot compile the function to generate managed
code
ERROR MESSAGE

Compiler Error C3645 'function': __clrcall cannot be used on functions compiled to


native code

Compiler Error C3646 'identifier': unknown override specifier

Compiler Error C3647 Obsolete.

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 C3650 'member': cannot be used as an explicit override, must be a


virtual member function of a base class

Compiler Error C3651 'member': cannot be used as an explicit override, must be a


member of a base class

Compiler Error C3652 'member': a function that explicitly overrides must be virtual

Compiler Error C3653 'identifier': cannot be used as a named override: a function


being overridden not found; did you forget to name the
function explicitly, using a:: operator?

Compiler Error C3654 'token': syntax error in explicit override

Compiler Error C3655 'member': function already explicitly overridden

Compiler Error C3656 'keyword': override specifier cannot be repeated

Compiler Error C3657 a destructor/finalizer cannot explicitly override or be explicitly


overridden

Compiler Error C3658 Obsolete.

Compiler Error C3659 'member': override specifier 'keyword' is not supported

Compiler Error C3660 'member1': hides inherited member 'member2'

Compiler Error C3661 explicit override list did not find any methods to override

Compiler Error C3662 'member': override specifier 'keyword' only allowed on


member functions of managed/WinRT classes

Compiler Error C3663 Obsolete.

Compiler Error C3664 'member': cannot be used as an explicit override, must have
'public' or 'protected' accessibility

Compiler Error C3665 'member': override specifier 'keyword' not allowed on a


destructor/finalizer
ERROR MESSAGE

Compiler Error C3666 'constructor': override specifier 'keyword' not allowed on a


constructor

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 C3671 'member': function does not override 'member'

Compiler Error C3672 pseudo-destructor expression can only be used as part of a


function call

Compiler Error C3673 'class': class does not have a copy-constructor

Compiler Error C3674 could not find standard library module 'module'

Compiler Error C3675 'function': is reserved because 'property' is defined

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 C3680 cannot concatenate user-defined string literals with


mismatched literal suffix identifiers

Compiler Error C3681 'fallthrough': attribute may only appear in an enclosing switch
statement

Compiler Error C3682 'operator identifier': literal operator/literal operator template


cannot be declared to have 'C linkage'

Compiler Error C3683 cannot define both raw literal operator and literal operator
template with the same literal suffix identifier

Compiler Error C3684 'operator identifier': declaration of literal operator has an


invalid parameter list

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 C3689 'operator identifier': literal operator/literal operator template


must be in a global or namespace scope

Compiler Error C3690 expected a string literal, but found a user-defined string literal
instead

Compiler Error C3691 invalid literal prefix 'prefix'

Compiler Error C3692 Obsolete.

Compiler Error C3693 Obsolete.

Compiler Error C3694 Obsolete.

Compiler Error C3695 Obsolete.

Compiler Error C3696 'keyword': cannot use this qualifier on '%'

Compiler Error C3697 'keyword': cannot use this qualifier on '^'

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 C3700 Obsolete.

Compiler Error C3701 'function': event source has no events

Compiler Error C3702 ATL is required for COM events

Compiler Error C3703 'event_handler': an event handler method must have the
same storage class as the source 'event'

Compiler Error C3704 'member': a vararg method cannot fire events

Compiler Error C3705 'function': cannot find eventing interface

Compiler Error C3706 'function': must be a COM interface to fire COM events

Compiler Error C3707 'member': dispinterface method must have a dispid


ERROR MESSAGE

Compiler Error C3708 'function': improper use of 'keyword'; must be a member of a


compatible event source

Compiler Error C3709 'function': improper syntax for specifying event in


__hook/__unhook

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 C3715 'pointer': must be a pointer to 'type'

Compiler Error C3716 Obsolete.

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 C3721 'signature': incompatible signature for event

Compiler Error C3722 a generic event is not allowed

Compiler Error C3723 'function': could not resolve event

Compiler Error C3724 must #include <windows.h> to use multi-threading with


events

Compiler Error C3725 Obsolete.

Compiler Error C3726 Obsolete.

Compiler Error C3727 'event': a managed event must be a member function or a


data member that is a pointer to a delegate

Compiler Error C3728 'event': event does not have a raise method
ERROR MESSAGE

Compiler Error C3729 Obsolete.

Compiler Error C3730 Obsolete.

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 C3734 'class': a managed/WinRT class cannot be a coclass

Compiler Error C3735 Obsolete.

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 C3740 'template': templates cannot source or receive events

Compiler Error C3741 'class': must be a coclass when the 'layout_dependent'


parameter of event_receiver is true

Compiler Error C3742 'token1': unbalanced token sequence in attribute argument of


'attribute', expected 'token2'

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 C3745 'function': only an event can be 'raised'

Compiler Error C3746 standard attribute 'identifier' may appear at most once in an
attribute list

Compiler Error C3747 missing default template/generic parameter: parameter


number

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 C3750 'token': unexpected token in attribute list

Compiler Error C3751 'identifier': unexpected identifier in attribute list

Compiler Error C3752 'attribute': cannot classify attribute; 'keyword' should not be
used in this context

Compiler Error C3753 a generic property is not allowed

Compiler Error C3754 delegate constructor: member function 'member' cannot be


called on an instance of type 'type'

Compiler Error C3755 'identifier': a delegate may not be defined

Compiler Error C3756 Obsolete.

Compiler Error C3757 'type': type not allowed for 'constexpr' function

Compiler Error C3758 'member': virtual function cannot be declared 'constexpr'

Compiler Error C3759 'member': member function of non-literal type cannot be


declared 'constexpr'

Compiler Error C3760 please use __property keyword to declare property in


managed/WinRT 'class'

Compiler Error C3761 'function': 'retval' can only appear on the last argument of a
function

Compiler Error C3762 unable to process attribute 'attribute'

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 C3767 'function': candidate function(s) not accessible

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 C3770 'type': is not a valid base class

Compiler Error C3771 'identifier': friend declaration cannot be found in the nearest
namespace scope

Compiler Error C3772 'identifier': invalid friend template declaration

Compiler Error C3773 please use /await compiler switch to enable coroutines

Compiler Error C3774 cannot find 'scope::identifier': Please include header header

Compiler Error C3775 return type of 'function' should not be 'type'

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 C3778 alloca: cannot be used in a coroutine

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 C3781 'keyword': cannot be a used in a coroutine of type 'type'.


Either keyword or keyword must be present in associated
promise_type

Compiler Error C3782 type: a coroutine's promise cannot contain both keyword and
keyword

Compiler Error C3783 'identifier': cannot be a coroutine

Compiler Error C3784 keyword expression cannot appear in this context

Compiler Error C3785 the first template argument to 'std::integer_sequence' must be


an integer type

Compiler Error C3786 the second template argument to


'std::make_integer_sequence' must be an integer constant
greater than or equal to zero

Compiler Error C3787 cannot deduce the return type of this coroutine

Compiler Error C3788 Obsolete.

Compiler Error C3789 Obsolete.

Compiler Error C3790 Obsolete.


ERROR MESSAGE

Compiler Error C3791 Obsolete.

Compiler Error C3792 Obsolete.

Compiler Error C3793 Obsolete.

Compiler Error C3794 Obsolete.

Compiler Error C3795 Obsolete.

Compiler Error C3796 Obsolete.

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 C3800 'declaration': cannot mix properties and events

Compiler Error C3801 'attribute': attribute may not have an argument clause

Compiler Error C3802 Obsolete.

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 C3810 Obsolete.

Compiler Error C3811 Obsolete.


ERROR MESSAGE

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 C3814 Obsolete.

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 C3817 'declaration': property can only be applied to a function

Compiler Error C3818 array property declaration 'property' shall not overload an
index property 'property'

Compiler Error C3819 Obsolete.

Compiler Error C3820 'identifier': initializers must be managed

Compiler Error C3821 'function': managed type or function cannot be used in an


unmanaged function

Compiler Error C3822 Obsolete.

Compiler Error C3823 Obsolete.

Compiler Error C3824 'type': this type cannot appear in this context (function
parameter, return type, or a static member)

Compiler Error C3825 'type': a managed/WinRT class can only support


managed/WinRT events

Compiler Error C3826 Obsolete.

Compiler Error C3827 standard attribute 'deprecated' may have either no arguments
or one string literal describing the reason

Compiler Error C3828 placement arguments cannot be specified for a 'keyword'


expression for type 'type'

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 C3833 'type': invalid target type for identifier

Compiler Error C3834 illegal explicit cast to a pinning pointer; use a pinned local
variable instead

Compiler Error C3835 Obsolete.

Compiler Error C3836 a static constructor is not allowed to have a member initializer
list

Compiler Error C3837 attributes are not allowed in this context

Compiler Error C3838 cannot inherit from 'type'

Compiler Error C3839 cannot change alignment in a managed/WinRT type

Compiler Error C3840 Obsolete.

Compiler Error C3841 Obsolete.

Compiler Error C3842 'identifier': 'const' and 'volatile' qualifiers on member functions
of managed/WinRT types are not supported

Compiler Error C3843 'identifier': ref-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 C3845 Obsolete.

Compiler Error C3846 'identifier': cannot import symbol from 'source': as 'identifier'
has already been imported from another assembly 'assembly'

Compiler Error C3847 Obsolete.

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 C3850 'token': a universal-character-name specifies an invalid


character

Compiler Error C3851 'token': a universal-character-name cannot designate a


character in the basic character set
ERROR MESSAGE

Compiler Error C3852 'member' having type 'type': aggregate initialization could not
initialize this member

Compiler Error C3853 '=': re-initializing a reference or assignment through a


reference-to-function is illegal

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 C3855 'function': template/generic parameter 'identifier' is


incompatible with the declaration

Compiler Error C3856 'class': class is not a class template/generic

Compiler Error C3857 'template': multiple template/generic parameter lists are not
allowed

Compiler Error C3858 'identifier': cannot be redeclared in current scope

Compiler Error C3859 virtual memory range for PCH exceeded; please recompile
with a command line option of '-Zmnumber' or greater

Compiler Error C3860 template/generic argument list following class


template/generic name must list parameters in the order used
in template/generic parameter list

Compiler Error C3861 'identifier': identifier not found

Compiler Error C3862 'function': cannot compile an unmanaged function with


/clr:pure or /clr:safe

Compiler Error C3863 array type 'type' is not assignable

Compiler Error C3864 Obsolete.

Compiler Error C3865 'keyword': can only be used on native member functions

Compiler Error C3866 destructor/finalizer call missing argument list

Compiler Error C3867 'function': non-standard syntax; use '&' to create a pointer to
member

Compiler Error C3868 'type': constraints on generic parameter 'parameter' differ


from those on the declaration

Compiler Error C3869 gcnew constraint is missing empty parameter list '()'

Compiler Error C3870 'parameter': '__declspec(specifier)' can only be applied to


parameters of integral type

Compiler Error C3871 'parameter': '__declspec(guard(overflow))' is only supported on


the first 64 parameters of a function
ERROR MESSAGE

Compiler Error C3872 '0xvalue': this character is not allowed in an identifier

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 C3876 Obsolete.

Compiler Error C3877 Obsolete.

Compiler Error C3878 Obsolete.

Compiler Error C3879 'member': cannot be an initonly data member

Compiler Error C3880 'member': cannot be a literal data member

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 C3884 'type': An array of unknown size cannot be value-initialized

Compiler Error C3885 'type': An array of unknown size cannot be initialized with an
empty initializer list

Compiler Error C3886 'member': a literal data member must be initialized

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 C3889 Obsolete.

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 C3895 'member': type data members cannot be 'volatile'

Compiler Error C3896 'member': improper initializer: this literal data member can
only be initialized with 'nullptr'

Compiler Error C3897 Obsolete.

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 C3900 'member': not allowed in current scope

Compiler Error C3901 'function': must have return type 'type'

Compiler Error C3902 'function': type of last parameter must be 'type'

Compiler Error C3903 'property': does not have set or get method

Compiler Error C3904 'property': must specify number parameter(s)

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 C3907 Obsolete.

Compiler Error C3908 access level less restrictive than that of 'identifier'

Compiler Error C3909 a managed/WinRT event declaration must occur in a


managed/WinRT type

Compiler Error C3910 'event': must define member 'member'

Compiler Error C3911 'member': function must have type 'type'

Compiler Error C3912 'event': type of event must be a delegate type

Compiler Error C3913 a default property must be indexed

Compiler Error C3914 a default property cannot be static

Compiler Error C3915 'identifier' has no default indexed property (class indexer)

Compiler Error C3916 Obsolete.


ERROR MESSAGE

Compiler Error C3917 'token': obsolete construct declaration style (did you mean to
use '[' ']' instead?)

Compiler Error C3918 usage requires 'identifier' to be a data member

Compiler Error C3919 'function': function must have type 'return_type (type)'

Compiler Error C3920 'operator': cannot define a postfix increment/decrement


CLR/WinRT operator Calling the postfix CLR/WinRT operator
will call the corresponding prefix CLR/WinRT operator
(op_Increment/op_Decrement), but with postfix semantics

Compiler Error C3921 Obsolete.

Compiler Error C3922 Obsolete.

Compiler Error C3923 'member': local class, struct or union definitions are not
allowed in a member function of a managed/WinRT class

Compiler Error C3924 error in argument #number of delegate constructor call


'constructor':

Compiler Error C3925 expected a loop (for, while, or do) following 'directive' directive

Compiler Error C3926 invalid constant in 'parallel' 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 C3929 Obsolete.

Compiler Error C3930 'function': no overloaded function has restriction specifiers


that are compatible with the ambient context 'context'

Compiler Error C3931 'type': cannot call a function that has restriction specifiers that
are incompatible with the ambient context

Compiler Error C3932 Obsolete.

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 C3935 'identifier': redefinition; overlapping restriction specifiers

Compiler Error C3936 'identifier': unrecognized restriction specifier


ERROR MESSAGE

Compiler Error C3937 empty restriction specifier is not allowed

Compiler Error C3938 'identifier': multiple restriction specifiers are not supported on
extern \042C\042 functions

Compiler Error C3939 'identifier': pointer to member functions, function pointers,


references to functions with 'amp' restriction specifier are not
allowed

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 C3941 'condition': requires '/clr' command line option

Compiler Error C3942 Obsolete.

Compiler Error C3943 Obsolete.

Compiler Error C3944 Obsolete.

Compiler Error C3945 'type': unable to throw or catch a winrt object which doesn't
derive from Platform::Exception

Compiler Error C3946 'type': typeid cannot be applied to this type

Compiler Error C3947 'typeid': typeid cannot be applied to a pack expansion

Compiler Error C3948 'keyword': a pack expansion cannot appear in this context

Compiler Error C3949 a pack expansion, '...', cannot appear in a parenthesized


abstract declarator

Compiler Error C3950 Obsolete.

Compiler Error C3951 Cannot use pointer-to-member in projected WinRT type


'type'. Use a delegate instead.

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 C3960 Obsolete.

Compiler Error C3961 static constructor is not supported

Compiler Error C3962 generic class is not supported

Compiler Error C3963 multi-dimensional array is not supported

Compiler Error C3964 jagged array is not supported

Compiler Error C3965 parameter array is not supported

Compiler Error C3966 'function': generic function is not supported

Compiler Error C3967 error importing 'identifier' from module 'module'

Compiler Error C3968 the token 'token' is not valid as module name separator; use
period ('.') instead

Compiler Error C3969 inconsistent module names: 'module1' and 'module1'

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 C3973 Obsolete.

Compiler Error C3974 Obsolete.

Compiler Error C3975 'class/struct identifier' was previously declared or defined with
a different modifier

Compiler Error C3976 'identifier1' must be declared as 'public' in order to use


'identifier2'

Compiler Error C3977 Usage requires a reference to an assembly that defines


'identifier'

Compiler Error C3978 'identifier': a static property is not allowed as a member of a


WinRT interface or value type
ERROR MESSAGE

Compiler Error C3979 'type': use attribute 'attribute' instead of 'value'

Compiler Error C3980 'type' cannot be emitted into metadata

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 C3988 'type': a native type cannot be public

Compiler Error C3989 'type': a nested type cannot be public

Compiler Error C3990 'type': attribute 'attribute' cannot be private or nested

Compiler Error C3991 'type': cannot implement a non-public or nested interface


'interface'

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 C3996 Obsolete.

Compiler Error C3998 'c++version': unsupported C++ version; defaulting to


'c++version'

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

invalid ProgID 'progid'


An invalid progid was specified with the #import statement. Check the Windows registry to ensure that you are
specifying a valid progid.
Compiler Error C3501
10/31/2018 • 2 minutes to read • Edit Online

there is no typelib registered for ProgID 'progid'


The class ID for a given progid does not have an associated type library. Therefore, you cannot pass this progid to
the #import statement.
Compiler Error C3505
10/31/2018 • 2 minutes to read • Edit Online

cannot load type library 'guid'

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

there is no typelib registered for LIBID 'id'


A typelib was not registered correctly. Use regsvr32.exe to register a type library.
Compiler Error C3507
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

'type': is not a valid Automation type


An invalid type was specified.

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>

extern "C" int printf_s(const char*, ...);

[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 WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers


#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)];

[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

cannot locate dependent type library 'type_lib'


no_registry and auto_search were passed to #import but the compiler was not able to find a referenced type
library.
To resolve this error, make sure that all type libraries and referenced type libraries are available to the compiler.
The following sample generates C3510:
Assume that the following two type libraries were built, and that C3510a.tlb was deleted or not on the path.

// 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;
};
};

And then the client code:

// 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

'invalid_param' : invalid parameter to embedded_idl attribute


A parameter was passed to the embedded_idl attribute of #import, but the compiler did not recognize the
parameter.
The only parameters that are allowed for embedded_idl are emitidl and no_emitidl .
The following sample generates C3519:

// 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

'auto' cannot be combined with any other type-specifier


A type specifier is used with the auto keyword.
To correct this error
1. Do not use a type specifier in a variable declaration that uses the auto keyword.

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

'symbol': a symbol whose type contains 'auto' must have an initializer


The specified variable does not have an initializer expression.
To correct this error
1. Specify an initializer expression, such as a simple assignment that uses equal-sign syntax, when you declare the
variable.

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

'type': incorrect usage of 'auto'


The indicated type cannot be declared with the auto keyword. For example, you cannot use the auto keyword to
declare an array or a method return type.
To correct this error
1. Ensure that the initialization expression yields a valid type.
2. Ensure that you do not declare an array or a method return type.

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

'type': a parameter cannot have a type that contains 'auto'


A method or template parameter cannot be declared with the auto keyword if the default /Zc:auto compiler
option is in effect.
To correct this error
1. Remove the auto keyword from the parameter declaration.

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

cannot deduce type for 'type1' from 'type2'


The type of the variable declared by the auto keyword cannot be deduced from the type of the initialization
expression. For example, this error occurs if the initialization expression evaluates to void , which is not a type.
To correct this error
1. Ensure that the type of the initialization expression is not void .
2. Ensure that the declaration is not a pointer to a fundamental type. For more information, see Fundamental
Types.
3. Ensure that if the declaration is a pointer to a type, the initialization expression is a pointer type.

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

'symbol': cannot be used before it is initialized


The indicated symbol cannot be used before it is initialized. In practice, this means that a variable cannot be used to
initialize itself.
To correct this error
1. Do not initialize a variable with itself.

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

'type': you cannot cast to a type that contains 'auto'


You cannot cast a variable to the indicated type because the type contains the auto keyword and the default
/Zc:auto compiler option is in effect.

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

in a declarator-list 'auto' must always deduce to the same type


All the declared variables in a declaration list do not resolve to the same type.
To correct this error
1. Ensure that all auto declarations in the list deduce to the same type.

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

'type': a template-argument cannot be a type that contains 'auto'


The indicated template argument type cannot contain a usage of the auto keyword.
To correct this error
1. Do not specify the template argument with the auto keyword.

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

'type': sizeof cannot be applied to a type that contains 'auto'


The sizeof operator cannot be applied to the indicated type because it contains the auto specifier.

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

'type': typeid cannot be applied to a type that contains 'auto'


The typeid operator cannot be applied to the indicated type because it contains the auto specifier.

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

only plain 'decltype(auto)' is allowed in this context


If decltype(auto) is used as a placeholder for the return type of a function, it must be used by itself. It cannot be
used as part of a pointer declaration ( decltype(auto*) ), a reference declaration ( decltype(auto&) ), or any other
such qualification.

See Also
auto
Compiler Error C3551
10/31/2018 • 2 minutes to read • Edit Online

"expected a late specified return type"


If you use the auto keyword as a placeholder for the return type of a function, you must provide a late-specified
return type. In the following example, the late-specified return type of function myFunction is a pointer to an array
of four elements of type int .

auto myFunction()->int(*)[4];

See Also
auto
Compiler Error C3552
10/31/2018 • 2 minutes to read • Edit Online

'typename': a late specified return type cannot contain 'auto'


If you use the auto keyword as a placeholder for the return type of a function, you must provide a late-specified
return type. However, you cannot use another auto keyword to specify the late-specified return type. For example,
the following code fragment yields error C3552.
auto myFunction->auto; // C3552
Compiler Error C3553
10/31/2018 • 2 minutes to read • Edit Online

decltype expects an expression not a type

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

'decltype' cannot be combined with any other type-specifier


You cannot qualify the decltype() keyword with any type specifier. For example, the following code fragment
yields error C3554.

int x;
unsigned decltype(x); // C3554
Compiler Error C3555
10/31/2018 • 2 minutes to read • Edit Online

incorrect argument to 'decltype'

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

'expression': incorrect argument to 'decltype'

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 callsMyFunction(decltype(myFunction) fn); // C3556


// One way to fix is to comment out the line above, and
// use static_cast to create specialized function pointer
// instances:
auto myFunctionInt = static_cast<void(*)(int)>(myFunction);
auto myFunctionFloatFloat = static_cast<void(*)(float,float)>(myFunction);
void callsMyFunction(decltype(myFunctionInt) fn, int n);
void callsMyFunction(decltype(myFunctionFloatFloat) fn, float f, float g);

void myFunction(int i) {
std::cout << "called myFunction(" << i << ")" << std::endl;
}

void myFunction(float f, float g) {


std::cout << "called myFunction(" << f << ", " << g << ")" << std::endl;
}

void callsMyFunction(decltype(myFunctionInt) fn, int n) {


fn(n);
}

void callsMyFunction(decltype(myFunctionFloatFloat) fn, float f, float g) {


fn(f, g);
}

int main() {
callsMyFunction(myFunction, 42);
callsMyFunction(myFunction, 0.1f, 2.3f);
}
Compiler Error C3603
10/31/2018 • 2 minutes to read • Edit Online

'Symbol' : type 'Type' not yet supported


You attempted to use a data type that is not yet supported by the .NET runtime in a managed object.
Compiler Error C3609
10/31/2018 • 2 minutes to read • Edit Online

'member': a sealed or final function must be virtual


The sealed and final keywords are only allowed on a class, struct, or member function marked virtual .
The following sample generates C3609:

// 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

'function': a sealed function cannot have a pure-specifier


A sealed function was declared incorrectly. For more information, see sealed.

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

'type': a sealed class cannot be abstract


Types defined by using value are sealed by default, and a class is abstract unless it implements all methods of its
base. A sealed abstract class can neither be a base class nor can it be instantiated.
For more information, see Classes and Structs.

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

constexpr function 'function' cannot result in a constant expression

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; }
};

constexpr bool f(const myarray<1> &arr)


{
return arr.size() == 10 || arr.size() == 11; // C3615 starting in Visual Studio 2017
}

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

'function': a method marked DllImport cannot be defined


A method marked with DllImportAttribute is defined in the specified.DLL.

Example
The following sample generates C3618.

// C3618.cpp
// compile with: /clr /c
using namespace System;
using namespace System::Runtime::InteropServices;

[ DllImport("user32.dll", EntryPoint="MessageBox", CharSet=CharSet::Ansi) ] // CHANGED


void Func();

void Func() {} // C3618, remove this function definition to resolve


Compiler Error C3619
10/31/2018 • 2 minutes to read • Edit Online

a template cannot be declared within a managed or WinRT type


Class templates are not allowed in a managed or WinRT class or interface.
C3619 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3622
10/31/2018 • 2 minutes to read • Edit Online

'class' : a class declared as 'keyword' cannot be instantiated


An attempt was made to instantiate a class marked as abstract. A class marked as abstract can be a base class,
but it cannot be instantiated.

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

'variable': bit fields are not supported in managed or WinRT types


The use of bit fields is not permitted on variables in a managed or WinRT class.
The following sample generates C3623:

// 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

'type': use of this type requires a reference to assembly 'assembly'


An assembly (reference) needed to compile your code was not specified; pass the assembly to the #using directive.

Example
The following sample generates C3624:

// C3624.cpp
// compile with: /clr /c
#using <System.Windows.Forms.dll>

// Uncomment the following 2 lines to resolve.


// #using <System.dll>
// #using <System.Drawing.dll>

using namespace System;

public ref class MyForm : public Windows::Forms::Form {}; // C3624


Compiler Error C3625
10/31/2018 • 2 minutes to read • Edit Online

'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

Only a value type can be boxed


Only value classes can be boxed.
Compiler Error C3628
10/31/2018 • 2 minutes to read • Edit Online

'base class' : managed or WinRTclasses only support public inheritance


An attempt was made to use a managed or WinRT class as a private or protected base class. A managed or WinRT
class can only be used as a base class with public access.
The following sample generates C3628 and shows how to fix it:

// C3628a.cpp
// compile with: /clr
ref class B {
};

ref class D : private B { // C3628

// The following line resolves the error.


// ref class D : public B {
};

int main() {
}
Compiler Error C3630
10/31/2018 • 2 minutes to read • Edit Online

error when processing the token 'token'


A token in source code could not be processed.
Compiler Error C3631
10/31/2018 • 2 minutes to read • Edit Online

'function': cannot overload managed or WinRT events


A managed or WinRT event cannot be overloaded.
C3631 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3632
10/31/2018 • 2 minutes to read • Edit Online

'event': illegal style of event for construct


__event declarations are not valid in all constructs.
C3632 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3633
10/31/2018 • 2 minutes to read • Edit Online

cannot define 'member' as a member of managed 'type'


CLR reference class data members cannot be of a non-POD C++ type. You can only instantiate a POD native type
in a CLR type. For example, a POD type cannot contain a copy constructor or an assignment operator.

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

'function' : cannot define an abstract method of a managed or WinRTclass


An abstract method can be declared in a managed or WinRT class, but it cannot be defined.

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

'function' : a friend function definition cannot be a specialization of a function type


A friend function was defined incorrectly for a template or generic.
The following sample generates C3637:

// 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() {}
};

C3637 can also occur when using generics:

// C3637c.cpp
// compile with: /clr

generic <class T>


void gf();

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

'member' : a referenced or virtual member function of a local class must be defined


The compiler requires certain functions to be defined.
The following sample generates C3640:

// 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

'function' : cannot compile the function to generate managed code


The presence of some keywords in a function will cause the function to be compiled to native.
The following sample generates C3644:

// C3644.cpp
// compile with: /clr
// processor: x86

void __clrcall Func2(int i) {


__asm {} // C3644
}
Compiler Error C3645
10/31/2018 • 2 minutes to read • Edit Online

'function' : __clrcall cannot be used on functions compiled to native code


The presence of some keywords in a function will cause the function to be compiled to native.

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

'specifier' : unknown override specifier

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

this explicit override syntax requires /clr:oldSyntax


When compiling for the latest managed syntax, the compiler found explicit override syntax for previous versions
that is no longer supported.
For more information, see Explicit Overrides.

Example
The following sample generates C3648:

// C3648.cpp
// compile with: /clr
public interface struct I {
void f();
};

public ref struct R : I {


virtual void I::f() {} // C3648
// try the following line instead
// virtual void f() = I::f{}
};
Compiler Error C3650
10/31/2018 • 2 minutes to read • Edit Online

'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();
};

public ref class S {


public:
static int f() { return 0; }
static int g() { return 0; }
};

public ref struct T1 : public S, I {


virtual int f() new sealed = S::f; // C3650
virtual int g() { return 0; } // OK does not override S::g
virtual void a() new sealed = I::a {} // OK
};
Compiler Error C3651
10/31/2018 • 2 minutes to read • Edit Online

'member' : cannot be used as an explicit override, must be a member of a base class


An explicit override was specified, but the function being overridden was in a type that is not a base type.
For more information, see Explicit Overrides.
The following sample generates C3651:

// C3651.cpp
// compile with: /clr /c
ref class C {
public:
virtual void func2();
};

ref class Other {


public:
virtual void func();
};

ref class D : public C {


public:
virtual void func() new sealed = Other::func; // C3651
virtual void func2() new sealed = C::func2; // OK
};
Compiler Error C3652
10/31/2018 • 2 minutes to read • Edit Online

'override' : a function that explicitly overrides must be virtual


A function that does an explicit override must be virtual. For more information, see Explicit Overrides.
The following sample generates C3652:

// C3652.cpp
// compile with: /clr /c
public interface class I {
void f();
};

public ref struct R : I {


void f() = I::f {} // C3652
// try the following line instead
// virtual void f() = I::f {}
};
Compiler Error C3653
10/31/2018 • 2 minutes to read • Edit Online

'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();
};

public ref struct X : public I {


virtual void f() new sealed = J {}; // C3653 no J in scope
virtual void g() {} // OK
virtual void h() new sealed = I::h {}; // OK
};
Compiler Error C3654
10/31/2018 • 2 minutes to read • Edit Online

'text' : syntax error in explicit override


An unexpected string was in an explicit override. For more information, see Explicit Overrides.
The following sample generates C3654:

// C3654.cpp
// compile with: /clr /c
public ref struct B {
virtual void f() = 0;
virtual void g() = 0;
virtual void h() = 0;
};

public ref struct Q : B {


virtual void f() = B::f, 3 {} // C3654
// try the following line instead
// virtual void g() = B::g, B::h {}
};
Compiler Error C3655
10/31/2018 • 2 minutes to read • Edit Online

'function' : function already explicitly overridden


A function can only be explicitly overridden once. For more information, see Explicit Overrides.
The following sample generates C3655:

// C3655.cpp
// compile with: /clr /c
public ref struct B {
virtual void f();
virtual void g();
};

public ref struct D : B {


virtual void f() new sealed = B::f;
virtual void g() new sealed = B::f; // C3655
// try the following line instead
// virtual void g() new sealed = B::g;
};
Compiler Error C3656
10/31/2018 • 2 minutes to read • Edit Online

'override' : override specifier cannot be repeated


An explicit override keyword can only be specified once. For more information, see Explicit Overrides.
The following sample generates C3656:

// C3656.cpp
// compile with: /clr /c
public interface struct O {
int f();
};

public ref struct V : O {


int f() override override { return 0; } // C3656
// try the following line instead
// int f() override { return 0; }
};
Compiler Error C3657
10/31/2018 • 2 minutes to read • Edit Online

destructors cannot explicitly override or be explicitly overridden


Destructors or finalizers cannot be explicitly overridden. For more information, see Explicit Overrides.

Example
The following sample generates C3657.

// C3657.cpp
// compile with: /clr
public ref struct I {
virtual ~I() { }
virtual void a();
};

public ref struct D : I {


virtual ~D() = I::~I {} // C3657
virtual void a() = I::a {} // OK
};
Compiler Error C3661
10/31/2018 • 2 minutes to read • Edit Online

explicit override list did not find any methods to override


An explicit override specified one or more type names. However, there was no function with the necessary
signature in the type(s) that matched the overriding function's signature. If you attempt to override based on type
name, there must be one or more virtual functions in the specified type(s) that match the signature of the
overriding function.
For more information, see Explicit Overrides.
Compiler Error C3662
10/31/2018 • 2 minutes to read • Edit Online

'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

'destructor' : override specifier 'keyword' not allowed on a destructor/finalizer


A keyword was used that is not allowed on a destructor or finalizer.
For example, a new slot cannot be requested on a destructor or finalizer. For more information, see Explicit
Overrides and Destructors and finalizers.
The following sample generates C3665:

// C3665.cpp
// compile with: /clr
public ref struct R {
virtual ~R() { }
virtual void a() { }
};

public ref struct S : R {


virtual ~S() new {} // C3665
virtual void a() new {} // OK
};
Compiler Error C3666
10/31/2018 • 2 minutes to read • Edit Online

'constructor' : override specifier 'keyword' not allowed on a constructor


An override specifier was used on a constructor, and that is not allowed. For more information, see Override
Specifiers.

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

virtual void g(int) override {} // C3668


virtual void h(int) override {} // OK
};
Compiler Error C3669
10/31/2018 • 2 minutes to read • Edit Online

'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

'override' : cannot override inaccessible base class method 'method'


An override can only take place on a function whose access level makes it available in a derived type. For more
information, see Explicit Overrides.
The following sample generates C3670:

// C3670.cpp
// compile with: /clr /c
public ref class C {
// Uncomment the following line to resolve.
// public:
virtual void g() { }
};

public ref class D : public C {


public:
virtual void f() new sealed = C::g {}; // C3670
};
Compiler Error C3671
10/31/2018 • 2 minutes to read • Edit Online

'function_1' : function does not override 'function_2'


When using explicit override syntax, the compiler generates an error if a function is not overridden. See Explicit
Overrides for more information.

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

pseudo-destructor expression can only be used as part of a function call


A destructor was called incorrectly. For more information, see Destructors.

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

'type' : class does not have a copy-constructor


A user-defined constructor is needed to copy objects of CLR ref types. For more information, see C++ Stack
Semantics for Reference Types.

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

[MyAttr(123, Version = 1)]


ref class ClassD {}; // Positional and named
Compiler Error C3675
10/31/2018 • 2 minutes to read • Edit Online

'function' : is reserved because 'property' is defined


When you declare a simple property, the compiler generates the get and set accessor methods, and those names
are present in the scope of your program. The compiler-generated names are formed by prepending get_ and set_
to the property name. Therefore, you cannot declare functions with the same name as the compiler-generated
accessors.
See property for more information.

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

'qualifier' : cannot use this qualifier on '^'


The tracking handle (^) was applied to a qualifier for which it was not designed.
The following sample generates C3697:

// 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

'type' : cannot use this type as argument of 'operator'


A managed object was declared incorrectly.
The following sample generates C3698:

// 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

'operator' : cannot use this indirection on type 'type'


An attempt was made to use indirection that is not allowed on type .

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

'function' : event_source has no events


You attempted to use event_source on a class that has no event methods. To fix this error, add one or more events
to the class.
The following sample generates C3701:

// 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

'function' : ATL is required for COM events


You attempted to use COM events without including the necessary ATL header files.
The following sample generates C3702:

// C3702.cpp
// uncomment the following line to resolve
// #define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

[module(dll, name=idid, uuid="12341234-1234-1234-1234-123412341234")];

[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() {}

// try the following line instead


// static void MyHandler() {}

void HookIt(CEventSrc* pSource) {


__hook(CEventSrc::MyEvent, pSource, &CEventHandler::MyHandler);
}

void UnhookIt(CEventSrc* pSource) {


__unhook(CEventSrc::MyEvent, pSource, &CEventHandler::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

'function' : a vararg method cannot fire events


You attempted to use __event on a vararg method. To fix this error, replace the fireEvent(int i, ...) call with the
fireEvent(int i) call as shown in the following code sample.

The following sample generates C3704:

// 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

'function' : cannot find eventing interface


You must define an event interface to use COM events. Note that the #include lines of the ATL header files shown
in the sample below are required for using COM events. To fix this error, uncomment the definition of the IEvents
interface in the sample code.
The following sample generates C3705:

// C3705.cpp
// compile with: /c
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

[module(dll, name="idid", uuid="12341234-1234-1234-1234-123412341234")];

// Uncomment the following 4 lines to resolve.


// [object, uuid("00000000-0000-0000-0000-000000000003")]
// __interface IEvents : IUnknown {
// HRESULT event1([in] int i);
// };

[dual, uuid("00000000-0000-0000-0000-000000000001")]
__interface IBase {
HRESULT fireEvents();
};

[coclass, event_source(com), uuid("00000000-0000-0000-0000-000000000002")]


class CEventSrc : public IBase {
public:
__event __interface IEvents; // C3705 uncomment IEvents to resolve
HRESULT fireEvents() {
HRESULT hr = IEvents_event1(123);
return hr;
}
};
Compiler Error C3706
10/31/2018 • 2 minutes to read • Edit Online

'function' : must be a COM interface to fire COM events


The event interface that you use to fire COM events must be a COM interface. In this situation, the interface should
either be defined using a Visual C++ attribute, or imported using #import from a type library with #import's
embedded_idl attribute.
Note that the #include lines of the ATL header files shown in the sample below are required for using COM
events. To fix this error, make IEvents (the eventing interface) a COM interface by applying one of the following
attributes to the interface definition: object, dual, or dispinterface.
If an interface is from a header file generated by MIDL, the compiler will not recognize it as a COM interface.
The following sample generates C3706:

// C3706.cpp
// compile with: /c
// C3706 expected
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

[module(dll, name="idid", uuid="12341234-1234-1234-1234-123412341234")];

// Uncomment the following line to resolve.


// [object, uuid="12341234-1234-1234-1234-123412341237"]
__interface IEvents : IUnknown {
HRESULT event1(/*[in]*/ int i); // uncomment [in]
};

[dual, uuid="12341234-1234-1234-1234-123412341235"]
__interface IBase {
HRESULT fireEvents();
};

[coclass, event_source(com), uuid="12341234-1234-1234-1234-123412341236"]


class CEventSrc : public IBase {
public:
__event __interface IEvents;

HRESULT fireEvents() {
HRESULT hr = IEvents_event1(123);
return hr;
}
};
Compiler Error C3707
10/31/2018 • 2 minutes to read • Edit Online

'function' : dispinterface method must have a dispid


If you use a method, you must assign it a dispid . To fix this error, assign a dispid to the
dispinterface
dispinterface method, for example, by uncommenting the id attribute on the method in the sample below. For
more information, see the attributes dispinterface and id.
The following sample generates C3707:

// 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

'interface': improper use of 'keyword'; must be a member of a compatible event source


To declare an interface as an event, the event declaration must be in an event source.
The following sample generates C3708:

// 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();
};

__event __interface I; // C3708

// put the event in an event source


[ coclass, event_source(com), uuid("00000000-0000-0000-0000-000000000003") ]
struct E : II {
__event __interface II;
};
Compiler Error C3709
10/31/2018 • 2 minutes to read • Edit Online

'function': improper syntax for specifying event in __hook/__unhook


When you specify an event source with __hook or __unhook, the first parameter must be a valid event method and
the second parameter must be a valid event source object (not a method).
The following sample generates C3709:

// C3709.cpp
// compile with: /LD
[event_source(native)]
class CEventSrc
{
public:
__event void event1();
};

[event_receiver(native)]
class CEventRec
{
public:
void handler1()
{
}

void HookEvents(CEventSrc* pSrc)


{
__hook(bad, pSrc, CEventRec::handler1); // C3709
// Try the following line instead:
// __hook(&CEventSrc::event1, pSrc, CEventRec::handler1);
}

void UnhookEvents(CEventSrc* pSrc)


{
__unhook(&CEventSrc::event1, pSrc, CEventRec::handler1);
}
};
Compiler Error C3710
10/31/2018 • 2 minutes to read • Edit Online

'function': improper syntax for specifying event handler in __hook/__unhook


When you specify an event handler with __hook or __unhook, the handler must be a valid method.

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");
}

void HookEvents(CEventSrc* pSrc)


{
__hook(&CEventSrc::event1, pSrc, 0); // C3710
// try the following line instead
// __hook(&CEventSrc::event1, pSrc, &CEventRec::handler1);
}

void UnhookEvents(CEventSrc* pSrc)


{
__unhook(&CEventSrc::event1, pSrc, &CEventRec::handler1);
}
};

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() {}

void HookEvents(CEventSrc* pSrc) {


__hook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3712
}
void UnhookEvents(CEventSrc* pSrc) {
__unhook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3712
}
};
Compiler Error C3713
10/31/2018 • 2 minutes to read • Edit Online

'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() {}

void HookEvents(CEventSrc* pSrc) {


__hook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3713
}

void UnhookEvents(CEventSrc* pSrc) {


__unhook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3713
}
};
Compiler Error C3714
10/31/2018 • 2 minutes to read • Edit Online

'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.

The following sample generates C3714:

// 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() {}

void HookEvents(CEventSrc* pSrc) {


__hook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3714
}

void UnhookEvents(CEventSrc* pSrc) {


__unhook(&CEventSrc::event1, pSrc, &CEventRec::handler1); // C3714
}
};
Compiler Error C3715
10/31/2018 • 2 minutes to read • Edit Online

'pointer': must be a pointer to 'class'


You specified a pointer in __hook or __unhook that did not point to a valid class. To fix this error, ensure that your
__hook and __unhook calls specify pointers to valid classes.
Compiler Error C3717
10/31/2018 • 2 minutes to read • Edit Online

'method': a method that fires events cannot be defined


You declared an event method that includes an implementation. An __event method declaration cannot have a
definition. To fix this error, ensure that no event method declarations have definitions. For example, in the code
below, remove the function body from the event1 declaration as indicated by the comments.
The following sample generates C3717:

// C3717.cpp
[event_source(native)]
class CEventSrc {
public:
__event void event1() { // C3717
}

// remove definition for event1 and substitute following declaration


// __event void event1();
};

[event_receiver(native)]
class CEventRec {
public:
void handler1() {
}

void HookEvents(CEventSrc* pSrc) {


__hook(CEventSrc::event1, pSrc, CEventRec::handler1);
}

void UnhookEvents(CEventSrc* pSrc) {


__unhook(CEventSrc::event1, pSrc, CEventRec::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_source(com), coclass, uuid("00000000-0000-0000-0000-000000000002")]


struct E
{
__event __interface I;
};

[event_receiver(com)]
struct R
{
void b()
{
printf_s("B::bar()\n");
}

void HookAndRun(E* pE)


{
__hook(&I::f, pE->GetUnknown(), &R::b);
__raise pE->f();
}
};

int main()
{
CComObject<E>* pE;
CComObject<E>::CreateInstance(&pE);

__hook(&I::f, pE->GetUnknown(), &R::b, &r); // C3718


__raise pE->f();
// try the following lines instead
// R r;
// r.HookAndRun(pE);
}
Compiler Error C3719
10/31/2018 • 2 minutes to read • Edit Online

'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"

[module(name="MyLibrary", version="1.2", helpfile="MyHelpFile")];

[object]
__interface I {
HRESULT func1();
};

[event_source(native), coclass]
struct A {
__event __interface I; // C3719

// try the following line instead


// __event func2();
};

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();
};

[coclass, event_source(com) , uuid("00000000-0000-0000-0000-000000000002")]


struct MyStruct {
__event __interface I;
};

[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

'signature': incompatible signature for event


An event was declared incorrectly. For more information, see __event.
C3721 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3722
10/31/2018 • 2 minutes to read • Edit Online

a generic event is not allowed


The compiler only allows generic classes, structs, and functions. For more information, see Generics.
The following sample generates C3722:

// C3722.cpp
// compile with: /clr
generic <typename T>
public delegate void MyEventHandler(System::Object^ sender, System::EventArgs^ e, T optional);

generic <class T>


public ref struct MyButton {
generic<typename U>
event MyEventHandler<U>^ Click; // C3722
};
Compiler Error C3723
10/31/2018 • 2 minutes to read • Edit Online

'function': could not resolve event


function could not resolve which event to call.
The following sample generates C3723:

// 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;

public delegate void delegate1();

public ref class CPSource {


public:
event delegate1^ event1;
};

public ref class CReceiver {


public:
void Handler1() {
}

void UnhookAll(CPSource^ pSrc) {


__unhook(&CPSource::event1, pSrc, &CReceiver::Handler1); // C3723
// Try the following line instead.
// pSrc->event1 -= gcnew delegate1(this, &CReceiver::Handler1);
}
};

int main() {
}
Compiler Error C3724
10/31/2018 • 2 minutes to read • Edit Online

must #include <windows.h> to use multi-threading with events


The windows.h file is required if you use multi-threading with events. To fix this error, add #include <windows.h> to
the top of the file in which event sources and event receivers are defined.

// 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() {
}

void HookEvents(CEventSrc* pSrc) {


__hook(CEventSrc::event1, pSrc, CEventRec::handler1);
}

void UnhookEvents(CEventSrc* pSrc) {


__unhook(CEventSrc::event1, pSrc, CEventRec::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

'event': event does not have a raise method


Metadata created with a language, such as C#, that does not allow an event to be raised from outside the class in
which it was defined, was included with the #using directive, and a Visual C++ program using CLR programming
attempted to raise the event.
To raise an event in a program developed in a language such as C#, the class containing the event needs to also
define a public method that raises the event.
Compiler Error C3731
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")];

// to resolve this C3732, use dual instead of object


// or inherit from IUnknown
[ object ]
__interface I : IDispatch
{
};

[ 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"

[coclass, event_source(com), // change 'com' to 'native' to resolve


uuid("00000000-0000-0000-0000-000000000001")]
class A
{
__event void func(); // C3733
};

int main()
{
}
Compiler Error C3734
10/31/2018 • 2 minutes to read • Edit Online

'class': a managed or WinRT class cannot be a coclass


The coclass attribute cannot be used with managed or WinRT classes.
The following sample generates C3734 and shows how to fix it:

// 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

'delegate': a delegate may not have an explicit calling convention


You cannot specify the calling convention for a delegate .

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)]

// use the following line instead


// [event_receiver(com, layout_dependent=true), coclass ]
struct B
{
void f();
B(A* a)
{
__hook(A, a, &B::f); // C3739
// use the following line instead to hook a single event
// __hook(&A::e, a, &B::f);
}
};

int main()
{
}
Compiler Error C3740
10/31/2018 • 2 minutes to read • Edit Online

templates cannot source or receive events


A templated class or struct cannot contain events.
The following sample generates C3740:

// 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

'class': must be a coclass when the 'layout_dependent' parameter of event_receiver = true


When layout_dependent=true for an event_receiver class, then the class must also have the coclass attribute.
The following sample generates C3741

// 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(); };

// Delete the following line to resolve.


[ event_receiver(com, layout_dependent=true)]

// class or struct must be declared with coclass


// Uncomment the following line to resolve.
// [ event_receiver(com, layout_dependent=true), coclass, uuid("00000000-0000-0000-0000-000000000002")]
struct R : I {
HRESULT f(){ return 0; }
R(){}
R(I* a){ __hook(I, a); }
};
Compiler Error C3743
10/31/2018 • 2 minutes to read • Edit Online

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.

The following sample generates C3743:

// C3743.cpp
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="xx")];
[object] __interface I { HRESULT f(); };

[event_receiver(com, layout_dependent=true), coclass]


struct R : I {
HRESULT f() {
return 0;
}
R() {
}

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

__unhook must have at least 3 arguments for managed events


The __unhook function must take three parameters when used in a program that is compiled for Managed
Extensions for C++.
__hook and __unhook are not compatible with /clr programming. Use the += and -= operators instead.
C3744 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3745
10/31/2018 • 2 minutes to read • Edit Online

'function': only an event can be 'raised'


Only a function defined with the __event keyword can be passed to the __raise keyword.
The following sample generates C3745:

// 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

missing default type parameter : parameter param


Generic or template parameters with default values cannot be followed in the parameter list by parameters that do
not have default values.
The following sample generates C3747:

// 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

'interface': managed interfaces may not fire events


The __event keyword cannot appear inside an interface.
The following sample generates C3748:

// 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

'attribute': a custom attribute may not be used inside a function


A custom attribute cannot be used inside a function. For more information on custom attributes, see the topic
attribute.

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() {}
};

void f1() { [ABC]; }; // C3749


Compiler Error C3752
10/31/2018 • 2 minutes to read • Edit Online

'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

a generic property is not allowed


Generic parameter lists can only appear on managed classes, structs, or functions.
For more information, see Generics and property.

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;

delegate void MyDel();

interface class MyInterface {};

ref struct MyClass : MyInterface {


void f() {}
};

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

'delegate': a delegate may not be defined


A delegate (C++ Component Extensions) can be declared but not defined.

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

'function': 'retval' can only appear on the last argument of a function


The retval attribute was used on a function argument that was not the last argument in the list.
The following sample generates C3761:

// 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

unable to process attribute 'attribute'


A user-defined attribute that inherits from System.Security.Permissions.SecurityAttribute is being used to define a
security attribute. Such an attribute cannot be used in the same assembly where it is defined.
Compiler Error C3763
10/31/2018 • 2 minutes to read • Edit Online

'type': 'retval' and 'out' can only appear on a data-pointer type


The out or retval attributes can only appear on parameters of type pointer. Either remove the attribute or make the
parameter of type pointer.
The following sample generates C3763:

// 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

'override_function': cannot override base class method 'base_class_function'


The compiler detected an ill-formed override. For example, the base class function was not virtual . For more
information, see override.

Example
The following sample generates C3764.

// C3764.cpp
// compile with: /clr /c
public ref struct A {
void g(int);
virtual void h(int);
};

public ref struct B : A {


virtual void g(int) override {} // C3764
virtual void h(int) override {} // OK
};

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() {}
};

ref struct B : public A {


virtual void Test() override {}
virtual void Test2() = A::Test {} // C3764
};
Compiler Error C3765
10/31/2018 • 2 minutes to read • Edit Online

'event': cannot define an event in a class/struct 'type' marked as an event_receiver


If a class is marked with the event_receiver attribute, the class cannot contain an __event declaration.
The following sample generates C3765:

// 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

'type' must provide an implementation for the interface method 'function'


A class that inherits from an interface must implement the interface members.

Example
The following sample generates C3766.

// C3766.cpp
// compile with: /clr /c

delegate void MyDel();

interface struct IFace {


virtual event MyDel ^ E;
};

ref struct Class1 : public IFace {}; // C3766

// 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

'function' candidate function(s) not accessible


A friend function defined in a class is not supposed to be treated as if it were defined and declared in the global
namespace scope. It can, however, be found by argument-dependent lookup.
C3767 may also be caused by a breaking change: native types are now private by default in a /clr compilation; see
Type visibility for more information.

Example
The following sample generates C3767:

// C3767a.cpp
// compile with: /clr
using namespace System;
public delegate void TestDel();

public ref class MyClass {


public:
static event TestDel^ MyClass_Event;
};

public ref class MyClass2 : public MyClass {


public:
void Test() {
MyClass^ patient = gcnew MyClass;
patient->MyClass_Event();
}
};

int main() {
MyClass^ x = gcnew MyClass;
x->MyClass_Event(); // C3767

// OK
MyClass2^ y = gcnew MyClass2();
y->Test();
};

The following sample generates C3767:


// C3767c.cpp
// compile with: /clr /c

ref class Base {


protected:
void Method() {
System::Console::WriteLine("protected");
}
};

ref class Der : public Base {


void Method() {
((Base^)this)->Method(); // C3767
// try the following line instead
// Base::Method();
}
};
Compiler Error C3768
10/31/2018 • 2 minutes to read • Edit Online

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

"identifier" : friend declaration cannot be found in the nearest namespace scope


The class template declaration for the specified template identifier cannot be found within the current namespace.
To correct this error
Ensure that the class template declaration for the template identifier is defined in the current namespace or that
the template identifier is a fully-qualified name.

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

"name" : invalid friend template declaration


It is invalid to declare a friend of a class template specialization. You cannot declare an explicit or partial
specialization of a class template and in the same statement declare a friend of that specialization. The name
placeholder identifies the invalid declaration.
To correct this error
Do not declare a friend of a class template specialization.
If appropriate for your application, declare a friend of the class template, or declare a friend of a particular
partial or explicit specialization.

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 {};

// A partial specialization of the class template.


template<class T> class A<T*> {};

// 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

// Instead, if it is appropriate for your application, declare a


// friend of the class template. Consequently, all specializations
// of the class template are friends:
// template<class T> friend class A;
// Or declare a friend of a particular partial specialization:
// friend class A<int*>;
// Or declare a friend of a particular explicit specialization:
// friend class A<char>;
};

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();

ref class Class1 {


public:
virtual event MyDel ^ E;
};

ref class Class2 : public Class1 {


public:
virtual event MyDel ^ E override; // C3797
};

// 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;
}

property int Prop_4 {


virtual int get() sealed;
virtual void set(int i) sealed;
}
};
Compiler Error C3799
10/31/2018 • 2 minutes to read • Edit Online

indexed property cannot have an empty parameter list


An indexed property was declared incorrectly. For more information, see How to: Use Properties in C++/CLI.

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

'declaration': cannot mix properties and events


You cannot declare a construct to be both a property and an event.
C3800 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3803
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

'token' : unexpected token, expected either '}' or an identifier


When defining a property, an invalid token was encountered. Remove the invalid token.
Compiler Error C3807
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

'class' : a managed or WinRT type cannot have any friend functions/classes/interfaces


Managed types and Windows Runtime types do not allow friends. To fix this error, do not declare friends inside
managed or Windows Runtime types.
The following sample generates C3809:

// 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

'property' must be the first token in a property declaration


When declaring a property, the __property keyword must be the first token on the line.
C3812 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3813
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

'declaration' was previously declared or defined with a different managed or WinRTmodifier


A forward declaration and an actual declaration require that there be no conflicts or inconsistencies in the
declaration of attributes.
The following sample generates C3816 and shows how to fix it:

// 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

'declaration' : property can only be applied to a function


The property keyword can only be a applied to a function definition.
C3817 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Error C3818
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

'name': initializers must be managed


The name initializer for a managed type must also be managed.
To correct this error
1. Specify a managed initializer method.

See Also
Initializers
Additional Startup Considerations
Compiler Error C3821
10/31/2018 • 2 minutes to read • Edit Online

'function': managed type or function cannot be used in an unmanaged function


Functions with inline assembly or setjmp cannot contain value types or managed classes. To fix this error, remove
the inline assembly and setjmp or remove the managed objects.
C3821 can also occur if you try to use automatic storage in a vararg function. For more information, see Variable
Argument Lists (...) (C++/CLI) and C++ Stack Semantics for Reference Types.

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

'class': a managed or WinRTclass can only support managed or WinRTevents


Only .NET events are supported in managed classes. Only Windows Runtime events are supported in Windows
Runtime classes. To fix this error in managed code, change type parameter of event_source and event_receiver
from native to managed . Alternatively, remove the attribute.

Example
The following sample generates C3825 and shows how to fix it:

// C3825a.cpp
// compile with: /clr
public delegate void del1();

[event_source(native)] // To fix, change 'native' to 'managed' or delete this line


ref class CEventSrc
{
public:
event del1^ event1; // C3825

void FireEvents() {
event1();
}
};

[event_receiver(native)] // To fix, change 'native' to 'managed' or delete this line


ref class CEventRec
{
public:
void handler1()
{
System::Console::WriteLine("Executing handler1().\n");
}
void HookEvents(CEventSrc^ pSrc)
{
pSrc->event1 += gcnew del1(this, &CEventRec::handler1);
}
void UnhookEvents(CEventSrc^ pSrc)
{
pSrc->event1 -= gcnew del1(this, &CEventRec::handler1);
}
};

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;
};

public value class MyClass : public MyStruct4 {}; // C3830

// OK
public interface struct MyInterface4 {
void i();
};

public value class MyClass2 : public MyInterface4 {


public:
virtual void i(){}
};
Compiler Error C3831
10/31/2018 • 2 minutes to read • Edit Online

'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

'type' : invalid target type for pointer_type


An interior_ptr or pin_ptr was declared incorrectly.
The following sample generates C3833:

// C3833.cpp
// compile with: /clr

ref class MyClass {


public:
int data;
MyClass() : data(35) {}
};

int main() {
interior_ptr<MyClass> p; // C3833

// OK
MyClass ^ h_MyClass = gcnew MyClass;
interior_ptr<int> i = &(h_MyClass->data);
System::Console::WriteLine(*i);
}

The following sample generates C3833:

// 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;

pin_ptr<int> p = safe_cast<pin_ptr<int> >(&x); // C3834


pin_ptr<int> p2 = &x; // OK
}
Compiler Error C3836
10/31/2018 • 2 minutes to read • Edit Online

static constructor is not allowed to have a member initializer list


A managed class cannot have a static constructor that also has a member initialization list. Static class constructors
are called by the common language runtime to do class initialization, initializing static data members.

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

cannot explicitly inherit from 'type'


The specified type cannot act as a base class in any class.

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

cannot change alignment in a managed or WinRT type


Alignment of variables in managed or Windows Runtime types is controlled by the CLR or Windows Runtime and
cannot be modified with align.
The following sample generates C3839:

// 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
{
};

And then compile this:

// 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()
{
}

typedef void (* pFunc1)();

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;
}

typedef void (* pFunc2)(int);

void glbFunc1()
{
}
typedef void (* pFunc1)();

struct S4
{
operator ()(int i)
{
i;
}

operator pFunc1() const


{
return &glbFunc1;
}

operator pFunc2() volatile


{
return &glbFunc2;
}

operator pFunc3()
{
return &glbFunc3;
}

// operator pFunc1() const volatile


// {
// return &glbFunc1;
// }
};

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

'char': a universal-character-name specifies an invalid character

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

'char': a universal-character-name cannot designate a character in the basic character set

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 };

S2 s2 = { 2 }; // C3852 reference member


// try the following line instead
// char c = 'a';
S2 s2 = { 2, c };
}
Compiler Error C3853
10/31/2018 • 2 minutes to read • Edit Online

'=': re-initializing a reference or assignment through a reference-to-function is illegal


Cannot assign to a reference through a function because functions are not lvalues.
The following samples generate C3853:

// C3853.cpp
// compile with: /EHsc
#include <iostream>
int afunc(int i)
{
return i;
}

typedef int (& rFunc_t)(int);

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;
}

typedef int (& rFunc_t)(int);


typedef int (* pFunc_t)(int);

int main()
{
rFunc_t rf = afunc; // OK binding a reference to function
pFunc_t pf = &afunc; // OK initializing a pointer to function

*pf = &afunc; // C3854


// try the following line instead
// pf = &afunc;
*rf = &afunc; // C3854
}
Compiler Error C3855
10/31/2018 • 2 minutes to read • Edit Online

'class': type parameter 'param' is incompatible with the declaration


The compiler found nontype template or generic parameters with different names. This can occur when a specified
template parameter in the definition of a template specialization is incompatible with its declaration.
The following sample generates C3855:

// C3855.cpp
template <int N>
struct C {
void f();
};

template <char N>


void C<N>::f() {} // C3855

Possible resolution:

// C3855b.cpp
// compile with: /c
template <int N>
struct C {
void f();
};

template <int N>


void C<N>::f() {}

C3855 can also occur when using generics:

// C3855c.cpp
// compile with: /clr
generic <class T>
ref struct GC1 {
generic <class U>
ref struct GC2;
};

generic <class T>


generic <class U>
generic <class V>
ref struct GC1<T>::GC2 { }; // C3855

Possible resolution:
// C3855d.cpp
// compile with: /clr /c
generic <class T>
ref struct GC1 {
generic <class U>
ref struct GC2;
};

generic <class T>


generic <class U>
ref struct GC1<T>::GC2 { };
Compiler Error C3856
10/31/2018 • 2 minutes to read • Edit Online

'type': class is not a class type


The most common cause for this error is when there are more generic or template parameter lists at the point of
definition than there were at the point of declaration.
The following sample generates C3856:

// C3856.cpp
template <class T>
struct S {
template <class T1>
struct S1;
void f();
};

template <class T> // C3856


template <class T1>
template <class T2> // extra template parameter list in definition
struct S<T>::S1{};

Possible resolution:

// C3856b.cpp
// compile with: /c
template <class T>
struct S {
template <class T1>
struct S1;
void f();
};

template <class T>


template <class T1>
struct S<T>::S1{};

C3856 can also occur when using generics:

// C3856c.cpp
// compile with: /clr
generic <class T>
ref struct GS {
generic <class U>
ref struct GS2;
};

generic <class T>


generic <class U>
generic <class V>
ref struct GS<T>::GS2 {}; // C3856

Possible resolution:
// C3856d.cpp
// compile with: /clr /c
generic <class T>
ref struct GS {
generic <class U>
ref struct GS2;
};

generic <class T>


generic <class U>
ref struct GS<T>::GS2 {};
Compiler Error C3857
10/31/2018 • 2 minutes to read • Edit Online

'type': multiple type parameter lists are not allowed


More than one template or generic was specified for the same type, which is not allowed.
The following sample generates C3857:

// 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 {};

C3857 can also occur when using generics:

// 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

'type': cannot be redeclared in current scope


The type cannot be declared twice in the same scope.
The following sample generates C3858:

// C3858.cpp
// compile with: /LD
template <class T>
struct Outer
{
struct Inner;
};

template <class T>


struct Outer<T>::Inner; // C3858
// try the following line instead
// struct Outer<T>::Inner{};
Compiler Error C3859
3/11/2019 • 2 minutes to read • Edit Online

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();
};

template <class T2, class T1>


void A<T1, T2>::f() {} // C3860

Possible resolution:

// C3860b.cpp
// compile with: /c
template <class T1, class T2>
struct A {
void f();
};

template <class T2, class T1>


void A<T2, T1>::f() {}

C3860 can also occur when using generics:

// C3860c.cpp
// compile with: /clr
generic<class T,class U>
ref struct GC {
void f();
};

generic<class T, class U>


void GC<T,T>::f() {} // C3860

Possible resolution:

// C3860d.cpp
// compile with: /clr /c
generic<class T,class U>
ref struct GC {
void f();
};

generic<class T, class U>


void GC<T,U>::f() {}
Compiler Error C3861
10/31/2018 • 2 minutes to read • Edit Online

'identifier': identifier not found

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
}

Identifier not in scope


The following sample generates C3861 because an identifier is only visible in the file scope of its definition, unless
it is declared in other source files that use it.

// 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;
}

Namespace qualification required


Exception classes in the C++ Standard Library require the std namespace.

// 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;
}
}

Obsolete function called


Obsolete functions have been removed from the CRT library.

// 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 );
}

ADL and friend functions


The following sample generates C3767 because the compiler cannot use argument dependent lookup for
FriendFunc :

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

'function': cannot compile an unmanaged function 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.
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

'calling_convention' : can only be used on native member functions


A calling convention was used on a function that was either a global function or on a managed member function.
The calling convention can only be used on a native (not managed) member function.
For more information, see Calling Conventions.
The following sample generates C3865:

// 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

function call missing argument list


Inside a nonstatic member function, a destructor or finalizer call did not have an argument list.
The following sample generates C3866:

// 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() {}
};

class Derived : public Base {


virtual void Bar();
};

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

// try the following line instead


void (X::*pmf2)() = &X::mf;
}

Example
The following sample generates C3867.
// C3867_4.cpp
// compile with: /c
class A {
public:
void f(int) {}

typedef void (A::*TAmtd)(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;

generic <typename T> ref struct MyStruct;


generic <typename U> where U : I1 ref struct MyStruct; // C3868

// OK
generic <typename T> ref struct MyStruct2;
generic <typename U> ref struct MyStruct2;

generic <typename T> where T : I1 ref struct MyStruct3;


generic <typename U> where U : I1 ref struct MyStruct3;
Compiler Error C3869
10/31/2018 • 2 minutes to read • Edit Online

gcnew constraint is missing empty parameter list '()'


The gcnew special constraint was specified without the empty parameter list. See Constraints on Generic Type
Parameters (C++/CLI) for more information.

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

'char': this character is not allowed in an identifier


The C++ compiler follows the C++11 standard on characters allowed in an identifier. Only certain ranges of
characters and universal character names are allowed in an identifier. Additional restrictions apply to the initial
character of an identifier. For more information and a list of allowed characters and universal character name
ranges, see Identifiers.
The range of characters allowed in an identifier is less restrictive when compiling C++/CLI code. Identifiers in code
compiled by using /clr should follow Standard ECMA-335: Common Language Infrastructure (CLI).
The following sample generates C3872:

// 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

'char': this character is not allowed as a first character of an identifier


The C++ compiler follows the C++11 standard on characters allowed in an identifier. Only certain ranges of
characters and universal character names are allowed in an identifier. Additional restrictions apply to the initial
character of an identifier. For more information and a list of allowed characters and universal character name
ranges, see Identifiers.
The range of characters allowed in an identifier is less restrictive when compiling C++/CLI code. Identifiers in code
compiled by using /clr should follow Standard ECMA-335: Common Language Infrastructure (CLI).
The following sample generates C3873:

// 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

return type of 'function' should be 'int' instead of 'type'


A function does not have the return type that was expected by the compiler.
The following sample generates C3874:

// C3874b.cpp
double main()
{ // C3874
}
Compiler Error C3880
10/31/2018 • 2 minutes to read • Edit Online

'var' : cannot be a literal data member


The type of a literal attribute must be, or compile-time convertible to, one of the following types:
integral type
string
enum with an integral or underlying type
The following sample generates C3880:

// 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

'var' : an initonly static data member must be initialized


A variable marked with initonly was not initialized correctly.
The following sample generates C3883:

// C3883.cpp
// compile with: /clr
ref struct Y1 {
initonly
static int staticConst1; // C3883
};

The following sample demonstrates a possible resolution:

// C3883b.cpp
// compile with: /clr /c
ref struct Y1 {
initonly
static int staticConst2 = 0;
};

The following sample shows how to initialize in a static constructor:

// 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

'var' : a literal data member must be initialized


A literal variable must be initialized when it is declaraed.
The following sample generates C3886:

// 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

'var' : you cannot take the address of a literal data member


A literal data member exists on the garbage-collected heap. An object on the garbage-collected heap can be
moved, so taking the address is not useful.
The following sample generates C3890:

// 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

'var' : a literal data member cannot be used as a l-value


A literal variable is const, and its value cannot be changed after it is initialized in the declaration.
The following sample generates C3891:

// 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

'var' : you cannot assign to a variable that is const


A const variable cannot be changed after it is declared and initialized.
The following sample generates C3892:

// 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");
}

// not the class constructor


Y1(int i) {
data_var = i; // C3894
}

static void Test() {}

};

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

'var' : type data members cannot be 'volatile'


Certain kinds of data members, for example literal or initonly, cannot be volatile.
The following sample generates C3895:

// 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

'var' : type data members can only be members of managed types


An initonly data member was declared in a native class. An initonly data member can only be declared in a CLR
class.
The following sample generates C3898:

// 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>

public ref struct R {


initonly int x;
R() {
x = omp_get_thread_num() + 1000; // OK
#pragma omp parallel num_threads(5)
{
// cannot assign to 'x' here
x = omp_get_thread_num() + 1000; // C3899
System::Console::WriteLine("thread {0}", omp_get_thread_num());
}
x = omp_get_thread_num() + 1000; // OK
}
};

int main() {
R^ r = gcnew R;
System::Console::WriteLine(r->x);
}
Compiler Error C3900
10/31/2018 • 2 minutes to read • Edit Online

'member': not allowed in current scope


Property blocks can contain function declarations and inline function definitions only. No members other than
functions are allowed in property blocks. No typedefs, operators, or friend functions are allowed. For more
information, see property.
Event definitions can only contain access methods and functions.
The following sample generates C3900:

// C3900.cpp
// compile with: /clr
ref class X {
property int P {
void set(int); // OK
int i; // C3900 variable declaration
};
};

The following sample generates C3900:

// 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

'accessor_function': must have return type 'type'


At least one get method's return type must match the property type. For more information, see property.
The following sample generates C3901:

// 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

'accessor': type of last parameter must be 'type'


The type of the last parameter of at least one set method must match the type of the property. For more
information, see property.
The following sample generates C3902:

// 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^){}
}

property double values[int,int] {


void set(int, int, float); // C3902
// try the following line instead
// void set(int, int, double){}
}
};
Compiler Error C3903
10/31/2018 • 2 minutes to read • Edit Online

'property': does not have set or get method


A property must have at least a get or a set method. For more information, see property.
The following sample generates C3903:

// 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

property double Q[,,,,] {


void f(){}
// Add one or both of the following lines.
// void set(int, char, int, char, double, double){}
// double get(int, char, int, char, double){return 1.1;}
} // C3903
};
Compiler Error C3904
10/31/2018 • 2 minutes to read • Edit Online

'property_accessor': must specify number parameter(s)


Check the number of parameters in your get and set methods against property dimensions.
The number of parameters for the get method must equal the number of dimensions of the property or be
zero for nonindexed properties.
The number of parameters of the set method must be one more than the number of dimensions of the
property.
For more information, see property.

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

access level less restrictive than 'construct'


A property accessor method (get or set) cannot have less restrictive access than the access specified on the
property itself. Similarly, for event accessor methods.
For more information, see property and event.
The following sample generates C3908:

// 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

aWinRT or managed event declaration must occur in a WinRT or managed type


A Windows Runtime event or managed event was declared in a native type. To fix this error, declare events in
Windows Runtime types or managed types.
For more information, see event.
The following sample generates C3909 and shows how to fix it:

// 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

'event': must define member 'method'


An event was defined, but did not contain the specified, required accessor method.
For more information, see event.
The following sample generates C3910:

// 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

event H^ E2; // OK data member


};
Compiler Error C3911
10/31/2018 • 2 minutes to read • Edit Online

'event_accessor_method': function must have type 'signature'


An event's accessor method was not properly declared.
For more information, see event.
The following sample generates C3911:

// 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

'event': type of event must be a delegate type


An event was declared but was not of the proper type.
For more information, see event.
The following sample generates C3912:

// 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

default property must be indexed


A default property was defined incorrectly.
For more information, see property.
The following sample generates C3913:

// 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

a default property cannot be static


A default property was declared incorrectly. For more information, see How to: Use Properties in C++/CLI.

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

'type' has no default indexed property (class indexer)


A type does not have a default, indexed property.
For more information, see property.

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

B ^ myb = gcnew B();


Console::WriteLine("{0}", myb[3]); // OK
}
Compiler Error C3917
10/31/2018 • 2 minutes to read • Edit Online

'property': obsolete construct declaration style


A property or event definition used syntax from a version before Visual Studio 2005.
For more information, see property.

Example
// C3917.cpp
// compile with: /clr /c
public ref class C {
private:
int m_length;
public:
C() {
m_length = 0;
}

property int get_Length(); // C3917

// The correct property definition:


property int Length {
int get() {
return m_length;
}

void set( int i ) {


m_length = i;
}
}
};
Compiler Error C3918
10/31/2018 • 2 minutes to read • Edit Online

usage requires 'member' to be a data member


C3918 can occur for several reasons related to events.

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();

event Del^ MyEvent {


void add(Del^ev) {
if ( MyEvent != nullptr) {} // C3918
if ( o != nullptr) {} // OK
}
void remove(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);

interface struct IEFace {


event MyDel ^ E;
};

ref struct EventSource : public IEFace {


virtual event MyDel ^ E;
void Fire_E(int i) {
if (E) // C3918
E(i);
}
};

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;

public delegate void del();

public ref class A {


public:
event del^ e {
void add(del ^handler ) {
d += handler;
}

void remove(del ^handler) {


d -= handler;
}

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

'event_method': function must have type 'type'


An event accessor method was not declared correctly.
For more information about events, see event.
The following sample generates C3919:

// 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:

PRODUCT COMPILER VERSION NUMBER

Visual C++ 2002 13.00.9466

Visual C++ 2003 13.10.3077

Visual C++ 2005 14.00.50727.762

Visual C++ 2008 15.00.21022.08

Visual C++ 2010 16.00.40219.01

Visual C++ 2012 17.00.51106.1

Visual C++ 2013 18.00.21005.1

Visual C++ 2015 RTM 19.00.23026.0

Visual C++ 2015 Update 1 19.00.23506.0

Visual C++ 2015 Update 2 19.00.23918.0

Visual C++ 2015 Update 3 19.00.24215.1

Visual C++ 2017 RTM 19.10.25017.0

Visual C++ 2017 version 15.3 19.11.25506.0

Visual C++ 2017 version 15.5 19.12.25830.0

Visual C++ 2017 version 15.6 19.13.26128.0

Visual C++ 2017 version 15.7 19.14.26428.0

Visual C++ 2017 version 15.8 19.15.26726.0

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.

Warnings introduced in Visual C++ 2017 version 15.8 (compiler version


19.15.26726.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.14.

C5046 'function' : Symbol involving type with internal linkage not


defined

Warnings introduced in Visual C++ 2017 version 15.7 (compiler version


19.14.26428.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.13.

C4642 'issue': could not import the constraints for generic parameter
'parameter'

C5045 Compiler will insert Spectre mitigation for memory load if


/Qspectre switch specified

Warnings introduced in Visual C++ 2017 version 15.6 (compiler version


19.13.26128.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.12.

C5044 An argument to command-line option option points to a


path 'path' that does not exist

Warnings introduced in Visual C++ 2017 version 15.5 (compiler version


19.12.25830.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.11.

C4843 'type1': An exception handler of reference to array or function


type is unreachable, use 'type2' instead

C4844 'export module module_name;' is now the preferred syntax


for declaring a module interface
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.

C5040 dynamic exception specifications are valid only in C++14 and


earlier; treating as noexcept(false)

C5041 'definition': out-of-line definition for constexpr static data


member is not needed and is deprecated in C++17

C5042 'declaration': function declarations at block scope cannot be


specified 'inline' in standard C++; remove 'inline' specifier

C5043 'specification': exception specification does not match


previous declaration

Warnings introduced in Visual C++ 2017 version 15.3 (compiler version


19.11.25506.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.10.

C4597 undefined behavior: description

C4604 'type': passing argument by value across native and managed


boundary requires valid copy constructor. Otherwise the
runtime behavior is undefined

C4749 conditionally supported: description

C4768 __declspec attributes before linkage specification are ignored

C4834 discarding return value of function with 'nodiscard' attribute

C4841 non-standard extension used: extension

C4842 the result of 'offsetof' applied to a type using multiple


inheritance is not guaranteed to be consistent between
compiler releases

C4869 'nodiscard' may only be applied to classes, enumerations, and


functions with non-void return type

C5033 'storage-class' is no longer a supported storage class

C5034 use of intrinsic 'intrinsic' causes function function to be


compiled as guest code

C5035 use of feature 'feature' causes function function to be


compiled as guest code
C5036 varargs function pointer conversion when compiling with
/hybrid:x86arm64 'type1' to 'type2'

C5037 'member-function': an out-of-line definition of a member of a


class template cannot have default arguments

C5038 data member 'member1' will be initialized after data member


'member2'

Warnings introduced in Visual C++ 2017 RTM (compiler version


19.10.25017.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.00.

C4468 'fallthrough': attribute must be followed by a case label or a


default label

C4698 'feature' is for evaluation purposes only and is subject to


change or removal in future updates.

C4839 non-standard use of class 'class' as an argument to a variadic


function

C4840 non-portable use of class 'class' as an argument to a variadic


function

Warnings introduced in Visual C++ 2015 Update 3 (compiler version


19.00.24215.1)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.00.23918.

C4467 usage of ATL attributes is deprecated

C4596 'name': illegal qualified name in member declaration

C4598 '#include <header>': header number number in the source


does not match source at that position

C4599 'argument': source argument number number does not


match source

Warnings introduced in Visual C++ 2015 Update 2 (compiler version


19.00.23918.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.00.23506.

C4466 Could not perform coroutine heap elision


C4595 'class': non-member operator new or delete functions may
not be declared inline

C4828 The file contains a character starting at offset 0xvalue that is


illegal in the current source character set (codepage number).

C4868 compiler may not enforce left-to-right evaluation order in


braced initializer list

Warnings introduced in Visual C++ 2015 Update 1 (compiler version


19.00.23506.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:19.00.23026.

C4426 optimization flags changed after including header, may be due


to #pragma optimize()

C4654 Code placed before include of precompiled header line will be


ignored. Add code to precompiled header.

C5031 #pragma warning(pop): likely mismatch, popping warning


state pushed in different file

C5032 detected #pragma warning(push) with no corresponding


#pragma warning(pop)

Warnings introduced in Visual C++ 2015 RTM (compiler version


19.00.23026.0)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:18.

C4427 'error': overflow in constant division, undefined behavior

C4438 'type': cannot be called safely in /await:clrcompat mode. If


'type' calls into the CLR it may result in CLR head corruption

C4455 'operator name': literal suffix identifiers that do not start with
an underscore are reserved

C4456 declaration of 'name' hides previous local declaration

C4457 declaration of 'name' hides function parameter

C4458 declaration of 'name' hides class member

C4459 declaration of 'name' hides global declaration

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

C4473 'function' : not enough arguments passed for format string

C4474 'function' : too many arguments passed for format string

C4475 'function' : length modifier 'modifier' cannot be used with


type field character 'character' in format specifier

C4476 'function' : unknown type field character 'character' in format


specifier

C4477 'function' : format string 'string' requires an argument of type


'type', but variadic argument number has type 'type'

C4478 'function' : positional and non-positional placeholders cannot


be mixed in the same format string

C4494 'type' : Ignoring __declspec(allocator) because the function


return type is not a pointer or reference

C4495 nonstandard extension '__super' used: replace with explicit


base class name

C4496 nonstandard extension 'for each' used: replace with ranged-


for statement

C4497 nonstandard extension 'sealed' used: replace with 'final'

C4498 nonstandard extension used: 'extension'

C4499 'specialization': an explicit specialization cannot have a


storage class (ignored)

C4576 a parenthesized type followed by an initializer list is a non-


standard explicit type conversion syntax

C4577 'noexcept' used with no exception handling mode specified;


termination on exception is not guaranteed. Specify /EHsc

C4578 'abs': conversion from 'type' to 'type', possible loss of data


(Did you mean to call 'name' or to #include <cmath>?)

C4582 'type': constructor is not implicitly called

C4583 'type': destructor is not implicitly called

C4587 'type': behavior change: constructor is no longer implicitly


called

C4588 'type': behavior change: destructor is no longer implicitly


called
C4589 Constructor of abstract class 'type' ignores initializer for
virtual base class 'type'

C4591 'constexpr' call-depth limit of number exceeded


(/constexpr:depth<NUMBER>)

C4592 'type': symbol will be dynamically initialized (implementation


limitation)

C4593 'type': 'constexpr' call evaluation step limit of value exceeded;


use /constexpr:steps<NUMBER> to increase the limit

C4647 behavior change: __is_pod(type) has different value in


previous versions

C4648 standard attribute 'carries_dependency' is ignored

C4649 attributes are ignored in this context

C4753 Cannot find bounds for pointer; MPX intrinsic function


ignored

C4771 Bounds must be created using a simple pointer; MPX intrinsic


function ignored

C4774 'description' : format string expected in argument number is


not a string literal

C4775 nonstandard extension used in format string 'string' of


function 'function'

C4776 '%character' is not allowed in the format string of function


'function'

C4777 'description' : format string 'string' requires an argument of


type 'type', but variadic argument number has type 'type'

C4778 'description' : unterminated format string 'string'

C4838 conversion from 'type' to 'type' requires a narrowing


conversion

C5022 'type': multiple move constructors specified

C5023 'type': multiple move assignment operators specified

C5024 'declaration': move constructor was implicitly defined as


deleted

C5025 'declaration': move assignment operator was implicitly


defined as deleted

C5026 'type': move constructor was implicitly defined as deleted


C5027 'type': move assignment operator was implicitly defined as
deleted

C5028 'name': Alignment specified in prior declaration (number) not


specified in definition

C5029 nonstandard extension used: alignment attributes in C++


apply to variables, data members and tag types only

C5030 attribute 'attribute' is not recognized

Warnings introduced in Visual C++ 2013 (compiler version


18.00.21005.1)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:17.

C4301 'type': overriding virtual function only differs from


'declaration' by const/volatile qualifier

C4316 'type': object allocated on the heap may not be aligned


number

C4380 'type': A default constructor cannot be deprecated

C4388 'token': signed/unsigned mismatch

C4423 'std::bad_alloc': will be caught by class ('type') on line number

C4424 catch for 'type' preceded by 'type' on line number;


unpredictable behavior may result if 'std::bad_alloc' is thrown

C4425 A SAL annotation cannot be applied to '...'

C4464 relative include path contains '..'

C4575 '__vectorcall' incompatible with the '/clr' option: converting to


'__stdcall'

C4609 'type' derives from default interface 'type' on type 'type'. Use
a different default interface for 'type', or break the
base/derived relationship.

C4754 Conversion rules for arithmetic operations in the comparison


at description(number) mean that one branch cannot be
executed. Cast 'type' to 'type' (or similar type of number
bytes).

C4755 Conversion rules for arithmetic operations in the comparison


at description(number) mean that one branch cannot be
executed in an inlined function. Cast 'type' to 'type' (or similar
type of number bytes).
C4767 section name 'name' is longer than 8 characters and will be
truncated by the linker

C4770 partially validated enum 'name' used as index

C4827 A public 'ToString' method with 0 parameters should be


marked as virtual and override

C4882 passing functors with non-const call operators to


concurrency::parallel_for_each is deprecated

C4973 'type': marked as deprecated

C4974 'type': marked as deprecated

C4981 Warbird: function 'declaration' marked as __forceinline not


inlined because it contains exception semantics

C4990 Warbird: message

C4991 Warbird: function 'declaration' marked as __forceinline not


inlined because protection level of inlinee is greater than the
parent

C4992 Warbird: function 'declaration' marked as __forceinline not


inlined because it contains inline assembly which cannot be
protected

Warnings introduced in Visual C++ 2012 (compiler version


17.00.51106.1)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:16.

C4330 attribute 'attribute' for section 'section' ignored

C4415 duplicate __declspec(code_seg('name'))

C4416 __declspec(code_seg(...)) contains empty string: ignored

C4417 an explicit template instantiation cannot have


__declspec(code_seg(...)): ignored

C4418 __declspec(code_seg(...)) ignored on an enum

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'

C4436 dynamic_cast from virtual base 'type' to 'type' in constructor


or destructor could fail with partially-constructed object
C4437 dynamic_cast from virtual base 'type' to 'type' could fail in
some contexts

C4443 expected pragma parameter to be '0', '1', or '2'

C4446 'type': cannot map member 'name' into this type, due to
conflict with the type name. The method was renamed to
'name'

C4447 'main' signature found without threading model. Consider


using 'int main(Platform::Array<Platform::String^>^ args)'.

C4448 'type' does not have a default interface specified in metadata.


Picking: 'type', which may fail at runtime.

C4449 'type' an unsealed type should be marked as


'[WebHostHidden]'

C4450 'type' should be marked as '[WebHostHidden]' because it


derives from 'type'

C4451 'type': Usage of ref class 'type' inside this context can lead to
invalid marshaling of object across contexts

C4452 'type': 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.

C4453 'type': A '[WebHostHidden]' type should not be used on the


published surface of a public type that is not
'[WebHostHidden]'

C4454 'type' is overloaded by more than the number of input


parameters without having [DefaultOverload] specified.
Picking 'declaration' as the default overload

C4471 'name': a forward declaration of an unscoped enumeration


must have an underlying type (int assumed)

C4472 'name' is a native enum: add an access specifier


(private/public) to declare a managed/WinRT enum

C4492 'type': matches base ref class method 'type', but is not marked
'override'

C4493 delete expression has no effect as the destructor of 'type'


does not have 'public' accessibility

C4585 'type': A WinRT 'public ref class' must either be sealed or


derive from an existing unsealed class

C4586 'type': A public type cannot be declared in a top-level


namespace called 'Windows'
C4695 #pragma execution_character_set: 'argument' is not a
supported argument: currently only 'UTF-8' is supported

C4703 potentially uninitialized local pointer variable 'name' used

C4728 /Yl- option ignored because PCH reference is required

C4745 volatile access of 'name' cannot be honored due to its size

C4746 volatile access of 'name' is subject to /volatile:<iso|ms>


setting; consider using __iso_volatile_load/store intrinsic
functions

C4872 floating point division by zero detected when compiling the


call graph for the concurrency::parallel_for_each at:
'description'

C4880 casting from 'type' to 'type': casting away constness from a


pointer or reference may result in undefined behavior in an
amp restricted function

C4881 the constructor and/or the destructor will not be invoked for
tile_static variable 'type'

C4966 'description' has __code_seg annotation with unsupported


segment name, annotation ignored

C4988 'type': variable declared outside class/function scope

C4989 'description': type has conflicting definitions.

Warnings introduced in Visual C++ 2010 (compiler version


16.00.40219.01)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:15.

C4352 'name': intrinsic function already defined

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'?

C4689 'character': unsupported character in #pragma


detect_mismatch; #pragma ignored

C4751 /arch AVX flag does not apply to Intel(R) Streaming SIMD
Extensions that are within inline ASM

C4752 found Intel(R) Advanced Vector Extensions; consider using the


appropriate /arch AVX flag
C4837 trigraph detected: '??character' replaced by 'character'

C4986 'declaration': exception specification does not match previous


declaration

C4987 nonstandard extension used: 'throw (...)'

Warnings introduced in Visual C++ 2008 (compiler version


15.00.21022.08)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:14.

C4396 'type': the inline specifier cannot be used when a friend


declaration refers to a specialization of a function template

C4413 'declaration': reference member is initialized to a temporary


that doesn't persist after the constructor exits

C4491 'description': has an illegal IDL version format

C4603 'name': macro is not defined or definition is different after


precompiled header use

C4627 'description': skipped when looking for precompiled header


use

C4750 'description': function with _alloca() inlined into a loop

C4910 'type': '__declspec(dllexport)' and 'extern' are incompatible on


an explicit instantiation

C4985 'declaration': attributes not present on previous declaration.

Warnings introduced in Visual C++ 2005 (compiler version


14.00.50727.762)
These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:13.

C4000 UNKNOWN WARNING Please choose the Technical Support


command on the Visual C++ Help menu, or open the
Technical Support help file for more information

C4272 'type': is marked __declspec(dllimport); must specify native


calling convention when importing a function.

C4333 'expression': right shift by too large amount, data loss

C4334 'expression': result of 32-bit shift implicitly converted to 64


bits (was 64-bit shift intended?)
C4335 Mac file format detected: please convert the source file to
either DOS or UNIX format

C4342 behavior change: 'type' called, but a member operator was


called in previous versions

C4350 behavior change: 'declaration' called instead of 'declaration'

C4357 param array argument found in formal argument list for


delegate 'declaration' ignored when generating 'type'

C4358 'expression': return type of combined delegates is not 'void';


returned value is undefined

C4359 'type': Alignment specifier is less than actual alignment


(number), and will be ignored.

C4362 'type': alignment greater than 8 bytes is not supported by


CLR

C4364 #using for assembly 'name' previously seen at


description(number) without as_friend attribute; as_friend not
applied

C4365 'expression': conversion from 'type' to 'type', signed/unsigned


mismatch

C4366 The result of the unary 'operator' operator may be unaligned

C4367 Conversion from 'type' to 'type' may cause datatype


misalignment exception

C4368 cannot define 'name' as a member of managed 'type': mixed


types are not supported

C4369 'type': enumerator value 'number' cannot be represented as


'type', value is 'number'

C4374 'declaration': interface method will not be implemented by


non-virtual method 'declaration'

C4375 non-public method 'declaration' does not override


'declaration'

C4376 access specifier 'specifier:' is no longer supported: please use


'specifier:' instead

C4377 native types are private by default; -d1PrivateNativeTypes is


deprecated

C4378 Must obtain function pointers to run initializers; consider


System::ModuleHandle::ResolveMethodHandle
C4379 Version version of the common language runtime is not
supported by this compiler. Using this version may cause
unexpected results

C4381 'declaration': interface method will not be implemented by


non-public method 'declaration'

C4382 throwing 'type': a type with __clrcall destructor or copy


constructor can only be caught in /clr:pure module

C4383 'type': the meaning of dereferencing a handle can change,


when a user-defined 'operator' operator exists; write the
operator as a static function to be explicit about the operand

C4384 #pragma 'directive' should only be used at global scope

C4393 'type': const has no effect on description data member;


ignored

C4394 'type': per-appdomain symbol should not be marked with


__declspec(value)

C4395 'type': member function will be invoked on a copy of the


initonly data member 'type'

C4397 DefaultCharSetAttribute is ignored

C4398 'type': per-process global object might not work correctly with
multiple appdomains; consider using __declspec(appdomain)

C4399 'type': per-process symbol should not be marked with


__declspec(value) when compiled with /clr:pure

C4400 'type': const/volatile qualifiers on this type are not supported

C4412 'declaration': function signature contains type 'type'; C++


objects are unsafe to pass between pure code and mixed or
native.

C4429 possible incomplete or improperly formed universal-


character-name

C4430 missing type specifier - int assumed. Note: C++ does not
support default-int

C4431 missing type specifier - int assumed. Note: C no longer


supports default-int

C4434 a static constructor must have private accessibility; changing


to private access

C4439 'type': function definition with a managed type in the


signature must have a __clrcall calling convention
C4441 calling convention of 'convention' ignored; 'convention' used
instead

C4445 'declaration': in a managed/WinRT type a virtual method


cannot be private

C4460 CLR/WinRT operator 'type', has parameter passed by


reference. CLR/WinRT operator 'operator' has different
semantics from C++ operator 'operator', did you intend to
pass by value?

C4461 'type': this class has a finalizer '!type' but no destructor '~type'

C4470 floating-point control pragmas ignored under /clr

C4480 nonstandard extension used: specifying underlying type for


enum 'type'

C4481 nonstandard extension used: override specifier 'specifier'

C4482 nonstandard extension used: enum 'type' used in qualified


name

C4483 syntax error: expected C++ keyword

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

C4486 'type': a private virtual method of a ref class or value class


should be marked 'sealed'

C4487 'type': matches inherited non-virtual method 'type' but is not


explicitly marked 'new'

C4488 'type': requires 'keyword' keyword to implement the interface


method 'type'

C4489 'keyword': not allowed on interface method 'name'; override


specifiers are only allowed on ref class and value class
methods

C4490 'keyword': incorrect use of override specifier; 'type' does not


match a base ref class method

C4538 'type': const/volatile qualifiers on this type are not supported

C4559 'type': redefinition; the function gains __declspec(value)

C4565 'type': redefinition; the symbol was previously declared with


__declspec(value)
C4566 character represented by universal-character-name 'character'
cannot be represented in the current code page (number)

C4568 'type': no members match the signature of the explicit


override

C4569 'type': no members match the signature of the explicit


override

C4570 'type': is not explicitly declared as abstract but has abstract


functions

C4571 Informational: catch(...) semantics changed since Visual C++


7.1; structured exceptions (SEH) are no longer caught

C4572 [ParamArray] attribute is deprecated under /clr, use '...' instead

C4580 [attribute] is deprecated; instead specify specifiedAttribute as


a base class

C4581 deprecated behavior: '"name"' replaced with 'name' to


process attribute

C4606 #pragma warning: 'number' ignored; Code Analysis warnings


are not associated with warning levels

C4631 MSXML or XPath unavailable, XML document comments will


not be processed. description

C4632 XML document comment: description - access denied:


description

C4633 XML document commentdescription: error: description

C4634 XML document commentdescription: cannot be applied:


description

C4635 XML document commentdescription: badly-formed XML:


description

C4636 XML document commentdescription: tag requires non-empty


'description' attribute.

C4637 XML document commentdescription: <include> tag


discarded. description

C4638 XML document commentdescription: reference to unknown


symbol 'description'.

C4639 MSXML error, XML document comments will not be


processed. description

C4641 XML document comment has an ambiguous cross reference:


C4678 base class 'declaration' is less accessible than 'name'

C4679 'description': could not import member

C4687 'type': a sealed abstract class cannot implement an interface


'type'

C4688 'name': constraint list contains assembly private type


'declaration'

C4690 [ emitidl( pop ) ]: more pops than pushes

C4691 'type': type referenced was expected in unreferenced module


'description', type defined in current translation unit used
instead

C4692 'name': signature of non-private member contains assembly


private native type 'declaration'

C4693 'type': a sealed abstract class cannot have any instance


members 'name'

C4694 'type': a sealed abstract class cannot have a base-class 'type'

C4720 in-line assembler reports: 'description'

C4721 'description': not available as an intrinsic

C4722 'description': destructor never returns, potential memory leak

C4726 ARM arch4/4T supports only '<cpsr_f> or <spsr_f>' with


immediate value

C4727 PCH named name with same timestamp found in name and
name. Using first PCH.

C4729 function too big for flow graph based warnings

C4730 'description': mixing _m64 and floating point expressions may


result in incorrect code

C4731 'description': frame pointer register 'register' modified by


inline assembly code

C4732 intrinsic 'intrinsic' is not supported in this architecture

C4733 Inline asm assigning to 'FS:0': handler not registered as safe


handler

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

C4739 reference to variable 'variable' exceeds its storage space

C4740 flow in or out of inline asm code suppresses global


optimization

C4742 'variable' has different alignment in 'location' and 'location':


number and number

C4743 'name' has different size in 'location' and 'location': number


and number bytes

C4744 'name' has different type in 'location' and 'location': 'type'


and 'type'

C4747 Calling managed 'type': Managed code may not be run under
loader lock, including the DLL entrypoint and calls reached
from the DLL entrypoint

C4761 integral size mismatch in argument; conversion supplied

C4764 Cannot align catch objects to greater than 16 bytes

C4788 'identifier': identifier was truncated to 'number' characters

C4789 buffer 'name' of size number bytes will be overrun; number


bytes will be written starting at offset number

C4801 Return by reference is not verifiable: description

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

C4826 Conversion from 'type' to 'type' is sign-extended. This may


cause unexpected runtime behavior.

C4829 Possibly incorrect parameters to function main. Consider 'int


main(Platform::Array<Platform::String^>^ argv)'

C4835 'type': the initializer for exported data will not be run until
managed code is first executed in the host assembly

C4867 'type': non-standard syntax; use '&' to create a pointer to


member

C4936 this __declspec is supported only when compiled with /clr or


/clr:pure

C4937 'name' and 'name' are indistinguishable as arguments to


'option'
C4938 'type': Floating point reduction variable may cause
inconsistent results under /fp:strict or #pragma fenv_access

C4939 #pragma vtordisp is deprecated and will be removed in a


future release of Visual C++

C4947 'type': marked as obsolete

C4949 pragmas 'managed' and 'unmanaged' are meaningful only


when compiled with '/clr[:option]'

C4950 'type': marked as obsolete

C4955 'description': import ignored; already imported from 'source'

C4956 'type': this type is not verifiable

C4957 'expression': explicit cast from 'type' to 'type' is not verifiable

C4958 'expression': pointer arithmetic is not verifiable

C4959 cannot define unmanaged class 'type' in /clr:safe because


accessing its members yields unverifiable code

C4960 'description' is too big to be profiled

C4961 No profile data was merged into 'location', profile-guided


optimizations disabled

C4962 'description': Profile-guided optimizations disabled because


optimizations caused profile data to become inconsistent

C4963 'description': no profile data found; different compiler options


were used in instrumented build

C4964 No optimization options were specified; profile info will not be


collected

C4965 implicit box of integer 0; use nullptr or explicit cast

C4970 delegate constructor: target object ignored since 'declaration'


is static

C4971 Argument order: <target object>, <target function> for


delegate constructor is deprecated, use <target function>,
<target object>

C4972 Directly modifying or treating the result of an unbox


operation as an lvalue is unverifiable

Warnings introduced in Visual C++ 2003 (compiler version 13.10.3077)


These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:13.00.9466.
C4343 #pragma optimize(description,off) overrides /Og option

C4344 behavior change: use of explicit template arguments results in


call to 'declaration'

C4346 'type': dependent name is not a type

C4348 'declaration': redefinition of default parameter: parameter


number

C4356 'type': static data member cannot be initialized via derived


class

C4408 anonymous struct did not declare any data members

C4544 'declaration': default template argument ignored on this


template declaration

C4545 expression before comma evaluates to a function which is


missing an argument list

C4546 function call before comma missing argument list

C4547 'expression': operator before comma has no effect; expected


operator with side-effect

C4548 expression before comma has no effect; expected expression


with side-effect

C4549 'expression': operator before comma has no effect; did you


intend 'expression'?

C4628 digraphs not supported with -Ze. Character sequence


'sequence' not interpreted as alternate token for 'token'

C4629 digraph used, character sequence 'sequence' interpreted as


token 'token' (insert a space between the two characters if
this is not what you intended)

C4671 'description': the copy constructor is inaccessible

C4676 'description': the destructor is inaccessible

C4677 'name': signature of non-private member contains assembly


private type 'declaration'

C4686 'type': possible change in behavior, change in UDT return


calling convention

C4812 obsolete declaration style: please use 'type::name' instead

C4813 'type': a friend function of a local class must have been


previously declared
C4821 Unable to determine Unicode encoding type, please save the
file with signature (BOM)

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

C4948 return type of 'declaration' does not match the last


parameter type of the corresponding setter

C4951 'description' has been edited since profile data was collected,
function profile data not used

C4952 'description': no profile data found in program database


'description'

C4953 Inlinee 'description' has been edited since profile data was
collected, profile data not used

C4954 'description': not profiled (contains __int64 switch expression)

Warnings introduced in Visual C++ 2002 (compiler version 13.00.9466)


These warnings and all warnings in later versions are suppressed by using the compiler option /Wv:12.

C4096 'type': interface is not a COM interface; will not be emitted to


IDL

C4097 expected pragma parameter to be 'restore' or 'off'

C4165 'HRESULT' is being converted to 'bool'; are you sure this is


what you want?

C4183 'name': missing return type; assumed to be a member


function returning 'int'

C4199 description

C4255 'name': no function prototype given: converting '()' to '(void)'

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

C4263 'declaration': member function does not override any base


class virtual member function
C4264 'declaration': no override available for virtual member
function from base 'class'; function is hidden

C4265 'type': class has virtual functions, but destructor is not virtual
instances of this class may not be destructed correctly

C4266 'declaration': no override available for virtual member


function from base 'class'; function is hidden

C4267 'expression': conversion from 'size_t' to 'type', possible loss of


data

C4274 #ident ignored; see documentation for #pragma


comment(exestr, 'string')

C4277 imported item 'type::name' exists as both data member and


function member; data member ignored

C4278 'name': identifier in type library 'description' is already a


macro; use the 'rename' qualifier

C4279 'name': identifier in type library 'description' is a keyword; use


the 'rename' qualifier

C4287 'expression': unsigned/negative constant mismatch

C4288 nonstandard extension used: 'name': loop control variable


declared in the for-loop is used outside the for-loop scope; it
conflicts with the declaration in the outer scope

C4289 nonstandard extension used: 'name': loop control variable


declared in the for-loop is used outside the for-loop scope

C4293 'expression': shift count negative or too big, undefined


behavior

C4295 'type': array is too small to include a terminating null character

C4296 'expression': expression is always value

C4297 'type': function assumed not to throw an exception but does

C4298 'name': identifier in type library 'description' is already a


macro; renaming to '__name'

C4299 'name': identifier in type library 'description' is a keyword;


renaming to '__name'

C4302 'expression': truncation from 'type' to 'type'

C4303 conversion from 'type' to 'type' is deprecated, use static_cast,


__try_cast or dynamic_cast

C4314 expected pragma parameter to be '32' or '64'


C4315 'type': 'this' pointer for member 'type' may not be aligned
number as expected by the constructor

C4318 passing constant zero as the length to memset

C4319 'expression': zero extending 'type' to 'type' of greater size

C4321 automatically generating an IID for interface 'type'

C4322 automatically generating a CLSID for class 'type'

C4323 re-using registered CLSID for class 'type'

C4324 'type': structure was padded due to alignment specifier

C4325 attributes for standard section 'description' ignored

C4326 return type of 'name' should be 'type' instead of 'type'

C4327 'expression': indirection alignment of LHS (number) is greater


than RHS (number)

C4328 'description': indirection alignment of formal parameter


number (number) is greater than the actual argument
alignment (number)

C4329 alignment specifier is ignored on enum

C4336 import cross-referenced type library 'library' before importing


'description'

C4337 cross-referenced type library 'library' in 'description' is being


automatically imported

C4338 #pragma description: standard section 'section' is used

C4339 'type': use of undefined type detected in CLR/WinRT meta-


data - use of this type may lead to a runtime exception

C4353 nonstandard extension used: constant 0 as function


expression. Use '__noop' function intrinsic instead

C4370 'declaration': layout of class has changed from a previous


version of the compiler due to better packing

C4371 'declaration': layout of class may have changed from a


previous version of the compiler due to better packing of
member 'member'
C4373 'type': virtual function overrides 'declaration', previous
versions of the compiler did not override when parameters
only differed by const/volatile qualifiers

C4387 'description': was considered

C4389 'expression': signed/unsigned mismatch

C4391 'declaration': incorrect return type for intrinsic function,


expected 'type'

C4392 'declaration': incorrect number of arguments for intrinsic


function, expected 'number' arguments

C4407 cast between different pointer to member representations,


compiler may generate incorrect code

C4420 'name': operator not available, using 'name' instead; run-time


checking may be compromised

C4440 calling convention redefinition from 'description' to


'description' ignored

C4442 embedded null terminator in __annotation argument. Value


will be truncated.

C4444 'name': top level '__unaligned' is not implemented in this


context

C4526 'type': static member function cannot override virtual function


'declaration' override ignored, virtual function will be hidden

C4531 C++ exception handling not available on Windows CE. Use


Structured Exception Handling

C4532 'description': jump out of finally block has undefined behavior


during termination handling

C4533 initialization of 'declaration' is skipped by 'goto declaration'

C4534 'declaration' will not be a default constructor for class 'type'


due to the default argument

C4535 calling _set_se_translator() requires /EHa

C4536 'description': type-name exceeds meta-data limit of 'number'


characters

C4537 'declaration': '.' applied to non-UDT type

C4542 Skipping generation of merged injected text file, cannot write


type file: 'filename': error

C4543 Injected text suppressed by attribute 'no_injected_text'


C4555 expression has no effect; expected expression with side-effect

C4557 '__assume' contains effect 'effect'

C4558 value of operand 'number' is out of range 'number - number'

C4561 '__fastcall' incompatible with the '/clr' option: converting to


'__stdcall'

C4562 fully prototyped functions are required with the '/clr' option:
converting '()' to '(void)'

C4564 method 'name' of class 'type' defines unsupported default


parameter 'parameter'

C4584 'type': base-class 'declaration' is already a base-class of


'declaration'

C4608 Initializing multiple members of union: 'type' and 'type'

C4619 #pragma warning: there is no warning number 'number'

C4623 'type': default constructor was implicitly defined as deleted

C4624 'type': destructor was implicitly defined as deleted

C4625 'type': copy constructor was implicitly defined as deleted

C4626 'type': assignment operator was implicitly defined as deleted

C4645 function declared with 'noreturn' has a return statement

C4646 function declared with 'noreturn' has non-void return type

C4659 #pragma 'description': use of reserved segment 'name' has


undefined behavior, use #pragma comment(linker, ...)

C4667 'declaration': no function template defined that matches


forced instantiation

C4668 'name' is not defined as a preprocessor macro, replacing with


'0' for 'value'

C4669 'expression': unsafe conversion: 'type' is a managed/WinRT


type object

C4674 'name' should be declared 'static' and have exactly one


parameter

C4680 'type': coclass does not specify a default interface


C4681 'type': coclass does not specify a default interface that is an
event source

C4682 'type': no directional parameter attribute specified, defaulting


to [in]

C4683 'declaration': event source has an 'out'-parameter; exercise


caution when hooking multiple event handlers

C4684 'description': WARNING!! attribute may cause invalid code


generation: use with caution

C4685 expecting '> >' found '>>' when parsing template parameters

C4700 uninitialized local variable 'name' used

C4701 potentially uninitialized local variable 'name' used

C4702 unreachable code

C4711 function 'name' selected for automatic inline expansion

C4714 function 'declaration' marked as __forceinline not inlined

C4715 'function': not all control paths return a value

C4716 'function': must return a value

C4717 'function': recursive on all control paths, function will cause


runtime stack overflow

C4718 'function': recursive call has no side effects, deleting

C4719 Double constant found when Qfast specified - use 'f' as a


suffix to indicate single precision

C4723 potential divide by 0

C4724 potential mod by 0

C4725 instruction may be inaccurate on some Pentiums

C4757 subscript is a large unsigned value, did you intend a negative


constant?

C4772 #import referenced a type from a missing type library;


'description' used as a placeholder

C4792 function 'function' declared using sysimport and referenced


from native code; import library required to link

C4794 segment of thread local storage variable 'name' changed from


'segment' to 'segment'
C4798 native code generated for p-code function 'name' with
exception handler or unwind semantics

C4799 function 'name' has no EMMS instruction

C4803 'declaration': the raise method has a different storage class


from that of the event, 'declaration'

C4810 value of pragma pack(show) == number

C4811 value of pragma conform(forScope, show) == value

C4820 'type': 'number' bytes padding added after type 'type'

C4905 wide string literal cast to 'type'

C4906 string literal cast to 'type'

C4912 'attribute': attribute has undefined behavior on a nested UDT

C4916 in order to have a dispid, 'type': must be introduced by an


interface

C4917 'type': a GUID can only be associated with a class, interface or


namespace

C4918 'character': invalid character in pragma optimization list

C4920 enum name member name=number already seen in enum


name as name=number

C4921 'name': attribute value 'value' should not be multiply specified

C4925 'declaration': dispinterface method cannot be called from


script

C4926 'declaration': symbol is already defined: attributes ignored

C4927 illegal conversion; more than one user-defined conversion has


been implicitly applied

C4928 illegal copy-initialization; more than one user-defined


conversion has been implicitly applied

C4929 'description': typelibrary contains a union; ignoring the


'embedded_idl' qualifier

C4930 'declaration': prototyped function not called (was a variable


definition intended?)

C4931 we are assuming the type library was built for number-bit
pointers
C4932 __identifier(description) and __identifier(description) are
indistinguishable

C4934 '__delegate(multicast)' is deprecated, use '__delegate' instead

C4935 assembly access specifier modified from 'description'

C4944 'name': cannot import symbol from 'source': as 'declaration'


already exists in the current scope

C4945 'name': cannot import symbol from 'source': as 'declaration'


has already been imported from another assembly 'source'

C4946 reinterpret_cast used between related classes: 'declaration'


and 'declaration'

C4995 'name': name was marked as #pragma deprecated

C4996 'issue': description

C4997 'type': coclass does not implement a COM interface or


pseudo-interface

C4998 EXPECTATION FAILED: description(number)

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

Compiler warning C4000 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) 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 1) C4005 'identifier': macro redefinition


WARNING MESSAGE

Compiler warning (level 1) C4006 #undef expected an identifier

Compiler Warning (level 2) C4007 'function': must be 'attribute'

Compiler warning (level 3) C4008 'function': 'atribute' attribute ignored

Compiler Warning (level 1) C4010 single-line comment contains line-continuation character

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 3) C4018 'expression': signed/unsigned mismatch

Compiler warning (level 4) C4019 empty statement at global scope

Compiler Warning (level 1) C4020 'function': too many actual parameters

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) C4028 formal parameter 'parameter_number' different from


declaration

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) C4033 'function' must return a value

Compiler Warning (level 1) C4034 sizeof returns 0

Compiler warning (level 3) C4035 'function': no return value


WARNING MESSAGE

Compiler warning (level 1) C4036 unnamed 'type' as actual parameter

Compiler warning (level 1) C4038 'modifier': illegal class modifier

Compiler warning (level 1) C4041 compiler limit: terminating browser output

Compiler Warning (level 1) C4042 'identifier': has bad storage class

Compiler warning (level 1) C4045 'array': array bounds overflow

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 1) C4051 type conversion; possible loss of data

Compiler warning (level 4) C4052 function declarations different; one contains variable
arguments

Compiler warning (level 4) C4053 one void operand for '?:'

Compiler warning (level 1) C4055 'conversion' : from data pointer 'type1' to function pointer
'type2'

Compiler Warning (level 2) C4056 overflow in floating-point constant arithmetic

Compiler warning (level 4) C4057 'operator': 'identifier1' differs in indirection to slightly different
base types from 'identifier2'

Compiler warning C4060 switch statement contains no 'case' or 'default' labels

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 C4064 switch of incomplete 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) C4068 unknown pragma

Compiler warning C4069 long double is the same precision as double

Compiler Warning (level 3) C4073 initializers put in library initialization area

Compiler Warning (level 1) C4074 initializers put in compiler reserved initialization area

Compiler warning (level 1) C4075 initializers put in unrecognized initialization area

Compiler warning (level 1) C4076 'type_modifier': can not be used with type 'typename'

Compiler warning (level 1) C4077 unknown check_stack option

Compiler Warning (level 1) C4079 unexpected token 'token'

Compiler warning (level 1) C4080 expected identifier for segment name; found 'symbol'

Compiler warning (level 1) C4081 expected 'token1'; found 'token2'

Compiler Warning (level 1) C4083 expected 'token'; found identifier 'identifier'

Compiler warning (level 1) C4085 expected pragma parameter to be 'on' or 'off'

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) C4088 'function': pointer mismatch in actual parameter


'parameter_number', formal parameter 'parameter_number'

Compiler Warning (level 1) C4089 'function': different types in actual parameter


'parameter_number', formal parameter 'parameter_number'

Compiler Warning (level 1) C4090 'operation': different 'modifier' qualifiers

Compiler Warning (level 1) C4091 keyword': ignored on left of 'type' when no variable is declared

Compiler Warning (level 4) C4092 sizeof returns 'unsigned long'

Compiler Warning (level 2) C4094 untagged 'token' declared no symbols

Compiler Warning (level 1) C4096 'identifier': interface is not a COM interface; will not be emitted
to IDL

Compiler warning (level 1) C4097 expected pragma parameter to be 'restore' or 'off'

Compiler Warning (level 1) C4098 'function': 'void' function returning a value

Compiler Warning (level 2) C4099 'identifier': type name first seen using 'object_type1' now seen
using 'object_type2'
WARNING MESSAGE

Compiler Warning (level 4) C4100 'identifier': unreferenced formal parameter

Compiler Warning (level 3) C4101 'identifier': unreferenced local variable

Compiler warning (level 3) C4102 'label': unreferenced label

Compiler Warning (level 1) C4103 'filename': alignment changed after including header, may be
due to missing #pragma pack(pop)

Compiler warning (level 1) C4109 unexpected identifier 'identifier'

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) C4116 unnamed 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 1) C4120 based/unbased mismatch

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 1) C4123 different base expressions specified

Compiler Warning (level 1) C4124 __fastcall with stack checking is inefficient

Compiler warning (level 4) C4125 decimal digit terminates octal escape sequence

Compiler Warning (level 4) C4127 conditional expression is constant

Compiler Warning (level 1) C4129 'character': unrecognized character escape sequence

Compiler warning (level 4) C4130 'operator': logical operation on address of string constant

Compiler warning (level 4) C4131 'function': uses old-style declarator

Compiler warning (level 4) C4132 'object': const object should be initialized

Compiler Warning (level 3) C4133 'expression': incompatible types - from 'type1' to 'type2'

Compiler warning C4137 'function': no return value from floating-point function


WARNING MESSAGE

Compiler warning (level 1) C4138 '*/' found outside of comment

Compiler warning (level 1) C4141 'modifier': used more than once

Compiler Warning (level 1) C4142 benign redefinition of type

Compiler warning (level 1) C4143 pragma 'same_seg' not supported; use __based allocation

Compiler Warning (level 1) C4144 'expression': relational expression as switch expression

Compiler warning (level 1) C4145 'expression1': relational expression as switch expression;


possible confusion with 'expression2'

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 4) C4152 nonstandard extension, function/data pointer conversion in


expression

Compiler warning (level 1) C4153 function/data pointer conversion in expression

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 1) C4157 pragma was ignored by C compiler

Compiler warning (level 1) C4158 assuming #pragma pointers_to_members(full_generality,


'inheritance_type')

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) C4162 'identifier': no function with C linkage found

Compiler warning (level 1) C4163 'identifier': not available as an intrinsic function

Compiler warning (level 1) C4164 'function': intrinsic function not declared


WARNING MESSAGE

Compiler warning (level 1) C4165 'HRESULT' is being converted to 'bool'; are you sure this is
what you want?

Compiler warning (level 1) C4166 illegal calling convention for constructor/destructor

Compiler warning (level 1) C4167 'function': only available as an intrinsic function

Compiler warning (level 1) C4168 compiler limit: out of debugger types, delete program
database 'database' and rebuild

Compiler Warning (level 1) C4172 returning address of local variable or temporary

Compiler warning (level 1) C4174 'name': not available as a #pragma component

Compiler warning (level 1) C4175 #pragma component(browser, on): browser info must initially
be specified on the command line

Compiler warning (level 1) C4176 'subcomponent': unknown subcomponent for #pragma


component browser

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 C4181 qualifier applied to reference type; 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) C4185 ignoring unknown #import attribute 'attribute'

Compiler warning (level 1) C4186 #import attribute 'attribute' requires 'argument_count'


arguments; ignored

Compiler warning (level 1) C4187 #import attributes 'attribute1' and 'attribute2' are
incompatible; both ignored

Compiler warning (level 1) C4188 constant expression is not integral

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) C4191 'operator/operation': unsafe conversion from


'type_of_expression' to 'type_required'\nCalling this function
through the result pointer may cause your program to fail

Compiler Warning (level 3) C4192 automatically excluding 'identifier' while importing type library
'library'

Compiler warning (level 3) C4193 #pragma warning(pop): no matching '#pragma warning(push)'

Compiler warning (level 1) C4194 #pragma start_map_region cannot be nested; ignored

Compiler warning (level 1) C4195 #pragma stop_map_region used without matching #pragma
start_map_region; ignored

Compiler warning (level 1) C4196 expected '%$L' or '%$L'; found '%$L'

Compiler Warning (level 3) C4197 'type': top-level volatile in cast is ignored

Compiler warning (level 1, level 2, level 3, and level 4) C4199 %s


Compiler Warning (level 4) C4001
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension 'single line comment' was used

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

too many actual parameters for macro 'identifier'


The number of actual parameters in the macro exceeds the number of formal parameters in the macro definition.
The preprocessor collects the extra parameters but ignores them during macro expansion.
C4002 can occur when incorrectly using Variadic Macros.
The following sample generates C4002:

// 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

not enough actual parameters for macro 'identifier'


The number of formal parameters in the macro definition exceeds the number of actual parameters in the macro.
Macro expansion substitutes empty text for the missing parameters.
The following sample generates C4003:

// 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

'identifier' : macro redefinition


The macro identifier is defined twice. The compiler uses the second macro definition.
To fix by checking the following possible causes
1. Defining a macro on the command line and in the code with a #define directive.
2. Macros imported from include files.
To fix by using the following possible solutions
1. Remove one of the definitions.
2. Use an #undef directive before the second definition.
The following sample generates C4005:

// C4005.cpp
// compile with: /W1 /EHsc
#include <iostream>
using namespace std;

#define TEST "test1"


#define TEST "test2" // C4005 delete or rename to resolve the warning

int main() {
cout << TEST << endl;
}
Compiler Warning (level 1) C4006
10/31/2018 • 2 minutes to read • Edit Online

#undef expected an identifier


The #undef directive did not specify an identifier to undefine. The directive is ignored. To resolve the warning, be
sure to specify an identifier. The following sample generates C4006:

// 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

'function' : must be 'attribute'


A required attribute for a function is not explicitly stated. For example, the function main must have the __cdecl
attribute. The compiler forces the attribute.
Compiler Warning (levels 2 and 3) C4008
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : 'attribute' attribute ignored


The compiler ignored the __fastcall , static, or inline attribute for a function (level 3 warning) or data (level 2
warning).
To fix by checking the following possible causes
1. __fastcall attribute with data.
2. static or inline attribute with main function.
Compiler Warning (level 1) C4010
10/31/2018 • 2 minutes to read • Edit Online

single-line comment contains line-continuation character


A single-line comment, which is introduced by //, contains a backslash (\) that serves as a line-continuation
character. The compiler considers the next line to be a continuation and treats it as a comment.
Some syntax-directed editors do not indicate the line following the continuation character as a comment. Ignore
syntax coloring on any lines that cause this warning.
The following sample generates C4010:

// 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

'function' undefined; assuming extern returning int


The compiler encountered a call to an undefined function.
To fix by checking the following possible causes
1. Incorrect spelling of function name
2. External functions not prototyped as extern
Compiler Warning (level 1) C4015
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : type of bit field must be integral


The bit field is not declared as an integer type. The compiler assumes the base type of the bit field to be unsigned.
Bit fields must be declared as unsigned integer types.
Compiler Warning (level 3) C4018
10/31/2018 • 2 minutes to read • Edit Online

'expression' : signed/unsigned mismatch


Comparing a signed and unsigned number required the compiler to convert the signed value to unsigned.
This warning may be fixed if you cast one of the two types when testing signed and unsigned types.
The following sample generates C4018:

// C4018.cpp
// compile with: /W3
int main() {
unsigned int uc = 0;
int c = 0;
unsigned int c2 = 0;

if (uc < c) uc = 0; // C4018

// OK
if (uc == c2) uc = 0;
}
Compiler Warning (level 4) C4019
10/31/2018 • 2 minutes to read • Edit Online

empty statement at global scope


A semicolon at global scope is not preceded by a statement.
This warning may be fixed if you remove the extra semicolon.

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

'function' : too many actual parameters


The number of actual parameters in a function call exceeds the number of formal parameters in the function
prototype or definition. The compiler passes the extra actual parameters according to the calling convention of the
function.
The following sample generates C4020:

// 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

'function' : pointer mismatch for actual parameter 'number'


The pointer type of the actual parameter differs from the pointer type of the corresponding formal parameter. The
actual parameter is passed without change.
Compiler Warning (level 3) C4023
10/31/2018 • 2 minutes to read • Edit Online

'symbol' : based pointer passed to unprototyped function : parameter number


Passing a based pointer to an unprototyped function causes the pointer to be normalized, with unpredictable
results.
This warning may be fixed if you use prototype functions that are passed based pointers.
Compiler Warning (level 1) C4024
10/31/2018 • 2 minutes to read • Edit Online

'function' : different types for formal and actual parameter 'number'


Corresponding formal and actual parameters have different types. The compiler passes the actual parameter
without change. The receiving function converts the parameter type to the type expected.
Compiler Warning (level 1) C4025
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

function declared with formal parameter list


The function declaration has formal parameters, but the function definition does not. Subsequent calls to this
function assume that the function takes no parameters.
Compiler Warning (level 1) C4027
10/31/2018 • 2 minutes to read • Edit Online

function declared without formal parameter list


The function declaration no formal parameters, but there are formal parameters in the function definition or actual
parameters in a call. Subsequent calls to this function assume that the function takes actual parameters of the types
found in the function definition or call.
Compiler Warning (level 1) C4028
10/31/2018 • 2 minutes to read • Edit Online

formal parameter 'number' different from declaration


The type of the formal parameter does not agree with the corresponding parameter in the declaration. The type in
the original declaration is used.
This warning is only valid for C source code.

Example
The following sample generates C4028.

// C4028.c
// compile with: /W1 /Za
void f(int , ...);
void f(int i, int j) {} // C4028

void g(int , int);


void g(int i, int j) {} // OK

int main() {}
Compiler Warning (level 1) C4029
3/12/2019 • 2 minutes to read • Edit Online

declared formal parameter list different from definition


Formal parameter types in the function declaration do not agree with those in the function definition. The compiler
uses the parameter list from the definition.
Compiler Warning (level 1) C4030
10/31/2018 • 2 minutes to read • Edit Online

first formal parameter list longer than the second list


A function was redeclared with different formal parameters. The compiler uses the formal parameters given in the
first declaration.
Compiler Warning (level 1) C4031
10/31/2018 • 2 minutes to read • Edit Online

second formal parameter list longer than the first list


A function is redeclared with different formal parameters. The compiler uses the formal parameters given in the
first declaration.
Compiler Warning (level 4) C4032
10/31/2018 • 2 minutes to read • Edit Online

formal parameter 'number' has different type when promoted


The parameter type is not compatible, through default promotions, with the type in a previous declaration.
This is an error in ANSI C (/Za) and a warning under Microsoft extensions (/Ze).

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

'function' must return a value


The function does not return a value. An undefined value is returned.
Functions that use return without a return value must be declared as type void .
This error is for C language code.
The following sample generates C4033:

// 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

unnamed 'type' as actual parameter


No type name is given for a structure, union, enumeration, or class used as an actual parameter. If you are using
/Zg to generate function prototypes, the compiler issues this warning and comments out the formal parameter in
the generated prototype.
Specify a type name to resolve this warning.

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

'modifier' : illegal ambient class modifier


This modifier cannot be used for classes with dllimport or dllexport attributes.
Compiler Warning (level 1) C4041
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : terminating browser output


Browser information exceeded the compiler limit.
This warning can be caused by compiling with /FR (browser information including local variables).
To fix by using the following possible solutions
1. Compile with /Fr (browser information without local variables).
2. Disable browser output (compile without /FR or /Fr).
Compiler Warning (level 1) C4042
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : has bad storage class


The specified storage class cannot be used with this identifier in this context. The compiler uses the default storage
class instead:
extern , if identifier is a function.
auto, if identifier is a formal parameter or local variable.
No storage class, if identifier is a global variable.
This warning can be caused by specifying a storage class other than register in a parameter declaration.
The following sample generates C4042

// 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

'array' : array bounds overflow


The array has too many initializers. Extra initializers are ignored.
Make sure that array elements and initializers match in size and quantity.
Compiler Warning (level 1) C4047
10/31/2018 • 2 minutes to read • Edit Online

'operator' : 'identifier1' differs in levels of indirection from 'identifier2'


A pointer can point to a variable (one level of indirection), to another pointer that points to a variable (two levels of
indirection), and so on.

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

char *p2 = 0; // one level of indirection


char *q2 = 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;

err = fopen_s(&myFile, "C4047.txt", "r");


if ((err != 0) || (myFile)) {
printf_s("fopen_s failed!\n");
exit(-1);
}
i = fgets(file_name, 256, myFile); // C4047
cs = fgets(file_name, 256, myFile); // OK
}
Compiler Warning (level 1) C4048
10/31/2018 • 2 minutes to read • Edit Online

different declared array subscripts : 'identifier1' and 'identifier2'


An expression involves pointers to arrays of different size. The pointers are used without conversion.
This warning may be fixed if you explicitly cast the arrays to the same or equivalent type.
Compiler Warning (level 1) C4049
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : terminating line number emission


The file contains more than 16,777,215 (224-1) source lines. The compiler stops numbering at 16,777,215.
For code after line 16,777,215:
The image will contain no debug information for line numbers.
Some diagnostics may be reported with incorrect line numbers.
.asm listings (/FAs) may have incorrect line numbers.
Compiler Warning (level 2) C4051
10/31/2018 • 2 minutes to read • Edit Online

type conversion; possible loss of data


An expression contains two data items with different base types. Converting one type causes the data item to be
truncated.
This warning may be fixed if you cast the data items to the appropriate type.
Compiler Warning (level 1) C4052
10/31/2018 • 2 minutes to read • Edit Online

function declarations different; one contains variable arguments


One declaration of the function does not contain variable arguments. It is ignored.
The following sample generates C4052:

// 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

one void operand for '?:'


The ?: operator is given an expression of type void . The value of the void operand is undefined.
Compiler Warning (level 1) C4055
10/31/2018 • 2 minutes to read • Edit Online

'conversion' : from data pointer 'type1' to function pointer 'type2'

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
}

Under /Ze, this is a level 4 warning.

// 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

overflow in floating point constant arithmetic


Floating-point constant arithmetic generates a result that exceeds the maximum allowable value.
This warning can be caused by compiler optimizations performed during constant arithmetic. You can safely ignore
this warning if it goes away when you turn off optimization (/Od).
The following sample generates C4056:

// 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

'operator' : 'identifier1' indirection to slightly different base types from 'identifier2'


Two pointer expressions refer to different base types. The expressions are used without conversion.
To fix by checking the following possible causes
1. Mixing signed and unsigned types.
2. Mixing short and long types.
Compiler Warning (level 4) C4061
10/31/2018 • 2 minutes to read • Edit Online

enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label

The enumerator has no associated handler in a switch statement.


This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

enumerator 'identifier' in switch of enum 'enumeration' is not handled


The enumerate has no associated handler in a switch statement, and there is no default label.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4062:

// 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

characters beyond first in wide-character constant ignored


The compiler processes only the first character of a wide-character constant.
Compiler Warning (level 1) C4067
10/31/2018 • 2 minutes to read • Edit Online

unexpected tokens following preprocessor directive - expected a newline

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

initializers put in library initialization area


Only third-party library developers should use the library initialization area, which is specified by #pragma
init_seg. The following sample generates C4073:

// C4073.cpp
// compile with: /W3
#pragma init_seg(lib) // C4073

// try this line to resolve the warning


// #pragma init_seg(user)

int main() {
}
Compiler Warning (level 1) C4074
10/31/2018 • 2 minutes to read • Edit Online

initializers put in compiler reserved initialization area


The compiler initialization area, which is specified by #pragma init_seg, is reserved by Microsoft. Code in this area
may be executed before initialization of the C run-time library.
The following sample generates C4074:

// C4074.cpp
// compile with: /W1
#pragma init_seg( compiler ) // C4074

// try this line to resolve the warning


// #pragma init_seg(user)

int main() {
}
Compiler Warning (level 1) C4075
10/31/2018 • 2 minutes to read • Edit Online

initializers put in unrecognized initialization area


A #pragma init_seg uses an unrecognized section name. The compiler ignores the pragma command.
The following sample generates C4075:

// 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

'type modifier' : can not be used with type 'typename'

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

unknown check_stack option


The old form of the check_stack pragma is used with an unknown argument. The argument must be + , - , (on)
, (off) , or empty.
The compiler ignores the pragma and leaves the stack checking unchanged.

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

unexpected token 'token'


An unexpected separator token occurs in a pragma argument list. The remainder of the pragma was ignored.
The following sample generates C4079:

// 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

expected identifier for segment name; found 'symbol'


The name of the segment in #pragma alloc_text must be a string or an identifier. The compiler ignores the pragma
if a valid identifier is not found.
The following sample generates C4080:

// C4080.cpp
// compile with: /W1
extern "C" void func(void);

#pragma alloc_text() // C4080

// try this line to resolve the warning


// #pragma alloc_text("mysection", func)

int main() {
}

void func(void) {
}
Compiler Warning (level 1) C4081
10/31/2018 • 2 minutes to read • Edit Online

expected 'token1'; found 'token2'


The compiler expected a different token in this context.

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

expected 'token'; found identifier 'identifier'


An identifier occurs in the wrong place in a #pragma statement.

Example
// C4083.cpp
// compile with: /W1 /LD
#pragma warning disable:4083 // C4083
#pragma warning(disable:4083) //correct

Check the syntax of the #pragma directives.


Compiler Warning (level 1) C4085
10/31/2018 • 2 minutes to read • Edit Online

expected pragma parameter to be 'on' or 'off'


The pragma requires an on or off parameter. The pragma is ignored.
The following sample generates C4085:

// 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

expected pragma parameter to be '1', '2', '4', '8', or '16'


The pragma parameter does not have the required value (1, 2, 4, 8, or 16).

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

'function' : declared with 'void' parameter list


The function declaration has no formal parameters, but the function call has actual parameters. Extra parameters
are passed according to the calling convention of the function.
This warning is for the C compiler.

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

'function' : pointer mismatch in actual parameter 'number', formal parameter 'number'


The corresponding formal and actual parameters have a different level of indirection. The actual parameter is
passed without change. The called function interprets its value as a pointer.
Compiler Warning (level 1) C4089
10/31/2018 • 2 minutes to read • Edit Online

'function' : different types in actual parameter 'number', formal parameter 'number'


The corresponding formal and actual parameters have different types. The actual parameter is passed without
change. The function casts the actual parameter to the type specified in the function definition.
Compiler Warning (level 1) C4090
10/31/2018 • 2 minutes to read • Edit Online

'operation' : different 'modifier' qualifiers


A variable used in an operation is defined with a specified modifier that prevents it from being modified without
detection by the compiler. The expression is compiled without modification.
This warning can be caused when a pointer to a const or volatile item is assigned to a pointer not declared as
pointing to const or volatile .
This warning is issued for C programs. In a C++ program, the compiler issues an error: C2440.
The following sample generates C4090:

// 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

'keyword' : ignored on left of 'type' when no variable is declared


The compiler detected a situation where the user probably intended a variable to be declared, but the compiler was
not able to declare the variable.

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

// __declspec attribute applies to varX


__declspec(dllimport) class X2 {} varX;

// __declspec attribute after the class or struct keyword


// applies to user defined type
class __declspec(dllimport) X3 {};

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

sizeof returns 'unsigned long'


The operand of the sizeof operator was very large, so sizeof returned an unsigned long. This warning occurs
under the Microsoft extensions (/Ze). Under ANSI compatibility (/Za), the result is truncated instead.
Compiler Warning (level 2) C4094
10/31/2018 • 2 minutes to read • Edit Online

untagged 'token' declared no symbols


The compiler detected an empty declaration using an untagged structure, union, or class. The declaration is
ignored.

Example
// C4094.cpp
// compile with: /W2
struct
{
}; // C4094

int main()
{
}

This condition generates an error under ANSI compatibility (/Za).


Compiler Warning (level 1) C4096
10/31/2018 • 2 minutes to read • Edit Online

'a': interface is not a COM interface; will not be emitted to IDL


An interface definition that you may have intended as a COM interface was not defined as a COM interface and
therefore will not be emitted to the IDL file.
See Interface Attributes for a list attributes that indicate an interface is a COM interface.
The following sample generates C4096:

// 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

expected pragma parameter to be 'restore' or 'off'


A pragma was passed an invalid value.
The following sample generates C4097:

// 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

'function' : void function returning a value


A function declared with return type void has a return statement that returns a value. The compiler assumes the
function returns a value of type int .
Compiler Warning (level 2) C4099
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

'identifier' : unreferenced formal parameter


The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored.
C4100 can also be issued when code calls a destructor on a otherwise unreferenced parameter of primitive type.
This is a limitation of the Visual C++ compiler.
The following sample generates C4100:

// 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

'identifier' : unreferenced local variable


The local variable is never used. This warning will occur in the obvious situation:

// 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

'label' : unreferenced label


The label is defined but never referenced. The compiler ignores the label.
The following sample generates C4102:

// C4102.cpp
// compile with: /W3
int main() {
int a;

test: // C4102, remove the unreferenced label to resolve

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)

// defintions and declarations

// uncomment the following line to resolve


// #pragma pack(pop)

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

unexpected identifier 'identifier'


The pragma containing the unexpected identifier is ignored.

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

#line requires an integer between 1 and number


The #line directive specifies an integer parameter that is outside the allowable range.
If the specified parameter is less than 1, the line counter is reset to 1. If the specified parameter is greater than
number, which is the compiler-defined limit, the line counter is unchanged. This is a level 1 warning under ANSI
compatibility (/Za) and a level 4 warning with Microsoft extensions (/Ze).
The following sample generates C4112:

// 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

'identifier1' differs in parameter lists from 'identifier2'


A function pointer is assigned to another function pointer, but the formal parameter lists of the functions do not
agree. The assignment is compiled without modification.
Compiler Warning (level 1) C4114
10/31/2018 • 2 minutes to read • Edit Online

same type qualifier used more than once


A type declaration or definition uses a type qualifier (const, volatile, signed, or unsigned) more than once. This
causes a warning with Microsoft extensions (/Ze) and an error under ANSI compatibility (/Za).
The following sample generates C4114:

// C4114.cpp
// compile with: /W1 /c
volatile volatile int i; // C4114

The following sample generates 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

'type' : named type definition in parentheses


The given symbol is used to define a structure, union, or enumerated type inside a parenthetical expression. The
scope of the definition may be unexpected.
In a C function call, the definition has global scope. In a C++ call, the definition has the same scope as the function
being called.
This warning can also be caused by declarators within parentheses (such as prototypes) that are not parenthetical
expressions.
This is a level-1 warning with C++ programs and C programs compiled under ANSI compatibility (/Za).
Otherwise, it is level 3.
Compiler Warning (level 1) C4116
10/31/2018 • 2 minutes to read • Edit Online

unnamed type definition in parentheses


A structure, union, or enumerated type with no name is defined in a parenthetical expression. The type definition is
meaningless.
In a C function call, the definition has global scope. In a C++ function call, the definition has the same scope as the
function being called.
Compiler Warning (level 1) C4117
10/31/2018 • 2 minutes to read • Edit Online

macro name 'name' is reserved; 'Command' ignored


To fix by checking the following possible causes
1. Trying to define or undefine a predefined macro.
2. Trying to define or undefine the preprocessor operator defined.
The following sample generates C4117:

// 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

different bases 'base1' and 'base2' specified


Two based pointers are incompatible because they have different bases. The compiler cannot convert between
them.
Compiler Warning (level 1) C4120
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

'symbol' : alignment of a member was sensitive to packing


The compiler added padding to align a structure member on the packing boundary but the packing value is less
than the member's size. For example, the following code snippet produces C4121:

// C4121.cpp
// compile with: /W4 /c
#pragma pack(2)
struct s
{
char a;
int b; // C4121
long long c;
};

To fix this issue, make one of the following changes:


Change the packing size to the size of the member that caused the warning or larger. For example, in this
snippet, change pack(2) to pack(4) or pack(8) .
Reorder member declarations by size, from largest to smallest. In the snippet, reverse the order of the
structure members such that the long long member precedes the int , and the int precedes the char .

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

'function' : alloc_text applicable only to functions with C linkage


The alloc_text pragma applies only to functions declared with extern c. It cannot be used with external C++
functions.
The pragma is ignored.
Compiler Warning (level 1) C4124
10/31/2018 • 2 minutes to read • Edit Online

__fastcall with stack checking is inefficient


The __fastcall keyword was used with stack checking enabled.
The __fastcall convention generates faster code, but stack checking causes slower code. When using __fastcall
, turn off stack checking with the check_stack pragma or /Gs.
This warning is issued only for the first function declared under these conditions.
Compiler Warning (level 4) C4125
10/31/2018 • 2 minutes to read • Edit Online

decimal digit terminates octal escape sequence


The compiler evaluates the octal number without the decimal digit and assumes the decimal digit is a character.

Example
// C4125a.cpp
// compile with: /W4
char array1[] = "\709"; // C4125
int main()
{
}

If the digit 9 is intended as a character, correct the example as follows:

// 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

conditional expression is constant

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

'character' : unrecognized character escape sequence


The character following a backslash (\) in a character or string constant is not recognized as a valid escape
sequence. The backslash is ignored and not printed. The character following the backslash is printed.
To print a single backslash, specify a double backslash (\\).
The C++ standard, in section 2.13.2 discusses escape sequences.
The following sample generates C4129:

// 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

'operator' : logical operation on address of string constant


Using the operator with the address of a string literal produces unexpected code.
The following sample generates C4130:

// 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".

To compare strings, use the strcmp function.


Compiler Warning (level 4) C4131
10/31/2018 • 2 minutes to read • Edit Online

'function' : uses old-style declarator


The specified function declaration is not in prototype form.
Old-style function declarations should be converted to prototype form.
The following example shows an old-style function declaration:

// C4131.c
// compile with: /W4 /c
void addrec( name, id ) // C4131 expected
char *name;
int id;
{ }

The following example shows a prototype form:

void addrec( char *name, int id )


{ }
Compiler Warning (level 4) C4132
10/31/2018 • 2 minutes to read • Edit Online

'object' : const object should be initialized


The constant is not initialized. The value of a symbol with the const attribute cannot be changed after its definition,
it should be given an initialization value.
Compiler Warning (level 3) C4133
10/31/2018 • 2 minutes to read • Edit Online

'type' : incompatible types - from 'type1' to 'type2'


This warning can be caused by trying to subtract two pointers of different types.
To avoid this warning, provide an appropriate type cast.
Compiler Warning (level 1) C4138
10/31/2018 • 2 minutes to read • Edit Online

'*/' found outside of comment


The closing-comment delimiter is not preceded by an opening-comment delimiter. The compiler assumes a space
between the asterisk (*) and the forward slash (/).

Example
// C4138a.cpp
// compile with: /W1
int */*comment*/ptr; // C4138 Ambiguous first delimiter causes warning
int main()
{
}

This warning can be caused by trying to nest comments.


This warning may be resolved if you comment out sections of code that contain comments, enclose the code in an
#if/#endif block, and set the controlling expression to zero:

// 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

'modifier' : used more than once

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

benign redefinition of type


A type is redefined in a manner that has no effect on the generated code.
To fix by checking the following possible causes:
A member function of a derived class has a different return type from the corresponding member function
of the base class.
A type defined with the typedef command is redefined using different syntax.
The following sample generates C4142:

// 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

pragma 'same_seg' not supported; use __based allocation


The #pragma same_seg is no longer supported. Use the __based keyword instead.
Compiler Warning (level 1) C4144
10/31/2018 • 2 minutes to read • Edit Online

'expression' : relational expression as switch expression


The specified relational expression was used as the control expression of a switch statement. The associated case
statements will be offered Boolean values. The following sample generates C4144:

// 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

'expression1' : relational expression as switch expression; possible confusion with 'expression2'


A switch statement uses a relational expression as its control expression, which results in a Boolean value for the
case statements. Did you mean expression2?

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

unary minus operator applied to unsigned type, result still unsigned


Unsigned types can hold only non-negative values, so unary minus (negation) does not usually make sense when
applied to an unsigned type. Both the operand and the result are non-negative.
Practically, this occurs when the programmer is trying to express the minimum integer value, which is -
2147483648. This value cannot be written as -2147483648 because the expression is processed in two stages:
1. The number 2147483648 is evaluated. Because it is greater than the maximum integer value of
2147483647, the type of 2147483648 is not int, but unsigned int .
2. Unary minus is applied to the value, with an unsigned result, which also happens to be 2147483648.
The unsigned type of the result can cause unexpected behavior. If the result is used in a comparison, then an
unsigned comparison might be used, for example, when the other operand is an int . This explains why the
example program below prints just one line.
The expected second line, 1 is greater than the most negative int , is not printed because
((unsigned int)1) > 2147483648 is false.
You can avoid C4146 by using INT_MIN from limits.h, which has the type signed int.

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

deletion of pointer to incomplete type 'type'; no destructor called


The delete operator is called to delete a type that was declared but not defined, so the compiler cannot find a
destructor.
The following sample generates C4150:

// C4150.cpp
// compile with: /W2
class IncClass;

void NoDestruct( IncClass* pIncClass )


{
delete pIncClass;
} // C4150, define class to resolve

int main()
{
}
Compiler Warning (level 4) C4152
10/31/2018 • 2 minutes to read • Edit Online

non standard extension, function/data ptr conversion in expression


A function pointer is converted to or from a data pointer. This conversion is allowed under Microsoft extensions
(/Ze) but not under ANSI C.
Compiler Warning (level 1) C4153
10/31/2018 • 2 minutes to read • Edit Online

function/data pointer conversion in expression


A function pointer is converted to or from a data pointer. This conversion is allowed under Microsoft extensions
(/Ze) but not under ANSI C.
Compiler Warning (level 1) C4154
10/31/2018 • 2 minutes to read • Edit Online

deletion of an array expression; conversion to pointer supplied


You cannot use delete on an array, so the compiler converts the array to a pointer.

Example
// C4154.cpp
// compile with: /c /W1
int main() {
int array[ 10 ];
delete array; // C4154 can't delete stack object

int *parray2 = new int [10];


int (&array2)[10] = (int(&)[10]) parray2;
delete [] array2; // C4154

// try the following line instead


delete [] &array2;
}
Compiler Warning (level 1) C4155
10/31/2018 • 2 minutes to read • Edit Online

deletion of an array expression without using the array form of 'delete'


The array form of delete should be used to delete an array. This warning occurs only under ANSI-compatibility
(/Za).

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]);

delete array; // C4155


// try the following line instead
// delete [] array; // C4155
}
Compiler Warning (level 2) C4156
10/31/2018 • 2 minutes to read • Edit Online

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

pragma was ignored by C compiler


Only the C++ compiler recognizes init_seg().
Compiler Warning (level 1) C4158
10/31/2018 • 2 minutes to read • Edit Online

assuming #pragma pointers_to_members(full_generality, inheritance)

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

#pragma pragma(pop,...) : has popped previously pushed identifier 'identifier'

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

// using the identifier resolves the warning


// #pragma pack(pop, f)

int main()
{
}
Compiler Warning (level 1) C4160
10/31/2018 • 2 minutes to read • Edit Online

#pragma (pop,...) : did not find previously pushed identifier 'identifier'

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)

#pragma pack(pop, id) // C4160


// use identifier when pushing to resolve the warning
// #pragma pack(push, id)

int main() {
}
Compiler Warning (level 3) C4161
10/31/2018 • 2 minutes to read • Edit Online

#pragma pragma(pop...) : more pops than pushes

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;

#pragma bss_seg(push, stack1, ".my_data2")


int l;

#pragma bss_seg(pop, stack1)


int m;

#pragma bss_seg(pop, stack1) // C4161


Compiler Warning (level 1) C4162
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : no function with C linkage found


A function with C linkage is declared but cannot be found.
To resolve this warning, compile in a .c file (invoke the C compiler). If you must invoke the C++ compiler, place
extern "C" before the function declaration.
The following sample generates C4162

// 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

'identifier' : not available as an intrinsic function


The specified function cannot be used as an intrinsic function. The compiler ignores the invalid function name.
The following sample generates C4163:

// 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

'identifier' : intrinsic function not declared


The specified intrinsic function is not declared; you may need to #include the appropriate header file.
Compiler Warning (level 1) C4165
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)

extern HRESULT hr;


int main() {
if (hr) {
// try either of the following ...
// if (FAILED(hr)) { // C4165 expected
// if (hr != S_OK) {
}
}
Compiler Warning (level 1) C4166
10/31/2018 • 2 minutes to read • Edit Online

illegal calling convention for constructor/destructor


Constructors and destructors cannot have calling conventions other than the default for the platform (except when
you explicitly specify __clrcall).
Compiler Warning (level 1) C4167
10/31/2018 • 2 minutes to read • Edit Online

function : only available as an intrinsic function


The #pragma function tries to force the compiler to use a conventional call to a function that must be used in
intrinsic form. The pragma is ignored.
To avoid this warning, remove the #pragma function.

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

returning address of local variable or temporary


A function returns the address of a local variable or temporary object. Local variables and temporary objects are
destroyed when a function returns, so the address returned is not valid.
Redesign the function so that it does not return the address of a local object.
The following sample generates C4172:

// C4172.cpp
// compile with: /W1 /LD
float f = 10;

const double& bar() {


// try the following line instead
// const float& bar() {
return f; // C4172
}
Compiler Warning (level 1) C4174
10/31/2018 • 2 minutes to read • Edit Online

'name' : not available as a #pragma component

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

'subcomponent' : unknown subcomponent for #pragma component browser


The component pragma contains an invalid subcomponent. To exclude references to a particular name, you must
use the references option before the name.

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

#pragma pragma should be at global scope


The pragma pragma should not be used within a local scope. The pragma will not be valid until global scope is
encountered after the current scope.
The following sample generates C4177:

// 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

//* is an incorrect comment delimiter. Use // or /* instead.


Compiler Warning (level 1) C4180
10/31/2018 • 2 minutes to read • Edit Online

qualifier applied to function type has no meaning; ignored


A qualifier, such as const, is applied to a function type defined by typedef .

Example
// C4180.cpp
// compile with: /W1 /c
typedef int FuncType(void);

// the const qualifier cannot be applied to the


// function type FuncType
const FuncType f; // C4180
Compiler Warning (level 1) C4182
10/31/2018 • 2 minutes to read • Edit Online

#include nesting level is 'number' deep; possible infinite recursion


The compiler ran out of space on the heap because of the number of nested include files. An include file is nested
when it is included from another include file.
This message is informational and precedes error C1076.
Compiler Warning (level 1) C4183
10/31/2018 • 2 minutes to read • Edit Online

'identifier': missing return type; assumed to be a member function returning 'int'


The inline definition of a member function in a class or a structure does not have a return type. This member
function is assumed to have a default return type of int .
The following sample generates C4183:

// 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

ignoring unknown #import attribute 'attribute'


The attribute is not a valid attribute of #import . It is ignored.

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

#import attribute 'attribute' requires count arguments; ignored


A #import attribute has the wrong number of arguments.

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

#import attributes 'attribute1' and 'attribute2' are incompatible; both ignored


A #import statement specified no_implementation and implementation_only attributes. Both are ignored.
Compiler Warning (level 4) C4189
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : local variable is initialized but not referenced


A variable is declared and initialized but not used.
The following sample generates C4189:

// 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 ();
};

extern "C" X func (); // C4190


Compiler Warning (level 3) C4191
10/31/2018 • 2 minutes to read • Edit Online

'operator/operation' : unsafe conversion from 'type of expression' to 'type required'


Several operations involving function pointers are considered unsafe:
Function types with different calling conventions.
Function types with different return conventions.
Argument or return types with different sizes, type categories, or classifications.
Differing argument list lengths (on __cdecl , only on cast from longer list to shorter list, even if shorter is
varargs).
Pointer to data (other than void*) aliased against a pointer to function.
Any other type difference that would yield an error or warning on a reinterpret_cast .
Calling this function through the result pointer might cause your program to crash.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4191:

// C4191.cpp
// compile with: /W3 /clr
#pragma warning(default: 4191)

void __clrcall f1() { }


void __cdecl f2() { }

typedef void (__clrcall * fnptr1)();


typedef void (__cdecl * fnptr2)();

int main() {
fnptr1 fp1 = static_cast<fnptr1>(&f1);
fnptr2 fp2 = (fnptr2) &f2;

fnptr1 fp3 = (fnptr1) &f2; // C4191


fnptr2 fp4 = (fnptr2) &f1; // C4191
};
Compiler Warning (level 3) C4192
10/31/2018 • 2 minutes to read • Edit Online

automatically excluding 'name' while importing type library 'library'


A #import library contains an item, name, that is also defined in the Win32 system headers. Due to limitations of
type libraries, names such as IUnknown or GUID are often defined in a type library, duplicating the definition
from the system headers. #import will detect these items and refuse to incorporate them in the .tlh and .tli header
files.
To override this behavior, use #import attributes no_auto_exclude and include().
Compiler Warning (level 3) C4197
11/9/2018 • 2 minutes to read • Edit Online

'type' : top-level volatile in cast is ignored


The compiler detected a cast to an r-value type which is qualified with volatile, or a cast of an r-value type to some
type that is qualified with volatile. According to the C standard (6.5.3), properties associated with qualified types
are meaningful only for l-value expressions.
The following sample generates C4197:

// 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;
}

void sigproc(int) // ctrl-C


{
signal(SIGINT, sigproc);
s.i = 0;
}
Compiler Warnings C4200 Through C4399
3/14/2019 • 14 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 (levels 2 and 4) C4200 nonstandard extension used: zero-sized array in struct/union

Compiler Warning (level 4) C4201 nonstandard extension used: nameless 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) C4204 nonstandard extension used: non-constant aggregate


initializer
WARNING MESSAGE

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) C4213 nonstandard extension used: cast on l-value

Compiler Warning (level 4) C4214 nonstandard extension used: bit field types other than int

Compiler Warning (level 1) C4215 nonstandard extension used: long float

Compiler Warning (level 1) C4216 nonstandard extension used: float long

Compiler Warning (level 1) C4218 nonstandard extension used: must specify at least a storage
class or a type

Compiler Warning (level 4) C4220 varargs matches remaining parameters

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 1) C4230 anachronism used: modifiers/qualifiers interspersed; qualifier


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 4) C4245 'conversion_type': conversion from 'type1' to 'type2',


signed/unsigned mismatch

Compiler Warning (level 2) C4250 'classname': inherits 'base_classname::member' via dominance

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) C4254 'operator': conversion from 'type1:field_bits' to


'type2:field_bits', possible loss of data

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) C4273 'function': inconsistent dll linkage

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) C4276 'function': no prototype provided; assumed no parameters

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 3) C4282 then through type 'type2'

Compiler Warning (level 3) C4283 and through type 'typeN'


WARNING MESSAGE

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 3) C4287 'operator': unsigned/negative constant mismatch

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 4) C4296 'operator': expression is always 'boolean_value'

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 C4301 'derived_class::function': overriding virtual function only differs


from 'base_class::function' by const/volatile qualifier

Compiler Warning (level 2) C4302 'conversion': truncation from 'type1' to 'type2'

Compiler warning C4303 C-style cast from 'type1' to 'type2' is deprecated, use
static_cast, __try_cast or dynamic_cast

Compiler Warning (level 1) C4305 'conversion': truncation from 'type1' to 'type2'

Compiler Warning (level 3) C4306 'conversion': conversion from 'type1' to 'type2' of greater size

Compiler Warning (level 2) C4307 'operator': integral constant overflow

Compiler Warning (level 2) C4308 negative integral constant converted to unsigned type
WARNING MESSAGE

Compiler Warning (level 2) C4309 'conversion': truncation of constant value

Compiler Warning (level 3) C4310 cast truncates constant value

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 C4314 expected pragma parameter to be '32' or '64'

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 C4318 passing constant zero as the length to memset

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 C4327 'assignment': indirection alignment of LHS ('alignment1') is


greater than RHS ('alignment2')

Compiler warning C4328 'function': indirection alignment of formal parameter


parameter_number (parameter_alignment) is greater than the
actual argument alignment (argument_alignment)

Compiler Warning (level 1) C4329 __declspec(align()) is ignored on enum

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 4) C4343 #pragma optimize("g",off) overrides /Og option

Compiler Warning (level 1) C4344 behavior change: use of explicit template arguments results in
call to 'function'

Compiler Warning (level 1) C4346 'name': dependent name is not a type

Compiler Warning (level 1) C4348 'type': redefinition of default parameter: parameter


'parameter_number'

Compiler Warning (level 1) C4350 behavior change: 'member1' called instead of 'member2'

Compiler warning (level 1) C4352 'identifier': intrinsic function already defined

Compiler Warning (level 1) C4353 nonstandard extension used: constant 0 as function


expression. Use '__noop' function intrinsic instead

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) C4365 'expression': conversion from 'type1' to 'type2',


signed/unsigned mismatch

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 3) C4373 'derived_class::function': virtual function overrides


'base_class::function', previous versions of the compiler did
not override when parameters only differed by const/volatile
qualifiers

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) C4383 'instance_dereference_operator': the meaning of dereferencing


a handle can change, when a user-defined
'instance_dereference_operator' operator exists; write the
operator as a static function to be explicit about the operand

Compiler Warning (level 1) C4384 #pragma 'make_public' should only be used at global scope

Compiler warning (level 3) C4387 'alternative': was considered

Compiler warning (level 4) C4388 'expression': signed/unsigned mismatch

Compiler Warning (level 4) C4389 'operator': signed/unsigned mismatch

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) C4392 'function_signature': incorrect number of arguments for


intrinsic function, expected 'argument_count' arguments

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 1) C4397 DefaultCharSetAttribute is ignored

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

nonstandard extension used : zero-sized array in struct/union


Indicates that a structure or union contains an array that has zero size.
Declaration of a zero-sized array is a Microsoft extension. This causes a Level-2 warning when a C++ file is
compiled and a Level-4 warning when a C file is compiled. C++ compilation also gives this warning: "Cannot
generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array." This example generates
warning C4200:

// 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

nonstandard extension used : nameless struct/union


Under Microsoft extensions (/Ze), you can specify a structure without a declarator as members of another structure
or union. These structures generate an error under ANSI compatibility (/Za).

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

nonstandard extension used : '...': prototype parameter in name list illegal


An old-style function definition contains variable arguments. These definitions generate an error under ANSI
compatibility (/Za).

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

nonstandard extension used : non-constant aggregate initializer


With Microsoft extensions (/Ze), you can initialize aggregate types (arrays, structures, unions, and classes) with
values that are not constants.

Example
// C4204.c
// compile with: /W4
int func1()
{
return 0;
}
struct S1
{
int i;
};

int main()
{
struct S1 s1 = { func1() }; // C4204
return s1.i;
}

Such initializations are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4205
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : static function declaration in function scope


With Microsoft extensions (/Ze), static functions can be declared inside another function. The function is given
global scope.

Example
// C4205.c
// compile with: /W4
void func1()
{
static int func2(); // C4205
};

int main()
{
}

Such initializations are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4206
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : translation unit is empty


The file was empty after preprocessing.
This extension can prevent your code from being portable to other compilers. It generates an error under ANSI
compatibility (/Za) and only applies to C source code.
Compiler Warning (level 4) C4207
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : extended initializer form


With Microsoft extensions (/Ze), you can initialize an unsized array of char using a string within braces.

Example
// C4207.c
// compile with: /W4
char c[] = { 'a', 'b', "cdefg" }; // C4207

int main()
{
}

Such initializations are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4208
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : delete [exp] - exp evaluated but ignored


With Microsoft extensions (/Ze), you can delete an array using a value within brackets with the delete operator. The
value is ignored.

// C4208.cpp
// compile with: /W4
int main()
{
int * MyArray = new int[18];
delete [18] MyArray; // C4208
MyArray = new int[18];
delete [] MyArray; // ok
}

Such values are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4210
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : function given file scope


With the default Microsoft extensions (/Ze), function declarations have file scope.

// 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

nonstandard extension used : redefined extern to static


With the default Microsoft extensions (/Ze), you can redefine an extern identifier as static.

Example
// C4211.c
// compile with: /W4
extern int i;
static int i; // C4211

int main()
{
}

Such redefinitions are invalid under ANSI compatibility (/Za).

See Also
Compiler Warning (level 4) C4212
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : function declaration used ellipsis


The function prototype has a variable number of arguments. The function definition does not.
The following sample generates C4212:

// 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

nonstandard extension used : cast on l-value


With the default Microsoft extensions (/Ze), you can use casts on the left side of an assignment statement.

Example
// C4213.c
// compile with: /W4
void *a;
void f()
{
int i[3];
a = &i;
*(( int * )a )++ = 3; // C4213
}

int main()
{
}

Such casts are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4214
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : bit field types other than int


With the default Microsoft extensions (/Ze), bitfield structure members can be of any integer type.

Example
// C4214.c
// compile with: /W4
struct bitfields
{
unsigned short j:4; // C4214
};

int main()
{
}

Such bit fields are invalid under ANSI compatibility (/Za).


Compiler Warning (level 1) C4215
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : long float


The default Microsoft extensions (/Ze) treat long float as double. ANSI compatibility (/Za) does not. Use double
to maintain compatibility.
The following sample generates C4215:

// C4215.cpp
// compile with: /W1 /LD
long float a; // C4215

// use the line below to resolve the warning


// double a;
Compiler Warning (level 1) C4216
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : float long


The default Microsoft extensions (/Ze) treat float long as double. ANSI compatibility (/Za) does not. Use double
to maintain compatibility. The following sample generates C4216:

// C4216.cpp
// compile with: /W1
float long a; // C4216

// use the line below to resolve the warning


// double a;

int main() {
}
Compiler Warning (level 1) C4218
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : must specify at least a storage class or a type


With the default Microsoft extensions (/Ze), you can declare a variable without specifying a type or storage class.
The default type is int .

Example
// C4218.c
// compile with: /W4
i; // C4218

int main()
{
}

Such declarations are invalid under ANSI compatibility (/Za).


Compiler Warning (level 4) C4220
10/31/2018 • 2 minutes to read • Edit Online

varargs matches remaining parameters


Under the default Microsoft extensions (/Ze), a pointer to a function matches a pointer to a function with similar,
but variable, arguments.

Example
// C4220.c
// compile with: /W4

int ( *pFunc1) ( int a, ... );


int ( *pFunc2) ( int a, int b);

int main()
{
if ( pFunc1 != pFunc2 ) {}; // C4220
}

Such pointers do not match under ANSI compatibility (/Za).


Compiler Warning (level 4) C4221
10/31/2018 • 2 minutes to read • Edit Online

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()
{
}

Such initializations are invalid under ANSI compatibility (/Za).


Compiler Warning (levels 1 and 4) C4223
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : non-lvalue array converted to pointer


In standard C, you cannot convert a non-lvalue array to a pointer. With the default Microsoft extensions (/Ze), you
can.
Compiler Warning (level 1) C4224
10/31/2018 • 2 minutes to read • Edit Online

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

nonstandard extension used : 'keyword' is an obsolete keyword

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

anachronism used : qualifiers on reference are ignored


Using qualifiers like const or volatile with C++ references is an outdated practice.

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

anachronism used : modifiers on data are ignored


Using a Microsoft modifier such as __cdecl on a data declaration is an outdated practice.

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

anachronism used : modifiers/qualifiers interspersed; qualifier ignored


Using a qualifier before a Microsoft modifier such as __cdecl is an outdated practice.

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

nonstandard extension used : 'keyword' keyword only supported in C++, not C

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

nonstandard extension used: 'keyword' keyword reserved for future use


The compiler does not yet implement the keyword you used.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning. For
example, to make C4234 into a level 4 warning issue,

#pragma warning(2:4234)

in your source code file.


Compiler Warning (level 4) C4235
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : 'keyword' keyword not supported on this architecture


The compiler does not support the keyword you used.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning. For
example, to make C4235 into a level 2 warning, use the following line of code

#pragma warning(2:4235)

in your source code file.


Compiler Warning (level 1) C4237
10/31/2018 • 2 minutes to read • Edit Online

'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

nonstandard extension used : class rvalue used as lvalue


For compatibility with previous versions of Visual C++, Microsoft extensions (/Ze) allow you to use a class type as
an rvalue in a context that implicitly or explicitly takes its address. In some cases, such as the example below, this
can be dangerous.

Example
// C4238.cpp
// compile with: /W4 /c
struct C {
C() {}
};

C * pC = &C(); // C4238

This usage causes an error under ANSI compatibility (/Za).


Compiler Warning (level 4) C4239
10/31/2018 • 2 minutes to read • Edit Online

nonstandard extension used : 'token' : conversion from 'type' to 'type'


This type conversion is not allowed by the C++ standard, but it is permitted here as an extension. This warning is
always followed by at least one line of explanation describing the language rule being violated.

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

'identifier' : conversion from 'type1' to 'type2', possible loss of data


The types are different. Type conversion may result in loss of data. The compiler makes the type conversion.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
For additional information on C4242, see Common Compiler Errors.
The following sample generates C4242:

// 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

'conversion type' conversion exists from 'type1' to 'type2', but is inaccessible


A pointer to a derived class is converted to a pointer to a base class, but the derived class inherits the base class
with private or protected access.
The following sample generates C4243:

// C4243.cpp
// compile with: /W3
// C4243 expected
struct B {
int f() {
return 0;
};
};

struct D : private B {};


struct E : public B {};

int main() {
// Delete the following 2 lines to resolve.
int (D::* d)() = (int(D::*)()) &B::f;
d;

int (E::* e)() = (int(E::*)()) &B::f; // OK


e;
}
Compiler Warning (level 2) C4244
10/31/2018 • 2 minutes to read • Edit Online

'argument' : conversion from 'type1' to 'type2', possible loss of data


A floating point type was converted to an integer type. A possible loss of data may have occurred.
If you get C4244, you should either change your program to use compatible types, or add some logic to your code,
to ensure that the range of possible values will always be compatible with the types you are using.
C4244 can also fire at level 3, and 4; see Compiler Warning (levels 3 and 4) C4244 for more information.

Example
The following sample generates C4244:

// C4244_level2.cpp
// compile with: /W2

int f(int x){ return 0; }


int main() {
double x = 10.1;
int i = 10;
return (f(x)); // C4244
// try the following line instead
// return (f(i));
}
Compiler Warning (levels 3 and 4) C4244
3/12/2019 • 2 minutes to read • Edit Online

'conversion' conversion from 'type1' to 'type2', possible loss of data


An integer type is converted to a smaller integer type. This is a level-4 warning if type1 is int and type2 is
smaller than int . Otherwise, it is a level 3 (assigned a value of type __int64 to a variable of type unsigned int ). A
possible loss of data may have occurred.
If you get C4244, you should either change your program to use compatible types, or add some logic to your code,
to ensure that the range of possible values will always be compatible with the types you are using.
C4244 can also fire at level 2; see Compiler Warning (level 2) C4244 for more information.
The conversion may have a problem due to implicit conversions.
The following sample generates C4244:

// 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
}

For more information, see Usual Arithmetic Conversions.

// 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

'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch


You tried to convert a signed const that has a negative value to an unsigned .
The following sample generates C4245:

// 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

'class1' : inherits 'class2::member' via dominance


Two or more members have the same name. The one in class2 is inherited because it is a base class for the other
classes that contained this member.
To suppress C4250, use the warning pragma.
Because a virtual base class is shared among multiple derived classes, a name in a derived class dominates a name
in a base class. For example, given the following class hierarchy, there are two definitions of func inherited within
diamond: the vbc::func() instance through the weak class, and the dominant::func() through the dominant class. An
unqualified call of func() through a diamond class object, always calls the dominate::func() instance. If the weak
class were to introduce an instance of func(), neither definition would dominate, and the call would be flagged as
ambiguous.

// C4250.cpp
// compile with: /c /W2
#include <stdio.h>
struct vbc {
virtual void func() { printf("vbc::func\n"); }
};

struct weak : public virtual vbc {};

struct dominant : public virtual vbc {


void func() { printf("dominant::func\n"); }
};

struct diamond : public weak, public dominant {};

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;
}
};

class B : virtual public A {


public:
virtual operator int () {
return 3;
}
};

class C : virtual public A {};

class E : public B, public C {}; // C4250

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;
}
};

class B : virtual public V {


public:
int b() {
return f(); // B::b() calls V::f()
}
};

class M : virtual public V {


public:
int f() {
return 7;
}
};

// because of dominance, f() is M::f() inside D,


// changing the meaning of B::b's f() call inside a D
class D : public B, public M {}; // C4250

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

'operator' : conversion from 'type1' to 'type2', possible loss of data


A larger bit field was assigned to a smaller bit field. There could be a loss of data.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4254:

// 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

'function' : no function prototype given: converting '()' to '(void)'


The compiler did not find an explicit list of arguments to a function. This warning is for the C compiler only.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4255:

// C4255.c
// compile with: /W4 /WX
#pragma warning (default : 4255)

void f() { // C4255


// try the following line instead
//void f(void) {
}

int main(int argc, char *argv[]) {


f();
}
Compiler Warning (level 4) C4256
10/31/2018 • 2 minutes to read • Edit Online

'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
{
};

struct S2: virtual public S1


{
S2( int i, ... ) // C4256
{
i = 0;
}
/*
// try the following line instead
S2( int i)
{
i = 0;
}
*/
};

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

'class' : class has virtual functions, but destructor is not virtual


When a class has virtual functions but a nonvirtual destructor, objects of the type might not be destroyed properly
when the class is destroyed through a base class pointer.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4265:

// 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);
};

class LocalBinding : private Engine {


virtual void OnException(int&,int);
}; // C4266

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);
};

class LocalBinding : private Engine {


virtual void OnException(int&,int);
virtual void OnException(int&, int&, int);
};
Compiler Warning (level 3) C4267
10/31/2018 • 2 minutes to read • Edit Online

'var' : conversion from 'size_t' to 'type', possible loss of data


The compiler detected a conversion from size_t to a smaller type.
To fix this warning, use size_t instead of type . Alternatively, use an integral type that is at least as large as
size_t .

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;
};

const X x1; // C4268

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

'function' : inconsistent DLL linkage


Two definitions in a file differ in their use of dllimport.

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

#ident ignored; see documentation for #pragma comment(exestr, 'string')


The #ident directive, which inserts a user-specified string in the object or executable file, is deprecated.
Consequently, the compiler ignores the directive.
Cau t i on

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.

To correct this error


Remove the #ident " string " directive.

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'

An exported class was derived from a class that wasn't exported.


To minimize the possibility of data corruption when exporting a class with __declspec(dllexport), make sure that:
All your static data is accessed 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 that use static data.
No inlined class functions use CRT functions, or other library functions, where you access static data.
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.
C4275 can be ignored in Visual C++ 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 .

// 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

'function' : no prototype provided; assumed no parameters


When you take the address of a function with the __stdcall calling convention, you must give a prototype so the
compiler can create the function's decorated name. Since function has no prototype, the compiler, when creating
the decorated name, assumes the function has no parameters.
Compiler Warning (level 3) C4278
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

'operator ->' was self recursive through type 'type'


Your code incorrectly allows operator-> to call itself.
The following sample generates C4280:

// 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

'operator ->' recursion occurred through type 'type'


Your code allows operator-> to call itself.
The following sample generates C4281:

// 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

then through type 'type'


This continuation of warning C4281shows that operator-> calls itself through type .
Compiler Warning (level 3) C4283
10/31/2018 • 2 minutes to read • Edit Online

and through type 'type'


This continuation of warning C4281 shows that operator-> calls itself through type .
Compiler Warning (level 2) C4285
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

'type1' : is caught by base class ('type2') on line number


The specified exception type is handled by a previous handler. The type for the second catch is derived from the
type of the first. Exceptions for a base class catch exceptions for a derived class.

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

'operator' : unsigned/negative constant mismatch


An unsigned variable was used in an operation with a negative number.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

C++ exception specification ignored except to indicate a function is not __declspec(nothrow )


A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with
exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in
future versions supporting exception specifications.
For more information, see Exception Specifications (throw ) .
You can avoid this warning by using the warning pragma:

#pragma warning( disable : 4290 )

The following code sample generates C4290:

// 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!";
}
};

void* operator new(size_t size, char* pszFilename, int nLine)


{
return malloc(size);
}

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.

void operator delete(void* pMem, char* pszFilename, int nLine)


{
free(pMem);
}
Compiler Warning (level 1) C4293
10/31/2018 • 2 minutes to read • Edit Online

'operator' : shift count negative or too big, undefined behavior


If a shift count is negative or too large, the behavior of the resulting image is undefined.

Example
The following sample generates C4293:

// C4293.cpp
// compile with: /c /W1
unsigned __int64 combine (unsigned lo, unsigned hi) {

return (hi << 32) | lo; // C4293

// try the following line instead


// return ( (unsigned __int64)hi << 32) | lo;
}
Compiler Warning (level 4) C4295
10/31/2018 • 2 minutes to read • Edit Online

'array' : array is too small to include a terminating null character

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

'operator' : expression is always false


An unsigned variable was used in a comparison operation with zero.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4296:

// 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

'function' : function assumed not to throw an exception but does


A function declaration contains a (possibly implicit) noexcept specifier, an empty throw exception specifier, or a
__declspec(nothrow ) attribute, and the definition contains one or more throw statements. To resolve C4297, do not
attempt to throw exceptions in functions that are declared __declspec(nothrow) , noexcept(true) or throw() .
Alternatively, remove the noexcept , throw() , or __declspec(nothrow) specification.
By default, the compiler generates implicit noexcept(true) specifiers for user-defined destructors and deallocator
functions and compiler-generated special member functions. This conforms to the ISO C++11 standard. To
prevent generation of implicit noexcept specifiers and revert the compiler to the non-standard behavior of Visual
Studio 2013, use the /Zc:implicitNoexcept- compiler option. For more information, see /Zc:implicitNoexcept
(Implicit Exception Specifiers).
For more information on exception specifications, see Exception Specifications (throw ). Also, see /EH (Exception
Handling Model) for information on how to modify exception handling behavior at compile time.
This warning is also generated for __declspec(dllexport) functions marked extern "C", even if they are C++
functions.
The following sample generates C4297:

// 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

'conversion' : truncation from 'type 1' to 'type 2'


The compiler detected a conversion from a larger type to a smaller type. Information may be lost.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4302:

// 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

'context' : truncation from 'type1' to 'type2'

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

'identifier' : conversion from 'type1' to 'type2' of greater size

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

'operator' : integral constant overflow


The operator is used in an expression that results in an integer constant overflowing the space allocated for it. You
may need to use a larger type for the constant. A signed int holds a smaller value than an unsigned int because
the signed int uses one bit to represent the sign.
The following sample generates C4307:

// 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

negative integral constant converted to unsigned type


An expression converts a negative integer constant to an unsigned type. The result of the expression is probably
meaningless.

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

'conversion' : truncation of constant value


The type conversion causes a constant to exceed the space allocated for it. You may need to use a larger type for
the constant.
The following sample generates C4309:

// 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

cast truncates constant value


A constant value is cast to a smaller type. The compiler performs the cast, which truncates data. The following
sample generates C4310:

// 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

'variable' : pointer truncation from 'type' to 'type'


This warning detects 64-bit pointer truncation issues. For example, if code is compiled for a 64-bit architecture, the
value of a pointer (64 bits) will be truncated if it is assigned to an int (32 bits). For more information, see Rules
for Using Pointers.
For additional information about common causes of warning C4311, see Common Compiler Errors.
The following code example generates C4311 when compiled for a 64-bit target, and then demonstrates how to fix
it:

// 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

'operation' : conversion from 'type1' to 'type2' of greater size


This warning detects an attempt to assign a 32-bit value to a 64-bit pointer type, for example, casting a 32-bit int
or long to a 64-bit pointer.
This can be an unsafe conversion even for pointer values that fit in 32 bits when sign extension occurs. If a negative
32-bit integer is assigned to a 64-bit pointer type, sign extension causes the pointer value to reference a memory
address different from the value of the integer.
This warning is only issued for 64-bit compilation targets. For more information, see Rules for Using Pointers.
The following code example generates C4312 when it is compiled for 64-bit targets:

// 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

__declspec(align(32)) struct S {}; // C4324

int main() {
new S; // C4316
}
Compiler Warning (level 1) C4319
10/31/2018 • 2 minutes to read • Edit Online

'~' : zero extending 'type1' to 'type2' of greater size

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

'struct_name' : structure was padded due to __declspec(align())


Padding was added at the end of a structure because you specified a __declspec(align) value.
For example, the following code generates C4324:

// 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

attributes for standard section 'section' ignored

Remarks
You may not change the attributes of a standard section. For example:

#pragma section(".sdata", long)

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

return type of 'function' should be 'type1' instead of 'type2'

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

__declspec(align()) is ignored on enum


Use of the align keyword of the __declspec modifier is not allowed on an enum . The following sample generates
C4329:

// 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

'operator' : right shift by too large amount, data loss


A right shift operation was too large an amount. All significant bits are shifted out and the result will always be
zero.

Example
The following sample generates C4333.

// C4333.cpp
// compile with: /c /W1
unsigned shift8 (unsigned char c) {
return c >> 8; // C4333

// try the following line instead


// return c >> 4; // OK
}
Compiler Warning (level 3) C4334
10/31/2018 • 2 minutes to read • Edit Online

'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

import cross-referenced type library 'type_lib1' before importing 'type_lib2'


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 found by the compiler.
Given two type libraries on disk created from the following two files (compiled with midl.exe):

// c4336a.idl
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12b")]
library c4336aLib
{
[uuid("f87070ba-c6d9-405c-a8e4-8cd9ca25c12c")]
enum E_C4336
{
one, two, three
};
};

The second type library:

// 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;
};
};

The following sample generates C4336:

// 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

cross-referenced type library 'typelib1' in 'typelib2' is being automatically imported


The auto_search attribute of the #import directive caused a type library to be implicitly imported.
Given two type libraries on disk created from the following two files (compiled with midl.exe):

// 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
};
};

and then the second .idl file,

// 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;
};
};

The following sample generates C4337:

// 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)

// Delete the following line to resolve.


class A;

// Uncomment the following line to resolve.


// class A{};

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

'value' : value wrapped from positive to negative value


The enum value is greater than the largest enum positive value wrapped around to a negative value.
Compiler Warning (level 1) C4342
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

#pragma optimize("g",off) overrides /Og option


This warning, only valid in the Itanium Processor Family (IPF ) compiler, reports that a pragma optimize overrode a
/Og compiler option.
The following sample generates C4343:

// 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

behavior change: use of explicit template arguments results in call to 'function'


A call to a function using explicit template arguments calls a different function than it would if explicit arguments
had not been specified
Compiler Warning (level 1) C4346
10/31/2018 • 2 minutes to read • Edit Online

'name' : dependent name is not a type


The typename keyword is required if a dependent name is to be treated as a type. For code that works the same in
all versions of Visual C++, add typename to the declaration.
The following sample generates C4346:

// 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, int N>


struct L{};

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

'type' : redefinition of default parameter : parameter number


A template parameter was redefined.
The following sample generates C4348:

// C4348.cpp
// compile with: /LD /W1
template <class T=int> struct A; // forward declaration

template <class T=int> struct A { };


// C4348, redefinition of default parameter
// try the following line instead
// template <class T> struct A { };
Compiler Warning (level 1) C4350
10/31/2018 • 2 minutes to read • Edit Online

behavior change: 'member1' called instead of 'member2'


An rvalue cannot be bound to a non-const reference. In versions of Visual C++ before Visual Studio 2003, it was
possible to bind an rvalue to a non-const reference in a direct initialization. This code now gives a warning.
For backward compatibility, it is still possible to bind rvalues to non-const references, but standard conversions are
preferred wherever possible.
This warning represents a change of behavior from the Visual C++ .NET 2002 compiler. If enabled, this warning
could possibly be given for correct code. For example, it could be given when using the std::auto_ptr class
template.
If you get this warning, examine your code to see if it depends on binding rvalues to non-const references. Adding
a const to the reference or providing a additional const-reference overload may solve the problem.
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.
The following sample generates C4350:

// 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();}
};

B source() { 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

'this' : used in base member initializer list


The this pointer is valid only within nonstatic member functions. It cannot be used in the initializer list for a base
class.
The base-class constructors and class member constructors are called before this constructor. In effect, you've
passed a pointer to an unconstructed object to another constructor. If those other constructors access any
members or call member functions on this, the result will be undefined. You should not use the this pointer until all
construction has completed.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4355:

// 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;
};

class CDerived : public CBase {


public:
CDerived() : CBase(this) {}; // C4355 "this" used in derived c'tor
virtual void function() {};
};

CBase::~CBase() {
m_pDerived -> function();
}

int main() {
CDerived myDerived;
}
Compiler Warning (level 2) C4356
10/31/2018 • 2 minutes to read • Edit Online

'member' : static data member cannot be initialized via derived class


The initialization of a static data member was ill formed. The compiler accepted the initialization. To avoid the
warning, initialize the member through the base class.
Use the warning pragma to suppress this warning.
The following sample generates C4356:

// C4356.cpp
// compile with: /W2 /EHsc
#include <iostream>

template <class T>


class C {
static int n;
};

class D : C<int> {};

int D::n = 0; // C4356


// try the following line instead
// int C<int>::n = 0;

class A {
public:
static int n;
};

class B : public A {};

int B::n = 10; // C4356


// try the following line instead
// int A::n = 99;

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

public delegate void g(int i, array<Object^>^ varargs); // OK


Compiler Warning (level 1) C4358
10/31/2018 • 2 minutes to read • Edit Online

'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

E^ e = gcnew E(gcnew Y, &Y::g);


E^ e2 = gcnew E(gcnew Y, &Y::g);
e += e2; // OK
}
Compiler Warning (level 3) C4359
10/31/2018 • 2 minutes to read • Edit Online

'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

'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch


For example, you tried to convert an unsigned value to a signed value.
C4365 is off by default. For more information, see Compiler Warnings That Are Off by Default.

Example
The following sample generates C4365.

// C4365.cpp
// compile with: /W4
#pragma warning(default:4365)

int f(int) { return 0; }


void Test(size_t i) {}

int main() {
unsigned int n = 10;
int o = 10;
n++;
f(n); // C4365
f(o); // OK

Test( -19 ); // C4365


}
Compiler Warning (level 4) C4366
10/31/2018 • 2 minutes to read • Edit Online

The result of the unary 'operator' operator may be unaligned


If a structure member could ever be unaligned because of packing, the compiler will warn when that member's
address is assigned to an aligned pointer. By default, all pointers are aligned.
To resolve C4366, either change the alignment of the structure or declare the pointer with the __unaligned
keyword.
For more information, see __unaligned and pack.

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 N prop; // C4368


int i[10]; // C4368

property O ^ prop2; // OK
N * m_p; // OK
};
Compiler Warning (level 1) C4369
10/31/2018 • 2 minutes to read • Edit Online

'enumerator' : enumerator value 'value' cannot be represented as 'type', value is 'new_value'


An enumerator was calculated to be greater than the greatest value for the specified underlying type. This caused
an overflow and the compiler wrapped the enumerator value to the lowest possible value for the type.

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");
}
};

struct Derived : Base


{
void f(const int i) { // C4373
printf("derived\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

'function1': interface method will not be implemented by non-virtual method 'function2'


The compiler expected to find the virtual keyword on a method definition.
The following sample generates C4374:

// C4374.cpp
// compile with: /clr /W1 /c /WX
public interface class I {
void f();
};

public ref struct B {


void f() {
System::Console::WriteLine("B::f()");
}
};

public ref struct C {


virtual void f() {
System::Console::WriteLine("C::f()");
}
};

public ref struct D : B, I {}; // C4374


public ref struct E : C, I {}; // OK
Compiler Warning (level 1) C4375
10/31/2018 • 2 minutes to read • Edit Online

non-public method 'method2' does not override 'method1'


A type that implements another type defined an override method, but the override was not public. Therefore, the
method does not override the base type method.
Compiler Warning (level 1) C4376
10/31/2018 • 2 minutes to read • Edit Online

access specifier 'old_specifier:' is no longer supported: please use 'new_specifier:' instead


For more information on specifying type and member accessibility in metadata, see Type visibility and Member
visibility in How to: Define and Consume Classes and Structs (C++/CLI).

Example
The following sample generates C4376.

// C4376.cpp
// compile with: /clr /W1 /c
public ref class G {
public public: // C4376
void m2();
};

public ref class H {


public: // OK
void m2();
};
Compiler Warning (level 1) C4377
10/31/2018 • 2 minutes to read • Edit Online

native types are private by default; -d1PrivateNativeTypes is deprecated


In previous releases, native types in assemblies were public by default, and an internal, undocumented compiler
option (/d1PrivateNativeTypes) was used to make them private.
All types, native and CLR, are now private by default in an assembly, so /d1PrivateNativeTypes is no longer
needed.

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

Must obtain function pointers to run initializers; consider System::ModuleHandle::ResolveMethodHandle


Under /clr, initializer symbols contain function tokens, not functions pointers. You need to convert tokens to
pointers using ResolveMethodHandle.

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

int myexit (PF pf) {


pfx[cxpf++] = pf;
return 0;
}

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)();
}

#pragma init_seg(".mine$m",myexit) // C4378


A bbbb; // crash

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);

int cxpf = 0; // number of destructors we need to call


PF pfx[200]; // ptrs to those dtors. Watch out for overflow!

ref class TypeClassHolder {


public:
static TypeClassHolder ^typeClass = gcnew TypeClassHolder();
};

CLRPF FuncTokenToFuncPtr(PF tknFunc) {


ModuleHandle type =
Type::GetTypeFromHandle(Type::GetTypeHandle(TypeClassHolder::typeClass))->Module->ModuleHandle;
return (CLRPF)type.ResolveMethodHandle((int)(size_t)(tknFunc)).GetFunctionPointer().ToPointer();
}

int myexit (PF pf) {


pfx[cxpf++] = pf;
return 0;
}

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

'function1': interface method will not be implemented by non-public method 'function2'


A class must implement all function in an interface. A class can satisfy this condition if one of its base classes
implements the function. However, the function must be implemented as a public function.
Compiler Warning (level 1) C4382
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

'instance_dereference_operator' : the meaning of dereferencing a handle can change, when a user-defined


'operator' operator exists; write the operator as a static function to be explicit about the operand
When you add a user-defined instance override of the dereference operator in a managed type, you potentially
override the ability of the type's dereference operator to return the handle's object. Consider writing a static, user-
defined dereference operator.
For more information, see Handle to Object Operator (^) and Tracking Reference Operator.
Also, an instance operator is not available to other language compilers via referenced metadata. For more
information, see User-Defined Operators (C++/CLI).

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

#pragma 'make_public' should only be used at global scope


The make_public pragma was applied incorrectly.

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

'operator' : signed/unsigned mismatch


An operation involved signed and unsigned variables. This could result in a loss of data.
The following sample generates C4389:

// 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

';' : empty controlled statement found; is this the intent?


A semicolon was found after a control statement that contains no instructions.
If you get C4390 because of a macro, you should use the warning pragma to disable C4390 in the module
containing the macro.
The following sample generates C4390:

// 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

'signature' : incorrect return type for intrinsic function, expected 'type'


A function declaration for a compiler intrinsic had the wrong return type. 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 C4391:

// 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

extern void _mm_load_ss(float *p); // C4391

#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

extern void _mm_stream_pd(double *dp); // C4392

#ifdef __cplusplus
}
#endif

int main()
{
}
Compiler Warning (level 1) C4393
10/31/2018 • 2 minutes to read • Edit Online

'var' : const has no effect on literal data member; ignored


A literal data member was also specified as const. Since a literal data member implies const, you do not need to
add const to the declaration.
The following sample generates C4393:

// 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

'function' : per-appdomain symbol should not be marked with __declspec(dllexport)


A function marked with the appdomain __declspec modifier is compiled to MSIL (not to native), and export tables
(export __declspec modifier) are not supported for managed functions.
You can declare a managed function to have public accessibility. For more information, see Type visibility and
Member visibility.
C4394 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 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;
};

public ref class R {


public:
static void f() {
System::Console::WriteLine("v.m_data = {0}", v.m_data);
v.Mutate(); // C4395
System::Console::WriteLine("v.m_data = {0}", v.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

[DllImport("kernel32", EntryPoint="CloseHandle", CharSet=CharSet::Unicode)] // OK


extern "C" bool ImportDefault(IntPtr hObject);

public ref class MySettingVC {


public:
void method() {
ImportDefault(IntPtr::Zero);
}
};

[StructLayout(LayoutKind::Explicit)]
public ref struct StructDefault1{};

public ref class ClassDefault1{};


Compiler Warning (level 3) C4398
10/31/2018 • 2 minutes to read • Edit Online

'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) C4401 'bitfield': member is bit field

Compiler Warning (level 1) C4402 must use PTR operator

Compiler Warning (level 1) C4403 illegal PTR operator

Compiler Warning (level 3) C4404 period on directive ignored

Compiler Warning (level 1) C4405 'identifier': identifier is reserved word


WARNING MESSAGE

Compiler Warning (level 1) C4406 operand on directive ignored

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 1) C4409 illegal instruction size

Compiler Warning (level 1) C4410 illegal size for operand

Compiler Warning (level 1) C4411 'identifier': symbol resolves to displacement register

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 C4413 'classname::member': reference member is initialized to a


temporary that doesn't persist after the constructor exits

Compiler Warning (level 3) C4414 'function': short jump to function converted to near

Compiler warning (level 1) C4415 duplicate __declspec(code_seg('name'))

Compiler warning (level 1) C4416 __declspec(code_seg(...)) contains empty string: ignored

Compiler warning (level 1) C4417 an explicit template instantiation cannot have


__declspec(code_seg(...)): ignored

Compiler warning (level 1) C4418 __declspec(code_seg(...)) ignored on an enum

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) C4421 'parameter': a reference parameter on a resumable function is


potentially unsafe

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) C4425 A SAL annotation cannot be applied to '...'

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 (level 4) C4429 possible incomplete or improperly formed universal-character-


name
WARNING MESSAGE

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 C4438 'function': cannot be called safely in /await:clrcompat mode. If


'function' calls into the CLR it may result in CLR head
corruption

Compiler Warning (Error) C4439 'function': function definition with a managed type in the
signature must have a __clrcall calling convention

Compiler Warning (level 1) C4440 calling convention redefinition from 'calling_convention1' to


'calling_convenction2' ignored

Compiler Warning (level 1) C4441 calling convention of 'calling_convention1' ignored;


'calling_convention2' used instead

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 C4449 'type' an unsealed type should be marked as


'[WebHostHidden]'

Compiler warning C4450 'type1' should be marked as '[WebHostHidden]' because it


derives from 'type2'

Compiler warning (level 4) C4451 'classname1::member': Usage of ref class 'classname2::member'


inside this context can lead to invalid marshaling of object
across contexts

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) C4457 declaration of 'identifier' hides function parameter

Compiler warning (level 4) C4458 declaration of 'identifier' hides class member

Compiler warning (level 4) C4459 declaration of 'identifier' hides global 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 4) C4464 relative include path contains '..'

Compiler Warning (level 1) C4470 floating-point control pragmas ignored under /clr

Compiler warning (level 4) C4471 'enumeration': a forward declaration of an unscoped


enumeration must have an underlying type (int assumed)
WARNING MESSAGE

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 C4482 nonstandard extension used: enum 'enumeration' used in


qualified name

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 4) C4487 'derived_class_function': matches inherited non-virtual


method 'base_class_function' but is not explicitly marked 'new'

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 C4498 nonstandard extension used: 'extension'

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) C4506 no definition for inline function 'function'

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 4) C4515 'namespace': namespace uses itself

Compiler Warning (level 4) C4516 'class::symbol': access-declarations are deprecated; member


using-declarations provide a better alternative
WARNING MESSAGE

Compiler Warning (level 4) C4517 access-declarations are deprecated; member using-


declarations provide a better alternative

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 3) C4521 'class': multiple copy constructors specified

Compiler Warning (level 3) C4522 'class': multiple assignment operators specified

Compiler Warning (level 3) C4523 'class': multiple destructors specified

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 1) C4533 initialization of 'variable' is skipped by 'goto label'

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) C4535 calling _set_se_translator() requires /EHa

Compiler Warning (level 4) C4536 'typename': type-name exceeds meta-data limit of


'character_limit' characters

Compiler Warning (level 1) C4537 'object': '.' applied to non-UDT type

Compiler Warning (level 3) C4538 'type': const/volatile qualifiers on this type are not supported

Compiler Warning (level 1) C4540 dynamic_cast used to convert to inaccessible or ambiguous


base; run-time test will fail ('type1' to 'type2')

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 3) C4543 Injected text suppressed by attribute 'no_injected_text'


WARNING 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) C4550 expression evaluates to a function which is missing an


argument list

Compiler Warning (level 1) C4551 function call missing argument list

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 3) C4557 '__assume' contains effect 'effect'

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) C4566 character represented by universal-character-name 'char'


cannot be represented in the current code page (number)

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 3) C4580 [attribute] is deprecated; instead specify System::Attribute or


Platform::Metadata as a base class

Compiler Warning (level 1) C4581 deprecated behavior: '"string"' replaced with 'string' to process
attribute

Compiler warning (level 4) C4582 'type': constructor is not implicitly called

Compiler warning (level 4) C4583 'type': destructor is not implicitly called

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 1) C4587 'anonymous_structure': behavior change: constructor is no


longer implicitly called

Compiler warning (level 1) C4588 'anonymous_structure': behavior change: destructor is no


longer implicitly called

Compiler warning (level 1) C4591 'constexpr' call-depth limit of number exceeded


(/constexpr:depth<NUMBER>)

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

'type' : const/volatile qualifiers on this type are not supported


The constand volatilequalifiers will not work with variables of common language runtime types.

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

'bitfield' : member is bit field


Inline assembly code tries to access a bit-field member. Inline assembly cannot access bit-field members, so the last
packing boundary before the bit-field member is used.
To avoid this warning, cast the bit field to an appropriate type before making the reference in inline assembly code.
The following sample generates C4401:

// 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
}

/* use the following __asm block to resolve the warning


int i = (int)bf.bit;
__asm {
mov i,0;
}
*/
}
Compiler Warning (level 1) C4402
10/31/2018 • 2 minutes to read • Edit Online

must use PTR operator


A type is used on an operand without a PTR operator when referring to or casting to a type in inline assembly
code.
The compiler assumes the PTR operator.
Compiler Warning (level 1) C4403
10/31/2018 • 2 minutes to read • Edit Online

illegal PTR operator


A PTR operator is used inappropriately in inline assembler code.
The compiler ignored the PTR operator.
Compiler Warning (level 3) C4404
10/31/2018 • 2 minutes to read • Edit Online

period on directive ignored


The optional period preceding the directive is ignored.
Compiler Warning (level 1) C4405
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : identifier is reserved word


A word reserved for inline assembly is used as a variable name. This may cause unpredictable results. To fix this
warning, avoid naming variables with words reserved for inline assembly. The following sample generates C4405:

// 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

operand on directive ignored


The directive does not take any operands, but an operand was specified.
The compiler ignored the given operand or operands.
Compiler Warning (level 1) C4407
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)();

PMF_C2 f1(PMF_C3 pmf) {


return (PMF_C2)pmf; // C4407, change type of cast,
// or reverse base class inheritance of C3 (i.e. : C2, C1)
}
Compiler Warning (level 4) C4408
10/31/2018 • 2 minutes to read • Edit Online

anonymousstruct or union did not declare any data members


An anonymous struct or union must have at least one data member.
The following sample generates C4408:

// 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

illegal instruction size


The instruction did not have a form with the specified size. The smallest legal size was used.
Compiler Warning (level 1) C4410
10/31/2018 • 2 minutes to read • Edit Online

illegal size for operand


One of the operands on the instruction had an incorrect size. The smallest legal size for the operand was used.
Compiler Warning (level 1) C4411
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : symbol resolves to displacement register


The identifier is a local symbol that resolves to a displacement register and therefore may be used on an operand
with another symbol.
Compiler Warning (level 2) C4412
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;
};

__declspec(dllimport) Unsafe * __cdecl func();


__declspec(dllimport) Safe * __cdecl func2();

int main() {
Unsafe *pUnsafe = func(); // C4412
// pUnsafe->Test();

Safe *pSafe = func2(); // OK


}

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);

// try the following line instead


// virtual void __cdecl 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"

void Unsafe::Test(int * pi) {


*pi++;
}

__declspec(dllexport) Unsafe * __cdecl func() { return new Unsafe; }


__declspec(dllexport) Safe * __cdecl func2() { return new Safe; }

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"

__declspec(dllimport) Unsafe * __cdecl func();


__declspec(dllimport) Safe * __cdecl func2();

int main() {
int n = 7;
Unsafe *pUnsafe = func(); // C4412
pUnsafe->Test(&n);

Safe *pSafe = func2(); // OK


}
Compiler Warning (level 3) C4414
10/31/2018 • 2 minutes to read • Edit Online

'function' : short jump to function converted to near


Short jumps generate compact instruction which branches to an address within a limited range from the
instruction. The instruction includes a short offset that represents the distance between the jump and the target
address, the function definition. During linking a function may be moved or subject to link-time optimizations that
cause the function to be moved out of the range reachable from a short offset. The compiler must generate a
special record for the jump, which requires the jmp instruction to be either NEAR or FAR. The compiler made the
conversion.
For example, the following code generates C4414:

// 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

possible incomplete or improperly formed universal-character-name


The compiler detected a character sequence that may be a badly formed universal character name. A universal
character name is \u followed by four hex digits, or \U followed by eight hex digits.
The following sample generates C4429:

// 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

missing type specifier - int assumed. Note: C no longer supports default-int


This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005: Visual
C++ no longer creates untyped identifiers as int by default. The type of an identifier must be specified explicitly.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

a class constructor must have private accessibility; changing to private access


C4434 indicates that the compiler changed the accessibility of a static constructor. Static constructors must have
private accessibility, as they are only meant to be called by the common language runtime. For more information,
see Static constructors.

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() {}
};

class B : public virtual A // C4435


{};

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

calling convention redefinition from 'calling_convention1' to 'calling_convention2' ignored


An attempt to change the calling convention was ignored.
The following sample generates C4440:

// 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

calling convention of 'cc1' ignored; 'cc2' used instead


Member functions in managed user-defined types and global function generics must use the __clrcall calling
convention. The compiler used __clrcall .

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) {}

ref struct MyStruct {


void __cdecl Test(){} // C4441
void Test2(){} // OK
};
Compiler Warning (level 1) C4445
10/31/2018 • 2 minutes to read • Edit Online

'function' : in a WinRT or managed type a virtual method cannot be private


If a virtual function is private, it cannot be accessed by a derived type. To fix this error, change the accessibility of
the virtual member function to protected or public.
Compiler Warning (level 4) C4456
10/31/2018 • 2 minutes to read • Edit Online

declaration of 'identifier' hides previous local declaration

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

declaration of 'identifier' hides function parameter

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

declaration of 'identifier' hides class member

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

declaration of 'identifier' hides global declaration

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>

public value struct V {


static V operator ++(V& me) { // C4460
// try the following line instead
// static V operator ++(V me) {

printf_s(__FUNCSIG__ " called\n");


V tmp = me;
me.m_i++;
return tmp;
}
int m_i;
};

int main() {
V v;
v.m_i = 0;

printf_s("%d\n", v.m_i); // Should print 0


v++; // Translates to "v = V::operator ++(v)"
printf_s("%d\n", v.m_i); // will print 0, hence the warning
}
Compiler Warning (level 1) C4461
10/31/2018 • 2 minutes to read • Edit Online

'type' : this class has a finalizer 'finalizer' but no destructor 'dtor'


The presence of a finalizer in a type implies resources to delete. Unless a finalizer is explicitly called from the type's
destructor, the common language runtime determines when to run the finalizer, after your object goes out of scope.
If you define a destructor in the type and explicitly call the finalizer from the destructor, you can deterministically
run your finalizer.
For more information, see Destructors and finalizers.

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;};

public ref struct R sealed : [Windows::Foundation::Metadata::Default] IR


{
R() {}
virtual event Windows::Foundation::TypedEventHandler<R ^, EventArgs^>^ e;
};
A GUID of the type Windows::Foundation::TypedEventHandler<R^, EventArgs^>^ is only used when the type is
accessed from another component. The first workaround works because it can only be accessed within its own
component after the workaround. Otherwise, the compiler has to assume the worst case and emit the warning.
Compiler Warning (level 4) C4463
10/31/2018 • 2 minutes to read • Edit Online

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

relative include path contains '..'

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:

#include "..\headers\C4426.h" // emits warning C4464

// 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

floating-point control pragmas ignored under /clr


The float-control pragmas:
fenv_access
float_control
fp_contract
have no effect under /clr.
The following sample generates C4470:

// 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>

void print_func(int a, float f)


{
printf_s("This takes %*f arguments.\n", f); // C4473, missing * width argument
printf_s("This takes %*f arguments.\n", a, f); // fix: supply width argument
}

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>

void scan_func(int a, float f)


{
char name[20];

scanf_s("%s", &name); // C4473, missing buffer size argument


scanf_s("%s", &name, sizeof(name)); // fix: supply buffer size argument
}

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>

void print_func(int a, float f)


{
printf_s("This takes int and double arguments %d and %f.\n", f, a); // C4477, expected int then double
printf_s("This takes int and double arguments %d and %f.\n", a, f); // fix: types in correct order
}

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

nonstandard extension used: override specifier 'keyword'


A keyword was used that is not in the C++ standard, for example, one of the override specifiers that also works
under /clr. For more information, see,
/clr (Common Language Runtime Compilation)
Override Specifiers

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 {};

ref class D : 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.

For more information, see new (new slot in vtable).

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"); }
};

public ref struct D : B {


void f() { Console::WriteLine("in D::f"); } // C4487
void g() new { Console::WriteLine("in D::g"); } // OK
};

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

'function' : requires 'keyword' keyword to implement the interface method 'interface_method'


A class must implement all members of an interface from which it directly inherits. An implemented member must
have public accessibility, and must be marked virtual.

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();
};

// implemented member not public


ref class B : MyI { virtual void f1() {} }; // C4488

// 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();
};

ref struct B : MyI { void f1() {} }; // C4488


ref struct C : MyI { virtual void f1() {} }; // OK
Compiler Warning (level 1) C4489
10/31/2018 • 2 minutes to read • Edit Online

'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

interface struct IFace {


void Test();
};

ref struct Class1 : public IFace {


virtual void Test() override {} // C4490
// try the following line instead
// virtual void Test() {}
};
Compiler Warning (level 1) C4502
10/31/2018 • 2 minutes to read • Edit Online

'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

'identifier' : decorated name length exceeded, name was truncated

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{};

typedef std::map<std::string, Field> Screen;


typedef std::map<std::string, Screen> WebApp;
typedef std::map<std::string, WebApp> WebAppTest;
typedef std::map<std::string, WebAppTest> Hello;
Hello MyWAT;

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

'function' : unreferenced local function has been removed


The given function is local and not referenced in the body of the module; therefore, the function is dead code.
The compiler did not generate code for this dead function.
Compiler Warning (level 1) C4506
10/31/2018 • 2 minutes to read • Edit Online

no definition for inline function 'function'


The given function was declared and marked for inlining but was not defined.
The compiler did not inline the function.
Make sure that external functions to be inlined are declared with the extern keyword.
Compiler Warning (level 1) C4508
10/31/2018 • 2 minutes to read • Edit Online

'function' : function should return a value; 'void' return type assumed


The function has no return type specified. In this case, C4430 should also fire and the compiler implements the fix
reported by C4430 (default value is int).
To resolve this warning, explicitly declare the return type of functions.
The following sample generates C4508:

// 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

'class' : default constructor could not be generated


The compiler cannot generate a default constructor for the specified class and no user-defined constructor was
created. You will not be able to create objects of this type.
There are several situations that prevent the compiler from generating a default constructor, including:
A const data member.
A data member that is a reference.
You need to create a user-defined default constructor for the class that initializes these members.
The following sample generates C4510:

// 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

'class' : copy constructor could not be generated


The compiler could not generate a default copy-constructor for a class; a base class may have a private copy-
constructor.
Compiler Warning (level 4) C4512
10/31/2018 • 2 minutes to read • Edit Online

'class' : assignment operator could not be generated


The compiler cannot generate an assignment operator for the given class. No assignment operator was created.
An assignment operator for the base class that is not accessible by the derived class can cause this warning.
To avoid this warning, specify a user-defined assignment operator for the class.
The compiler will also generate an assignment operator function for a class that does not define one. This
assignment operator is a memberwise copy of the data members of an object. Because const data items cannot
be modified after initialization, if the class contains a const item, the default assignment operator would not work.
Another cause of the C4512 warning is a declaration of a nonstatic data member of reference type. If the intent is
to create a non-copyable type, you must also prevent the creation of a default copy constructor.
You can resolve the C4512 warning for your code in one of three ways:
Explicitly define an assignment operator for the class.
Remove const or the reference operator from the data item in the class.
Use the #pragma warning statement to suppress the warning.

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; }
};

// Type designer intends this to be non-copyable because it has a


// reference member
class Base3
{
private:
char& cr;

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

'class' : destructor could not be generated


The compiler cannot generate a default destructor for the given class; no destructor was created. The destructor is
in a base class that is not accessible to the derived class. If the base class has a private destructor, make it public or
protected.
Compiler Warning (level 4) C4514
10/31/2018 • 2 minutes to read • Edit Online

'function' : unreferenced inline function has been removed


The optimizer removed an inline function that is not called.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4514:

// 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

'namespace' : namespace uses itself


A namespace is used recursively.
The following sample generates C4515:

// 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

'class::symbol' : access-declarations are deprecated; member using-declarations provide a better alternative


The ANSI C++ committee has declared access declarations (changing the access of a member in a derived class
without the using keyword) to be outdated. Access declarations may not be supported by future versions of C++.
The following sample generates C4516:

// 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

access-declarations are deprecated; member using-declarations provide a better alternative


The ANSI C++ committee has declared access declarations (changing the access of a member in a derived class
without the using keyword) to be outdated. Access declarations may not be supported by future versions of C++.
Compiler Warning (level 1) C4518
10/31/2018 • 2 minutes to read • Edit Online

'specifier' : storage-class or type specifier(s) unexpected here; ignored


The following sample generates C4518:

// C4518.cpp
// compile with: /c /W1
_declspec(dllexport) extern "C" void MyFunction(); // C4518

extern "C" void MyFunction(); // OK


Compiler Warning (level 3) C4521
10/31/2018 • 2 minutes to read • Edit Online

'class' : multiple copy constructors specified


The class has multiple copy constructors of a single type. This warning is informational; the constructors are
callable in your program.
Use the warning pragma to suppress this warning.

Example
The following sample generates C4521.

// C4521.cpp
// compile with: /EHsc /W3
#include <iostream>

using namespace std;


class A {
public:
A() { cout << "A's default constructor" << endl; }
A( A &o ) { cout << "A&" << endl; }
A( const A &co ) { cout << "const A&" << endl; } // C4521
};

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

'class' : multiple assignment operators specified


The class has multiple assignment operators of a single type. This warning is informational; the constructors are
callable in your program.
Use the warning pragma to suppress this warning.

Example
The following sample generates C4522.

// C4522.cpp
// compile with: /EHsc /W3
#include <iostream>

using namespace std;


class A {
public:
A& operator=( A & o ) { cout << "A&" << endl; return *this; }
A& operator=( const A &co ) { cout << "const A&" << endl; return *this; } // C4522
};

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

'class' : multiple destructors specified


The class has multiple destructors.
Compiler Warning (level 1) C4526
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;
};

struct myStruct2: public myStruct1 {


static void __stdcall func( int );
};

The following are possible fixes:


If the function was intended to override the base class virtual function, remove the static specifier.
If the function was intended to be a static member function, rename it so it doesn't conflict with the base
class virtual function.
Compiler Warning (level 1) C4530
10/31/2018 • 2 minutes to read • Edit Online

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
}

Compile the sample with /EHsc to resolve the warning.


Compiler Warning (level 1) C4532
10/31/2018 • 2 minutes to read • Edit Online

'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

initialization of 'variable' is skipped by 'instruction'


An instruction in your program changed the flow of control, such that, an instruction that initialized a variable was
not executed. The following sample generates C4533:

// 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

calling _set_se_translator() requires /EHa


The use of _set_se_translator requires the /EHa compiler option and not /EHs.

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" );
}
}

void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp ) {


printf_s( "In trans_func.\n" );
throw SE_Exception();
}
Compiler Warning (level 4) C4536
10/31/2018 • 2 minutes to read • Edit Online

'type name' : type-name exceeds meta-data limit of 'limit' characters


A type name would be truncated in metadata if it was a managed type. See C3180 for more information.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Compiler Warning (level 1) C4537
10/31/2018 • 2 minutes to read • Edit Online

'object' : 'operator' applied to non-UDT type

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;
};

void f1(S &s) {


__asm mov eax, s.member; // C4537
// try the following code instead
// or, make the declaration "void f1(S s)"
/*
mov eax, s
mov eax, [eax]s.member
*/
}
Compiler Warning (level 3) C4538
10/31/2018 • 2 minutes to read • Edit Online

'type' : const/volatile qualifiers on this type are not supported


A qualifier keyword was applied to an array incorrectly. For more information, see array.
The following sample generates C4538:

// 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

Injected text suppressed by attribute 'no_injected_text'


The no_injected_text attribute appeared in source code, which means the compiler will prevent attributes from
injecting code.
This warning is to remind you that attributes will not be able to inject code.
Compiler Warning (level 1) C4544
10/31/2018 • 2 minutes to read • Edit Online

'declaration': Default template argument ignored on this template declaration


A default template argument was specified in an incorrect location and was ignored. A default template argument
for a class template can only be specified in the declaration or definition of the class template and not on a member
of the class template.
This sample generates C4545, and the next sample shows how to fix it:

// C4544.cpp
// compile with: /W1 /LD
template <class T>
struct S
{
template <class T1>
struct S1;
void f();
};

template <class T=int>


template <class T1>
struct S<T>::S1 {}; // C4544

In this example, the default parameter applies to class template S :

// C4544b.cpp
// compile with: /LD
template <class T = int>
struct S
{
template <class T1>
struct S1;
void f();
};

template <class T>


template <class T1>
struct S<T>::S1 {};
Compiler Warning (level 1) C4545
10/31/2018 • 2 minutes to read • Edit Online

expression before comma evaluates to a function which is missing an argument list


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 C4545:

// 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

function call before comma missing argument list


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.

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

expression before comma has no effect; expected expression 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 C4548:

// 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

expression evaluates to a function which is missing an argument list


A dereferenced pointer to a function is missing an argument list.

Example
// C4550.cpp
// compile with: /W1
bool f()
{
return true;
}

typedef bool (*pf_t)();

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

function call missing argument list


A function call must include the open and close parentheses after the function name even if the function takes no
parameters.
The following sample generates C4551:

// 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

'operator' : operator has no effect; expected operator with side-effect


If an expression statement has an operator with no side effect as the top of the expression, it's probably a mistake.
To override this warning, put the expression in parentheses.
The following sample generates C4552:

// 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

'operator' : operator has no effect; did you intend 'operator'?


If an expression statement has an operator with no side effect as the top of the expression, it's probably a mistake.
The following sample generates C4553:

// 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

expression has no effect; expected expression with side-effect


This warning informs you when an expression has no effect.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
For example:

// 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

value of intrinsic immediate argument 'value' is out of range 'lowerbound - upperbound'

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

'__assume' contains effect 'effect'


The value passed to an __assume statement2 was modified.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4557:

// 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

value of operand 'value' is out of range 'lowerbound - upperbound'


The value passed to an assembly language instruction is out of the range specified for the parameter. The value will
be truncated.
The following sample generates C4558:

// 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

'function' : redefinition; the function gains __declspec(modifier)

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

'__fastcall' incompatible with the '/clr' option: converting to '__stdcall'


The __fastcall function-calling convention cannot be used with the /clr compiler option. The compiler ignores the
calls to __fastcall . To fix this warning, either remove the calls to __fastcall or compile without /clr.
The following sample generates C4561:

// 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

method 'method' of class 'class' defines unsupported default parameter 'parameter'


The compiler detected a method with one or more parameters with default values. The default value(s) for the
parameters will be ignored when the method is invoked; explicitly specify values for those parameters. If you do
not explicitly specify values for those parameters, the C++ compiler will generate an error.
Given the following .dll created with Visual Basic, which allows default parameters on method arguments:

' 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

'function' : redefinition; the symbol was previously declared with __declspec(modifier)

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

'type' : is not explicitly declared as abstract but has abstract functions


A type that contains abstract functions should itself be marked as abstract.

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

[ParamArray] attribute is deprecated under /clr, use '...' instead


An obsolete style for specifying a variable argument list was used. When compiling for the CLR, use ellipsis syntax
instead of ParamArrayAttribute. For more information, see Variable Argument Lists (...) (C++/CLI).

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

[attribute] is deprecated; instead specify System::Attribute or Platform::Metadata as a base class


[attribute] is no longer the preferred syntax for creating user-defined attributes. For more information, see User-
Defined Attributes. For CLR code, derive attributes from System::Attribute . For Windows Runtime code, derive
attributes from Platform::Metadata .

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;
};

public ref class Attr2 : System::Attribute {


public:
int m_t;
};
Compiler Warning (level 1) C4581
10/31/2018 • 2 minutes to read • Edit Online

deprecated behavior: '"string1"' replaced with 'string2' to process attribute


This error can be generated as a result of compiler conformance work that was done for Visual C++ 2005:
parameter checking for Visual C++ attributes.
In previous versions, attribute values were accepted whether or not they were enclosed in quotation marks. If the
value is an enumeration, it must not be enclosed in quotation marks.

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 {};

[coclass, uuid(12345678-1111-2222-3333-123456789012), threading("free")] // C4581


// try the following line instead
// [coclass, uuid(12345678-1111-2222-3333-123456789012), threading(free)]
class CSample : public IMyI {};
Compiler Warning (level 1) C4584
10/31/2018 • 2 minutes to read • Edit Online

'class1' : base-class 'class2' is already a base-class of 'class3'


The class you defined inherits from two classes, one of which inherits from the other. For example:

// C4584.cpp
// compile with: /W1 /LD
class A {
};

class B : public A {
};

class C : public A, public B { // C4584


};

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) C4612 error in include filename

Compiler warning (level 1) C4613 'symbol': class of segment cannot be changed

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 3) C4648 standard attribute 'carries_dependency' is ignored

Compiler warning (level 3) C4649 attributes are ignored in this context


WARNING MESSAGE

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) C4662 explicit instantiation; template-class 'identifier1' has no


definition from which to specialize 'identifier2'

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) C4670 'identifier': this base class is inaccessible

Compiler warning (level 4) C4671 'identifier': the copy constructor is inaccessible

Compiler warning (level 4) C4672 'identifier1': ambiguous. First seen as 'identifier2'

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 4) C4676 '%s': the destructor is inaccessible

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 1) C4679 'member': could not import member

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 4) C4682 'parameter': no directional parameter attribute specified,


defaulting to [in]

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 1) C4689 '%c': unsupported character in #pragma detect_mismatch;


#pragma ignored

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) C4695 #pragma execution_character_set: 'character set' is not a


supported argument: currently only 'UTF-8' is supported

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) C4702 unreachable code

Compiler Warning (level 4) C4703 potentially uninitialized local pointer variable '%s' used

Compiler Warning (level 4) C4706 assignment within conditional expression

Compiler Warning (level 4) C4709 comma operator within array index expression

Compiler Warning (level 4) C4710 'function': function not inlined

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, Error) C4716 'function': must 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 2) C4720 in-line assembler reports: 'message'

Compiler warning (level 1) C4721 'function': not available as an intrinsic

Compiler warning (level 1) C4722 'function': destructor never returns, potential memory leak

Compiler Warning (level 3) C4723 potential divide by 0

Compiler warning (level 3) C4724 potential mod by 0

Compiler warning (level 3) C4725 instruction may be inaccurate on some Pentiums

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 C4746 volatile access of 'expression' is subject to /volatile:<iso|ms>


setting; consider using __iso_volatile_load/store intrinsic
functions

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 4) C4749 conditionally supported: offsetof applied to non-standard-


layout type 'type'

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 2) C4756 overflow in constant arithmetic

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 C4770 partially validated enum 'name' used as index

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 3) C4778 'function' : unterminated format string 'string'

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 and 3) C4793 'function': function compiled as native:\n\t'reason'

Compiler warning (level 1) C4794 segment of thread local storage variable '%s' changed from
'%s' to '%s'

Compiler Warning (level 1) C4799 function 'function' has no EMMS instruction


Compiler Warning (level 1) C4600
10/31/2018 • 2 minutes to read • Edit Online

#pragma 'macro name' : expected a valid non-empty string


You cannot specify an empty string when you push or pop a macro name with either the pop_macro or
push_macro.
The following sample generates C4600:

// 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

object 'class' can never be instantiated - user-defined constructor required


The class has no user-defined or default constructors. No instantiation is performed. The following sample
generates C4610:

// C4610.cpp
// compile with: /W4
struct A {
int &j;

A& A::operator=( const A& );


}; // C4610

/* use this structure definition to resolve the warning


struct B {
int &k;

B(int i = 0) : k(i) {
}

B& B::operator=( const B& );


} b;
*/

int main() {
}
Compiler Warning (level 4) C4611
10/31/2018 • 2 minutes to read • Edit Online

interaction between 'function' and C++ object destruction is non-portable


On some platforms, functions that include catch may not support C++ object semantics of destruction when out
of scope.
To avoid unexpected behavior, avoid using catch in functions that have constructors and destructors.
This warning is only issued once; see pragma warning.
Compiler Warning (level 1) C4612
10/31/2018 • 2 minutes to read • Edit Online

error in include filename

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

'segment' : class of segment cannot be changed


You tried to create a segment with the same class name as a segment used by the compiler. No new segment class
was created.
Compiler Warning (level 1) C4615
10/31/2018 • 2 minutes to read • Edit Online

#pragma warning : unknown user warning type


An invalid warning specifier was used with pragma warning. To resolve the error, use a valid warning specifier.
The following sample generates C4615:

// C4615.cpp
// compile with: /W1 /LD
#pragma warning(enable : 4401) // C4615, 'enable' not valid specifier

// use the code below to resolve the error


// #pragma warning(default : 4401)
Compiler Warning (level 1) C4616
10/31/2018 • 2 minutes to read • Edit Online

#pragma warning : warning number 'number' not a valid compiler warning


The warning number specified in the warning pragma cannot be reassigned. The pragma was ignored.
The following sample generates C4616:

// 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

pragma parameters included an empty string; pragma ignored


A null string was given as an argument to a #pragma.
The pragma was processed without the argument.
The following sample generates C4618:

// C4618.cpp
// compile with: /W1 /LD
#pragma code_seg("") // C4618
Compiler Warning (level 3) C4619
10/31/2018 • 2 minutes to read • Edit Online

#pragma warning : there is no warning number 'number'


An attempt was made to disable a warning that does not exist.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4619:

// 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();
};

class D : public B {}; // C4623 - to fix, make B's constructor public


class E : public C {}; // OK - class C constructor is public

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();
};

class D : public B {}; // C4624 B's destructor not public


Compiler Warning (level 4) C4625
10/31/2018 • 2 minutes to read • Edit Online

'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 C : private virtual A {};


struct B : C {}; // C4625 no copy constructor

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
{

}; // C4626 - to fix, make B's copy constructor public

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

'header_file': skipped when looking for precompiled header use

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

'symbol' : 'extern' storage class specifier illegal on member definition


A data member or member function is defined as extern . Members cannot be external, although entire objects
can. The compiler ignores the extern keyword. The following sample generates C4630:

// C4630.cpp
// compile with: /W1 /LD
class A {
void func();
};

extern void A::func() { // C4630, remove 'extern' to resolve


}
Compiler Warning (level 1) C4631
10/31/2018 • 2 minutes to read • Edit Online

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

XML document comment: file - access denied: reason


The path to .xdc file ( file ) was not valid, and no .xdc file created.
The following sample generates C4632:

// C4632.cpp
// compile with: /clr /docv:\\falsedir /LD /W1
// C4632 expected

/// Text for class MyClass.


public ref class MyClass {};
Compiler Warning (level 3) C4633
3/12/2019 • 2 minutes to read • Edit Online

XML document comment target: error: reason


A name passed to the <param> tag was not found by the compiler.
The following sample generates C4633:

// C4633.cpp
// compile with: /clr /doc /LD /W3

/// Text for class MyClass.


public ref class MyClass {
// C4633 remove line for Int3
/// <param name="Int1">Used to indicate status.</param>
/// <param name="Int3">Used to indicate status.</param>
void MyMethod(int Int1) {
Int1 = 0;
Int1++;
}
};
Compiler Warning (level 4) C4634
3/12/2019 • 2 minutes to read • Edit Online

XML document comment: cannot be applied: reason


XML documentation tags can not be applied to all C++ constructs. For example, you cannot add a documentation
comment to a namespace or template.
For more information, see XML Documentation.

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

XML document comment target: badly-formed XML: reason


The compiler found some problem with the XML tags. Fix the problem and recompile
The following sample generates C4635:

// C4635.cpp
// compile with: /doc /clr /W3 /c
/// <summary>
/// The contents of the folder have changed.
/// <summary/> // C4635

// try the following line instead


// /// </summary>
public ref class Test {};

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

XML document comment target: <include> tag discarded. reason


The syntax of an <include> tag was not correct.
The following sample generates C4637:

// C4637.cpp
// compile with: /clr /doc /LD /W3
using namespace System;

/// Text for class MyClass.


public ref class MyClass {
public:
/// <include file="c:\davedata\jtest\xml_include.doc"/>
// Try the following line instead:
// /// <include file='xml_include.doc' path='MyDocs/MyMembers/*' />
void MyMethod() {
}
}; // C4637
Compiler Warning (level 3) C4638
10/31/2018 • 2 minutes to read • Edit Online

XML document comment target: reference to unknown symbol 'symbol'

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;

/// Text for class MyClass.


public ref class MyClass {
public:
/// <summary> Text </summary>
/// <see cref="aSymbolThatAppearsNowhereInMyProject"/>
// Try the following line instead:
// /// <see cref="System::Console::WriteLine"/>
void MyMethod() {}
}; // C4638
Compiler Warning (level 4) C4639
10/31/2018 • 2 minutes to read • Edit Online

MSXML error, XML document comments will not be processed. reason


This warning can occur for any number of reasons.
To resolve this warning:
Recompile.
Reinstall MSXML by reinstalling the common language runtime.
Edit or remove the documentation comment that is causing the warning and recompile.
When C4639 is issued, all further XML comment processing is disabled, and the .xdc file is not generated.
Compiler Warning (level 3) C4640
10/31/2018 • 2 minutes to read • Edit Online

'instance' : construction of local static object is not thread-safe


A static instance of an object is not thread safe.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4640:

// 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

XML document comment has an ambiguous cross reference


The compiler was unable to unambiguously resolve a reference. To resolve this warning, specify the parameter
information necessary to make the reference unambiguous.
For more information, see XML Documentation.

Example
The following sample generates C4641.

// C4641.cpp
// compile with: /W3 /doc /clr /c

/// <see cref="f" /> // C4641


// try the following line instead
// /// <see cref="f(int)" />
public ref class GR {
public:
void f( int ) {}
void f( char ) {}
};
Compiler Warning (level 3) C4645
10/31/2018 • 2 minutes to read • Edit Online

function declared with __declspec(noreturn) has a return statement


A return statement was found in a function that is marked with the noreturn __declspec modifier. The return
statement was ignored.
The following sample generates C4645:

// 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

function declared with __declspec(noreturn) has non-void return type


A function marked with the noreturn __declspec modifier should have a void return type.
The following sample generates C4646:

// 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

'identifier' : no suitable definition provided for explicit template instantiation request


A member of the template class is not defined.

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

'function' : no function template defined that matches forced instantiation


You cannot instantiate a function template that has not been declared.
The following sample will cause C4667:

// C4667a.cpp
// compile with: /LD /W1
template
void max(const int &, const int &); // C4667 expected

To avoid this warning, first declare the function template:

// 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>

#pragma warning (default : 4668) // turn warning on

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

'cast' : unsafe conversion: 'class' is a managed or WinRT type object


A cast contains a Windows Runtime or managed type. The compiler completes the cast by performing a bit-wise
copy of one pointer to the other, but provides no other checking. To resolve this warning, do not cast classes
containing managed members or Windows Runtime types.
The following sample generates C4669 and shows how to fix it:

// 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

'identifier' : this base class is inaccessible


The specified base class of an object to be thrown in a try block is not accessible. The object cannot be instantiated
if it is thrown. Check that the base class is inherited with the correct access specifier.
The following sample generates C4670:

// 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

'identifier1' : ambiguous. First seen as 'identifier2'


The specified object to be thrown in a try block is ambiguous. The object cannot be disambiguated if it is thrown.
Compiler Warning (level 4) C4673
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;
}
};

class Derv : private Base {


public:
Derv() {}
~Derv() {}
};

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

'method' should be declared 'static' and have exactly one parameter


The signature of a conversion operator was not correct. The method is not considered a user-defined conversion.
For more information on defining operators, see User-Defined Operators (C++/CLI) and User-Defined
Conversions (C++/CLI).

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

'function': signature of non-private member contains assembly private type 'private_type'


A type that has public accessibility outside the assembly uses a type that has private access outside the assembly. A
component that references the public assembly type will not be able to use the type member or members that
reference the assembly private type.

Example
The following sample generates C4677.

// C4677.cpp
// compile with: /clr /c /W1
delegate void TestDel();
public delegate void TestDel2();

public ref class MyClass {


public:
static event TestDel^ MyClass_Event; // C4677
static event TestDel2^ MyClass_Event2; // OK
};
Compiler Warning (level 1) C4678
10/31/2018 • 2 minutes to read • Edit Online

base class 'base_type' is less accessible than 'derived_type'


A public type derives from a private type. If the public type is instantiated in a referenced assembly, members of the
private base type will not be accessible.
C4678 is only reachable using the obsolete compiler option /clr:oldSyntax. It is an error when using /clr, to have
a base class that is less accessible that its derived class.
Compiler Warning (level 1) C4679
10/31/2018 • 2 minutes to read • Edit Online

'member' : could not import member

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

'class' : coclass does not specify a default interface


A default interface was not specified for a class that was marked with the coclass attribute. In order for an object to
be useful, it must implement an interface.
The following sample generates C4680:

// 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();
};

// to resolve C4680, specify a source interface also


// for example, default(IMyIface1, IMyface2)
[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f), default(IMyIface1), source(IMyIface1) ]
class CMyClass : public IMyIface1
{ // C4680
};

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

'parameter' : no directional parameter attribute specified, defaulting to [in]


A method on a parameter in an attributed interface does not have one of the directional attributes: in or out. The
parameter defaults to in.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4682:

// C4682.cpp
// compile with: /W4
#pragma warning(default : 4682)
#include <windows.h>
[module(name="MyModule")];

[ library_block, object, uuid("c54ad59d-d516-41dd-9acd-afda17565c2b") ]


__interface IMyIface : IUnknown
{
HRESULT f1(int i, int *pi); // C4682
// try the following line
// HRESULT f1([in] int i, [in] int *pi);
};

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

expecting '> >' found '>>' when parsing template parameters


A template definition was not terminated correctly.
Compiler Warning (level 3) C4686
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;

template <class T>


C<T> f(T);

template <class T>


class C {};

int main() {
f(1); // C4686
}

template <class T>


C<T> f(T) {
return C<int>();
}
Compiler Warning C4687
10/31/2018 • 2 minutes to read • Edit Online

'class': a sealed abstract class cannot implement an interface 'interface'


A sealed, abstract type is typically only useful to hold static member functions.
For more information, see abstractand sealed.
C4687 is issued as an error by default. You can suppress C4687 with the warning pragma. If you are certain that
you want to implement an interface in a sealed, abstract type, you can suppress C4687.

Example
The following sample generates C4687.

// C4687.cpp
// compile with: /clr /c
interface class A {};

ref struct B sealed abstract : A {}; // C4687


ref struct C sealed : A {}; // OK
ref struct D abstract : A {}; // OK
Compiler Warning (level 1) C4688
10/31/2018 • 2 minutes to read • Edit Online

'constraint': constraint list contains assembly private type 'type'


A constraint list has an assembly private type, meaning it will not be available when the type is accessed from
outside the assembly. For more information, see Generics.

Example
The following sample generates C4688.

// C4688.cpp
// compile with: /clr /c /W1
ref struct A {}; // private type
public ref struct B {};

// Delete the following 3 lines to resolve.


generic <class T>
where T : A // C4688
public ref struct M {};

generic <class T>


where T : B
public ref struct N {};
Compiler Warning (level 4) C4690
10/31/2018 • 2 minutes to read • Edit Online

[ emitidl( pop ) ] : more pops than pushes

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

// Uncomment the following line to resolve.


// #using "C4691_a.dll"
#using "C4691_b.dll"

// Delete the following line to resolve.


ref class Original_Type;

public ref class MyClass : Client {};


Compiler Warning (level 1) C4692
10/31/2018 • 2 minutes to read • Edit Online

'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

'class': a sealed abstract class cannot have a base-class 'base_class'

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

uninitialized local variable 'name' used

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>

// function takes an int reference to initialize


void initialize(int& i)
{
i = 21;
}

int main()
{
int s, t, u, v; // Danger, uninitialized variables

s = t + u + v; // C4700: t, u, v used before initialization


std::cout << "Value in s: " << s << std::endl;

int w, x; // Danger, uninitialized variables


initialize(x); // fix: call function to init x before use
int y{10}; // fix: initialize y, z when declared
int z{11}; // This C++11 syntax is recommended over int z = 11;

w = x + y + z; // Okay, all values initialized before use


std::cout << "Value in w: " << w << std::endl;
}

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

Potentially uninitialized local variable 'name' used


The local variable name might have been used without being assigned a value. This could lead to unpredictable
results.

Example
The following code generates C4701 and C4703.

#include <malloc.h>

void func(int size)


{
void* p;
if (size < 256) {
p = malloc(size);
}

if (p != nullptr) // C4701 and C4703


free(p);
}

void main()
{
func(9);
}

c:\src\test.cpp(10) : warning C4701: potentially uninitialized local variable 'p' used


c:\src\test.cpp(10) : warning C4703: potentially uninitialized local pointer variable 'p' used

To correct this warning, initialize the variable as shown in this example:

#include <malloc.h>

void func(int size)


{
void* p = nullptr;
if (size < 256) {
p = malloc(size);
}

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>

using namespace std;


extern "C" __declspec(dllexport) void Function2(){}

int main() {
try {
Function2();
}
catch (...) {
cout << "Exp: Function2!" << endl; // C4702
}
}
Compiler Warning (level 4) C4703
11/9/2018 • 2 minutes to read • Edit Online

Potentially uninitialized local pointer variable 'name' used


The local pointer variable name might have been used without being assigned a value. This could lead to
unpredictable results.

Example
The following code generates C4701 and C4703.

#include <malloc.h>

void func(int size)


{
void* p;
if (size < 256) {
p = malloc(size);
}

if (p != nullptr) // C4701 and C4703


free(p);
}

void main()
{
func(9);
}

c:\src\test.cpp(10) : warning C4701: potentially uninitialized local variable 'p' used


c:\src\test.cpp(10) : warning C4703: potentially uninitialized local pointer variable 'p' used

To correct this warning, initialize the variable as shown in this example:

#include <malloc.h>

void func(int size)


{
void* p = nullptr;
if (size < 256) {
p = malloc(size);
}

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

assignment within conditional expression


The test value in a conditional expression was the result of an assignment.
An assignment has a value (the value on the left side of the assignment) that can be used legally in another
expression, including a test expression.
The following sample generates C4706:

// 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

comma operator within array index expression


When a comma occurs in an array index expression, the compiler uses the value after the last comma.

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;

// Prints 10, not 11


printf_s("\n%d",arr[0][1,0]); // C4709
}
Compiler Warning (level 4) C4710
10/31/2018 • 2 minutes to read • Edit Online

'function' : function not inlined


The given function was selected for inline expansion, but the compiler did not perform the inlining.
Inlining is performed at the compiler's discretion. The inline keyword, like the register keyword, is used as a hint
for the compiler. The compiler uses heuristics to determine if it should inline a particular function to speed up the
code when compiling for speed, or if it should inline a particular function to make the code smaller when compiling
for space. The compiler will only inline very small functions when compiling for space.
In some cases, the compiler will not inline a particular function for mechanical reasons. See C4714 for a list of
reasons the compiler may not inline a function.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Compiler Warning (level 1) C4711
10/31/2018 • 2 minutes to read • Edit Online

function 'function' selected for inline expansion


The compiler performed inlining on the given function, although it was not marked for inlining.
C4711 is enabled if /Ob2 is specified.
Inlining is performed at the compiler's discretion. This warning is informational.
This warning is off by default. To enable a warning, use #pragma warning. See Compiler Warnings That Are Off by
Default for more information.
Compiler Warning (level 4) C4714
10/31/2018 • 2 minutes to read • Edit Online

function 'function' marked as __forceinline not inlined


The given function was selected for inline expansion, but the compiler did not perform the inlining.
Although __forceinline is a stronger indication to the compiler than __inline , inlining is still performed at the
compiler's discretion, but no heuristics are used to determine the benefits from inlining this function.
In some cases, the compiler will not inline a particular function for mechanical reasons. For example, the compiler
will not inline:
A function if it would result in mixing both SEH and C++ EH.
Some functions with copy constructed objects passed by value when -GX/EHs/EHa is on.
Functions returning an unwindable object by value when -GX/EHs/EHa is on.
Functions with inline assembly when compiling without -Og/Ox/O1/O2.
Functions with a variable argument list.
A function with a try (C++ exception handling) statement.
The following sample generates C4714:

// 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

'function' : not all control paths return a value


The specified function can potentially not return a value.

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

'function' must return a value


The given function did not return a value.
Only functions with a return type of void can use the return command without an accompanying return value.
An undefined value will be returned when this function is called.
This warning is automatically promoted to an error. If you wish to modify this behavior, use#pragma warning.
The following sample generates C4716:

// 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

'function call' : recursive call has no side effects, deleting


A function contains a recursive call, but otherwise has no side effects. A call to this function is being deleted. The
correctness of the program is not affected, but the behavior is. Whereas leaving the call in could result in a runtime
stack overflow exception, deleting the call removes that possibility.
Compiler Warning (level 1) C4722
10/31/2018 • 2 minutes to read • Edit Online

'function' : destructor never returns, potential memory leak


The flow of control terminates in a destructor. The thread or the entire program will terminate and allocated
resources may not be released. Furthermore, if a destructor will be called for stack unwinding during exception
processing, the behavior of executable is undefined.
To resolve, remove the function call that causes the destructor to not return.

Example
The following sample generates C4722:

// C4722.cpp
// compile with: /O1 /W1 /c
#include <stdlib.h>
class C {
public:
C();
~C() { exit(1); }; // C4722
};

extern void func (C*);

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

instruction may be inaccurate on some Pentiums


Your code contains an inline assembly instruction that may not produce accurate results on some Pentium
microprocessors.
The following sample generates C4725:

// 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

function too big for flow graph based warnings


This warning is generated when a function is too big to be compiled with reliable checking for situations that would
generate a warning. This warning is only generated when the /Od compiler option used.
To resolve this warning, break the function into smaller functions.
Compiler Warning (Level 1) C4730
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)
{
}

int main(__m64 a, __m64 b)


{
__m64 m;
double f;
f = 1.0;
m = _m_paddb(a, b);
// uncomment the next line to resolve C4730
// _m_empty();
func(f * 3.0); // C4730
}
Compiler Warning (Level 1) C4731
10/31/2018 • 2 minutes to read • Edit Online

'pointer' : frame pointer register 'register' modified by inline assembly code


A frame pointer register was modified. You must save and restore the register in your inline assembly block or
frame variable (local or parameter, depending on the register modified), or your code may not work properly.
The following sample generates C4731:

// 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

Inline asm assigning to 'FS:0' : handler not registered as safe handler


A function modifying the value at FS:0 to add a new exception handler may not work with Safe Exceptions,
because the handler may not be registered as a valid exception handler (see /SAFESEH).
To resolve this warning, either remove the FS:0 definition or turn off this warning and use .SAFESEH to specify the
safe exception handlers.
The following sample generates C4733:

// 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

storing 32-bit float result in memory, possible loss of performance


C4738 warns that the result of an assignment, cast, passed argument, or other operation may need to be rounded
or that the operation ran out of registers and needed to use memory (spilling). This can result in performance loss.
To resolve this warning and avoid rounding, compile with /fp:fast or use double instead of float .
To resolve this warning and avoid running out of registers, change the order of computation and modify your use
of inlining
This warning is off by default. For more information, see Compiler Warnings That Are Off by Default.

Example
The following sample generates C4738:

// C4738.cpp
// compile with: /c /fp:precise /O2 /W3
// processor: x86
#include <stdio.h>

#pragma warning(default : 4738)

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

reference to variable 'var' exceeds its storage space


A value was assigned to a variable, but the value is greater than the size of the variable. Memory will be written
beyond the variable's memory location, and data loss is possible.
To resolve this warning, only assign a value to a variable whose size can accommodate the value.
The following sample generates C4739:

// 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

flow in or out of inline asm code suppresses global optimization


When there is a jump in to or out of an asm block, global optimizations are disabled for that function.
The following sample generates C4740:

// 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>

extern unsigned global;

main()
{
printf_s("%d\n", global);
}
Compiler Warning C4746
10/31/2018 • 2 minutes to read • Edit Online

volatile access of '<expression>' is subject to /volatile:[iso|ms] setting; consider using __iso_volatile_load/store


intrinsic functions.
C4746 is emitted whenever a volatile variable is accessed directly. It is intended to help developers identify code
locations that are affected by the specific volatile model currently specified (which can be controlled with the
/volatile compiler option). In particular, it can be useful in locating compiler-generated hardware memory barriers
when /volatile:ms is used.
The __iso_volatile_load/store intrinsics can be used to explicitly access volatile memory without being affected by
the volatile model. Using these intrinsics will not trigger C4746.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
Compiler Warning (level 1) C4747
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>

// Uncomment the following line to resolve.


// #pragma unmanaged

BOOL WINAPI DllMain(HANDLE hInstance, ULONG Command, LPVOID Reserved) {


return TRUE;
};
Compiler Warning (level 1) C4750
10/31/2018 • 2 minutes to read • Edit Online

'identifier': function with _alloca() inlined into a loop


The 'identifier' function forces inline expansion of the _alloca function within a loop, which might cause a stack
overflow when the loop is executed.
To correct this error
1. Ensure that the 'identifier' function is not modified with the __forceinline specifier.
2. Ensure that the 'identifier' function does not contain a _alloca function that is contained in a loop.
3. Do not specify the /O1, /O2, /Ox, or /Og compilation switch.
4. Place the _alloca function in a try-except statement that will catch a stack overflow.

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>

char * volatile newstr;

__forceinline void myFunction(void) // C4750 warning


{
// The _alloca function does not require a __try/__except
// block because the example uses compiler option /c.
newstr = (char * volatile) _alloca(1000);
}

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"

int sum_overflow(unsigned long a, unsigned long b)


{
unsigned long long x = a + b; // C4754

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:

// Casting one operand is sufficient to force all the operands in


// the addition be upcast according to C/C++ conversion rules, but
// casting both is clearer.
unsigned long long x =
(unsigned long long)a + (unsigned long long)b;

Example
The next sample also generates C4754.
// C4754b.cpp
// Compile with: /W4 /c
#include "errno.h"

int wrap_overflow(unsigned long a)


{
if (a + sizeof(unsigned long) < a) // C4754
{
// never executes!
return EOVERFLOW;
}
return 0;
}

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:

// Casting the result of sizeof() to unsigned long ensures


// that all the addition operands are 32-bit, so any overflow
// is detected by the check.
if (a + (unsigned long)sizeof(unsigned long) < a)

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;

if (a + sizeof(unsigned long) < a || // incorrect check


condition1() ||
a == 0) { // C4754 warning reported on this line
// never executes!
return INVALID_PARAMETER;
}
Compiler Warning (level 2) C4756
10/31/2018 • 2 minutes to read • Edit Online

overflow in constant arithmetic


The compiler generated an exception while doing constant arithmetic during compilation.
The following sample generates C4756:

// 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

Cannot align catch objects to greater than 16 bytes


An alignment greater than 16 was specified, but on some platforms, if the function throws an exception, the stack
will force an alignment of not greater than 16.

Example
The following sample generates C4764:

// C4764.cpp
// compile with: /W4 /EHsc
// processor: x64 IPF
#include <stdio.h>

class A
{
public:
int x;
};

typedef __declspec(align(32)) A ALIGNEDA;

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
};
};

This is the second type library needed to reproduce C4772.

// 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;
};
};

The following sample generates C4772:

// 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

'identifier' : identifier was truncated to 'number' characters


The compiler limits the maximum length allowed for a function name. When the compiler generates funclets for
EH/SEH code, it forms the funclet name by prepending the function name with some text, for example "__catch",
"__unwind", or another string.
The resulting funclet name can be too long, and the compiler will truncate it and generate C4788.
To resolve this warning, shorten the original function name. If the function is a C++ template function or method,
use a typedef for part of the name. For example:

C1<x, y, z<T>>::C2<a,b,c>::f

can be replaced by:

typedef C1<x, y, z<T>>::C2<a,b,c> new_class ;


new_class::f

This warning only occurs in the x64 compiler.


Compiler Warning (Level 1) C4789
10/31/2018 • 2 minutes to read • Edit Online

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() {}

// Uncomment the following line to resolve.


// #pragma warning(disable : 4792)
#pragma unmanaged
void func(void){
puts("test");
}
Compiler Warning (level 1 and 3) C4793
10/31/2018 • 2 minutes to read • Edit Online

'function' : function is compiled as native code: 'reason'

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.

REASON MESSAGE REMARKS

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
}
}

warning C4793: 'asmfunc' : function is compiled as native code:


Inline native assembly ('__asm') is not supported in managed code

The following sample generates C4793.

// C4793_b.cpp
// compile with: /c /clr /W3
#include <setjmp.h>
jmp_buf test_buf;

void f() {
setjmp(test_buf); // C4793 warning
}

warning C4793: 'f' : function is compiled as native code:


A function using '_setjmp' must be compiled as native
Compiler Warning (level 1) C4794
10/31/2018 • 2 minutes to read • Edit Online

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

No EMMS at end of function 'function'

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) C4810 value of pragma pack(show) == n

Compiler warning (level 1) C4811 value of pragma conform(forScope, show) == value

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 4) C4837 trigraph detected: '??character' replaced by 'character'


WARNING MESSAGE

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 C4843 'type1': An exception handler of reference to array or function


type is unreachable, use 'type2' instead

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) C4905 wide string literal cast to 'LPSTR'

Compiler Warning (level 1) C4906 string literal cast to 'LPWSTR'

Compiler warning (level 1) C4910 '<identifier>: '__declspec(dllexport)' and 'extern' are


incompatible on an explicit instantiation
WARNING MESSAGE

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 4) C4932 __identifier(identifier) and __identifier(identifier) are


indistinguishable

Compiler warning (level 1) C4934 '__delegate(multicast)' is deprecated, use '__delegate' instead

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 C4939 #pragma vtordisp is deprecated and will be removed in a


future release of Visual C++

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 1) C4947 'type_or_member': marked as obsolete

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, Error) C4950 'type_or_member': marked as obsolete

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 4) C4960 'function' is too big to be profiled

Compiler warning (level 1) C4961 No profile data was merged into '.pgd file', profile-guided
optimizations disabled

Compiler warning (level 4) C4962 'function': Profile-guided optimizations disabled because


optimizations caused profile data to become inconsistent
WARNING MESSAGE

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 1) C4973 'symbol': marked as deprecated

Compiler warning (level 1) C4974 'symbol': marked as deprecated

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) C4987 nonstandard extension used: 'throw (...)'

Compiler warning (level 4) C4988 'variable': variable declared outside class/function scope

Compiler warning (level 4) C4989 'type': type has conflicting definitions.

Compiler warning (level 3) C4990 Warbird: message

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 3) C4996 'description': message

Compiler warning (level 1) C4997 'class': coclass does not implement a COM interface or
pseudo-interface
WARNING MESSAGE

Compiler warning (level 1) C4998 EXPECTATION FAILED: expectation(value)

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 C5022 'type': multiple move constructors specified

Compiler warning C5023 'type': multiple move assignment operators specified

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 3) C5030 attribute 'attribute' is not recognized

Compiler warning (level 4) C5031 #pragma warning(pop): likely mismatch, popping warning
state pushed in different file

Compiler warning (level 4) C5032 detected #pragma warning(push) with no corresponding


#pragma warning(pop)

Compiler warning (level 1) C5033 'storage-class' is no longer a supported storage class

Compiler warning C5034 use of intrinsic 'intrinsic' causes function function to be


compiled as guest code

Compiler warning C5035 use of feature 'feature' causes function function to be


compiled as guest code

Compiler warning (level 1) C5036 varargs function pointer conversion when compiling with
/hybrid:x86arm64 'type1' to 'type2'

Compiler warning (error) C5037 'member-function': an out-of-line definition of a member of a


class template cannot have default arguments

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

'type' : forcing value to bool 'true' or 'false' (performance warning)

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;

// To fix, instead try:


// bool 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;

public delegate void Del();

ref struct E {
Del ^ _pd1;
event Del ^ E1 {
void add (Del ^ pd1) {
_pd1 = dynamic_cast<Del ^>(Delegate::Combine(_pd1, pd1));
}

void remove(Del^ pd1) {


_pd1 = dynamic_cast<Del^> (Delegate::Remove(_pd1, pd1));
}

virtual void raise() { // C4803 warning (remove virtual)


if (_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

'operation' : unsafe use of type 'bool' in operation


This warning is for when you used a bool variable or value in an unexpected way. For example, C4804 is
generated if you use operators such as the negative unary operator (-) or the complement operator ( ~ ). The
compiler evaluates the expression.

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

'operation' : unsafe mix of type 'type' and type 'type' in operation


This warning is generated for comparison operations between bool and int. The following sample generates
C4805:

// C4805.cpp
// compile with: /W1
int main() {
int i = 1;
bool b = true;

if (i == b) { // C4805, comparing bool and int variables


}
}
Compiler Warning (level 1) C4806
10/31/2018 • 2 minutes to read • Edit Online

'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

value of pragma pack(show ) == n


This warning is issued when you use the show option of the pack pragma. n is the current pack value.
For example, the following code shows how the C4810 warning works with the pack pragma:

// 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

value of pragma conform(forScope, show ) == value


This warning is issued when you use the show option of the conform pragma. value is the current conform value.
Compiler Warning (level 1) C4812
10/31/2018 • 2 minutes to read • Edit Online

obsolete declaration style: please use 'new_syntax' instead


In the current release of Visual C++, the explicit constructor specialization is still supported, but it may not be
supported in a future release.
The following sample generates C4812:

// 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>

extern "C" int printf_s(const char *, ...);

#pragma warning(disable : 4200)

struct S1
{
int i;
char cArr[];
};

void TestErr(S1 s1) // C4816 param with zero-array


// not passed by reference
{
printf_s("%d %c %c\n", s1.i, s1.cArr[0], s1.cArr[1]);
}

void TestOk(S1 &s1)


{
printf_s("%d %c %c\n", s1.i, s1.cArr[0], s1.cArr[1]);
}

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

'bytes' bytes padding added after construct 'member_name'


The type and order of elements caused the compiler to add padding to the end of a struct. See align for more
information on padding in a struct.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.
The following sample generates C4820:

// C4820.cpp
// compile with: /W4 /c
#pragma warning(default : 4820)

// Delete the following 4 lines to resolve.


__declspec(align(2)) struct MyStruct {
char a;
int i; // C4820
};

// 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

'member' : local class member function does not have a body


A local class member function was declared but not defined in class. To use a local class member function, you
must define it in the class. You cannot declare it in class and define it out of class.
Any out-of-class definition for a local class member function will be an error.
The following sample generates C4822:

// 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;
};

void f(G ^ pG) {


try {
pin_ptr<int> p = &pG->m;
// manually unpin, ignore warning
// p = nullptr;
throw gcnew Exception;
}
catch(Exception ^) {}
} // C4823 warning

int main() {
f( gcnew G );
}
Compiler Warning (level 1) C4829
11/9/2018 • 2 minutes to read • Edit Online

Possibly incorrect parameters to function main. Consider 'intmain(Platform::Array<Platform::String^>^ argv)'


Certain functions, such as main, cannot take reference type parameters. While compilation will succeed, the
resulting image will probably not run.
The following sample generates C4829:

// 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;

__declspec(dllexport) int m = f(); // C4835


__declspec(dllexport) int *p = &n; // C4835

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

conversion from 'type_1' to 'type_2' requires a narrowing conversion


An implicit narrowing conversion was found when using aggregate or list initialization.
The C language allows implicit narrowing conversions in assignments and initialization, and C++ follows suit,
even though unexpected narrowing is a cause of many code errors. To make code safer, the C++ standard requires
a diagnostic message when a narrowing conversion occurs in an initialization list. In Visual C++, the diagnostic is
Compiler Error C2397 when using the uniform initialization syntax supported beginning in Visual Studio 2015.
The compiler generates warning C4838 when using the list or aggregate initialization syntax supported by Visual
Studio 2013.
A narrowing conversion can be okay when you know the possible range of converted values can fit in the target. In
this case, you know more than the compiler does. If you make a narrowing conversion intentionally, make your
intentions explicit by using a static cast. Otherwise, this warning message almost always indicates that you have a
bug in your code. You can fix it by making sure the objects you initialize have types that are large enough to handle
the inputs.
The following sample generates C4838 and shows one way to fix it:

// C4838.cpp -- C++ narrowing conversion diagnostics


// Compile by using: cl /EHsc C4838.cpp

struct S1 {
int m1;
double m2, m3;
};

void function_C4838(double d1) {


double ad[] = { 1, d1 }; // OK
int ai[] = { 1, d1 }; // warning C4838
S1 s11 = { 1, 2, d1 }; // OK
S1 s12 { d1, 2, 3 }; // warning C4838
S1 s13 { static_cast<int>(d1), 2, 3 }; // possible fix for C4838
}
Compiler Warning (level 3) C4839
10/31/2018 • 2 minutes to read • Edit Online

non-standard use of class 'type' as an argument to a variadic function

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

non-portable use of class 'type' as an argument to a variadic function

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);

printf("%i\n", s); // warning C4840 : non-portable use of class 'main::S'


// as an argument to a variadic function
// To correct the error, you can perform a static cast
// to convert the object before passing it:
printf("%i\n", static_cast<int>(s));
}

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 operator->*(HasCopyConstructor a, HasCopyConstructor b) { return a.x + b.x; }

// This version of operator->* does not trigger the warning:


// int operator->*(const HasCopyConstructor& a, const HasCopyConstructor& b) { return a.x + b.x; }

int main()
{
HasCopyConstructor a{ 1 };
HasCopyConstructor b{ 2 };

a->*b; // C4866 for call to operator->*


};
Compiler Warning C4867
10/31/2018 • 2 minutes to read • Edit Online

'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) {}

typedef void (A::*TAmtd)(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;

HasCopyConstructor(int x): x(x) {}

HasCopyConstructor(const HasCopyConstructor& h): x(h.x)


{
printf("Constructing %d\n", h.x);
}
};

class TripWarning4868
{
public:
// note that taking "HasCopyConstructor" parameters by-value will trigger copy-construction.
TripWarning4868(HasCopyConstructor a, HasCopyConstructor b) {}

// This variation will not trigger the warning:


// TripWarning4868(const HasCopyConstructor& a, const 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

wide string literal cast to 'LPSTR'


The compiler detected an unsafe cast. The cast did succeed, but you should use a conversion routine.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

// try the following lines instead


// wchar_t y[128];
// size_t sizeOfConverted;
// errcode err = 0;
//
// err = mbstowcs_s(&sizeOfConverted, &y[0], 128, "12345", 4);
// if (err != 0)
// {
// printf_s("mbstowcs_s failed!");
// exit (-1);
// }
// wprintf(L"%s\n", y);

return 0;
}
Compiler Warning (level 1) C4906
10/31/2018 • 2 minutes to read • Edit Online

string literal cast to 'LPWSTR'


The compiler detected an unsafe cast. The cast did succeed, but you should use a conversion routine.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

// try the following lines instead


// char y[128];
// size_t numberOfCharConverted = 0;
// errcode err = 0;
// err = wcstombs_s(&numberOfCharConverted , &y[0], 128,
// L"12345", 4);
// if (err != 0)
// {
// printf_s("wcstombs_s failed!");
// return -1;
// }
// printf_s("%s\n", y);

return 0;
}
Compiler Warning (level 1) C4910
10/31/2018 • 2 minutes to read • Edit Online

'<identifier>' : '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation


The explicit template instantiation named <identifier> is modified by both the __declspec(dllexport) and extern
keywords. However, these keywords are mutually exclusive. The __declspec(dllexport) keyword means instantiate
the template class, while the extern keyword means do not automatically instantiate the template class.

See Also
Explicit Instantiation
dllexport, dllimport
General Rules and Limitations
Compiler Warning (level 1) C4912
10/31/2018 • 2 minutes to read • Edit Online

'attribute': attribute has undefined behavior on a nested UDT


Attributes that apply to nested UDTs (user-defined type, which could be a typedef, union, or struct) may be ignored.
The following code shows how this warning would be generated:

// C4912.cpp
// compile with: /W1
#include <windows.h>
[emitidl, module(name="xx")];

[object, uuid("00000000-0000-0000-0000-000000000002")]
__interface IMy
{
};

[coclass, default(IMy), appobject, uuid("00000000-0000-0000-0000-000000000001")]


class CMy : public IMy
{
[export, v1_enum] typedef enum myEnum { k3_1 = 1, k3_2 = 2 } myEnumv; // C4912
};
int main()
{
}
Compiler Warning (level 4) C4913
10/31/2018 • 2 minutes to read • Edit Online

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;

a, b; // OK calls user defined operator


a, s; // C4913 uses builtin comma operator
// uncomment the conversion code in B to resolve.
}
Compiler Warning (level 1) C4917
10/31/2018 • 2 minutes to read • Edit Online

'declarator' : a GUID can only be associated with a class, interface or namespace


A user-defined structure other than class, interface, or namespace cannot have a GUID.
This warning is off by default. See Compiler Warnings That Are Off by Default for more information.

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

'character' : invalid character in pragma optimization list


An unknown character was found in the optimization list of an optimize pragma statement.
For example, the following statement generates C4918:

// 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

enum enum member member=value already seen in enum enum as member=value


If a .tlb that you pass to #import has the same symbol defined in two or more enums, this warning indicates that
subsequent identical symbols are ignored and will be commented out in the .tlh file.
Assuming a .tlb that contains:

library MyLib
{
typedef enum {
enumMember = 512
} AProblem;

typedef enum {
enumMember = 1024
} BProblem;
};

the following samples generates C4920,

// 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

'method': dispinterface method cannot be called from script


Scripting languages cannot create a VT_BYREF 'in' parameter, it can only create VT_BYREF 'out' parameters.
Another way to resolve this warning is not make the parameter (in the definition and implementation) a pointer
type.
The following sample generates C4925:

// 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

'identifier': symbol is already defined: attributes ignored


A forward declaration was found but an attributed construct with the same name already exists. The attributes for
the forward declaration are ignored.
The following sample generates C4926:

// 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);
}

B& f2( B& b)


{
return 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
{
};

template <class T>


struct Ptr
{
operator T*()
{
return 0;
}

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

'file': typelibrary contains a union; ignoring the 'embedded_idl' qualifier


The embedded_idl attribute of #import could not be applied to the type library because a union is present in the
type library. To resolve this warning, don't use embedded_idl.

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;

[export, public] typedef struct _TDW_TYPE {


[switch_is(sU)] TD_UNION_TYPE w;
short sU;
} TD_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

'prototype': prototyped function not called (was a variable definition intended?)


The compiler detected an unused function prototype. If the prototype was intended as a variable declaration,
remove the open/close parentheses.
The following sample generates C4930:

// 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)
{
}

bool GetResult() const


{
return _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

// try one of the following lines instead


// IfFailedThrow<> ift(MyMethod());
// IfFailedThrow<>(this->MyMethod());
// IfFailedThrow<>((*this).MyMethod());

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

__identifier(identifier) and __identifier(identifier) are indistinguishable


The compiler is unable to distinguish between _finally and __finally or __try and _try as a parameter passed to
__identifier. You should not attempt to use them both as identifiers in the same program, as it will result in a C2374
error.
The following sample generates C4932:

// 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

assembly access specifier modified from 'access'


The assembly visibility of a type was modified. The compiler uses the last specifier that it encounters. For example,
the assembly visibility of a forward declaration may be different from the assembly visibility of the class definition.
C4935 is only reachable using the obsolete compiler option /clr:oldSyntax.
Compiler Warning C4936
10/31/2018 • 2 minutes to read • Edit Online

this __declspec is supported only when compiled with /clr or /clr:pure

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

'text1' and 'text2' are indistinguishable as arguments to 'directive'


Because of the way the compiler processes arguments to directives, names that have meaning to the compiler, such
as keywords with multiple text representations (single and double underscore forms), cannot be distinguished.
Examples of such strings are __cdecl and __forceinline. Note, under /Za, only the double underscore forms are
enabled.
The following sample generates C4937:

// 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;

double test(int first, int last) {


double sum = 0.0;
#pragma omp parallel for reduction(+: sum) // C4938
for (int i = first ; i <= last ; ++i)
sum += a[i];
return sum;
}

Without explicit parallelization, the sum is computed as follows:

sum = a[first] + a[first + 1] + ... + a[last];

With explicit parallelization (and two threads), the sum is computed as follows:

sum1 = a[first] + ... a[first + last / 2];


sum2 = a[(first + last / 2) + 1] + ... a[last];
sum = sum1 + sum2;
Compiler Warning (level 1) C4939
10/31/2018 • 2 minutes to read • Edit Online

#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;
};

#using "C4944.dll" // C4944 ClassA also defined C4944.dll

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

reinterpret_cast used between related classes: 'class1' and 'class2'


Do not use reinterpret_cast to cast between related types. Use static_cast instead, or for polymorphic types, use
dynamic_cast.
By default, this warning is off. For more information, see Compiler Warnings That Are Off by Default.
The following code example generates C4946:

// C4946.cpp
// compile with: /W1
#pragma warning (default : 4946)
class a {
public:
a() : m(0) {}
int m;
};

class b : public virtual a {


};

class b2 : public virtual a {


};

class c : public b, public b2 {


};

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

'type_or_member' : marked as obsolete


A member or type was marked as obsolete with the ObsoleteAttribute class.

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(){}
};

// Any reference to Func1 should generate a warning


[System::ObsoleteAttribute]
Int32 Func1(Int32 a, Int32 b) {
return (a + b);
}

// Any reference to Func2 should generate a warning with message


[System::ObsoleteAttribute("Will be removed in next version")]
Int32 Func2(Int32 a, Int32 b) {
return (a + b);
}

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

When #pragma unmanaged is used without /clr, C4949 is a level 4 warning.


The following sample generates C4949:

// C4949b.cpp
// compile with: /LD /W4
#pragma unmanaged // C4949
Compiler Warning C4950
10/31/2018 • 2 minutes to read • Edit Online

'type_or_member' : marked as obsolete


A member or type was marked as obsolete with the ObsoleteAttribute attribute.
C4950 is always issued as an error. You can turn off this warning by using the warning pragma directive or the /wd
compiler option.

Example
The following sample generates C4950:

// C4950.cpp
// compile with: /clr
using namespace System;

// Any reference to Func3 should generate an error with message


[System::ObsoleteAttribute("Will be removed in next version", true)]
Int32 Func3(Int32 a, Int32 b) {
return (a + b);
}

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

'function' : no profile data found in program database 'pgd_file'

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

'type' : this type is not verifiable

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

'cast' : explicit cast from 'cast_from' to 'cast_to' is not verifiable

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

'operation' : pointer arithmetic is not verifiable

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

// Uncomment the following line to resolve.


// #pragma warning( disable : 4959 )
struct X {
int data;
};

int main() {
X x;
x.data = 10; // C4959
}
Compiler Warning (level 4) C4960
10/31/2018 • 2 minutes to read • Edit Online

'function' is too big to be profiled


When using /LTCG:PGOPTIMIZE, the compiler detected an input module with a function larger than 65,535
instructions. Such a large function is not available for profile-guided optimizations.
To resolve this warning, reduce the size of the function.
Compiler Warning C4961
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

No optimization options were specified; profile info will not be collected


/GL and /LTCG were specified, but no optimizations were requested, so no .pgc files will be generated and,
therefore, no profile-guided optimizations will be possible.
If you want .pgc files to be generated when you run your application, specify one of the /O compiler options.
The following sample generates C4964:

// 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

implicit box of integer 0; use nullptr or explicit cast


Visual C++ features implicit boxing of value types. An instruction that resulted in a null assignment using
Managed Extensions for C++ now becomes an assignment to a boxed int.
For more information, see Boxing.

Example
The following sample generates C4965.

// C4965.cpp
// compile with: /clr /W1
int main() {
System::Object ^o = 0; // C4965

// the previous line is the same as the following line


// using Managed Extensions for C++
// System::Object *o = __box(0);

// 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

Directly modifying or treating the result of an unbox operation as an lvalue is unverifiable


Dereferencing a handle to a value type, also known as unboxing, and then assigning to it is not verifiable.
For more information, see Boxing.

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

'symbol name': attributes not present on previous declaration.


The Microsoft source code annotation language (SAL ) annotations on the current method declaration or definition
differ from the annotations on an earlier declaration. The same SAL annotations must be used in the definition and
declarations of a method.
The SAL provides a set of annotations that you can use to describe how a function uses its parameters, the
assumptions it makes about them, and the guarantees it makes on finishing. The annotations are defined in the
sal.h header file.
Notice that the SAL macros will not expand unless the project has the /analyze flag specified. When you specify
/analyze, the compiler can throw C4985, even if no warnings or errors appeared without /analyze.
To correct this error
1. Use the same SAL annotations on the definition of a method and all its declarations.

See Also
SAL Annotations
Compiler Warning C4986
10/31/2018 • 2 minutes to read • Edit Online

'function': exception specification does not match previous declaration


This warning can be generated when there is an exception specification in one declaration and not the other.
By default, C4986 is off. For more information, see Compiler Warnings That Are Off by Default.

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

'function': name was marked as #pragma deprecated


The compiler encountered a function that was marked with pragma deprecated. The function may no longer be
supported in a future release. You can turn this warning off with the warning pragma (example below ).

Example
The following sample generates C4995:

// C4995.cpp
// compile with: /W3
#include <stdio.h>

// #pragma warning(disable : 4995)


void func1(void)
{
printf("\nIn func1");
}

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.

Specific C4996 messages


Here are some of the common sources of C4996 warnings and errors.
POSIX function names
The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name:
new_name. See online help for details.
Microsoft has renamed some POSIX functions in the CRT to conform with C99 and C++03 rules for
implementation-defined global function names. Only the original POSIX names are deprecated, not the functions
themselves. In most cases, a leading underscore was added to the POSIX function name to create a standard
conformant name. The compiler issues a deprecation warning for the original function name, and suggests the
preferred name.
To fix this issue, we usually recommend you change your code to use the suggested function names instead.
However, the updated names are Microsoft-specific. If you need to use the existing function names for portability
reasons, you can turn these warnings off. The POSIX functions are still available in the library under their original
names.
To turn off deprecation warnings for these functions, define the preprocessor macro
_CRT_NONSTDC_NO_WARNINGS. You can define this macro at the command line by including the option
/D_CRT_NONSTDC_NO_WARNINGS .

Unsafe CRT Library functions


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.
Microsoft has deprecated some CRT and C++ Standard Library functions and globals in favor of more secure
versions. In most cases, the deprecated functions allow unchecked read or write access to buffers, which can lead
to serious security issues. The compiler issues a deprecation warning for these functions, and suggests the
preferred function.
To fix this issue, we recommend you use the function or variable safe_version instead. If you have verified that it's
not possible for a buffer overwrite or overread to occur in your code, and you cannot change the code for
portability reasons, you can turn off the warning.
To turn off deprecation warnings for these functions in the CRT, define _CRT_SECURE_NO_WARNINGS. To turn
off warnings about deprecated global variables, define _CRT_SECURE_NO_WARNINGS_GLOBALS. For more
information about these deprecated functions and globals, see Security Features in the CRT and Safe Libraries:
C++ Standard Library.
Unsafe Standard Library functions
'std::function_name::_Unchecked_iterators::_Deprecate' Call to std::function_name with 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 warning appears in debug builds because certain C++ Standard Library template functions do not check
parameters for correctness. In most cases, this is because not enough information is available to the function to
check container bounds, or because iterators may be used incorrectly with the function. This warning helps you
identify these function uses, because they may be a source of serious security holes in your program. For more
information, see Checked Iterators.
For example, this warning appears in Debug mode if you pass an element pointer to std::copy instead of a plain
array. To fix this issue, use an appropriately declared array, so the library can check the array extents and do
bounds checking.

// C4996_copyarray.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_copyarray.cpp
#include <algorithm>

void example(char const * const src) {


char dest[1234];
char * pdest3 = dest + 3;
std::copy(src, src + 42, pdest3); // C4996
std::copy(src, src + 42, dest); // OK, copy can tell that dest is 1234 elements
}

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>

using namespace std;

template <typename C> void print(const string& s, const C& c) {


cout << s;

for (const auto& e : c) {


cout << e << " ";
}

cout << endl;


}

int main()
{
vector<int> v(16);
iota(v.begin(), v.end(), 0);
print("v: ", v);

// OK: vector::iterator is checked in debug mode


// (i.e. an overrun triggers a debug assertion)
vector<int> v2(16);
transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; });
print("v2: ", v2);

// OK: back_insert_iterator is marked as checked in debug mode


// (i.e. an overrun is impossible)
vector<int> v3;
transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; });
print("v3: ", v3);

// OK: array::iterator is checked in debug mode


// (i.e. an overrun triggers a debug assertion)
array<int, 16> a4;
transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; });
print("a4: ", a4);

// OK: Raw arrays are checked in debug mode


// (i.e. an overrun triggers a debug assertion)
// NOTE: This applies only when raw arrays are
// given to C++ Standard Library algorithms!
int a5[16];
transform(v.begin(), v.end(), a5, [](int n) { return n * 5; });
print("a5: ", a5);

// WARNING C4996: Pointers cannot be checked in debug mode


// (i.e. an overrun triggers undefined behavior)
int a6[16];
int * p6 = a6;
transform(v.begin(), v.end(), p6, [](int n) { return n * 6; });
print("a6: ", a6);

// OK: stdext::checked_array_iterator is checked in debug mode


// (i.e. an overrun triggers a debug assertion)
int a7[16];
int * p7 = a7;
transform(v.begin(), v.end(),
stdext::make_checked_array_iterator(p7, 16),
[](int n) { return n * 7; });
print("a7: ", a7);

// WARNING SILENCED: stdext::unchecked_array_iterator


// is marked as checked in debug mode, but it performs no checking,
// so an overrun triggers undefined behavior
int a8[16];
int * p8 = a8;
transform( v.begin(), v.end(),
transform( v.begin(), v.end(),
stdext::make_unchecked_array_iterator(p8),
[](int n) { return n * 8; });
print("a8: ", a8);
}

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>

using namespace std;


using namespace stdext;

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
}

Unsafe MFC or ATL code


C4996 can also occur if you use MFC or ATL functions that were deprecated for security reasons.
To fix this issue, we strongly recommend you change your code to use updated functions instead.
For information on how to suppress these warnings, see _AFX_SECURE_NO_WARNINGS.
Obsolete CRT functions and variables
This function or variable has been superseded by newer library or operating system functionality.
Consider using new_item instead. See online help for details.
Some library functions and global variables are deprecated as obsolete. These functions and variables may be
removed in a future version of the library. The compiler issues a deprecation warning for these items, and suggests
the preferred alternative.
To fix this issue, we recommend you change your code to use the suggested function or variable.
To turn off deprecation warnings for these items, define _CRT_OBSOLETE_NO_WARNINGS. For more
information, see the documentation for the deprecated function or variable.
Marshalling errors in CLR code
C4996 can also occur when you use the CLR marshaling library. In this case C4996 is an error, not a warning. This
error occurs when you use marshal_as to convert between two data types that require a marshal_context Class.
You can also receive this error when the marshaling library does not support a conversion. For more information
about the marshaling library, see Overview of Marshaling in C++.
This example generates C4996 because the marshaling library requires a context to convert from a
System::String to a const char * .

// C4996_Marshal.cpp
// compile with: /clr
// C4996 expected
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>

using namespace System;


using namespace msclr::interop;

int main() {
String^ message = gcnew String("Test String to Marshal");
const char* result;
result = marshal_as<const char*>( message );
return 0;
}

Example: User-defined deprecated function


You can use the deprecated attribute in your own code to warn callers when you no longer recommend use of
certain functions. In this example, C4996 is generated for the line on which the deprecated function is declared,
and for the line on which the function is used.

// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>

// #pragma warning(disable : 4996)


void func1(void) {
printf_s("\nIn func1");
}

__declspec(deprecated) void func1(int) {


printf_s("\nIn func2");
}

int main() {
func1();
func1(1); // C4996
}
Compiler Warning (level 1) C4997
10/31/2018 • 2 minutes to read • Edit Online

'class': coclass does not implement a COM interface or pseudo-interface


A class marked with the coclass attribute did not implement an interface.
The following sample generates C4997:

// 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

int G, G1, G2;

__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;
}

void baz(int ** p, int i)


{
if (i < G1) {
foo(bar(p, i + G2));
}
bar1(p, i);
}

int main() { }

The compiler output when the warning is enabled looks something like this:

C:\Users\username\source\repos\C5045>cl /W3 /w35045 C5045.cpp


Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26431 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

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

'function' : Symbol involving type with internal linkage not defined

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();
};
}

// g has a pointer to an unnamed struct as a parameter type. This type is


// distinct from any similar type declared in other files, so this function
// cannot be defined in any other file.
// Note that if the struct was declared "typedef struct { int x; int y; } S, *PS;"
// it would have a "typedef name for linkage purposes" and g could be defined
// in another file that provides a compatible definition for S.

typedef struct { int x; int y; } *PS;


int g(PS p);

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.
}

To fix these issues, define the functions in this file.


Vectorizer and Parallelizer Messages
11/9/2018 • 19 minutes to read • Edit Online

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.

INFORMATIONAL MESSAGE DESCRIPTION

5001 Loop vectorized.

5002 Loop not vectorized due to reason 'description'.

5011 Loop parallelized.

5012 Loop not parallelized due to reason 'description'.

5021 Unable to associate loop with pragma.

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.

REASON CODE EXPLANATION


REASON CODE EXPLANATION

500 This is a generic message that covers several cases—for


example, the loop includes multiple exits, or the loop header
does not end by incrementing the induction variable.

501 Induction variable is not local; or upper bound is not loop-


invariant.

502 Induction variable is stepped in some manner other than a


simple +1.

503 Loop includes exception-handling or switch statements.

504 Loop body may throw an exception that requires destruction


of a C++ object.

void code_500(int *A)


{
// Code 500 is emitted if the loop has non-vectorizable flow.
// This can include "if", "break", "continue", the conditional
// operator "?", or function calls.
// It also encompasses correct definition and use of the induction
// variable "i", in that the increment "++i" or "i++" must be the last
// statement in the loop.

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.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

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.

for (int i=0; i<bound(); ++i)


{
A[i] = A[i] + 1;
}

// To resolve code 501, ensure that the induction variable is


// a local variable, and ensure that the upperbound is a
// a local variable, and ensure that the upperbound is a
// provably loop invariant value.

for (int i=0, imax = bound(); i<imax; ++i)


{
A[i] = A[i] + 1;
}
}

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.

for (i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}

// To resolve code 501, ensure that the induction variable is


// a local variable, and ensure that the upperbound is a
// provably loop invariant value.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

void code_502(int *A)


{
// Code 502 is emitted if the compiler cannot discern
// the induction variable of the loop. In this case,
// there are three increments to "i", one of which
// is conditional.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
++i;

if (i < 100)
{
++i;
}
}

// To resolve code 502, ensure that there is just one


// increment of the induction variable, placed in the usual
// spot in the "for" loop.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

void code_503(int *A, int x)


{
// Code 503 is emitted if there are inadmissible
// operations in the loop - for example, exception handling and
// switch statements.

for (int i = 0; i<1000; ++i)


{
switch (x)
{
case 1: A[i] = A[i] + 1;
case 1: A[i] = A[i] + 1;
case 2: A[i] = A[i] + 2;
case 3: A[i] = A[i] + 3;
break;
}
}

// To resolve code 503, try to remove as many switch statements


// and exception handling constructs as possible.
}

// compile with /EHsc

int code_504_helper();
class C504
{
public:
C504();
~C504();
};

void code_504(int *A) {


// Code 504 is emitted if a C++ object was created and
// that object requires EH unwind tracking information under
// /EHs or /EHsc.

for(int i = 0; i < 1000; ++i)


{
C504 c;
A[i] = code_504_helper();
}

10xx
The 10xx reason codes apply to the auto-parallelizer.

REASON CODE EXPLANATION

1000 The compiler detected a data dependency in the loop body.

1001 The compiler detected a store to a scalar variable in the loop


body, and that scalar has a use beyond the loop.

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.

1004 There is a scalar reduction in the loop body. Scalar reduction


can occur if the loop has been vectorized.

1005 The no_parallel pragma was specified.

1006 This function contains openmp. Resolve this by removing any


openmp in this function.

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.

1009 The compiler detected an attempt to parallelize a "do-while"


loop. The auto-parallelizer only targets for loops.

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.

// You can resolve this by using the ivdep pragma.


// CAUTION -- the compiler will trust your
// assertion that there are no data dependencies
// in the loop body. If there are, you are generating
// code that may have race conditions.

#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.

// Resolve this by rewriting your code so


// that the scalar is not needed.

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;
}
}
}
}

extern "C" void __stosb(unsigned char*, unsigned char, size_t);


void code_1003(unsigned char *dst)
{
// Code 1003 is emitted when the loop body contains an intrinsic
// call that may read or write to memory.

// This can be resolved by using the ivdep pragma.


// CAUTION -- the compiler will trust your
// assertion that there are no data dependencies
// in the loop body. If there are, you are generating
// code that may have race conditions.

#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.

// You can resolve this by rewriting your code so that it


// does not have a scalar reduction.

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>

// Compile with /openmp


void code_1006()
{
// Code 1006 is emitted when this function contains
// openmp. Resolve this by removing any openmp in this
// function.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}

#pragma omp parallel num_threads(4)


#pragma omp parallel num_threads(4)
{
int i = omp_get_thread_num();
A[i] = A[i] + 1;
}
}

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.

// You can resolve this by specifying the hint_parallel


// pragma. CAUTION -- if the loop does not perform
// enough work, parallelizing might cause a potentially
// large performance penalty.

// #pragma loop(hint_parallel(0)) // hint_parallel will force this through


for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
}

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 "!=".

// You can resolve this by replacing it with an ordering comparator


// like "<".
#pragma loop(hint_parallel(0))
for (int i = 0; i != 1000; ++i)
{
A[i]++;
}
}

11xx
The 11xx reason codes apply to the auto-vectorizer.

REASON CODE EXPLANATION

1100 Loop contains control flow—for example, "if" or "?".

1101 Loop contains datatype conversion—perhaps implicit—that


cannot be vectorized.

1102 Loop contains non-arithmetic or other non-vectorizable


operations.

1103 Loop body includes shift operations whose size might vary
within the loop.

1104 Loop body includes scalar variables.

1105 Loop includes a unrecognized reduction operation.

1106 Outer loop not vectorized.

void code_1100(int *A, int x)


{
// Code 1100 is emitted when the compiler detects control flow
// in the loop - for example, "if", the ternary operator "?", and
// the like. Resolve this by flattening or removing control
// flow in the loop body.

// Not all control flow causes 1100; some is indeed


// vectorized.

for (int i=0; i<1000; ++i)


{
// straightline code is more amenable to vectorization
if (x)
{
A[i] = A[i] + 1;
}
}
}

extern "C" int __readcr0();


void code_1102(int *A)
{
// Code 1102 is emitted when the compiler is unable to vectorize
// an operation in the loop body. For example, intrinsics and other
// non-arithmetic, non-logical, and non-memory operations are not
// vectorizable.

// Resolve this by removing as many non-vectorizable operations


// as possible from the loop body.

for (int i=0; i<1000; ++i)


{
A[i] = __readcr0();
}
}

void code_1103(int *A, int *B)


{
// Code 1103 is emitted when the compiler is unable to vectorize
// a "shift" operation. In this example, there are two shifts
// that cannot be vectorized.
// that cannot be vectorized.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] >> B[i]; // not vectorizable

int x = B[i];
A[i] = A[i] >> x; // not vectorizable
}

// To resolve this, ensure that your shift amounts are loop


// invariant. If the shift amounts cannot be loop invariant,
// it may not be possible to vectorize this loop.

int x = B[0];
for (int i=0; i<1000; ++i)
{
A[i] = A[i] >> x; // vectorizable
}
}

int code_1104(int *A, int *B)


{
// When it vectorizes a loop, the compiler must 'expand' scalar
// variables to a vector size such that they can fit in
// vector registers. Code 1104 is emitted when the compiler
// cannot 'expand' such scalars.

// In this example, we try to 'expand' x to be used in the


// vectorized loop. However, there is a use of 'x'
// beyond the loop body, which prohibits this expansion.

// To resolve this, try to limit scalars to be used only in


// the loop body and not beyond, and try to keep their types
// consistent with the loop types.

int x;
for (int i=0; i<1000; ++i)
{
x = B[i];
A[i] = A[i] + x;
}

return x;
}

int code_1105(int *A)


{
// The compiler performs an optimization that's known as "reduction"
// when it operates on each element of an array and computes
// a resulting scalar value - for example, in this piece of code, which
// computes the sum of each element in the array:

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:

for (int i=0; i<1000; ++i)


{
s += A[i] + s; // code 1105
}

// Similarly, reductions of "float" or "double" types require


// that the /fp:fast switch is thrown. Strictly speaking,
// that the /fp:fast switch is thrown. Strictly speaking,
// the reduction optimization that the compiler performs uses
// "floating point reassociation". Reassociation is only
// allowed when /fp:fast is thrown.

return s;
}

void code_1106(int *A)


{
// Code 1106 is emitted when the compiler tries to vectorize
// an outer loop.

for (int i=0; i<1000; ++i) // this loop is not vectorized


{
for (int j=0; j<1000; ++j) // this loop is vectorized
{
A[j] = A[j] + 1;
}
}
}

12xx
The 12xx reason codes apply to the auto-vectorizer.

REASON CODE EXPLANATION

1200 Loop contains loop-carried data dependences that prevent


vectorization. Different iterations of the loop interfere with
each other such that vectorizing the loop would produce
wrong answers, and the auto-vectorizer cannot prove to itself
that there are no such data dependences.

1201 Array base changes during the loop.

1202 Field in a struct is not 32 or 64 bits wide.

1203 Loop body includes non-contiguous accesses into an array.


void fn();
void code_1200(int *A)
{
// Code 1200 is emitted when data dependence is prohibiting
// vectorization. This can only be resolved by rewriting the
// loop, and considering the marking of loop function calls as
// __forceinline.

for (int i=0; i<1000; ++i)


{
A[i] = A[i-1] + 1; // vectorization-prohibiting
fn(); // vectorization-prohibiting
}
}

void code_1201(int *A)


{
// Code 1201 is emitted when an array base changes
// in the loop body. Resolve this by rewriting your
// code so that varying the array base is not necessary.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
A++;
}
}

struct S_1202
{
short a;
short b;
} s[1000];

short sA[1000], sB[1000], sC[1000];

void code_1202(S_1202 *s)


{
// Code 1202 is emitted when non-vectorizable struct accesses
// are present in the loop body. Only struct accesses
// that are 32 or 64 bits are vectorized.

for (int i=0; i<1000; ++i)


{
s[i].a = s[i].b + 1; // this 16 bit struct access is not vectorizable
sA[i] += sB[i] * sC[i]; // this ensures we don't emit reason code '1300'
}
}

void code_1203(int *A)


{
// Code 1203 is emitted when non-vectorizable memory references
// are present in the loop body. Vectorization of some non-contiguous
// memory access is supported - for example, the gather/scatter pattern.

for (int i=0; i<1000; ++i)


{
A[i] += A[0] + 1; // constant memory access not vectorized
A[i] += A[i*2+2] + 2; // non-contiguous memory access not vectorized
}
}

13xx
The 13xx reason codes apply to the auto-vectorizer.
REASON CODE EXPLANATION

1300 Loop body contains no—or very little—computation.

1301 Loop stride is not +1.

1302 Loop is a "do-while".

1303 Too few loop iterations for vectorization to provide value.

1304 Loop includes assignments that are of different sizes.

1305 Not enough type information.

void code_1300(int *A, int *B)


{
// Code 1300 is emitted when the compiler detects that there is
// no computation in the loop body.

for (int i=0; i<1000; ++i)


{
A[i] = B[i]; // Do not vectorize, instead emit memcpy
}
}

void code_1301(int *A)


{
// Code 1301 is emitted when the stride of a loop is not positive 1.
// Only loops that have a stride of positive 1 are vectorized;
// rewriting your loop may be required.

for (int i=0; i<1000; i += 2)


{
A[i] = A[i] + 1;
}
}

void code_1302(int *A)


{
// Code 1302 is emitted for "do-while" loops. Only "while"
// and "for" loops are vectorized.

int i = 0;
do
{
A[i] = A[i] + 1;
} while (++i < 1000);
}

int code_1303(int *A, int *B)


{
// Code 1303 is emitted when the compiler detects that
// the number of iterations of the loop is too small to
// make vectorization profitable.

// If the loop computation fits perfectly in


// vector registers - for example, the upperbound is 4, or 8 in
// this case - then the loop _may_ be vectorized.

// This loop is not vectorized because there are 5 iterations

for (int i=0; i<5; ++i)


{
A[i] = A[i] + 1;
A[i] = A[i] + 1;
}

// This loop is vectorized

for (int i=0; i<4; ++i)


{
A[i] = A[i] + 1;
}

// This loop is not vectorized because runtime pointer checks


// are required to check that A and B don't overlap. It is not
// worth it to vectorize this loop.

for (int i=0; i<4; ++i)


{
A[i] = B[i] + 1;
}

// This loop is not vectorized because of the scalar reduction.

int s = 0;
for (int i=0; i<4; ++i)
{
s += A[i];
}
return s;
}

void code_1304(int *A, short *B)


{
// Code 1304 is emitted when the compiler detects
// different sized statements in the loop body.
// In this case, there is an 32-bit statement and a
// 16-bit statement.

// In cases like this consider splitting the loop into loops to


// maximize vector register utilization.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
B[i] = B[i] + 1;
}
}

typedef struct S_1305


{
int a;
int b;
} S_1305;

void code_1305( S_1305 *s, S_1305 x)


{
// Code 1305 is emitted when the compiler can't discern
// proper vectorizable type information for this loop.
// This includes non-scalar loop types such as struct
// assignments, as in this example.

// Resolve this by ensuring that your loops have statements


// that operate on integers or floating point types.

for (int i=0; i<1000; ++i)


{
s[i] = x;
}
}
14xx
The 14xx reason codes occur when some option that is incompatible with auto-vectorization is specified.

REASON CODE EXPLANATION

1400 #pragma loop(no_vector) is specified.

1401 /kernel switch is specified when targeting x86 or ARM.

1402 /arch:SSE2 or higher switch is not specified when targeting


x86.

1403 /arch:ATOM switch is specified and the loop includes


operations on doubles.

1404 /O1 or /Os switch is specified.

1405 Vectorization is disabled to aid in dynamic-initializer-to-static-


initializer optimization.
void code_1400(int *A)
{
// Code 1400 is emitted when the no_vector pragma
// is specified.

#pragma loop(no_vector)
for (int i=0; i<1000; ++i)
{
A[i] = A[i] + 1;
}
}

// Compile with /kernel


void code_1401(int *A)
{
// Code 1401 is emitted when /kernel is specified.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

// Compile with /arch:IA32


void code_1402(int *A)
{
// Code 1401 is emitted when /arch:IA32 is specified.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

// Compile with /favor:ATOM


void code_1403(double *A)
{
// Code 1401 is emitted when /favor:ATOM is specified, and
// the loop contains operations on "double" arrays.

for (int i=0; i<1000; ++i)


{
A[i] = A[i] + 1;
}
}

// Compile with /O1 or /Os


void code_1404(int *A)
{
// Code 1401 is emitted when compiling for size.

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.

REASON CODE EXPLANATION

1500 Possible aliasing on multi-dimensional arrays.


REASON CODE EXPLANATION

1501 Possible aliasing on arrays-of-structs.

1502 Possible aliasing and array index is other than n + K.

1503 Possible aliasing and array index has multiple offsets.

1504 Possible aliasing; would require too many runtime checks.

1505 Possible aliasing, but runtime checks are too complex.

void code_1500(int A[100][100], int B[100][100])


{
// Code 1500 is emitted when runtime pointer
// disambiguation checks are required, and
// there are multidimensional array references.

for (int i=0; i<100; ++i)


{
for (int j=0; j<100; ++j)
{
A[i][j] = B[i][j] + 1;
}
}
}

typedef struct S_1501


{
int a;
int b;
} S_1501;

int iA[1000], iB[1000], iC[1000];

void code_1501(S_1501 *s1, S_1501 *s2)


{
// Code 1501 is emitted when runtime pointer
// disambiguation checks are required, and
// there are array-of-struct accesses in the
// loop body.

for (int i=0; i<100; ++i)


{
s1[i].a = s2[i].b + 1;
iA[i] += iB[i] * iC[i]; // this is to ensure we don't emit reason code '1300'
}
}

void code_1502(int *A, int *B)


{
// Code 1502 is emitted when runtime pointer
// disambiguation checks are required, and
// an array reference has an offset that varies
// in the loop.

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.

for (int i=0; i<100; ++i)


{
A[i] = B[i+x] + B[i+y] + 1; // multiple offsets when addressing 'B': {x, y}
A[i] = B[i+x] + B[i] + 1; // multiple offsets when addressing 'B': {x, 0}
A[i] = B[i+x] + B[i+x] + 1; // this is vectorized
}
}

void code_1504(int *A1, int *A2, int *A3, int *A4,


int *A5, int *A6, int *A7, int *A8,
int *A9, int *A10, int *A11, int *A12,
int *A13, int *A14, int *A15, int *A16)
{
// Code 1504 is emitted when too many runtime
// pointer disambiguation checks are required.

for (int i=0; i<100; ++i)


{
++A1[i];
++A2[i];
++A3[i];
++A4[i];
++A5[i];
++A6[i];
++A7[i];
++A8[i];
++A9[i];
++A10[i];
++A11[i];
++A12[i];
++A13[i];
++A14[i];
++A15[i];
++A16[i];
}
}

void code_1505(int *A, int *B)


{
// Code 1505 is emitted when runtime pointer
// disambiguation checks are required, but are
// too complex for the compiler to discern.

for (int i=0; i<100; ++i)


{
for (int j=0; j<100; ++j)
{
for (int k=0; k<100; ++k)
{
A[i+j-k] = B[i-j+k] * 2;
}
}
}
}

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

cannot write to file 'filename' [: reason]


BSCMAKE combines the .sbr files generated during compilation into one browser database. If the resulting
browser database exceeds 64 MB, or if the number of input (.sbr) files exceeds 4092, this error will be emitted.
If the problem is caused by more than 4092 .sbr files, you must reduce the number of input files. From within
Visual Studio, this can be accomplished by /FR your entire project, then recheck on a file by file basis.
If the problem is caused by a .bsc file larger than 64MB, reducing the number of .sbr files as input will decrease the
size of the resulting .bsc file. In addition, the amount of browse information may be reduced through the use of the
/Em (Exclude Macro Expanded Symbols), /El (Exclude Local Variables), and /Es (Exclude System Files).

See Also
BSCMAKE Options
BSCMAKE Error BK1504
10/31/2018 • 2 minutes to read • Edit Online

cannot position in file 'filename' [: reason]


BSCMAKE could not move to a location in the file.
To fix by checking the following possible causes
1. A full disk.
2. A hardware error.
3. File truncation due to insufficient disk space or interruption of the compiler while creating the .sbr file.
BSCMAKE Error BK1505
10/31/2018 • 2 minutes to read • Edit Online

cannot read from file 'filename' [: reason]


BSCMAKE cannot read from the file.
To fix by checking the following possible causes
1. File corruption.
2. File truncation to the compiler running out of disk space or being interrupted while creating the .sbr file.
BSCMAKE Error BK1506
10/31/2018 • 2 minutes to read • Edit Online

cannot open file 'filename' [: reason]


BSCMAKE cannot open the file.
To fix by checking the following possible causes
1. File locked by another process. If reason says Permission denied, the browser may be using the file. Close
the Browse window and retry the build.
2. A full disk.
3. A hardware error.
4. The specified output file has the same name as an existing subdirectory.
BSCMAKE Error BK1507
10/31/2018 • 2 minutes to read • Edit Online

cannot open temporary file 'filename' [: reason]


BSCMAKE cannot open a temporary file.
To fix by checking the following possible causes
1. The TMP environment variable is not set to a valid drive and directory.
2. A full disk.
BSCMAKE Error BK1508
10/31/2018 • 2 minutes to read • Edit Online

cannot delete temporary file 'filename' [: reason]


BSCMAKE cannot delete one of its temporary files.
To fix by checking the following possible causes
1. Another process has the file open.
2. A hardware error.
BSCMAKE Error BK1509
10/31/2018 • 2 minutes to read • Edit Online

out of heap space


BSCMAKE ran out of memory, including virtual memory.
To fix by using the following possible solutions
1. Free some disk space.
2. Increase the size of the swap file.
3. Increase the size of the Windows swap file.
4. Reduce the memory BSCMAKE requires by using /Ei or /Es to eliminate some input files or /Em to
eliminate macro bodies.
BSCMAKE Error BK1510
10/31/2018 • 2 minutes to read • Edit Online

corrupt .SBR file filename


The given .sbr file does not have the expected format. Recompile to create a new .sbr.
BSCMAKE Error BK1512
10/31/2018 • 2 minutes to read • Edit Online

filename: capacity exceeded


BSCMAKE cannot build a browse information file because the number of definitions, references, modules, or other
information exceeds the limit.
To fix by using the following possible solutions
1. Exclude some information using /Em, /Es, or /Ei.
2. Omit the /Iu option.
BSCMAKE Error BK1513
10/31/2018 • 2 minutes to read • Edit Online

nonincremental update requires all .SBR files


BSCMAKE cannot build a new browse information (.bsc) file because one or more .sbr files are truncated. To find
the names of the truncated .sbr files, read the BK4502 warnings that accompany this error.
BSCMAKE can update a .bsc file with a truncated .sbr file but cannot build a new one. BSCMAKE may build a new
.bsc file for the following reasons:
Missing .bsc file.
Wrong filename specified for .bsc file.
Corrupted .bsc file.
To resolve this issue, delete the truncated .sbr files and rebuild, or clean the solution and rebuild. (In the IDE, choose
Build, Clean Solution, and then choose Build, Rebuild Solution.)
BSCMAKE Error BK1514
10/31/2018 • 2 minutes to read • Edit Online

all .SBR files truncated, none found in filename


None of the .sbr files specified for an update were part of the original browse information (.bsc) file. To find the
names of the .sbr files that caused this error, read the BK4502 warnings that precede it.
To fix by checking the following possible causes
1. Wrong filename specified for .sbr or .bsc.
2. Corrupted .bsc file required BSCMAKE to rebuild it.
BSCMAKE Error BK1515
10/31/2018 • 2 minutes to read • Edit Online

bscfile: incompatible version: cannot incrementally update


The .bsc file was created with another version of BSCMAKE. Recreate the .bsc file.
BSCMAKE Error BK1516
10/31/2018 • 2 minutes to read • Edit Online

bscfile corrupt; cannot incrementally update


The .bsc file was corrupted, possibly due to a system failure during the build. Delete the .bsc file, rebuild all .sbr files,
then rebuild the .bsc file.
BSCMAKE Error BK1517
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

truncated .SBR file 'filename' not in filename


A zero-length .sbr file that was not originally part of the .bsc file was specified during an update.
To fix by checking the following possible causes
1. Wrong filename specified.
2. File deleted. (Error BK1513 results.)
3. File corrupted, requiring BSCMAKE to do a full build.
BSCMAKE Warning BK4503
10/31/2018 • 2 minutes to read • Edit Online

minor error in .SBR file filename ignored


The .sbr file contained an error that did not halt the build, but the resulting .bsc file may be incorrect. To fix this
issue, recompile to create a new .sbr.
BSCMAKE Warning BK4504
10/31/2018 • 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

This section is a reference to the errors generated by the diagnostics 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.
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

exception executing user function


The code being executed caused a general protection fault. This error is identical to CAN0001.
Expression Evaluator Error CXX0002
10/31/2018 • 2 minutes to read • Edit Online

error accessing user memory


The expression attempts to reference memory that is not allocated to the program being debugged.
This error is identical to CAN0002.
Expression Evaluator Error CXX0004
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

operator not supported


An unsupported C operator was specified in an expression. Write an equivalent expression using the supported C
operators.
This error is identical to CAN0005.
Expression Evaluator Error CXX0006
10/31/2018 • 2 minutes to read • Edit Online

missing left parenthesis


Unbalanced parentheses were found in the expression. Retype the expression with balanced parentheses.
This error is identical to CAN0006.
Expression Evaluator Error CXX0007
10/31/2018 • 2 minutes to read • Edit Online

missing right parenthesis


Unbalanced parentheses were found in the expression. Retype the expression with balanced parentheses.
This error is identical to CAN0007.
Expression Evaluator Error CXX0008
10/31/2018 • 2 minutes to read • Edit Online

missing " at end of string


The double quote expected at the end of the string literal was missing. Retype the expression, enclosing the string
literal in double quotation marks.
This error is identical to CAN0008.
Expression Evaluator Error CXX0009
10/31/2018 • 2 minutes to read • Edit Online

missing ' after character constant


The single quote expected at the end of the character constant was missing. Retype the expression, enclosing the
character constant in single quotation marks.
This error is identical to CAN0009.
Expression Evaluator Error CXX0010
10/31/2018 • 2 minutes to read • Edit Online

missing left bracket


The expression contains unbalanced square brackets. Retype the expression with balanced square brackets.
This error is identical to CAN0010.
Expression Evaluator Error CXX0011
10/31/2018 • 2 minutes to read • Edit Online

missing right bracket


The expression contains unbalanced square brackets. Retype the expression with balanced square brackets.
This error is identical to CAN0011.
Expression Evaluator Error CXX0012
10/31/2018 • 2 minutes to read • Edit Online

missing left curly brace


The expression contains an unbalanced curly brace. Retype the expression with balanced curly braces.
This error is identical to CAN0012.
Expression Evaluator Error CXX0013
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

expression too complex (stack overflow )


The expression entered was too complex or nested too deeply for the amount of storage available to the C
expression evaluator.
Overflow usually occurs because of too many pending calculations.
Rearrange the expression so that each component of the expression can be evaluated as it is encountered, rather
than having to wait for other parts of the expression to be calculated.
Break the expression into multiple commands.
This error is identical to CAN0015.
Expression Evaluator Error CXX0016
10/31/2018 • 2 minutes to read • Edit Online

constant too big


The C expression evaluator cannot accept an unsigned integer constant larger than 4,294,967,295 (0FFFFFFFF
hexadecimal), or a floating-point constant whose magnitude is larger than approximately 1.8E+308.
This error is identical to CAN0016.
Expression Evaluator Error CXX0017
10/31/2018 • 2 minutes to read • Edit Online

symbol not found


A symbol specified in an expression could not be found.
One possible cause of this error is a case mismatch in the symbol name. Because C and C++ are case-sensitive
languages, a symbol name must be given in the exact case in which it is defined in the source.
This error can occur when trying to typecast a variable in order to watch the variable during debugging. The
typedef declares a new name for a type, but it does not define a new type. The typecast attempted in the debugger
requires the name of a defined type.
This error is identical to CAN0017.
To fix by using the following possible solutions
1. Make sure the symbol is already declared at the point in the program where it is being used.
2. Use an actual type name to cast variables in the debugger, rather than a typedef -defined name.
Expression Evaluator Error CXX0018
10/31/2018 • 2 minutes to read • Edit Online

bad register name


A specified register does not exist or cannot be displayed.
The Watch window can display the following registers:
AX SP DS IP
BX BP ES FL
CX SI SS GS
DX DI CS SS
EAX ESP DS EIP
EBX EBP ES EFL
ECX ESI FS
EDX EDI CS
This error is identical to CAN0018.
Expression Evaluator Error CXX0019
10/31/2018 • 2 minutes to read • Edit Online

bad type cast


The C expression evaluator cannot perform the type cast as written.
This error is identical to CAN0019.
To fix by checking the following possible causes
1. The specified type is unknown.
2. There were too many levels of pointer types. For example, the type cast

(char **)h_message

cannot be evaluated by the C expression evaluator.


Expression Evaluator Error CXX0020
10/31/2018 • 2 minutes to read • Edit Online

operand types bad for this operation


An operator was applied to an expression with an invalid type for that operator.
For example, it is not valid to take the address of a register or subscript an array with a floating-point expression.
This error is identical to CAN0020.
Expression Evaluator Error CXX0021
10/31/2018 • 2 minutes to read • Edit Online

struct or union used as scalar


A structure or union was used in an expression, but no element was specified.
When manipulating a structure or union variable, the name of the variable may appear by itself, without a field
qualifier. If a structure or union is used in an expression, it must be qualified with the specific element desired.
Specify the element whose value is to be used in the expression.
This error is identical to CAN0021.
Expression Evaluator Error CXX0022
10/31/2018 • 2 minutes to read • Edit Online

function call before _main


The C expression evaluator cannot evaluate a function before the debugger has entered the function _main. The
program is not properly initialized until _main has been called.
This error is identical to CAN0022.
Expression Evaluator Error CXX0023
10/31/2018 • 2 minutes to read • Edit Online

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

operation needs l-value


An expression that does not evaluate to an l-value was specified for an operation that requires an l-value.
An l-value (so called because it appears on the left side of an assignment statement) is an expression that refers to
a memory location.
For example, buffer[count] is a valid l-value because it points to a specific memory location. The logical
comparison zed != 0 is not a valid l-value because it evaluates to TRUE or FALSE, not to a memory address.
This error is identical to CAN0024.
Expression Evaluator Error CXX0025
10/31/2018 • 2 minutes to read • Edit Online

operator needs struct/union


An operator that takes an expression of struct or union type was applied to an expression that is not a struct or
union.
Components of class, structure, or union variables must have a fully qualified name. Components cannot be
entered without full specification.
This error is identical to CAN0025.
Expression Evaluator Error CXX0026
10/31/2018 • 2 minutes to read • Edit Online

bad format string


A format string was improperly specified. Check the syntax of the expression.
This error is identical to CAN0026.
For more information, see Format Specifiers in C++.
Expression Evaluator Error CXX0027
10/31/2018 • 2 minutes to read • Edit Online

tp addr not l-value


Check the syntax of the expression.
This error is identical to CAN0027.
Expression Evaluator Error CXX0028
10/31/2018 • 2 minutes to read • Edit Online

not struct/union element


An expression of the form 'Struct.Member' or 'pStruct->Member' was specified, but <member> is not an element
of the structure.
The expression may not be parenthesized correctly.
This error is identical to CAN0028.
Expression Evaluator Error CXX0029
10/31/2018 • 2 minutes to read • Edit Online

not struct pointer


The member-selection operator (->) was applied to an expression that is not a pointer to a structure.
Check that the entire expression is parenthesized correctly, or type cast the address expression to the appropriate
structure pointer type.
This error is identical to CAN0029.
Expression Evaluator Error CXX0030
10/31/2018 • 2 minutes to read • Edit Online

expression not evaluatable


The debugger's expression evaluator could not obtain a value for the expression as written. One likely cause is that
the expression refers to memory that is outside the program's address space (dereferencing a null pointer is one
example). Windows does not allow access to memory that is outside of the program's address space.
You may want to rewrite your expression using parentheses to control the order of evaluation.
This error is identical to CAN0030.
Expression Evaluator Error CXX0031
10/31/2018 • 2 minutes to read • Edit Online

expression not expandable


The expression evaluator encountered an internal error.
You may be able to write an equivalent expression that can be evaluated correctly.
This error is identical to CAN0031.
Expression Evaluator Error CXX0032
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

error in OMF type information


The executable file did not have a valid object module format (OMF ) for debugging.
This error is identical to CAN0033.
To fix by checking the following possible causes
1. The executable file was not created with the linker released with this version of Visual C++. Relink the object
code using the current version of LINK.exe.
2. The .exe file may have been corrupted. Recompile and relink the program.
Expression Evaluator Error CXX0034
10/31/2018 • 2 minutes to read • Edit Online

types incompatible with operator


The operand types specified are not legal for the operation.
For example, a pointer cannot be multiplied by any value.
You may need to type cast the operands to a type compatible with the operator.
Expression Evaluator Error CXX0036
10/31/2018 • 2 minutes to read • Edit Online

bad context {...} specification


This message can be generated by any of several errors in the use of the context operator ({}).
The syntax of the context operator ({}) was given incorrectly.
The syntax of the context operator is:
{function,module,dll}expression
This specifies the context of expression. The context operator has the same precedence and usage as a type
cast.
Trailing commas can be omitted. If any of function, module, or dll contains a literal comma, you must enclose
the entire name in parentheses.
The function name was spelled incorrectly, or does not exist in the specified module or dynamic-link library.
Because C is a case-sensitive language, function must be given in the exact case as it is defined in the source.
The module or DLL could not be found.
Check the full path name of the specified module or DLL.
This error is identical to CAN0036.
Expression Evaluator Error CXX0037
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

function argument count and/or type mismatch


The function call as specified does not match the prototype for the function.
Retype the call with the correct number of arguments. Type cast each argument to match the prototype, as
necessary.
This error is identical to CAN0038.
Expression Evaluator Error CXX0039
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

function requires implicit conversion


The C expression evaluator does not support implicit conversions involving constructor calls.
This error is identical to CAN0040.
Expression Evaluator Error CXX0041
10/31/2018 • 2 minutes to read • Edit Online

class element must be static member or member function


A nonstatic member of a class (or structure or union) was used without specifying which instantiation of the class
to use.
Only static data members or member functions can be used without specifying an instantiation.
This error is identical to CAN0041.
Expression Evaluator Error CXX0043
10/31/2018 • 2 minutes to read • Edit Online

this pointer used outside member function


The this pointer can only be used for nonstatic member functions.
This error is identical to CAN0043.
Expression Evaluator Error CXX0044
10/31/2018 • 2 minutes to read • Edit Online

use of _based(void) pointer requires :> operator


A pointer based on void cannot be used directly. You must form a complete pointer using the :> operator.
This error is identical to CAN0044.
Expression Evaluator Error CXX0045
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 )

when queue is not a function.


This error is identical to CAN0045.
Expression Evaluator Error CXX0046
10/31/2018 • 2 minutes to read • Edit Online

argument list required for member function


An expression called a member function but did not specify any actual parameters.
This error is identical to CAN0046.
Expression Evaluator Error CXX0047
10/31/2018 • 2 minutes to read • Edit Online

argument list does not match a function


An expression called a function with an actual parameter list that did not match the formal parameter list of any
function with the same name defined in the program.
Overloaded functions can be called only if there is an exact parameter match or a match that does not require the
construction of an object.
This error is identical to CAN0047.
Expression Evaluator Error CXX0048
10/31/2018 • 2 minutes to read • Edit Online

calling sequence not supported


A function specified in the expression uses a calling sequence not supported by the C expression evaluator. You
cannot call this function in a Watch window expression.
This error is identical to CAN0048.
Expression Evaluator Error CXX0049
10/31/2018 • 2 minutes to read • Edit Online

obsolete OMF - please relink program


The program used an old OMF (Object Module Format).
Relink the program using the current linker version.
This error is identical to CAN0049.
Expression Evaluator Error CXX0050
10/31/2018 • 2 minutes to read • Edit Online

left side of :: must be class/struct/union


The symbol on the left side of the scope-resolution operator ( :: ) was not a class, structure, or union.
This error is identical to CAN0050.
Expression Evaluator Error CXX0051
10/31/2018 • 2 minutes to read • Edit Online

more than one overloaded symbol specified in breakpoint


The expression evaluator could not determine which of more than one overloaded symbol to use as a breakpoint.
This error is identical to CAN0051.
Expression Evaluator Error CXX0052
10/31/2018 • 2 minutes to read • Edit Online

member function not present


A member function was specified as a breakpoint but could not be found. Setting a breakpoint at a function that
has been inlined can cause this error.
Recompile the file with inlining forced off (/Ob0) to set a breakpoint in this function.
An expression called a function that was not defined.
This error is identical to CAN0052.
Expression Evaluator Error CXX0053
10/31/2018 • 2 minutes to read • Edit Online

nonfunction symbol match while binding breakpoints


A symbol used as a breakpoint was not a function. Specifying a data member as a breakpoint can cause this error.
This error is identical to CAN0053.
Expression Evaluator Error CXX0054
10/31/2018 • 2 minutes to read • Edit Online

register in breakpoint expression illegal


A register cannot be used in a breakpoint expression.
This error is identical to CAN0054.
Expression Evaluator Error CXX0055
10/31/2018 • 2 minutes to read • Edit Online

ambiguous symbol in context operator


A symbol in the context operator ({}) referred to more than one symbol in the program.
The scope resolution operator ( :: ) may be able to resolve the ambiguity.
This error is identical to CAN0055.
Expression Evaluator Error CXX0056
10/31/2018 • 2 minutes to read • Edit Online

error in line number


An invalid line number was specified.
This error is identical to CAN0056.
Expression Evaluator Error CXX0057
10/31/2018 • 2 minutes to read • Edit Online

no code at line number


No code was generated for the specified line number. It cannot be used as a breakpoint.
This error is identical to CAN0057.
Expression Evaluator Error CXX0058
10/31/2018 • 2 minutes to read • Edit Online

overloaded operator not found


A class type was specified as the left operand in an expression, but an overloaded operator was not defined for the
class.
This error is identical to CAN0058.
Expression Evaluator Error CXX0059
10/31/2018 • 2 minutes to read • Edit Online

left operand is class not a function name


The left operand of a function call was a class name and could not be resolved to a function call. Omitting the name
of a member function in an expression can cause this error.
This error is identical to CAN0059.
Expression Evaluator Error CXX0060
10/31/2018 • 2 minutes to read • Edit Online

register is not available


An expression specified a register that cannot be used. This error can be caused by trying to access a register that
does not exist on the machine running.
This error is identical to CAN0060.
Expression Evaluator Error CXX0061
10/31/2018 • 2 minutes to read • Edit Online

function nesting depth exceeded


The expression contains a function nesting depth greater than the limit. Modify the expression to reduce the
nesting depth.
This error is identical to CAN0061.
Expression Evaluator Error CXX0062
10/31/2018 • 2 minutes to read • Edit Online

constructor calls not supported


An expression made a call to a constructor. Expressions cannot make explicit calls to constructors or make
conversions that require a call to a constructor.
This error is identical to CAN0062.
Expression Evaluator Error CXX0063
10/31/2018 • 2 minutes to read • Edit Online

overloaded operator -> not supported


The expression used an overloaded class member access operator (->).
This error is identical to CAN0063.
Expression Evaluator Error CXX0064
10/31/2018 • 2 minutes to read • Edit Online

can't set breakpoint on bound virtual member function


A breakpoint was set on a virtual member function through a pointer to an object, such as:

pClass->vfunc( int );

A breakpoint can be set on a virtual function by entering the class, such as:

Class::vfunc( int );

This error is identical to CAN0064.


Expression Evaluator Error CXX0065
10/31/2018 • 2 minutes to read • Edit Online

variable needs stack frame


An expression contained a variable that exists within the current scope but hasn't been created yet.
This error can occur when you have stepped into the prolog of a function but not yet set up the stack frame for the
function, or if you have stepped into the exit code for the function.
Step through the prolog code until the stack frame has been set up before evaluating the expression.
This error is identical to CAN0065.
Expression Evaluator Error CXX0066
10/31/2018 • 2 minutes to read • Edit Online

static member not present


A static member of a class could not be found or was not defined. This error can result from a static class member
that is declared but not defined, or is only defined and referenced in modules that do not contain debug
information.
This error is identical to CAN0066.
Expression Evaluator Error CXX0067
10/31/2018 • 2 minutes to read • Edit Online

function evaluation not supported


The expression contained a function call. Some expression evaluators do not support function calls.
This error is identical to CAN0067.
Expression Evaluator Error CXX0069
10/31/2018 • 2 minutes to read • Edit Online

variable needs stack frame


The expression evaluator cannot evaluate the variable because it does not occur in a stack frame. This may be
caused by variables declared as part of an inline function.
Expression Evaluator Error CXX0072
10/31/2018 • 2 minutes to read • Edit Online

Error: type information missing or unknown


The .pch file did not get linked in, or the code has a reference to a type that is in a module not compiled with /Zi.
This error is identical to CAN0067.
Command-Line Errors D8000 Through D9999
10/31/2018 • 2 minutes to read • Edit Online

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.

Error and warning messages


Command-Line Error D8016
Command-Line Error D8021
Command-Line Error D8022
Command-Line Error D8027
Command-Line Error D8036
Command-Line Error D8037
Command-Line Error D8045
Command-Line Warning D9024
Command-Line Warning D9025
Command-Line Warning D9026
Command-Line Warning D9027
Command-Line Warning D9028
Command-Line Warning D9035
Command-Line Warning D9036
Command-Line Warning D9040
Command-Line Warning D9041
Command-Line Warning D9043

See also
C/C++ Build Errors
Command-Line Error D8016
10/31/2018 • 2 minutes to read • Edit Online

'option1' and 'option2' command-line options are incompatible


The command-line options cannot be specified together.
Check environment variables, such as CL, for option specifications.
/clr implies /EHa, and you cannot specify any other /EH compiler option with /clr. For more information, see /clr
(Common Language Runtime Compilation).
You may get D8016 after updating a Visual C++ 6.0 project: the project update wizard process may enable /RTC
for each source code file in the project, which overrides the /RTC setting for the project. To resolve, change the
/RTC setting for each source code file in the project to the default setting, which means the project setting for /RTC
will be in effect for each file.
See /RTC (Run-Time Error Checks) for information on changing the /RTC property setting.
Command-Line Error D8021
10/31/2018 • 2 minutes to read • Edit Online

invalid numeric argument 'number'


A number greater than 65,534 was specified as a numeric argument.
Command-Line Error D8022
10/31/2018 • 2 minutes to read • Edit Online

cannot open 'messagefile'


The given file was not in the current directory or in a directory specified in the PATH environment variable. The
message file contains a brief summary of compiler command-line syntax and options.
Move this file to the current directory or a directory in the current path. If this file cannot be found, run the SETUP
program to copy it from the distribution disks.
Command-Line Error D8027
10/31/2018 • 2 minutes to read • Edit Online

cannot execute 'component'


The compiler could not run the given compiler component or linker.
To fix by checking the following possible causes
1. Not enough memory to load the component. If NMAKE invoked the compiler, run the compiler outside of
the makefile.
2. The current operating system could not run the component. Make sure the path points to the executable
files appropriate to your operating system.
3. The component was corrupted. Recopy the component from the distribution disks, using the SETUP
program.
4. An option was specified incorrectly. For example:

cl /B1 file1.c
Command-Line Error D8036
10/31/2018 • 2 minutes to read • Edit Online

'/option' not allowed with multiple source files


These compiler options cannot be used with multiple source files:
Name assembly file listing (/Fa)
Rename object file (/Fo)
Create source browser information without local variables (/Fr)
Create source browser information that includes local variables (/FR )
Command-Line Error D8037
3/12/2019 • 2 minutes to read • Edit Online

cannot create temporary il file; clean temp directory of old il files


There is not enough space to create temporary compiler intermediate files. To remedy this error, remove any old
MSIL files in the directory specified by the TMP environment variable. These files will be of the form
_CL_hhhhhhhh.ss, where h represents a random hexadecimal digit and ss represents the type of IL file. Also, be
sure to update your machine with the latest operating system patches.

See Also
Command-Line Errors D8000 Through D9999
MSVC Compiler Options
Command-Line Error D8045
10/31/2018 • 2 minutes to read • Edit Online

cannot compile C file 'file' with the /clr option


Only C++ source code files can be passed to a compilation that uses /clr. Use /TP to compile a .c file as a .cpp file;
see /Tc, /Tp, /TC, /TP (Specify Source File Type) for more information.
For more information, see /clr (Common Language Runtime Compilation).
D8045 can also occur if you compile an ATL application using Visual C++. See How to: Migrate to /clr for more
information.
Command-Line Warning D9024
10/31/2018 • 2 minutes to read • Edit Online

unrecognized source file type 'filename', object file assumed


The extension of the specified file was not recognized. The file was assumed to be an object file and was passed to
the linker.
The following extensions are recognized:
.c (C source file)
.cxx (C++ source file)
.cpp (C++ source file)
.obj (Object file)
.lib (Library file)
.def (Module definition file)
.exp (Linker exports file, created by LINK /LIB )
Command-Line Warning D9025
3/12/2019 • 2 minutes to read • Edit Online

overriding 'option1' with 'option2'


The option1 option was specified but was then overridden by option2. The option2 option was used.
If two options specify contradictory or incompatible directives, the directive specified or implied in the option
farthest to the right on the command line is used.
If you get this warning when compiling from the development environment, and are not sure where the conflicting
options are coming from, consider the following:
An option can be specified either in code or in the project's project settings. If you look at the compiler's
Command Line Property Pages and if you see the conflicting options in the All Options field then the
options are set in the project's property pages, otherwise, the options are set in source code.
If the options are set in project's property pages, look on the compiler's Preprocessor property page (with
the project node selected in the Solution Explorer). If you do not see the option set there, check the
Preprocessor property page settings for each source code file (in Solution Explorer) to make sure it's not
added there.
If the options are set in code it could be set either in code or in the windows headers. You might try creating
a preprocessed file (/P ) and search it for the symbol.
Command-Line Warning D9026
10/31/2018 • 2 minutes to read • Edit Online

options apply to entire command line


An option was specified on a command after a filename was specified. The option was applied to the file that
preceded it.
For example, in the command

CL verdi.c /G5 puccini.c

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

source file '<filename>' ignored


CL.exe ignored the input source file.
This warning can be caused by a space between the /Fo option and an output filename on a command line with the
/c option. For example:

cl /c /Fo output.obj input.c

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

minimal rebuild failure, reverting to normal build


The project .idb file is corrupt. Delete the file and rebuild.
For more information on minimal rebuilds and the .idb file, see the /Gm compiler option.
Command-Line Warning D9035
12/11/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

'option_2' instead of 'option_1'

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:

cl /EHsc /LD /wd6001 filename.cpp

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

unknown error; consult documentation for technical support options

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

debugging information corrupt; recompile module


This error can be caused because the compilation was terminated before a valid object file was created.
Recompile the given object file. If recompiling does not correct the problem, note the circumstances of the error, try
to isolate the problem, and create a reproducible test case. Then consult the technical-support help file, or the
technical-support section in one of your manuals.
Linker Tools Error LNK1104
3/12/2019 • 9 minutes to read • Edit Online

cannot open file 'filename'

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.

Possible causes and solutions


This error can occur when the linker attempts to open a file either for reading or for writing. To narrow down the
possible causes, first check what kind of file it is, and use the following sections to help identify and fix the specific
issue.
Cannot open your app or its .pdb file
If the filename is the executable your project builds, or an associated .pdb file, the most common cause is that your
application is already running when you try to rebuild it, or it is loaded in a debugger. To fix this issue, stop the
program and unload it from the debugger before building it again. If the app is open in another program, such as a
resource editor, close it. In extreme cases, you may need to use Task Manager to terminate the process, or stop and
restart Visual Studio.
Antivirus programs often temporarily block access to newly created files, especially .exe and .dll executable files. To
fix this issue, try excluding your project build directories from the antivirus scanner.
Cannot open a Microsoft Library file
If the file that can't be opened is one of the standard library files provided by Microsoft, such as kernel32.lib, you
may have a project configuration error or an installation error. Verify that the Windows SDK has been installed,
and if your project requires other Microsoft libraries such as MFC, make sure that the MFC components were also
installed by the Visual Studio installer. You can run the installer again to add optional components at any time. For
more information, see Modify Visual Studio. Use the Individual components tab in the installer to choose specific
libraries and SDKs.
If you're building a project that was created using an older version of Visual Studio, the platform toolset and
libraries for that version may not be installed. If the error message occurs for a versioned library name, such as
msvcr100.lib, this is probably the cause. To fix this issue, you have two options: you can upgrade the project to use
the current platform toolset you have installed, or you can install the older toolset and build the project unchanged.
For more information, see Upgrading Projects from Earlier Versions of Visual C++ and Use native multi-targeting
in Visual Studio to build old projects.
If you see this error when you build for a new target platform or configuration, the libraries for that project
configuration or platform toolset may not be installed. Verify that the Platform toolset and Windows SDK
Version specified in the General property page for your project are installed, and verify that the required libraries
are available in the Library Directories specified in the VC++ Directories Property Page for your configuration
settings. There are separate settings for Debug and Retail configurations, as well as 32-bit and 64-bit
configurations, so if one build works but another causes an error, make sure the settings are correct and the
required tools and libraries are installed for every configuration you build.
If you are using the Visual Studio IDE to build a project that was copied from another computer, the installation
locations for libraries may be different. Check the Library Directories property on the VC++ Directories Property
Page for the project and update it if necessary. To see and edit the current library paths set in the IDE, choose the
drop-down control for the Library Directories property and choose Edit. The Evaluated value section of the
Library Directories dialog lists the current paths searched for library files.
This error can also occur when the path to the Windows SDK is out of date. If you have installed a version of the
Windows SDK that is newer than your version of Visual Studio, make sure that the paths specified in the VC++
Directories Property Page are updated to match the new SDK. If you use the Developer Command Prompt, make
sure that the batch file that initializes the environment variables is updated for the new SDK paths. This problem
can be avoided by using the Visual Studio installer to install updated SDKs.
Cannot open a third-party library file
There are several common causes for this issue:
The path to your library file may be incorrect, or you may not have specified it to the linker.
You may have installed a 32-bit version of the library, but you are building for 64-bits, or vice-versa.
The library may have dependencies on other libraries that are not installed.
To fix a path issue, verify that the LIB environment variable is set and contains all the directories for the libraries
you use, for every configuration you build. In the IDE, the LIB variable is set by the Library Directories property
on the VC++ Directories Property Page. Make sure all the directories that contain the libraries you need are listed
here, for every configuration you build.
If you need to supply a library directory that overrides a standard library directory, you can use the /LIBPATH
option on the command line, or in the IDE, you can use the Additional Library Directories property in the
Configuration Properties > Linker > General property page for your project.
Make sure you have installed every version of the library you need for the configurations you build. Consider
using the vcpkg package management utility to automate the installation and setup for many common libraries.
When you can, it's best to build your own copies of third-party libraries, so you are sure to have all the local
dependencies that the libraries require, and they are built for the same configurations as your project.
Cannot open a file built by your project
You may see this error if the file filename is built by your solution, but does not yet exist when the linker tries to
access it. This can happen when one project depends on another project, but the projects are not built in the correct
order. To fix this issue, make sure your project references are set in the project that uses the file so the missing file
is built before it is required. For more information, see Adding references in Visual C++ projects and Managing
references in a project.
Cannot open file 'C:\Program.obj'
If you see this error, or a similar error involving an unexpected .obj file in the root of your drive, the problem is
almost certainly a library path that is not wrapped in double quotes.
To fix this issue for command-line builds, check the /LIBPATH option parameters, the paths specified in the LIB
environment variable, and the paths specified on the command line, and make sure to use double-quotes around
any paths that include spaces.
To fix this issue in the IDE, check the Library Directories property on the Configuration Properties > VC++
Directories property page, the Additional Library Directories property in the Configuration Properties >
Linker > General property page, and the Additional Dependencies property in the Configuration Properties
> Linker > Input property page for your project. Make sure all the directory paths that contain the libraries you
need are wrapped in double-quotes if necessary.
Other common issues
This error can occur when the library filename or path specified to the linker on the command line or in a #pragma
comment( lib, "library_name" ) directive is incorrect, or the path has an invalid drive specification. Check your
spelling and the file extension, and verify the file exists at the specified location.
Another program may have the file open and the linker cannot write to it. Antivirus programs often temporarily
block access to newly created files. To fix this issue, try excluding your project build directories from the antivirus
scanner.
If you are using a parallel build option, it's possible that Visual Studio has locked the file on another thread. To fix
this issue, verify that you do not build the same code object or library in multiple projects, and that you use build
dependencies or project references to pick up built binaries in your project.
When you specify individual libraries in the Additional Dependencies property directly, use spaces to separate
the library names, not commas or semicolons. If you use the Edit menu item to open the Additional
Dependencies dialog box, use newlines to separate the names, not commas, semicolons, or spaces. Also use
newlines when you specify library paths in the Library Directories and Additional Library Directories dialog
boxes.
You may see this error when the path for filename expands to more than 260 characters. Change the names or
rearrange your directory structure if needed to shorten the paths to the required files.
This error can occur because the file is too large. Libraries or object files more than a gigabyte in size may cause
problems for the 32-bit linker. A possible fix for this issue is to use the 64-bit toolset. For more information on how
to do this at the command line, see How to: Enable a 64-Bit Visual C++ Toolset on the Command Line. For
information on how to do this in the IDE, see Using MSBuild with the 64-bit Compiler and Tools and this Stack
Overflow post: How to make Visual Studio use the native amd64 toolchain.
This error can occur if you have insufficient file permissions to access filename. This can happen if you use an
ordinary user account and attempt to access library files in protected system directories, or use files copied from
other users that have their original permissions set. To fix this issue, move the file to a writeable project directory. If
the file is in a writeable directory but has inaccessible permissions, you can use an Administrator command
prompt and run the takeown.exe command to take ownership of the file.
The error can occur when you don't have enough disk space. The linker uses temporary files in several cases. Even
if you have sufficient disk space, a very large link can deplete or fragment the available disk space. Consider using
the /OPT (Optimizations) option; doing transitive COMDAT elimination reads all the object files multiple times.
If the filename is named LNKnnn, which is a filename generated by the linker for a temporary file, the directory
specified in the TMP environment variable may not exist, or more than one directory may be specified for the TMP
environment variable. Only one directory path should be specified for the TMP environment variable.
Linker Tools Error LNK1106
10/31/2018 • 2 minutes to read • Edit Online

invalid file or disk full: cannot seek to location


The tool could not read or write to location in a memory-mapped file.
To fix by checking the following possible causes
1. Disk full.
Free up some space and link again.
2. Trying to link over a network.
Some networks do not fully support the memory-mapped files used by the linker. Try linking on your local
disk.
3. Bad block on your disk.
Although the operating system and disk hardware should have detected such an error, you may want to run
a disk-checking program.
4. Out of heap space.
See C1060 for more information.
Linker Tools Error LNK1107
10/31/2018 • 2 minutes to read • Edit Online

invalid or corrupt file: cannot read at location


The tool could not read the file. Recreate the file.
LNK1107 could also occur if you attempt to pass a module (.dll or .netmodule extension created with
/clr:noAssembly or /NOASSEMBLY ) to the linker; pass the .obj file instead.
If you compile the following sample:

// 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

invalid machine type type


The machine type specified in the object header is not valid.
This error can be caused if the file is corrupt. Rebuild the object.
Linker Tools Error LNK1120
10/31/2018 • 2 minutes to read • Edit Online

number unresolved externals

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

failure during conversion to COFF: file invalid or corrupt

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.

To fix the problem


Apply all service packs and updates for your version of Visual Studio. This is particularly important for
Visual Studio 2010.
Try building with incremental linking disabled. On the menu bar, choose Project, Properties. In the
Property Pages dialog box, expand Configuration Properties, Linker. Change the value of Enable
Incremental Linking to No.
Verify that the version of CVTRES.EXE found first in your PATH environment variable matches the version
of the build tools, or the version of the Platform Toolset, used by your project.
Try turning off the Embed Manifest option. On the menu bar, choose Project, Properties. In the Property
Pages dialog box, expand Configuration Properties, Manifest Tool, Input and Output. Change the
value of Embed Manifest to No.
Make sure that the file type is valid. For example, make sure that an OMF object is 32-bit and not 16-bit. For
more information, see .Obj Files as Linker Input and PE Format.
Make sure that the file is not corrupt. Rebuild it, if necessary.

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

invalid or corrupt file


The input file either has a corrupt header or is zero size or abnormally small.
LNK1136 may also be caused if the file was incorrectly specified as an additional dependency.
Linker Tools Error LNK1140
10/31/2018 • 2 minutes to read • Edit Online

too many modules for program database; link with /PDB:NONE


The project contains more than 4096 modules.
To fix by using the following possible solutions
1. Relink using /PDB:NONE.
2. Compile some modules without debugging information.
3. Reduce the number of modules.
Linker Tools Error LNK1141
3/12/2019 • 2 minutes to read • Edit Online

failure during build of exports file


LINK could not build the exports (.exp) file.
Causes of this error include system problems such as insufficient memory and syntax errors in options or module-
definition statements.
This error is preceded by another error that gives additional information.

See Also
.Exp Files as Linker Input
Linker Tools Error LNK1143
10/31/2018 • 2 minutes to read • Edit Online

invalid or corrupt file: no symbol for COMDAT section number


This error can be caused if the object file is corrupt.
Rebuild the file.
Linker Tools Error LNK1152
10/31/2018 • 2 minutes to read • Edit Online

cannot resolve one or more undecorated symbols


This error is preceded by one warning LNK4022 for each undecorated symbol that could not be resolved and by at
least two warnings LNK4002 for the duplicate symbols found for the undecorated symbol.
Linker Tools Error LNK1158
3/12/2019 • 2 minutes to read • Edit Online

cannot run 'filename'


The given executable file called by LINK is not in the directory that contains LINK nor in a directory specified in the
PATH environment variable.
For example, you will get this error if you try to use the PGOPTIMIZE parameter to the /LTCG linker option on a
machine with a 32-bit operating system.
Linker Tools Error LNK1164
10/31/2018 • 2 minutes to read • Edit Online

section section alignment (number) greater than /ALIGN value


The alignment size for the given section in the object file exceeds the value specified with the /ALIGN option. The
/ALIGN value must be a power of 2 and must equal or exceed the section alignment given in the object file.
Either recompile with a smaller section alignment or increase the /ALIGN value.
Linker Tools Error LNK1166
10/31/2018 • 2 minutes to read • Edit Online

cannot adjust code at offset=offset, va=value


LINK was unable to pad the code as required.
Certain instructions are not allowed to cross page boundaries on some processors. LINK attempts to add pads to
correct this situation. In this case, LINK could not work around the problem.
Linker Tools Error LNK1168
10/31/2018 • 2 minutes to read • Edit Online

cannot open filename for writing


The linker can’t write to filename . The file may be in use and its file handle locked by another process, or you may
not have write permission for the file, or for the directory or network share it is located in. This error is often
caused by a transient condition—for example, a lock held by an anti-virus program, a file search indexing process,
or a delay in releasing a lock held by the Visual Studio build system.
To fix this issue, verify that the filename file handle is not locked, and that you have write permission for the file. If
it is an executable, verify that it is not already running.
You can use the Windows SysInternals utilities Handle or Process Explorer to determine which process has a file
handle lock on filename . You can also use Process Explorer to release locks on open file handles. For information
about how to use these utilities, see the Help files that come with them.
If the file is locked by an anti-virus program, you can fix this issue by excluding your build output directories from
automatic scanning by the anti-virus program. Anti-virus scanners are often triggered by the creation of new files
in the file system, and they hold locks on the files while the scan proceeds. Consult your anti-virus program
documentation for details about how to exclude specific directories from scanning.
If the file is locked by a search indexing service, you can fix this issue by excluding your build output directories
from automatic indexing. Consult the documentation for the indexing service for more information. To change the
Windows search indexing service, use Indexing Options in the Windows Control Panel. For more information,
see Improve Windows searches using the index: frequently asked questions.
If your executable can’t be overwritten by the build process, it may be locked by File Explorer. If the Application
Experience service has been disabled, File Explorer may hold on to an executable file handle lock for an extended
time. To fix this issue, run services.msc and then open the Properties dialog box for the Application Experience
service. Change the Startup type from Disabled to Manual.
Linker Tools Error LNK1169
10/31/2018 • 2 minutes to read • Edit Online

one or more multiply defined symbols found


The build failed due to multiple definitions of one or more symbols. This error is preceded by error LNK2005.
The /FORCE or /FORCE:MULTIPLE option overrides this error.
Linker Tools Error LNK1179
10/31/2018 • 2 minutes to read • Edit Online

invalid or corrupt file: duplicate COMDAT 'filename'


An object module contains two or more COMDATs with the same name.
This error can be caused by using /H, which limits the length of external names, and /Gy, which packages functions
in COMDATs.

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

cannot open input file 'filename'


The linker could not find filename because it does not exist or the path was not found.
Some common causes for error LNK1181 include:
filename is referenced as an additional dependency on the linker line, but the file does not exist.
A /LIBPATH statement that specifies the directory containing filename is missing.

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

BADFIXUPSECTION:: invalid fixup target 'symbol'; possible zero length section


During a VxD link, the target of a relocation did not have a section. With LINK386 (an older version), an OMF
GROUP record (generated by a MASM GROUP directive) may have been used to combine the zero length section
with another non-zero length section. COFF format does not support the GROUP directive and zero-length
sections. When LINK automatically converts this type of OMF objects to COFF, this error may occur.
Linker Tools Error LNK1189
10/31/2018 • 2 minutes to read • Edit Online

LIBTOOMANYMEMBERS:: library limit of number objects exceeded


The limit of 65535 objects or members in a library has been exceeded.
To fix this issue, split your library into two or more libraries with fewer objects or members.
Linker Tools Error LNK1196
10/31/2018 • 2 minutes to read • Edit Online

invalid or corrupt import object: unknown version


The import library is corrupted. Rebuild the library.
Linker Tools Error LNK1200
10/31/2018 • 2 minutes to read • Edit Online

error reading program database 'filename'


The program database (PDB ) could not be read.
This error can be caused by file corruption.
If filename is the PDB for an object file, recompile the object file using /Zi.
If filename is the PDB for the main output file, and this error occurred during an incremental link, delete the PDB
and relink.
Linker Tools Error LNK1201
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

precompiled type information not found; 'filename' not linked or overwritten

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

metadata operation failed (HRESULT) : error


The linker received an error from the .NET runtime while attempting to do a metadata update through the .NET
runtime.
HRESULT is the HRESULT from the .NET runtime method. error is the .NET-supplied text.
You probably have a mismatched linker and .NET runtime; reinstall Visual C++.
Linker Tools Error LNK1218
10/31/2018 • 2 minutes to read • Edit Online

warning treated as error; no output file generated


When you link with /WX, any linker warnings will be treated as errors, and no output file will be created.
See /WX (Treat Linker Warnings as Errors) for more information.
Linker Tools Error LNK1221
10/31/2018 • 2 minutes to read • Edit Online

a subsystem can't be inferred and must be defined


The linker does not have enough information to infer which subsystem you want to target.
To fix this error, use /SUBSYSTEM.
Linker Tools Error LNK1223
10/31/2018 • 2 minutes to read • Edit Online

invalid or corrupt file: file contains invalid .pdata contributions


For RISC platforms that use pdata, this error will occur if the compiler emitted a .pdata section with unsorted
entries.
To fix this issue, try compiling without /GL (Whole Program Optimization) enabled. Empty function bodies can
also cause this error in some cases.
Linker Tools Error LNK1224
10/31/2018 • 2 minutes to read • Edit Online

invalid image base address


You specified an invalid base address for the image. Base addresses must be 64KB aligned (the last four hex digits
must be zero) and image base must fit within a 32-bit signed or unsigned value.
Linker Tools Error LNK1237
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

failed to compile IDL content


The linker spawned MIDL to compile embedded IDL but there was a problem. Check the errors specified by MIDL.
Linker Tools Error LNK1241
10/31/2018 • 2 minutes to read • Edit Online

resource file 'resource file' already specified


This error is generated if you run cvtres manually from the command line and if you then pass the resulting .obj
file to the linker in addition to other .res files.
To specify multiple .res files, pass them all to the linker as .res files, not from within .obj files created by cvtres.
Linker Tools Error LNK1245
10/31/2018 • 2 minutes to read • Edit Online

invalid subsystem 'subsystem' specified; /SUBSYSTEM must be WINDOWS, WINDOWSCE, or CONSOLE


/clr was used to compile the object and one of the following conditions was true:
A custom entry point was defined ( /ENTRY ), such that, the linker could not infer a subsystem.
A value was passed to the /SUBSYSTEM linker option that is not valid for /clr objects.
For both situations, the resolution is to specify a valid value to the /SUBSYSTEM linker option.
Linker Tools Error LNK1248
10/31/2018 • 2 minutes to read • Edit Online

image size ('size') exceeds maximum allowable size (80000000)

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

ALINK operation failed : reason


A common reason for LNK1256 is an incorrect version number for an assembly. The value 65535 is not allowed
for any part of the assembly version number. The valid range for assembly versions is 0 - 65534.
LNK1256 can also be caused if ALINK could not find the named key container. Delete the key container and add it
again to the strong name CSP by using Sn.exe (Strong Name Tool).
Another reason for LNK1256 is a version mismatch between the linker and Alink.dll. This can be caused by a
corrupted Visual Studio installation. Use Programs and Features in the Windows Control Panel to repair or
reinstall Visual Studio.
The following sample generates LNK1256:

// 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

/LTCG:PGINSTRUMENT specified but no code generation required; instrumentation failed


/LTCG:PGINSTRUMENT was specified but no .obj files were found that were compiled with /GL.
Instrumentation cannot take place and the link failed. There must be at least one .obj file on the command line that
is compiled with /GL so that the instrumentation can occur.
Profile guided optimization (PGO ) is only available in 64-bit compilers.
Linker Tools Error LNK1277
10/31/2018 • 2 minutes to read • Edit Online

object record not found in pgd (filename)


When using /LTCG:PGOPTIMZE, the path of one of the input .lib, def, or .obj files was different from the path on
which they were found during /LTCG:PGINSTRUMENT. This may be explained by a change in the LIB
environment variable after /LTCG:PGINSTRUMENT. The full path to the input files is stored in the .pgd file.
/LTCG:PGOPTIMIZE requires that the inputs be identical to the /LTCG:PGINSTRUMENT phase.
To resolve this warning, do one of the following:
Run /LTCG:PGINSTRUMENT, redo all test runs, and run /LTCG:PGOPTIMIZE.
Change the LIB environment variable to what it was when you ran /LTCG:PGINSTRUMENT.
It is not recommended that you work around LNK1277 by using /LTCG:PGUPDATE.
Linker Tools Error LNK1282
10/31/2018 • 2 minutes to read • Edit Online

unable to /REBASE file; it has been signed


You attempted to change the base address of a signed assembly with the /REBASE option for editbin. To do this,
first change the base address and then sign the assembly.
Linker Tools Error LNK1287
10/31/2018 • 2 minutes to read • Edit Online

invalid managed entry point function


The entry point is not valid for a managed image. The return type of a managed entry point function can only be
void or int . The type of the parameter of a managed entry point function can only be void or String [] .
Linker Tools Error LNK1296
10/31/2018 • 2 minutes to read • Edit Online

unable to load filename


The given DLL was unavailable.
The possible locations for the DLL are the current directory, the system directory, the Windows directory, and the
directories specified in the PATH environment variable.
Linker Tools Error LNK1301
3/12/2019 • 2 minutes to read • Edit Online

LTCG clr modules found, incompatible with /LTCG:parameter


A module compiled with /clr and /GL was passed to the linker along with one of the profile guided optimizations
(PGO ) parameters of /LTCG.
Profile guided optimizations are not supported for /clr modules.
For more information, see:
/GL (Whole Program Optimization)
/LTCG (Link-time Code Generation)
/clr (Common Language Runtime Compilation)
Profile-Guided Optimizations
To correct this error
1. Do not compile with /clr or do not link with one of the PGO parameters to /LTCG.

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

only support linking safe .netmodules; unable to link file .netmodule


A .netmodule (compiled with /LN ) was passed to the linker in a user attempt to invoke MSIL linking. A C++
module is valid for MSIL linking if it is compiled with /clr:safe.
To correct this error, compile with /clr:safe to enable MSIL linking, or pass the /clr or /clr:pure .obj file to the
linker instead of the module.
For more information, see
/LN (Create MSIL Module)
.netmodule Files as Linker Input
Linker Tools Error LNK1306
10/31/2018 • 2 minutes to read • Edit Online

DLL entry point function cannot be managed; compile to native

DllMain cannot be compiled to MSIL; it must be compiled to native.


To resolve this issue,
Compile the file that contains the entry point without /clr.
Put the entry point in a #pragma unmanaged section.

For more information, see:


/clr (Common Language Runtime Compilation)
managed, unmanaged
Initialization of Mixed Assemblies
DLLs and Visual C++ run-time library behavior

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

type1 module detected; invalid with switch /CLRIMAGETYPE:type2

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

invalid or corrupt file: unable to import assembly


When building an assembly, a file other than a module or assembly compiled with /clr was passed to the
/ASSEMBLYMODULE linker option. If you passed an object file to /ASSEMBLYMODULE, just pass the object
directly to the linker, instead of to /ASSEMBLYMODULE.

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

ijw/native module detected; cannot link with pure modules

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

corrupt or invalid COFF symbol table (undefined static or label symbol)


The compiler-generated content for a section in the given object appears to be corrupt.
This error may represent a failure of the compiler.
Linker Tools Error LNK1318
10/31/2018 • 2 minutes to read • Edit Online

Unexpected PDB error; cause 'details'

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

entry point must be defined


The linker did not find an entry point, the initial function to call in your executable. By default, the linker looks for a
main or wmain function for a console app, a WinMain or wWinMain function for a Windows app, or DllMain for a
DLL that requires initialization. You can specify another function by using the /ENTRY linker option.
This error can have several causes:
You may not have included the file that defines your entry point in the list of files to link. Verify that the file that
contains the entry point function is linked into your app.
You may have defined the entry point using the wrong function signature; for example, you may have
misspelled or used the wrong case for the function name, or specified the return type or parameter types
incorrectly.
You may not have specified the /DLL option when building a DLL.
You may have specified the name of the entry point function incorrectly when you used the /ENTRY linker
option.
If you are using the LIB tool to build a DLL, you may have specified a .def file. If so, remove the .def file from the
build.
When building an app, the linker looks for an entry point function to call to start your code. This is the function that
is called after the app is loaded and the runtime is initialized. You must supply an entry point function for an app, or
your app can't run. An entry point is optional for a DLL. By default, the linker looks for an entry point function that
has one of several specific names and signatures, such as int main(int, char**) . You can specify another function
name as the entry point by using the /ENTRY linker option.

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

unresolved external symbol "symbol"


The compiled code makes a reference or call to symbol, but that symbol isn't defined in any of the libraries or
object files specified to the linker.
This error message is followed by fatal error LNK1120. You must fix all LNK2001 and LNK2019 errors to fix error
LNK1120.

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.

What is an unresolved external symbol?


A symbol is the name for a function or global variable used internally by a compiled object file or library. A symbol
is defined in the object file where storage is allocated for a global variable, or for a function, where the compiled
code for the function body is placed. An external symbol is a symbol that's referenced, that is, used or called in one
object file, but defined in a different library or object file. An exported symbol is one that's made publicly available
by the object file or library that defines it. The linker must resolve, or find the matching definition for, every
external symbol referenced by an object file when it is linked into an application or DLL. The linker generates an
error when it can't resolve an external symbol by finding a matching exported symbol in any of the linked files.

Use the decorated name to find the error


The C++ compiler and linker use Name Decoration, also known as name-mangling, to encode extra information
about the type of a variable or the return type, parameter types, scope, and calling convention of a function in the
symbol name. This decorated name is the symbol name the linker searches for to resolve external symbols.
Because the extra information becomes part of the symbol name, a link error can result if the declaration of a
function or variable does not exactly match the definition of the function or variable. This can happen even if the
same header file is used in both the calling code and the defining code, if different compiler flags are used when
compiling the source files. For example, you can get this error if your code is compiled to use the __vectorcall
calling convention, but you link to a library that expects clients to call it using the default __cdecl or __fastcall
calling convention. In this case, the symbols do not match because the calling conventions are different
To help you find the cause of this kind of error, the linker error message shows you both the "friendly name," the
name used in source code, and the decorated name (in parentheses) for the unresolved external symbol. You don't
need to know how to translate the decorated name to be able to compare it with other decorated names. You can
use command line tools that are included with the compiler to compare the expected symbol name and the actual
symbol name:
The /EXPORTS and /SYMBOLS options of the DUMPBIN command line tool can help you discover which
symbols are defined in your .dll and object or library files. You can use this to verify that the exported decorated
names match the decorated names the linker searches for.
In some cases, the linker can only report the decorated name for a symbol. You can use the UNDNAME command
line tool to get the undecorated form of a decorated name.

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:

void CALLTYPE test(void)

The following table shows the linker name for various calling conventions.

CALLING CONVENTION EX TERN "C" OR .C FILE .CPP, .CXX OR /TP

C naming convention ( __cdecl ) _test ?test@@ZAXXZ

Fastcall naming convention ( @test@0 ?test@@YIXXZ


__fastcall )

Standard Call naming convention ( _test@0 ?test@@YGXXZ


__stdcall )

Vectorcall naming convention ( test@@0 ?test@@YQXXZ


__vectorcall )

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,

#pragma section(".data$mylong", read, write, long)


__declspec(allocate(".data$mylong"))
char rg0[1] = { 1 };
char rg1[2] = { 1 };
char rg2[4] = { 1 };
char rg3[8] = { 1 };
char rg4[16] = { 1 };
char rg5[32] = { 1 };

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 };

This error is followed by fatal error LNK1165 .


Linker Tools Error LNK2005
10/31/2018 • 5 minutes to read • Edit Online

symbol already defined in object

The symbol symbol was defined more than once.


This error is followed by fatal error LNK1169.
Possible causes and solutions
Generally, this error means you have broken the one definition rule, which allows only one definition for any used
template, function, type, or object in a given object file, and only one definition across the entire executable for
externally visible objects or functions.
Here are some common causes for this error.
This error can occur when a header file defines a variable. For example, if you include this header file in
more than one source file in your project, an error results:

// LNK2005_global.h
int global_int; // LNK2005

Possible solutions include:


Declare the variable extern in the header file: extern int global_int; , then define it and optionally
initialize it in one and only one source file: int global_int = 17; . This variable is now a global that
you can use in any source file by declaring it extern , for example, by including the header file. We
recommend this solution for variables that must be global, but good software engineering practice
minimizes global variables.
Declare the variable static: static int static_int = 17; . This restricts the scope of the definition to
the current object file, and allows multiple object files to have their own copy of the variable. We
don't recommend you define static variables in header files because of the potential for confusion
with global variables. Prefer to move static variable definitions into the source files that use them.
Declare the variable selectany: __declspec(selectany) int global_int = 17; . This tells the linker to
pick one definition for use by all external references and to discard the rest. This solution is
sometimes useful when combining import libraries. Otherwise, we do not recommend it as a way to
avoid linker errors.
This error can occur when a header file defines a function that isn't inline . If you include this header file in
more than one source file, you get multiple definitions of the function in the executable.

// LNK2005_func.h
int sample_function(int k) { return 42 * (k % 167); } // LNK2005

Possible solutions include:


Add the inline keyword to the function:
```h
// LNK2005_func_inline.h
inline int sample_function(int k) { return 42 * (k % 167); }
```

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:

oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject


already defined in uuid.lib(go7.obj)

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

Fixup target is not aligned 'symbol_name'


LINK found a fixup target in your object file that was not aligned properly.
This error can be caused by custom secton alignment (for example, #pragma pack), align modifier, or by using
assembly language code that modifies secton alignment.
If your code does not use any of the above, this may be caused by the compiler.
Linker Tools Error LNK2011
10/31/2018 • 2 minutes to read • Edit Online

precompiled object not linked in; image may not run


If you use precompiled headers, LINK requires that all of the object files created with precompiled headers must be
linked in. If you have a source file that you use to generate a precompiled header for use with other source files,
you now must include the object file created along with the precompiled header.
For example, if you compile a file called STUB.cpp to create a precompiled header for use with other source files,
you must link with STUB.obj or you will get this error. In the following command lines, line one is used to create a
precompiled header, COMMON.pch, which is used with PROG1.cpp and PROG2.cpp in lines two and three. The
file STUB.cpp contains only #include lines (the same #include lines as in PROG1.cpp and PROG2.cpp) and is
used only to generate precompiled headers. In the last line, STUB.obj must be linked in to avoid LNK2011.

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

fixup type fixup overflow. Target 'symbol name' is out of range


The linker cannot fit the necessary address or offset into the given instruction because the target symbol is too far
away from the instruction's location.
You can resolve this problem by creating multiple images or by using the /ORDER option so the instruction and
target are closer together.
When the symbol name is a user-defined symbol (and not a compiler-generated symbol), you can also try the
following actions to resolve the error:
Change the static function to be non-static.
Rename the code section containing the static function to be the same as the caller.
Use DUMPBIN /SYMBOLS , to see if a function is static.
Linker Tools Error LNK2017
10/31/2018 • 2 minutes to read • Edit Online

'symbol' relocation to 'segment' invalid without /LARGEADDRESSAWARE:NO


You are trying to build a 64-bit image with 32-bit addresses. To do this, you must:
Use a fixed load address.
Restrict the image to 3 GB.
Specify /largeaddressaware:no.
Linker Tools Error LNK2019
10/31/2018 • 9 minutes to read • Edit Online

unresolved external symbol 'symbol' referenced in function 'function'


The compiled code for function makes a reference or call to symbol, but that symbol isn't defined in any of the
libraries or object files specified to the linker.
This error message is followed by fatal error LNK1120. You must fix all LNK2001 and LNK2019 errors to fix error
LNK1120.

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.

Third-party library issues and Vcpkg


If you see this error when you are trying to configure a third-party library as part of your build, consider using
Vcpkg, the Visual C++ Package Manager, to install and build the library. Vcpkg supports a large and growing list
of third-party libraries, and sets all the configuration properties and dependencies required for successful builds
as part of your project. For more information, see the related Visual C++ Blog post.

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;
};

// Uncomment the following line to fix the error.


// int C::s;

int main() {
C c;
C::s = 1;
}

Declaration parameters do not match definition


Code that invokes template functions must have matching template function declarations. Declarations must
include the same template parameters as the definition. The following sample generates LNK2019 on a user-
defined operator, and shows how to fix it.

// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class


Test {
// The operator<< declaration does not match the definition below:
friend ostream& operator<<(ostream&, Test&);
// To fix, replace the line above with the following:
// template<typename T> friend ostream& operator<<(ostream&, Test<T>&);
};

template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
return os;
}

int main() {
Test<int> t;
cout << "Test: " << t << endl; // LNK2019 unresolved external
}

Inconsistent wchar_t type definitions


This sample creates a DLL that has an export that uses WCHAR , which resolves to wchar_t .

// 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

If you are using function inlining, you must:


Have the inline functions implemented in the header file you include.
Have inlining turned ON in the header file.

// 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"); }
};

void _load_config_used::Test() { printf("in Test\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;

// module cannot see the implementation of PublicStatMemFunc1


testclsObject.PublicStatMemFunc1();
}

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);

static int lnktest3 = 3;


int lnktest4 = 4;

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();
};

// Should be void A::Test() {}


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

unresolved token 'token'


Similar to an undefined external error, except that the reference is via metadata. In metadata, all functions and data
must be defined.
To resolve:
Define the missing function or data, or
Include the object file or library in which the missing function or data is already defined.

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

template <typename T>


ref struct Base {
virtual void f1() {};
};

template <typename T>


ref struct Base2 {
virtual void f1() {};
};

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

metadata operation failed (HRESULT) : error_message

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

bad dll or entry point <dll or entry point>


The linker is loading an incorrect version of msobj90.dll. Ensure that link.exe and msobj90.dll in your path have the
same version.
A dependency of msobj90.dll may not be present. The dependency list for msobj90.dll is:
Msvcr90.dll
Kernel32.dll
Check your machine for any other copies of msobj90.dll that may be out of date.
Linker Tools Error LNK2026
10/31/2018 • 2 minutes to read • Edit Online

module unsafe for SAFESEH image


/SAFESEH was specified, but a module was not compatible with the safe exception handling feature. If you want to
use this module with /SAFESEH, then you will need to recompile the module.
Linker Tools Error LNK2027
10/31/2018 • 2 minutes to read • Edit Online

unresolved module reference 'module'


A file passed to the linker has a dependency on a module that was neither specified with /ASSEMBLYMODULE
nor passed directly to the linker.
To resolve LNK2027, do one of the following:
Do not pass to the linker the file that has the module dependency.
Specify the module with /ASSEMBLYMODULE.
If the module is a safe .netmodule, pass the module directly to the linker.
For more information, see /ASSEMBLYMODULE (Add a MSIL Module to the Assembly) and .netmodule Files as
Linker Input.
Linker Tools Error LNK2028
10/31/2018 • 2 minutes to read • Edit Online

"exported_function" (decorated_name) referenced in function "function_containing_function_call"


(decorated_name)

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

unable to generate p/invoke for "function_declaration" decorated_name; calling convention missing in


metadata

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

unresolved typeref token (token) for 'type'


A type doesn’t have a definition in MSIL metadata.
LNK2033 can occur when compiling with /clr:safe and where there is only a forward declaration for a type in an
MSIL module, where the type is referenced in the MSIL module.
The type needs to be defined under /clr:safe.
For more information, see /clr (Common Language Runtime Compilation).

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.

Possible causes and solutions


This error can occur when an object file in your project is out-of-date. Before you try other solutions to this error,
perform a clean build to ensure that the object files are current.
Visual Studio defines the following symbols to prevent the linking of incompatible code, which can cause run-time
errors or other unexpected behavior.
_MSC_VER Indicates the major and minor version numbers of the Visual C++ compiler that's used to build
an app or library. Code that's compiled by using one version of the Visual C++ compiler is incompatible
with code that's compiled by using a version that has different major and minor version numbers. For more
information, see _MSC_VER in Predefined Macros.
If you're linking to a library that's not compatible with the version of the Visual C++ compiler that you're
using, and you cannot acquire or build a compatible version of the library, you can use an earlier version of
the compiler to build your project: change the Platform Toolset property of the project to the earlier
toolset. For more information, see How to: Modify the Target Framework and Platform Toolset.
_ITERATOR_DEBUG_LEVEL Indicates the level of security and debugging features that are enabled in the C++
Standard Library. These features can change the representation of certain C++ Standard Library objects and
thereby make them incompatible with those that use different security and debugging features. For more
information, see _ITERATOR_DEBUG_LEVEL.
RuntimeLibrary Indicates the version of the C++ Standard Library and C runtime that's used by an app or
library. Code that uses one version of the C++ Standard Library or C runtime is incompatible with code that
uses a different version. For more information, see /MD, /MT, /LD (Use Run-Time Library).
_PPLTASKS_WITH_WINRT Indicates that code that uses the Parallel Patterns Library (PPL ) is linked to objects
compiled by using a different setting for the /ZW compiler option. (/ZW supports C++/CX.) Code that uses
or depends on the PPL must be compiled by using the same /ZW setting that's used in the rest of the app.
Ensure that the values of these symbols are consistent throughout the projects in your Visual Studio solution, and
also that they are consistent with code and libraries that your app links to.

Third-party library issues and Vcpkg


If you see this error when you are trying to configure a third-party library as part of your build, consider using
Vcpkg, the Visual C++ Package Manager, to install and build the library. Vcpkg supports a large and growing list of
third-party libraries, and sets all the configuration properties and dependencies required for successful builds as
part of your project. For more information, see the related Visual C++ Blog post.

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

no object files specified; libraries used


The linker was passed one or more .lib files, but no .obj files.
Because the linker is not able to access information in a .lib file that it is able to access in an .obj file, this warning
indicates that you will have to explicitly specify other linker options. For example, you may have to specify the
/MACHINE, /OUT, or /ENTRY options.
Linker Tools Warning LNK4002
10/31/2018 • 2 minutes to read • Edit Online

symbol defined in object


The symbol, displayed in its decorated form, was specified in its undecorated form in object , but a unique match
to a decorated symbol could not be found. This warning is always preceded by warning LNK4022 and followed by
fatal error LNK1152.
Linker Tools Warning LNK4006
10/31/2018 • 2 minutes to read • Edit Online

symbol already defined in object; second definition ignored


The given symbol , displayed in its decorated form, was multiply defined. When this warning is encountered,
symbol will be added twice, but only its first form will be used.

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

invalid subsystem version number number; default subsystem version assumed


You can specify a version for the image's subsystem (/SUBSYSTEM ). Each subsystem has a minimum version
requirement. If the specified version is lower than the minimum, this warning will occur and the linker will just use
the default subsystem.
Linker Tools Warning LNK4014
10/31/2018 • 2 minutes to read • Edit Online

cannot find member object "objectname"


LIB could not find objectname in the library.
The /REMOVE and /EXTRACT options require the full name of the member object that is to be deleted or copied
to a file. The full name includes the path of the original object file. To see the full names of member objects in a
library, use DUMPBIN /ARCHIVEMEMBERS or LIB /LIST.
Linker Tools Warning LNK4020
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 PDB file filename has a corrupted type record.


This issue is often secondary to other build issues; unless this is the first reported build issue, deal with the other
errors and warnings first. If this is the first reported issue, you may need to clean your build directories and rebuild
your project. If you use parallel build processes, see if the error persists when you serialize your build.
Linker Tools Warning LNK4022
10/31/2018 • 2 minutes to read • Edit Online

cannot find unique match for symbol 'symbol'


LINK or LIB found multiple matches for the given undecorated symbol and it could not resolve the ambiguity. No
output file (.exe, .dll, .exp, or .lib) is produced. This warning is followed by one warning LNK4002 for each duplicate
symbol and is finally followed by fatal error LNK1152.
To prevent this warning, specify the symbol in its decorated form. Run DUMPBIN on the object to see decorated
names.
Linker Tools Warning LNK4037
10/31/2018 • 2 minutes to read • Edit Online

'symbol' does not exist; ignored

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

section 'name' specified with /SECTION option does not exist


DUMPBIN or EDITBIN could not find a section called name in the input file.
To see the sections in a file, run DUMPBIN with the /HEADERS option.
Linker Tools Warning LNK4044
10/31/2018 • 2 minutes to read • Edit Online

unrecognized option 'option'; ignored


The given option is not a valid option for this tool. The tool ignored the option.
To see a list of valid options, run the tool with no arguments or options.
Linker Tools Warning LNK4049
10/31/2018 • 2 minutes to read • Edit Online

locally defined symbol 'symbol' imported


The symbol was both exported from and imported to the program.
This warning is generated by the linker when you declare a symbol by using the __declspec(dllexport) storage-
class attribute in one object file and reference it by using the __declspec(dllimport) attribute in another.
Warning LNK4049 is a more general version of Linker Tools Warning LNK4217. The linker generates Warning
LNK4049 when it cannot determine from which function the imported symbol was referenced.
The common cases where LNK4049 is generated instead of LNK4217 are:
Performing incremental linking by using the /INCREMENTAL option.
Performing whole-program optimization by using the /LTCG option.
To resolve LNK4049, try one of the following:
Remove the __declspec(dllimport) name declaration from the forward declaration of the symbol which
triggered LNK4049. You can search for symbols within a binary image by using the DUMPBIN utility. The
DUMPBIN/SYMBOLS switch displays the COFF symbol table of the image. For more information on the
DUMPBIN utility, see DUMPBIN Reference.
Temporarily disable incremental linking and whole-program optimization. Recompiling the application will
generate Warning LNK4217, which will include the name of the function from which the imported symbol
was referenced. Remove the __declspec(dllimport) declaration from the imported symbol and enable
incremental linking or whole-program optimization as required.
Although the final generated code will behave correctly, the code generated to call the imported function is less
efficient than calling the function directly. This warning will not appear when you compile by using the option /clr.
For more information on import and export data declarations, see dllexport, dllimport.

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

__declspec(dllexport) int func()


{
return 3;
}

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

__declspec(dllimport) int func();


// try the following line instead
// int func();

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

'function' cannot be ordered; ignored


The given function was not compiled as a packaged function. Recompile using /Gy.
Linker Tools Warning LNK4070
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

cannot be incrementally linked on subsequent links


LINK found multiple definitions for one or more symbols, but /FORCE or /FORCE:MULTIPLE was used to create
an output file regardless of errors. LINK deleted the incremental status (.ilk) file.
Linker Tools Warning LNK4073
10/31/2018 • 2 minutes to read • Edit Online

cannot create map for .ilk file; linking nonincrementally


There was not a large enough contiguous space in shared memory for LINK to create the incremental status (.ilk)
file. LINK performed a nonincremental build.
Linker Tools Warning LNK4075
3/12/2019 • 2 minutes to read • Edit Online

ignoring "option1" due to "option2" specification


The second option overrides the first.
Mutually exclusive linker options are being specified. Examine your linker options. Where linker options are
specified depends on how you are building your project.
If you are building in the development environment, look in the linker property pages for your project, and
see where both linker options are being specified. See Set compiler and build properties for more
information.
If you build at the command line, look at the linker options specified there.
If you build with build scripts, look through your scripts to see where these linker options are being
specified.
When you find where the mutually exclusive linker options are specified, remove one of the linker options.
Some specific examples:
If you link a module that was compiled with /ZI, which implies an internal linker option called
/EDITANDCONTINUE, and a module that was compiled with /OPT:REF, /OPT:ICF, or /INCREMENTAL:NO,
which imply no /EDITANDCONTINUE, you will get LNK4075. See /Z7, /Zi, /ZI (Debug Information Format)
for more information.
Linker Tools Warning LNK4076
10/31/2018 • 2 minutes to read • Edit Online

invalid incremental status file 'filename'; linking nonincrementally


LINK cannot write to the incremental status (.ilk) file. Either filename is corrupt or it is not an incremental linking
database. Remove the file and relink.
Linker Tools Warning LNK4078
10/31/2018 • 2 minutes to read • Edit Online

multiple 'section name' sections found with different attributes


LINK found two or more sections that have the same name but different attributes.
This warning can be caused by an import library or exports file that was created by a previous version of LINK or
LIB.
Recreate the file and relink.

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() {} };

int myexit (PF pf) { return 0; }

#pragma section(".mine$a", read, write)


// try the following line instead
// #pragma section(".mine$a", read)
__declspec(allocate(".mine$a")) int ii = 1;

#pragma section(".mine$z", read, write)


// try the following line instead
// #pragma section(".mine$z", read)
__declspec(allocate(".mine$z")) int i = 1;

#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

defaultlib 'library' conflicts with use of other libs; use /NODEFAULTLIB:library


You are trying to link with incompatible libraries.

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.

TO USE THIS RUN-TIME LIBRARY IGNORE THESE LIBRARIES

Single-threaded (libc.lib) libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

Multithreaded (libcmt.lib) libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

Multithreaded using DLL (msvcrt.lib) libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib

Debug Single-threaded (libcd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib

Debug Multithreaded (libcmtd.lib) libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib

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:

/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib


/NODEFAULTLIB:msvcrtd.lib
Linker Tools Warning LNK4099
10/31/2018 • 2 minutes to read • Edit Online

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

export of deleting destructor 'name'; image may not run correctly


The program has attempted to export a deleting destructor. The resulting delete may occur across a DLL boundary
such that a process can free memory that it does not own. Make sure that the given symbol is not listed in your
.def file, and that the symbol is not listed as an argument of the /IMPORT or /EXPORT option in the linker
command line.
If you are rebuilding the C run-time library, you can ignore this message.
Linker Tools Warning LNK4104
10/31/2018 • 2 minutes to read • Edit Online

export of symbol 'symbol' should be PRIVATE


The symbol can be one of the following:
DllCanUnloadNow

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

no argument specified with option 'option'; ignoring option


This warning occurs only when the /LIBPATH option is set. If no directory is specified with this option, then the
linker ignores the option and generates this warning message.
If you do not need to override the existing environmental library settings, remove the /LIBPATH option from the
linker command line. If you want to use an alternate search path for libraries, specify the alternate path following
the /LIBPATH option.

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

/DELAYLOAD:dll name ignored


The linker cannot delay load the requested DLL.
Linker Tools Warning LNK4197
10/31/2018 • 2 minutes to read • Edit Online

export 'exportname' specified multiple times; using first specification

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

To fix by checking the following possible causes


1. The same export is specified both on the command line (through export:) and in the .def file.
2. The same export is listed twice in the .def file with different attributes.
Linker Tools Warning LNK4199
10/31/2018 • 2 minutes to read • Edit Online

/DELAYLOAD:dllname ignored; no imports found from dllname


The linker ignores dllname because it does not need any of the functions that dllname exports.
Linker Tools Warning LNK4200
10/31/2018 • 2 minutes to read • Edit Online

corrupt line number information in object file; ignored


The line number information in the object file is corrupt. Rebuild.
Linker Tools Warning LNK4204
10/31/2018 • 2 minutes to read • Edit Online

'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

section section exists; there may be unhandled static initializers or terminators

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

Exported entry point entry


An entry point was exported from a DLL. The entry point of a DLL does not need to be exported.
Linker Tools Warning LNK4217
10/31/2018 • 2 minutes to read • Edit Online

locally defined symbol 'symbol' imported in function 'function'


__declspec(dllimport) was specified for a symbol even though the symbol is defined locally. Remove the
__declspec modifier to resolve this warning.

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

invalid 'linker option' value 'value'; assumed default


An out-of-range value was specified with the /TLBID option. The default value for /TLBID is 1.
Linker Tools Warning LNK4221
11/9/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

exported symbol 'symbol' should not be assigned an ordinal


The following symbols should not be exported by ordinal:
DllCanUnloadNow

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

option is no longer supported; ignored

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

metadata operation warning (HRESULT) : warning_message

The linker detected metadata differences when merging:


One or more referenced assemblies with the assembly currently being built.
One or more source code files in a compilation.
For example, LNK4227 may be caused if you have two global functions with the same name but parameter
information declared differently (that is, declarations are not consistent in all compilands). Use ildasm.exe /TEXT
/METADATA object_file on each .obj file to see how the types differ.
LNK4227 is also used to report problems that originate with another tool. Search for the warning message for
more information.
The metadata problems must be fixed to resolve the warning.

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)];

ref class MyClass


{
};

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

invalid directive /directive found; ignored


A directive passed via the comment pragma was not valid. The linker ignores /directive .
Linker Tools Warning LNK4237
10/31/2018 • 2 minutes to read • Edit Online

/SUBSYSTEM:NATIVE specified when importing from 'dll'; Use /SUBSYSTEM:CONSOLE or


/SUBSYSTEM:WINDOWS.
/SUBSYSTEM:NATIVE was specified when building a windows (Win32) application that directly uses one or more
of the following:
kernel32.dll
gdi32.dll
user32.dll
one of the msvcrt* dlls.
Resolve this warning by not specifying /SUBSYSTEM:NATIVE.
Linker Tools Warning LNK4247
10/31/2018 • 2 minutes to read • Edit Online

entry point 'decorated_function_name' already has a thread attribute; 'attribute' ignored


An entry point, specified with /ENTRY (Entry-Point Symbol), had a threading attribute, but
/CLRTHREADATTRIBUTE (Set CLR Thread Attribute) was also specified, with a different threading model.
The linker ignored the value specified with /CLRTHREADATTRIBUTE.
To resolve this warning:
Remove /CLRTHREADATTRIBUTE from your build.
Remove attribute from your source code file.
Remove both the attribute from source and /CLRTHREADATTRIBUTE from your build, and accept the
default CLR threading model.
Change the value passed to /CLRTHREADATTRIBUTE, such that, it agrees with the attribute in source.
Change the attribute in source, such that, it agrees with the value passed to /CLRTHREADATTRIBUTE.
The following sample generates LNK4247

// 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

Failed waiting for quiet time to sweep.


The application did not allow pgosweep to run. If possible, run pgosweep when the application is in an idle state.
Profile-Guided Optimization Warning PG1087
10/31/2018 • 2 minutes to read • Edit Online

The PGC file 'file' is not valid.


A .pgc file is corrupt, possibly due to an abnormal end to a profiling session. Rerun the profiling scenario and
terminate normally.
Profile-Guided Optimization Error PG0165
10/31/2018 • 2 minutes to read • Edit Online

Reading 'Filename.pgd' : 'PGD version is not supported (version mismatch)'.


PGD files are specific to a particular compiler toolset. This error is generated when you are using a different
compiler than the one used for Filename.pgd. This error indicates that this compiler toolset cannot use the data
from Filename.pgd to optimize the current program.
To resolve this problem, regenerate Filename.pgd by using the current compiler toolset.
Math Errors M6101 through M6205
12/10/2018 • 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:

long double ld() {};


main ()
{
ld();
}

Program terminates with exit code 139.


Math Error M6201
10/31/2018 • 2 minutes to read • Edit Online

'function' : _DOMAIN error


An argument to the given function was outside the domain of legal input values for that function.

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

'function' : _SING error


An argument to the given function was a singularity value for this function. The function is not defined for that
argument.
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 M6203
10/31/2018 • 2 minutes to read • Edit Online

'function' : _OVERFLOW error


The given function result was too large to be represented.
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 M6205
10/31/2018 • 2 minutes to read • Edit Online

'function' : _TLOSS error


A total loss of significance (precision) occurred.
This error may be caused by giving a very large number as the operand of sin, cos, or tan because the operand
must be reduced to a number between 0 and 2*pi.
NMAKE Errors U1000 through U4011
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

syntax error : ')' missing in macro invocation

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

syntax error : illegal character 'character' in macro


The given character appears in a macro but is not a letter, number, or underscore.
This error can be caused by a missing colon in a macro expansion:

syntax error : illegal character '=' in macro


NMAKE Fatal Error U1007
10/31/2018 • 2 minutes to read • Edit Online

double quotation mark not allowed in name


The specified target name or filename contained a double quotation mark (").
Double quotation marks can surround a filename but cannot be contained within it.
NMAKE Fatal Error U1023
10/31/2018 • 2 minutes to read • Edit Online

syntax error in expression


An expression is invalid.
Check the allowed operators and operator precedence.
NMAKE Fatal Error U1033
10/31/2018 • 2 minutes to read • Edit Online

syntax error : 'string' unexpected


The string is not part of the valid syntax for a makefile.
To fix by checking the following possible causes
1. If the closing set of angle brackets (<<) for an inline file are not at the beginning of a line, the following error
occurs:

syntax error : 'EOF' unexpected

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:

syntax error : '=' unexpected

3. If the semicolon (;) in a comment line in TOOLS.INI is not at the beginning of the line, the following error
occurs:

syntax error : ';' unexpected

4. If the makefile has been formatted by a word processor, the following error can occur:

syntax error : ':' unexpected


NMAKE Fatal Error U1034
10/31/2018 • 2 minutes to read • Edit Online

syntax error : separator missing


The colon (:) that separates targets and dependents is missing.
NMAKE Fatal Error U1035
10/31/2018 • 2 minutes to read • Edit Online

syntax error : expected ':' or '=' separator


Either a colon (:) or an equal sign (=) was expected.
To fix by checking the following possible causes
1. A colon did not follow a target.
2. A colon and no space (such as a:) followed a single-letter target. NMAKE interpreted it as a drive
specification.
3. A colon did not follow an inference rule.
4. A macro definition was not followed by an equal sign.
5. A character followed a backslash (\) that was used to continue a command to a new line.
6. A string appeared that did not follow any NMAKE syntax rule.
7. The makefile was formatted by a word processor.
NMAKE Fatal Error U1036
10/31/2018 • 2 minutes to read • Edit Online

syntax error : too many names to left of '='


Only one string is allowed to the left of a macro definition.
NMAKE Fatal Error U1045
3/12/2019 • 2 minutes to read • Edit Online

spawn failed : message


A program or command called by NMAKE failed for the given reason. When NMAKE calls another program—for
example, the compiler or linker—the call may fail, or an error may be returned by the called program. This message
is used to report the error.
To fix this issue, first determine the cause of the error. You can use the commands reported by the NMAKE /N
option to verify the environment settings and to repeat the actions performed by NMAKE on the command line.
NMAKE Fatal Error U1050
10/31/2018 • 2 minutes to read • Edit Online

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

file 'filename' not found

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

out of environment space


The operating system ran out of room for environment variables.
Either increase the environment space or set fewer environment variables.
NMAKE Fatal Error U1056
10/31/2018 • 2 minutes to read • Edit Online

cannot find command processor


The command processor was not in the path specified in the COMSPEC or PATH environment variables.
NMAKE uses COMMAND.COM or CMD.EXE as a command processor when executing commands. It looks for the
command processor first in the path set in COMSPEC. If COMSPEC does not exist, NMAKE searches the
directories specified in PATH.
NMAKE Fatal Error U1059
10/31/2018 • 2 minutes to read • Edit Online

syntax error : '}' missing in dependent

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

MAKEFILE not found and no target specified


The NMAKE command line did not specify a makefile or a target, and the current directory did not contain a file
named MAKEFILE.
NMAKE requires either a makefile or a command-line target (or both). To make a makefile available to NMAKE,
either specify the /F option or place a file named MAKEFILE in the current directory. NMAKE can create a
command-line target by using an inference rule if a makefile is not provided.
NMAKE Fatal Error U1065
10/31/2018 • 2 minutes to read • Edit Online

invalid option 'option'


The option is not valid for NMAKE.
NMAKE Fatal Error U1070
10/31/2018 • 2 minutes to read • Edit Online

cycle in macro definition 'macroname'


The given macro definition contained a macro whose definition contained the given macro. Circular macro
definitions are invalid.

Example
The following macro definitions

ONE=$(TWO)
TWO=$(ONE)

cause the following error:

cycle in macro definition 'TWO'


NMAKE Fatal Error U1071
10/31/2018 • 2 minutes to read • Edit Online

cycle in dependency tree for target 'targetname'


A circular dependency exists in the dependency tree for the given target. The given target is a dependent of one of
the dependents of the given target. Circular dependencies are invalid.
NMAKE Fatal Error U1073
10/31/2018 • 2 minutes to read • Edit Online

don't know how to make 'targetname'


The specified target does not exist, and there is no command to execute or inference rule to apply.
To fix by using the following possible solutions
1. Check the spelling of the target name.
2. If targetname is a pseudotarget, specify it as a target in another description block.
3. If targetname is a macro invocation, be sure it does not expand to a null string.
NMAKE Fatal Error U1076
10/31/2018 • 2 minutes to read • Edit Online

name too long


A string exceeded one of the following limits:
1024 characters for a macro name.
256 characters for a target pathname.
2048 characters for a command.
NMAKE Fatal Error U1077
10/31/2018 • 2 minutes to read • Edit Online

'program' : return code 'value'


The given command or program called by NMAKE failed and returned the given exit code.
To suppress this error and continue the NMAKE session, use the /I option, the .IGNORE dot directive, or the dash
(-) command modifier. To continue the NMAKE session for unrelated parts of the dependency tree, use the /K
option.
NMAKE Fatal Error U1078
10/31/2018 • 2 minutes to read • Edit Online

constant overflow at 'expression'


The given expression contained a constant that exceeded the range - 2,147,483,648 to 2,147,483,647. The constant
appeared in one of the following situations:
An expression specified with a preprocessing directive
An error level specified with the dash (-) command modifier
NMAKE Fatal Error U1083
10/31/2018 • 2 minutes to read • Edit Online

target macro 'target' expands to nothing


The given target is an invocation of a macro that has not been defined or has a null value. NMAKE cannot process
a null target.
NMAKE Fatal Error U1086
10/31/2018 • 2 minutes to read • Edit Online

inference rule cannot have dependents


The colon (:) in an inference rule must be followed by one of these:
Newline character
Semicolon (;), which can be followed by a command
Number sign (#), which can be followed by a comment
NMAKE Fatal Error U1087
10/31/2018 • 2 minutes to read • Edit Online

cannot have : and :: dependents for same target


A target cannot be specified in both a single-colon (:) and a double-colon ( :: ) dependency.
To specify a target in multiple description blocks, use :: in each dependency line.
NMAKE Fatal Error U1088
10/31/2018 • 2 minutes to read • Edit Online

invalid separator '::' on inference rule


An inference rule must be followed by a single colon (:).
NMAKE Fatal Error U1095
10/31/2018 • 2 minutes to read • Edit Online

expanded command line 'commandline' too long


After macro expansion, the given command line exceeded the limit on length of command lines for the operating
system.
MS -DOS permits up to 128 characters on a command line.
If the command is for a program that can accept command-line input from a file, change the command and supply
input from either a file on disk or an inline file. For example, LINK and LIB accept input from a response file.
NMAKE Fatal Error U1097
10/31/2018 • 2 minutes to read • Edit Online

filename-parts syntax requires dependent


The current dependency does not have either an explicit dependent or an implicit dependent. Filename-parts
syntax, which uses the percent ( % ) specifier, represents components of the first dependent of the current target.
NMAKE Fatal Error U1099
10/31/2018 • 2 minutes to read • Edit Online

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

macro 'macroname' is illegal in the context of batch rule 'rule'


NMAKE generates this error when the command block of a batch-mode rule directly or indirectly references a
special file macro that is not $<.
$< is the only allowed macro for batch-mode rules.
NMAKE Warning U4001
10/31/2018 • 2 minutes to read • Edit Online

command file can be invoked only from command line

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

too many rules for target 'targetname'


More than one description block was specified for the given target using single colons (:) as separators. NMAKE
executed the commands in the first description block and ignored later blocks.
To specify the same target in multiple dependencies, use double colons ( :: ) as the separator in each dependency
line.
NMAKE Warning U4006
10/31/2018 • 2 minutes to read • Edit Online

special macro undefined : 'macroname'


The given special macro name is undefined and expands to nothing.
NMAKE Warning U4007
10/31/2018 • 2 minutes to read • Edit Online

filename 'filename' too long; truncating to 8.3


The base name of the given file has more than eight characters, or the extension has more than three characters.
NMAKE truncated the name to an eight-character base and a three-character extension.
If long filenames are supported by your file system, enclose the name in double quotation marks ( ").
NMAKE Warning U4010
10/31/2018 • 2 minutes to read • Edit Online

'target' : build failed; /K specified, continuing ...


A command in the commands block for the given target returned a nonzero exit code. The /K option told NMAKE
to continue processing unrelated parts of the build and to issue an exit code 1 when the NMAKE session is
finished.
If the given target is, itself, a dependent for another target, NMAKE issues warning U4011 after this warning.
NMAKE Warning U4011
10/31/2018 • 2 minutes to read • Edit Online

'target' : not all dependents available; target not built


A dependent of the given target either did not exist or was out-of-date, and a command for updating the
dependent returned a nonzero exit code. The /K option told NMAKE to continue processing unrelated parts of the
build and to issue an exit code 1 when the NMAKE session is finished.
This warning is preceded by warning U4010 for each dependent that failed to be created or updated.
C Runtime Errors R6002 through R6035
12/10/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

floating-point support not loaded


The necessary floating-point library was not linked.

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.

Information for Programmers


This error can occur in your app when the floating-point library was not linked. Check for one of these causes:
A format string for a printf_s or scanf_s function contained a floating-point format specification and the
program did not contain any floating-point values or variables. To fix this issue, use a floating-point
argument to correspond to the floating-point format specification, or perform a floating-point assignment
elsewhere in the program. This causes floating-point support to be loaded.
The compiler minimizes a program's size by loading floating-point support only when necessary. The
compiler cannot detect floating-point operations or floating-point format specifications in format strings, so
it does not load the necessary floating-point routines. To fix this issue, use a floating-point format
specification and supply a floating-point argument, or perform a floating-point assignment elsewhere in the
program. This causes floating-point support to be loaded.
In a mixed-language program, a C library was specified before a FORTRAN library when the program was
linked. Relink and specify the C library last.
C Runtime Error R6008
10/31/2018 • 2 minutes to read • Edit Online

not enough space for arguments

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.

Information for Programmers


There was enough memory to load the program but not enough memory to create the argv array. This can be
caused by extremely low memory conditions, or by unusually large command lines or environment variable usage.
Consider one of the following solutions:
Increase the amount of memory available to the program.
Reduce the number and size of command-line arguments.
Reduce the environment size by removing unnecessary variables.
C Runtime Error R6009
10/31/2018 • 2 minutes to read • Edit Online

not enough space for environment

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.

Information for Programmers


There was enough memory to load the program, but not enough memory to create the envp array. This can be
caused by extremely low memory conditions, or by unusually large environment variable usage. Consider one of
the following solutions:
Increase the amount of memory available to the program.
Reduce the number and size of command-line arguments.
Reduce the environment size by removing unnecessary variables.
C Runtime Error R6016
10/31/2018 • 2 minutes to read • Edit Online

not enough space for thread data

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.

Information for Programmers


This error occurs because the program did not receive enough memory from the operating system to complete a
_beginthread or _beginthreadex call, or thread local storage has not been initialized by _beginthread or
_beginthreadex .

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

unexpected multithread lock error

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.

Information for Programmers


The process received an unexpected error while trying to access a C runtime multithread lock on a system
resource. This error usually occurs if the process inadvertently alters the runtime heap data. However, it can also be
caused by an internal error in the runtime library or operating-system code.
To fix this issue, check for heap corruption bugs in your code. For more information and examples, see CRT Debug
Heap Details. Next, check that you are using the latest redistributables for your app deployment. For information,
see Deployment in Visual C++.
C Runtime Error R6018
10/31/2018 • 2 minutes to read • Edit Online

unexpected heap error

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.

Information for Programmers


The program encountered an unexpected error while performing a memory-management operation.
This error usually occurs if the program inadvertently alters the run-time heap data. However, it can also be caused
by an internal error in the runtime or operating-system code.
To fix this issue, check for heap corruption bugs in your code. For more information and examples, see CRT Debug
Heap Details. Next, check that you are using the latest redistributables for your app deployment. For information,
see Deployment in Visual C++.
C Runtime Error R6019
10/31/2018 • 2 minutes to read • Edit Online

unable to open console device

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.

Information for Programmers


This error occurs because the app called a console function, but the operating system did not grant access to the
console. Except in debugging mode, console functions are generally not allowed in Microsoft Store apps. If your
app requires administrator privileges to run, make sure it is installed to run as administrator by default.
C Runtime Error R6024
10/31/2018 • 2 minutes to read • Edit Online

not enough space for _onexit/atexit table

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.

Information for Programmers


This error occurs because there was no memory available for the _onexit or atexit function. This error is caused
by a low -memory condition. You may consider pre-allocating buffers at app startup to assist in saving user data
and performing a clean app exit in low -memory conditions.
C Runtime Error R6025
10/31/2018 • 2 minutes to read • Edit Online

pure virtual function call

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.

Information for Programmers


No object has been instantiated to handle the pure virtual function call.
This error is caused by calling a virtual function in an abstract base class through a pointer which is created by a
cast to the type of the derived class, but is actually a pointer to the base class. This can occur when casting from a
void* to a pointer to a class when the void* was created during the construction of the base class.
C Runtime Error R6026
10/31/2018 • 2 minutes to read • Edit Online

not enough space for stdio initialization

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.

Information for Programmers


This error occurs when there is not enough free memory available to initialize the standard I/O support in the C
runtime. This error usually occurs at app startup. Verify that your app and the drivers and dlls that it loads do not
corrupt the heap at startup.
C Runtime Error R6027
10/31/2018 • 2 minutes to read • Edit Online

not enough space for lowio initialization

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.

Information for Programmers


This error occurs when there is not enough free memory available to initialize the low -level I/O support in the C
runtime. This error usually occurs at app startup. Verify that your app and the drivers and dlls that it loads do not
corrupt the heap at startup.
C Runtime Error R6028
10/31/2018 • 2 minutes to read • Edit Online

unable to initialize heap

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.

Information for Programmers


This error occurs when the operating system failed to create the memory pool for the application. Specifically, the
C Runtime (CRT) called the Win32 function HeapCreate , which returned NULL indicating failure.
If this error occurs during app startup, the system may be unable to satisfy heap requests because defective drivers
are loaded. Check Windows Update or your hardware vendor’s web site for updated drivers.
C Runtime Error R6030
10/31/2018 • 2 minutes to read • Edit Online

CRT not initialized

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.

Information for Programmers


This error occurs if you are using the C Runtime (CRT), but the CRT startup code was not executed. It is possible to
get this error if the linker switch /ENTRY is used to override the default starting address, usually
mainCRTStartup, wmainCRTStartup for a console EXE, WinMainCRTStartup or wWinMainCRTStartup for a
Windows EXE, or _DllMainCRTStartup for a DLL. Unless one of the above functions is called on startup, the C
Runtime will not be initialized. These startup functions are ordinarily called by default when you link to the C
runtime library and use the normal main, wmain, WinMain, or DllMain entry points.
It's also possible to get this error when another program uses code injection techniques to trap certain DLL library
calls. Some intrusive security programs use this technique. In versions of Visual C++ before Visual Studio 2015,
it's possible to use a statically-linked CRT library to address the issue, but this is not recommended for reasons of
security and application updates. Correcting this issue may require end-user action.
C Runtime Error R6031
10/31/2018 • 2 minutes to read • Edit Online

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.

Information for Programmers


This diagnostic indicates that MSIL instructions were executing during loader lock. For more information, see
Initialization of Mixed Assemblies.
C Runtime Error R6032
10/31/2018 • 2 minutes to read • Edit Online

Not enough space for locale information

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.

Information for Programmers


The runtime maintains information about the locale on each thread so that it can process calls to locale-sensitive
functions. If the allocation of the memory for this information fails, the runtime is unable to proceed because too
many of its basic facilities depend on it.
C Runtime Error R6033
10/31/2018 • 2 minutes to read • Edit Online

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.

Information for Programmers


This diagnostic indicates that MSIL instructions were executing during loader lock. This can occur if you have
compiled native C++ by using the /clr flag. Only use the /clr flag on modules that contain managed code. For more
information, see Initialization of Mixed Assemblies.
C Runtime Error R6035
10/31/2018 • 2 minutes to read • Edit Online

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 .

// Wrong way to call __security_init_cookie


DllEntryPoint(...) {
DllInitialize();
...
__try {
...
} __except()... {
...
}
}

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

out of heap space


To fix by using the following possible solutions
1. Increase the Windows swap-file space. For more information about increasing the swap-file space, see
virtual memory in Windows help.
2. Split the current file into smaller files and compile them separately.
3. Remove other programs or drivers running on the system.
Resource Compiler Fatal Error RC1004
10/31/2018 • 2 minutes to read • Edit Online

unexpected end of file found


This error can be caused by missing linefeed and carriage return characters on the last line of a text file.
Resource Compiler Fatal Error RC1009
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : macros too deeply nested 'macro'


The file exceeds the Resource Compiler limit for macro nesting. Revise the specified source file to decrease the
nesting depth of its macros.
Resource Compiler Fatal Error RC1011
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : 'identifier' : macro definition too big


Try to split the definition into shorter definitions.
Resource Compiler Fatal Error RC1015
10/31/2018 • 2 minutes to read • Edit Online

cannot open include file 'filename'


The given include file does not exist, could not be opened, or was not found.
Make sure that the environment settings are valid and that the correct path for the file is specified. Ensure that
sufficient file handles are available to the Resource Compiler. If the file is on a network drive, make sure that you
have permissions to open the file.
RC1015 can occur even if the include file exists in a directory specified as an Additional Include Directory in the
Configuration Properties -> Resources -> General property page; specify the complete path to the include file.
Resource Compiler Fatal Error RC1017
10/31/2018 • 2 minutes to read • Edit Online

invalid integer constant expression


The expression in an #if directive either did not exist or does not evaluate to a constant.
Resource Compiler Fatal Error RC1018
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

invalid preprocessor command 'string'


The characters following the number sign (#) did not form a valid preprocessor directive.
The number sign cannot be used as the first character in an identifier.
Resource Compiler Fatal Error RC1022
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

"too many option options, 'string'"


The given option was specified too many times. The given string is the argument to the option that caused the
error.
Resource Compiler Fatal Error RC1052
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : #if or #ifdef blocks nested too deeply


The program exceeded the maximum allowable nesting levels for #if and #ifdef directives.
This error can be caused by include files that use these preprocessor directives.
To fix this issue, reduce the number of nested #if and #ifdef directives in your resource file. If the issue is caused
by header files that are included in your resource file, reduce the number of nested #if and #ifdef directives in
the header files. If this is not possible, consider creating and including a new header file in your resource file, by
running the preprocessor on the existing included header files. For more information, see the /P (Preprocess to a
File) compiler option.
Resource Compiler Fatal Error RC1067
10/31/2018 • 2 minutes to read • Edit Online

compiler limit : identifier overflowed internal buffer


An internal compiler limit was exceeded.
Resource Compiler Fatal Error RC1101
10/31/2018 • 2 minutes to read • Edit Online

no resource binary filename specified

The Rename Output (/fo) option was not followed by a filename.


Use the following syntax for the /fo option:

RC /fo outfilename infilename.rc


Resource Compiler Fatal Error RC1102
10/31/2018 • 2 minutes to read • Edit Online

internal error : too many arguments to RCPP


Too many arguments were passed to the Resource Compiler preprocessor. Reduce the number of symbols defined
with the Define Symbols (/d) option by defining them in your source. This error can also be caused by specifying
too many include file search paths using the Include Search Path option (/i).
Resource Compiler Fatal Error RC1105
10/31/2018 • 2 minutes to read • Edit Online

invalid switch, option: too many /d switches


Too many symbols were defined using the Define Symbols (/d) option. Define some symbols in your source and
recompile.
Resource Compiler Fatal Error RC1109
10/31/2018 • 2 minutes to read • Edit Online

error creating resource-name


Could not create specified .res file. Make sure it is not being created on a read-only drive. Use the /V option to find
out whether the file is being created.
Resource Compiler Fatal Error RC1116
10/31/2018 • 2 minutes to read • Edit Online

RC terminating after preprocessor errors


The Resource Compiler halted due to other errors. Fix the other errors and recompile.
Resource Compiler Fatal Error RC1120
10/31/2018 • 2 minutes to read • Edit Online

out of memory, needed number bytes


The Resource Compiler ran out of storage for items that it stores in its heap. Usually this is the result of having too
many symbols.
To fix by using the following possible solutions
1. Increase the Windows swap file space. For more information about increasing the swap-file space, see
virtual memory in Windows help.
2. Eliminate unnecessary include files, especially unneeded #define s and function prototypes.
3. Split the current file into two or more files and compile them separately.
4. Remove other programs or drivers running in the system, which could be consuming significant amounts of
memory.
Resource Compiler Fatal Error RC1121
10/31/2018 • 2 minutes to read • Edit Online

I/O error reading file


The Resource Compiler was not able to read a file. Check that the drive containing the file is available and that the
file is valid.
Resource Compiler Fatal Error RC1203
10/31/2018 • 2 minutes to read • Edit Online

invalid hexadecimal default language ID specified.


The Specify Default Language (/l) option was followed by an invalid hexadecimal language ID. See Language and
Country/Region Strings in the Run-Time Library Reference for a list of valid language IDs.
Resource Compiler Fatal Error RC1205
10/31/2018 • 2 minutes to read • Edit Online

invalid code page


The Specify Code Page (/c) option was followed by an invalid code page. See Code Pages in the Run-Time Library
Reference for more information.
Resource Compiler Fatal Error RC1208
10/31/2018 • 2 minutes to read • Edit Online

input file has .RES extension


The .RES extension is used for Resource Compiler output. The .RC extension should be used for Resource Compiler
scripts.
Resource Compiler Error RC2001
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

too many chars in constant


A character constant contained more than two characters.
Character constants are limited to one character (standard character constants) or two characters (long character
constants).
Note that an escape sequence (for example, \t for tab) is converted to a single character.
Resource Compiler Error RC2017
10/31/2018 • 2 minutes to read • Edit Online

illegal escape sequence


An escape sequence appeared where one was not expected.
An escape sequence — a backslash ( \ ) followed by a number or letter — may occur only in a character or string
constant.
Resource Compiler Error RC2101
10/31/2018 • 2 minutes to read • Edit Online

Invalid directive in preprocessed RC file


The Resource Compiler file contains a #pragma directive.
Use the #ifndef preprocessor directive with the RC_INVOKED constant that the Resource Compiler defines when
it processes an include file. Place the #pragma directive inside a block of code that is not processed when the
RC_INVOKED constant is defined. Code in the block is processed only by the C/C++ compiler and not by the
Resource Compiler. The following sample code demonstrates this technique:

#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

unexpected end of file in string literal


An end of file was found before the end of a string. The string is probably missing a closing double quotation mark
(").
Resource Compiler Error RC2104
10/31/2018 • 2 minutes to read • Edit Online

undefined keyword or key name: key


The specified keyword or key name is not defined.
This error is often caused by a typo in the resource definition, or in the included header file. It can also be caused by
a missing header file.
To fix the issue, locate the header file that should contain the defined keyword or key name and verify that it is
included in your resource file, and that the keyword or key name is spelled correctly. If your project was created
with a precompiled header, and you subsequently remove it, make sure that the resource file still includes any
required headers.
To verify the defined keywords and key names in your resource file, in Visual Studio, open the Resource View
window —on the menu bar, choose View, Resource View—and then open the shortcut menu for the .rc file and
choose Resource Symbols to view the list of defined symbols. To modify the included headers, open the shortcut
menu for the .rc file and choose Resource Includes.
If you encounter this message:

undefined keyword or key name: MFT_STRING

open \MCL\MFC\Include\AfxRes.h and add this include directive:

#include <winresrc.h>
Resource Compiler Error RC2107
10/31/2018 • 2 minutes to read • Edit Online

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.
Resource Compiler Error RC2109
10/31/2018 • 2 minutes to read • Edit Online

expected numerical dialog constant


A DIALOG statement requires integer values for the x, y, width, and height fields. Make sure these values are
included after the DIALOG keyword and that they are not negative.
Resource Compiler Error RC2111
10/31/2018 • 2 minutes to read • Edit Online

invalid control type


Each CONTROL statement in a DIALOG statement must be one of the following: 3STATE, AUTO3, AUTOCHECK,
AUTORADIO, BEDIT, CHECKBOX, COMBOBOX, CONTROL, CTEXT, DEFPUSHBUTTON, EDITTEXT,
GROUPBOX, HEDIT, ICON, IEDIT, LISTBOX, LTEXT, PUSHBOX, PUSHBUTTON, RADIOBUTTON, RTEXT,
SCROLLBAR, USERBUTTON.
Make sure these CONTROL statements are spelled correctly.
Resource Compiler Error RC2112
10/31/2018 • 2 minutes to read • Edit Online

BEGIN expected in dialog


The BEGIN keyword must immediately follow the DIALOG keyword.
Resource Compiler Error RC2113
10/31/2018 • 2 minutes to read • Edit Online

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.
Resource Compiler Error RC2114
10/31/2018 • 2 minutes to read • Edit Online

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.
Resource Compiler Error RC2116
10/31/2018 • 2 minutes to read • Edit Online

expecting number for ID


Expecting a number for the id field of a control statement in the DIALOG statement. Make sure you have a
number or #define statement for the control ID.
Resource Compiler Error RC2122
10/31/2018 • 2 minutes to read • Edit Online

unknown menu subtype


The item -definition field of the MENU statement can contain only MENUITEM and POPUP statements.
Resource Compiler Error RC2124
10/31/2018 • 2 minutes to read • Edit Online

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.
Resource Compiler Error RC2127
10/31/2018 • 2 minutes to read • Edit Online

version WORDs separated by commas expected


Version numbers in a version resource should be of type WORD, and separated by commas.
Resource Compiler Error RC2135
10/31/2018 • 2 minutes to read • Edit Online

file not found: filename


The file specified in the Resource Compiler command line was not found. Check to see whether the file has been
moved to another directory and whether the file name and path are typed correctly.
Files are searched for using the INCLUDE environment variable or the Visual C++ INCLUDE setting.
Resource Compiler Error RC2144
10/31/2018 • 2 minutes to read • Edit Online

PRIMARY LANGUAGE ID not a number


The PRIMARY LANGUAGE ID must be a hexadecimal language ID. See Language and Country/Region Strings in
the Run-Time Library Reference for a list of valid Language IDs.
This error can also occur if resources have been added and deleted from the .RC file using a tool. To fix this issue,
open the .RC file in a text editor and clean up any unused resources manually.
Resource Compiler Error RC2147
10/31/2018 • 2 minutes to read • Edit Online

SUBLANGUAGE ID not a number


The SUBLANGUAGE ID value must be a number.
The LANGUAGE statement must use the following syntax:
LANGUAGE primary_language_ID,secondary_language_ID
Valid SUBLANGUAGE IDs are defined as SUBLANG_ constants in the WINNT.h file.
Resource Compiler Error RC2148
10/31/2018 • 2 minutes to read • Edit Online

SUBLANGUAGE ID too large


The SUBLANGUAGE ID value was out of range.
The LANGUAGE statement must use the following syntax:
LANGUAGE primary_language_ID,secondary_language_ID
Valid SUBLANGUAGE IDs are defined as SUBLANG_ constants in the WINNT.h file.
Resource Compiler Error RC2151
10/31/2018 • 2 minutes to read • Edit Online

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.
Resource Compiler Error RC2152
10/31/2018 • 2 minutes to read • Edit Online

invalid control character


A control character in the ACCELERATORS statement is invalid. A valid control character consists of one letter
(only) following a caret (^).
Resource Compiler Error RC2162
10/31/2018 • 2 minutes to read • Edit Online

expected macro formal parameter


The token following a stringizing operator (#) was not a formal parameter name.
Resource Compiler Error RC2163
10/31/2018 • 2 minutes to read • Edit Online

accelerator type required [ASCII or VIRTKEY ]


The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.
Resource Compiler Error RC2164
10/31/2018 • 2 minutes to read • Edit Online

unexpected value in RCDATA


The raw -data values in the RCDATA statement must be integers or strings, each separated by a comma. Make sure
you did not leave out a comma or leave out a quotation mark around a string.
Resource Compiler Error RC2165
10/31/2018 • 2 minutes to read • Edit Online

string not found in DLGINCLUDE statement


The statement did not specify a valid include file.
The DLGINCLUDE statement must use the following syntax:
DLGINCLUDE "filename.h"
Resource Compiler Error RC2167
10/31/2018 • 2 minutes to read • Edit Online

unrecognized VERSIONINFO field; BEGIN or comma expected


An unrecognized field was found in the FIXED part of a VERSIONINFO structure declaration. A VERSIONINFO
field must be DWORDS separated by a comma.
Resource Compiler Error RC2169
10/31/2018 • 2 minutes to read • Edit Online

resource file filename is not in 2.03 format


The specified resource used a format earlier than version 2.03. The resource file must be converted or recreated
using the format for version 3.00 or later.
Resource Compiler Error RC2170
10/31/2018 • 2 minutes to read • Edit Online

bitmap file filename is not in 3.00 format


Bitmaps using the Windows version 2.x format cannot be used in version 3.x resource files.
To fix this issue, redraw or convert the bitmap to 3.x format.
Resource Compiler Error RC2171
10/31/2018 • 2 minutes to read • Edit Online

unknown DIB header format


The bitmap header is not a BITMAPCOREHEADER or BITMAPINFOHEADER structure.
Resource Compiler Error RC2175
10/31/2018 • 2 minutes to read • Edit Online

resource file filename is not in 3.00 format


The specified resource used a format earlier than version 3.00. The resource file must be converted or recreated
using the format for version 3.00 or later.
Resource Compiler Warning RC4002
10/31/2018 • 2 minutes to read • Edit Online

too many actual parameters for macro 'identifier'


The number of actual parameters specified with the given identifier was greater than the number of formal
parameters given in the macro definition of the identifier.
The additional actual parameters were collected but ignored during expansion of the macro.
Resource Compiler Warning RC4005
10/31/2018 • 2 minutes to read • Edit Online

'identifier' : macro redefinition


The identifier is defined twice. The compiler used the second macro definition.
This warning can be caused by defining a macro on the command line and in the code with a #define directive. It
also can be caused by macros imported from include files.
To eliminate the warning, either remove one of the definitions or use an #undef directive before the second
definition.
Resource Compiler Warning RC4093
10/31/2018 • 2 minutes to read • Edit Online

unescaped newline in character constant in inactive code


The constant expression of an #if , #elif , #ifdef, or #ifndef preprocessor directive evaluated to zero, making the
code that follows inactive. Within that inactive code, a newline character appeared within a set of single or double
quotation marks.
All text until the next double quotation mark was considered to be within a character constant.
Resource Compiler Warning RC4214
10/31/2018 • 2 minutes to read • Edit Online

Codepage not valid : ignored


The .rc file contained a codepage argument and the codepage specified is invalid. See IsValidCodePage for more
information.
Resource Compiler Errors RW1004 through RW4004
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

Unexpected end of file


This error can be caused by missing linefeed and carriage-return characters on the last line of a text file.
Resource Compiler Fatal Error RW1009
10/31/2018 • 2 minutes to read • Edit Online

Error creating resource-name


Could not create specified .res file. Make sure it is not being created on a read-only drive. Use /V to find out
whether the file is being created.
Resource Compiler Fatal Error RW1016
10/31/2018 • 2 minutes to read • Edit Online

RC terminating after preprocessor errors


The Resource Compiler halted due to other errors. Fix the other errors and recompile.
Resource Compiler Fatal Error RW1022
10/31/2018 • 2 minutes to read • Edit Online

I/O error writing file


The Resource Compiler could not write to a file.
To fix by checking the following possible causes
1. Insufficient disk space. Free space must equal at least twice the size of the executable file you are creating.
2. Volume is read-only.
3. Bad sector.
4. Sharing violation.
Resource Compiler Fatal Error RW1023
10/31/2018 • 2 minutes to read • Edit Online

I/O error writing file, drive full


Free space must equal at least twice the size of the executable file you are creating.
Resource Compiler Fatal Error RW1025
10/31/2018 • 2 minutes to read • Edit Online

Out of far heap memory


Check for memory-resident software that might be taking up too much space. Use the CHKDSK program to find
out how much memory you have.
If you are creating a large resource file, split the resource script into two files. After creating two .res files, use the
MS -DOS command line to join them together:

copy first.res /b + second.res /b full.res


Resource Compiler Fatal Error RW1030
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

Invalid directive in preprocessed RC file


The RC file contains a #pragma directive.
Use the #ifndef preprocessor directive with the RC_INVOKED constant that the Resource Compiler defines when
it processes an include file. Place the #pragma directive inside a block of code that is not processed when the
RC_INVOKED constant is defined. Code in the block is processed only by the C/C++ compiler and not by the
Resource Compiler. The following sample code demonstrates this technique:

#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.

23. Expecting number for ID


Expecting a number for the id field of a control statement in the DIALOG statement. Make sure you have
a number or #define statement for the control ID.
24. Expecting quoted string in dialog class
The class field of the CLASS option in the DIALOG statement must be an integer or a string, enclosed in
double quotation marks.
25. Expecting quoted string in dialog title
The captiontext field of the CAPTION option in the DIALOG statement must be an ASCII character string
enclosed in double quotation marks.
26. File not found: filename
The file specified in the Resource Compiler command line was not found. Check to see whether the file has
been moved to another directory and whether the filename or path is typed correctly. Files are searched for
using the INCLUDE environment variable or the Visual Workbench setting, if available.
27. Font names must be ordinals
The pointsize field in the FONT statement must be an integer, not a string.
28. Invalid accelerator
An event field in the ACCELERATORS statement was not recognized or was more than two characters in
length.
29. Invalid accelerator type (ASCII or VIRTKEY )
The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.
30. Invalid control character
A control character in the ACCELERATORS statement is invalid. A valid control character consists of one
letter (only) following a caret (^).
31. Invalid control type
Each control statement in a DIALOG statement must be one of the following: CHECKBOX, COMBOBOX,
CONTROL, CTEXT, DEFPUSHBUTTON, EDITTEXT, GROUPBOX, ICON, LISTBOX, LTEXT, PUSHBUTTON,
RADIOBUTTON, RTEXT, SCROLLBAR. Make sure these control statements are spelled correctly.
32. Invalid type
The resource type was not among the types defined in the WINDOWS.h file.
33. Text string or ordinal expected in control
The text field of a CONTROL statement in the DIALOG statement must be either a text string or an ordinal
reference to the type of control. If using an ordinal, make sure that you have a #define statement for the
control.
34. Mismatched parentheses
Make sure you have closed every open parenthesis in the DIALOG statement.
35. Unexpected value in RCData
The raw -data values in the RCDATA statement must be integers or strings, each separated by a comma.
Make sure you did not leave out a comma or leave out a quotation mark around a string.
36. Unknown menu subtype
The item -definition field of the MENU statement can contain only MENUITEM and POPUP statements.
Resource Compiler Error RW2003
11/9/2018 • 2 minutes to read • Edit Online

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

.EXE processing options (/L /M /P /T /K /E /31 or /30)


You specified EXE processing options, but there was no executable file to process. Don't use these options with a
.res file.
Resource Compiler Warning RW4003
10/31/2018 • 2 minutes to read • Edit Online

SHIFT or CONTROL used without VIRTKEY


In an accelerator table resource, SHIFT or CONTROL requires VIRTKEY. Because SHIFT and CONTROL are
indicated as flag bits in a VIRTKEY type accelerator, they cannot exist independent from a VIRTKEY.
Resource Compiler Warning RW4004
10/31/2018 • 2 minutes to read • Edit Online

ASCII character not equivalent to virtual key code


A string literal was used for the virtual key code in a VIRTKEY type accelerator.
This warning allows you to continue, but be aware that the accelerator keys generated may not match the string
you indicated. (VIRTKEYs use different key codes than ASCII accelerators.)
While string literals are syntactically valid, you can only ensure that you get the accelerator you want by using the
VK_* #define values in WINDOWS.h.
CVTRES Errors CVT1100 Through CVT4001
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

duplicate resource — type:type, name:name, language:language, flags:flags, size:size


The given resource was specified more than once.
You can get this error if the linker is creating a type library and you did not specify /TLBID and a resource in your
project already uses 1. In this case, specify /TLBID and specify another number up to 65535.
CVTRES Fatal Error CVT1103
10/31/2018 • 2 minutes to read • Edit Online

cannot read filename


An unrecoverable error occurred when CVTRES attempted to read the given file.
This error can be caused by file corruption.
CVTRES Fatal Error CVT1105
10/31/2018 • 2 minutes to read • Edit Online

cannot seek in file


CVTRES could not go to a location in the file.
This error can be caused by file corruption.
CVTRES Warning CVT4001
10/31/2018 • 2 minutes to read • Edit Online

machine type not specified; assumed type

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

error result returned from 'command line'.

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

Error spawning 'command line'.

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

Could not generate command line for the 'tool' tool.

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

Unable to create a temporary file in directory 'directory'.


The call to create a temporary file failed. Reasons for failure include:
Ran out of temporary file names.
The temp directory is read-only.
There is no temp directory or TMP environment variable.
Your computer is out of free disk space.
Project Build Error PRJ0006
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

Could not create output directory 'directory'.


Visual C++ failed to create an output directory. Possible reasons include:
The directory in which the output directory was to be created is read-only.
Computer is out of disk space.
You specified an invalid directory path.
User permissions are not sufficient to create the directory.
Project Build Error PRJ0008
3/12/2019 • 2 minutes to read • Edit Online

Could not delete file 'file'.


Make sure that the file is not open by another process and is not write-protected.
During a rebuild or clean, Visual C++ deletes all known intermediate and output files for the build, as well as any
files that meet the wildcard specifications in the Extensions to Delete on Clean property in the General
Configuration Settings Property Page.
You will see this error if Visual C++ is not able to delete a file. To resolve the error, make the file and its directory
writeable for the user doing the build.
Project Build Error PRJ0009
10/31/2018 • 2 minutes to read • Edit Online

Build log could not be opened for writing.


Make sure that the file is not open by another process and is not write-protected.
After setting the Build Logging property to Yes and performing a build or rebuild, Visual C++ was unable to
open the build log in exclusive mode.
Inspect the Build Logging setting by opening the Options dialog box (on the Tools menu, click Options
command) and then selecting VC++ Build in the Projects folder. The build file is called BuildLog.htm and is
written to the intermediate directory $(IntDir).
Possible reasons for this error:
You are running two processes of Visual C++ and trying to build the same configuration of the same project
in both simultaneously.
The build log file is opened in a process that locks the file.
The user does not have permission to create a file.
The current user does not have write access to the file BuildLog.htm.
Project Build Error PRJ0013
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 current working directory is invalid.


The path to the current working directory is longer than _MAXPATH. To resolve this error, do not create your
project at such a deep level.
Project Build Warning PRJ0018
3/12/2019 • 2 minutes to read • Edit Online

The following environment variables were not found:


An environment variable is not defined. This error lists the environment variables that were not defined.
See Macros for Custom Build Commands for information on macros in the build process.
Project Build Error PRJ0019
3/12/2019 • 2 minutes to read • Edit Online

A tool returned an error code from


An error level was nonzero for a custom build step or build event.
You will also see PRJ0019 when a tool returned an error code but no error message. This can happen, for example,
if you redirect the output of MIDL to NUL.
See Troubleshooting Custom Build Steps and Build Events for more information.
This error can also occur when you are running as a member of the Users group and Administrative access is
needed. For more information, see Running as a Member of the Users Group.
Project Build Error PRJ0020
3/12/2019 • 2 minutes to read • Edit Online

Tool 'tool', Property 'property' contains invalid file name 'file'.

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

Tool 'tool', Property 'property' contains invalid file name.

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

Unknown Tool, Property 'property' contains invalid file name 'file'.

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

Tool 'tool', Unknown Property contains invalid file name 'file'.

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

Macro expansion error. Evaluate recursion exceeded 32 levels for $(macro).


This error is caused by recursion in your macros. For example, if you set the Intermediate Directory property
(see General Property Page (Project)) to $(IntDir), you will have recursion.
To resolve this error, do not define macros or properties in terms of macros they are used to define.
Project Build Error PRJ0031
10/31/2018 • 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.

FOR INFORMATION ABOUT SEE

The compiler options to use /doc

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:

<c> <code> <example>

<exception>1 <include>1 <list>

<para> <param>1 <paramref>1

<permission>1 <remarks> <returns>

<see>1 <seealso>1 <summary>

<value>

1. Compiler verifies syntax.


In the current release, the MSVC compiler does not support <paramref> , a tag that is supported by other Visual
Studio compilers. Visual C++ may support <paramref> in a future release.

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

/// Text for class MyClass.


class MyClass {
public:
int m_i;
MyClass() : m_i(0) {}

/// <summary><c>MyMethod</c> is a method in the <c>MyClass</c> class.


/// </summary>
int MyMethod(MyClass * a) {
return a -> m_i;
}
};

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

/// Text for class MyClass.


public ref class MyClass {
public:
/// <summary>
/// GetZero method
/// </summary>
/// <example> This sample shows how to call the GetZero method.
/// <code>
/// int main()
/// {
/// return GetZero();
/// }
/// </code>
/// </example>
static int GetZero() {
return 0;
}
};

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;

/// Text for class EClass.


public ref class EClass : public Exception {
// class definition ...
};

/// <exception cref="System.Exception">Thrown when... .</exception>


public ref class TestClass {
void Test() {
try {
}
catch(EClass^) {
}
}
};
See also
XML Documentation
<include>
3/12/2019 • 2 minutes to read • Edit Online

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

/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test"]/*' />


public ref class Test {
void TestMethod() {
}
};

/// <include file='xml_include_tag.doc' path='MyDocs/MyMembers[@name="test2"]/*' />


public ref class Test2 {
void Test() {
}
};

The second file, xml_include_tag.doc, contains the following documentation comments:


<MyDocs>

<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 .

A list or table can have as many <item> blocks as needed.


Compile with /doc to process documentation comments to a file.

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

using namespace System;

/// <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

/// Text for class MyClass.


public ref class MyClass {
public:
/// <returns>Returns zero.</returns>
int GetZero() { return 0; }
};

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 {};

// the following cref shows another way to specify the reference,


// such that, the compiler will resolve the reference
/// <see cref="C < T >"/>

// the following cref shows how to hard-code the reference


/// <see cref="T:C`1">
/// </see>
ref class B {};

/// <see cref="A">


/// </see>
/// <typeparam name="T"></typeparam>
generic<class T>
ref class C {};

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 for class A.


public ref struct A {
/// <summary><seealso cref="A::Test"/>
/// <seealso cref="B::Test"/>
/// </summary>
void MyMethod(int Int1) {}

/// text
void Test() {}
};

/// Text for class B.


public ref struct B {
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 for class MyClass.


public ref class MyClass {
public:
/// <summary>MyMethod is a method in the MyClass class.
/// <para>Here's how you could make a second paragraph in a description. <see
cref="System::Console::WriteLine"/> for information about output statements.</para>
/// <seealso cref="MyClass::MyMethod2"/>
/// </summary>
void MyMethod(int Int1) {}

/// 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

You cannot add documentation comments to a


namespace, cref references to a namespace are possible.

T type: class, interface, struct, enum, delegate

D typedef

F field

P property (including indexers or other indexed properties)

M method (including such special methods as constructors,


operators, and so forth)

E event

! error string

The rest of the string provides information about the error.


The MSVC compiler generates error information for links
that cannot be resolved.

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">

For a type that is defined as public class MyClass<T, U> .


For methods taking generic types as parameters, the generic type parameters are specified as numbers
prefaced with back ticks (for example `0, `1). Each number representing a zero-based array notation for the
type's generic parameters.
Example
The following examples show how the ID strings for a class and its members would be generated.

// xml_id_strings.cpp
// compile with: /clr /doc /LD
///
namespace N {
// "N:N"

/// <see cref="System" />


// <see cref="N:System"/>
ref class X {
// "T:N.X"

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:

/// This is the form that is shown in documentation examples and


used by the Visual C++ project templates.

/** */ These are multiline delimiters.

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

You might also like