Managed Extensions for C++

Starting with Visual C++ version 7.0, the standard C++ language has been extended to provide support for programming in the NGWS runtime world. Managed Extensions for C++ are comprised of keywords and attributes.

Managed Extensions are designed to make the task of programming NGWS applications easier and quicker by implementing the following features:

  • Smooth migration of existing C++ applications to the NGWS platform.

    Managed Extensions are designed to migrate an existing C++ application to the NGWS platform (also known as the Virtual Execution System) with a single recompile. Once your application has successfully compiled, you can begin accessing the features of the NGWS runtime.

  • Language interoperability.

    By adhering to the NGWS runtime Common Language Specification (CLS), any class you create in C++ will be immediately accessible in any Visual Basic program or any other CLS-compliant language that targets the NGWS runtime, such as C#.

  • Easy access to the NGWS feature set.

    Managed Extensions give you access to the entire NGWS runtime feature set within your existing C++ application without giving up any of the traditional C++ benefits, such as custom memory allocation, direct access to the Windows APIs, and efficient manipulation of low-level machine details.

  • Memory management.

    Managed Extensions provide access to a garbage-collected memory heap provided by the NGWS runtime and automatic management of objects allocated from this heap. Garbage collection provides an automatic performance boost for most applications and allows the developer to focus on more important aspects of the application instead of on management of objects and pointers.

The following table contains links to information on Managed Extensions for C++ and managed programming:

For information about | See
Managed Extensions reference topics | Managed Extensions for C++ Keywords
Managed Extensions sample programs | Visual C++ Samples
Managed classes, objects, arrays, delegates, and value classes | Introduction to Managed Extensions for C++
Managed Extensions articles with procedures | Adding Support for Managed Extensions for C++ to an Existing Application
Compiler options | /com+ (NGWS runtime Compilation)
NGWS framework | NGWS Framework and runtime SDK

See Also

Writing Managed Programs

© 2000 Microsoft Corporation. All rights reserved.


Introduction to Managed Extensions for C++

Because Managed Extensions for C++ use a garbage-collected heap and targets the NGWS platform, several areas related to code and general programming procedures are new to C++ developers. The following list provides a general overview of these areas. Each topic contains information on various subjects related to Managed Extensions and provides sample code to illustrate the points of the article:

  • Managed Classes
  • Managed Arrays
  • Managed Strings
  • Value Classes in Managed Extensions for C++
  • Delegates in Managed Extensions for C++
  • Properties of Managed Objects
  • Handling Exceptions with Managed Extensions for C++
  • Using Global Attributes in Managed Exceptions for C++

See Also

Managed Extensions for C++


Managed Classes

Managed classes are a powerful and versatile feature of Managed Extensions for C++. In addition to the standard features of a C++ class, the NGWS runtime and the Visual C++ compiler provide new features for managed classes:

  • Extensible metadata

    A key concept for implementing modern component software, Managed Extensions provide built-in support for metadata and enables declaring new types and categories of metadata.

  • Garbage collection

    Managed Extensions allow the developer to specify that certain classes be allocated exclusively on the garbage-collected NGWS runtime heap, thereby removing the burden of lifetime management for the developer. Specifically, this means that you no longer must deal with complex bugs associated with reference counting or circular-reference leaks.

  • Simplified language interoperability

    Any managed class written in Managed Extensions is immediately usable from Visual Basic or any other language that targets the NGWS runtime. This ability removes the need for error-prone MIDL files or the restriction of using only BSTRs for your string objects.

  • Versionable

    A new version of a managed class that includes new methods and data members can be deployed, while maintaining binary compatibility with existing client software.

  • Binary headers

    Any file type that is able to contain metadata (.exe, .obj, or .dll) can be directly included into an Managed Extensions source file. The precompiled form also increases compilation speed.

    Note An ordinary C++ class is referred to as an unmanaged class. Unmanaged classes are always allocated from the standard C++ runtime heap.

There are three kinds of managed classes:

Managed class type | Purpose
Garbage-Collected Classes | Allocated on the NGWS runtime heap and the most general-purpose type of managed class.
Value Classes | Represents a small, short-lived data item (allocated on the stack) for which full garbage collection would be too costly.
Managed Interface Classes | Offers direct support for COM-style interface programming in C++.

The following features apply to all types of managed classes:

  • A managed class can inherit from any number of managed interfaces, or a managed class, or any number of managed interfaces and a managed class.
  • A managed class can declare a static class constructor.
  • A managed class can contain properties.
  • A managed class can have a visibility specifier. For more information, see Assemblies in Managed Extensions.
  • A managed class can implement any number of constructors and a destructor.
  • A managed class can have pointers to unmanaged classes as data members.

The following restrictions apply to all types of managed classes:

  • A managed class cannot inherit from unmanaged classes, and unmanaged classes cannot inherit from managed classes.
  • A managed class does not support friends.
  • A managed class cannot contain an instance of or a reference to an unmanaged class with nonstatic member functions.
  • A managed class should not be used with the sizeof operator.
  • Class or method names containing characters from the double-byte character set (DBCS) are CLS compliant. However, this is not true for managed classes or methods compiled using Managed Extensions for C++.

Garbage-Collected Classes

Because garbage-collected classes are allocated from the NGWS runtime heap, the following usage restrictions exist:

  • A garbage-collected class has exactly one base class. There is no multiple inheritance of garbage-collected classes. If no base class is specified, it is assumed to be the NGWS frameworks root class System::Object.
  • All instances of a garbage-collected class are created on the NGWS runtime garbage-collected heap using the built-in operator new. This means that only pointers to a garbage-collected class type are allowed. Object or parameter declarations or a function return of a garbage-collected class type is not allowed.
  • The __gc keyword cannot be used to qualify an unmanaged class type in an object declaration.
  • A garbage-collected class cannot have a copy constructor.
  • A garbage-collected class cannot override operator& or operator new.

Destroying a Managed Object

As in standard C++, a managed class may have a destructor, which can be called explicitly.

Note During garbage collection, the destructor is invoked before the associated memory is released.

A managed class may be explicitly destructed, either by calling the destructor directly or by using the delete operator. This allows an object to release its resources at a well-defined point. The destructor will not be called again when the garbage collector runs; only the memory will be reclaimed.

The following example demonstrates the explicit invoking of a managed object destructor:

void main ()
{
   ManagedObject* mObj1 = new ManagedObject();
   mObj1->AllocateResources();   // Allocate resources from the managed heap.
   delete mObj1;   // Frees those resources now.

// Alternatively, the objects destructor may be called directly
   mObj1 = new ManagedObject();
   mObj1->~ManagedObject();
}

If a garbage-collected class derives from a garbage-collected class authored in another language, the finalization method (if any) of the base class is treated as the destructor and is called automatically at the end of the destructor for the derived class.

Note A garbage-collected class may implement a finalization method. This method is called before unloading the object and is automatically called only once for each class.

If you are not certain that an object is dead, you can assign the value 0 to the pointer that references it. If that is the last pointer to the object, the garbage collector will automatically reclaim it.

Value Classes

A value class differs from a garbage-collected class in that instances can be allocated on the run-time stack and as static or heap-allocated variables under certain conditions. A value class is declared by applying the __value keyword to a class or struct declaration. Value classes are designed to hold small data items with short lifetimes, so as not to have the overhead of garbage collection for every allocation. They can also be members of a garbage-collected class.

In addition to those features common to all managed classes, the following features are also supported for value classes:

  • A value class cannot implement a copy constructor. You cannot declare a pointer to a value class.
  • A value class can derive from one or more managed interfaces.
  • A value class can override any method of the System::ValueType class.
  • A value class can be allocated from the run-time stack or from the NGWS runtime heap as a member of a managed class.
  • A value class that does not contain any managed pointers can be allocated anywhere an unmanaged class can be allocated.

In addition to those restrictions common to all managed classes, the following restrictions are also in effect for value classes:

  • A value class can only inherit from one or more managed interfaces. It cannot inherit from a garbage-collected or another value class.
  • A value class cannot declare any virtual methods not previously defined by System::ValueType.
  • A value class cannot have the __abstract keyword applied to it.
  • By definition, a value-class is sealed and therefore a value-class cannot be used as a base-class
  • A value class cannot be allocated directly from the NGWS runtime heap. However, instances of the value class may exist in the NGWS runtime heap by embedding in garbage-collected classes or boxing.
  • Value classes cannot use an initializer list if the value class contains managed objects.

Value Classes and Boxing

When the __box keyword is applied to a class or struct object, it is referred to as boxing the class or struct. This instance can then be treated as a managed object.

For every definition of a value class, there exists a unique boxed value class type corresponding to the original value class. All boxed value class types inherit from the garbage-collected class System::ValueType. Enumerated types that are boxed (sometimes referred to as managed enums) inherit from the garbage-collected class System::Enum. You cannot define boxed types directly; the compiler generates them on demand as needed. Referring to the boxed value class by its boxed type is more precise than using the generic type Object and allows the user to avoid expensive dynamic cast operations when accessing the underlying value type.

Because a boxed value class implicitly inherits from System::ValueType and therefore System::Object, a value class may directly call any function it specifically implements without being boxed first. This includes any overrides of virtual member functions defined in System::ValueType. The following example overrides the ToString member of ValueType and then invokes it directly from an instance of the value class V:

__value struct V
{
   // Override ValueType::ToString
   String *ToString() { return i.ToString(); }
   int i;
};

void main()
{
   V v = {10};
   Console::WriteLine(v.ToString());   // Boxing not required
}

A value class member can be accessed from the boxed version using the same syntax as accessing an unboxed value member. The following example demonstrates this by accessing the data member (i)of a boxed value class (V):

__value struct V
{
   int i;
};

void main()
{
   V v = {10};
   __box V* pbV= __box(v);
   assert(pbV->i == 10);
}

To call a virtual function of System::ValueType that has not been overridden in the value type, boxing is required. The following example uses the same value class (without the explicit override of ToString), invoking ToString by boxing the value class first:

__value struct V
{
   int i;
};

void main()
{
   V v = {10};
   v.i = 10;
   Console::WriteLine(v.ToString());   // Error: boxing required
   Console::WriteLine(__box(v)->ToString());   // OK: prints V
}

Managed Interfaces

An interface declaration is made by applying the __interface keyword to an existing class declaration:

__interface IMyInterface
{
   void method_one();
};

A managed interface embodies the COM notion of an interface (with the added benefits of being managed) and is declared by applying the __gc keyword to an existing interface declaration:

__gc __interface IMyInterface
{
   void method_one();
};

The previous code sample declares a managed interface (IMyInterface) that is essentially a managed C++ abstract base class. Like an abstract base class, the methods of a managed interface are implicitly pure virtual methods.

The following rules apply to managed interfaces:

  • A managed interface cannot contain data members or static members.
  • A managed interface can contain only the public access specifier, which is the default.
  • A managed interface cannot provide implementations for any declared methods of the managed interface.
  • A managed interface can only inherit from other managed interfaces.
  • A managed interface cannot have the __sealed keyword applied to it.

Implementation of Ambiguous Base Interface Methods

Managed Extensions for C++ allow two or more base interfaces of a class to declare identical methods. These ambiguous interface methods are implemented by providing a fully qualified name in the definition. The following example demonstrates this by declaring and defining the Calculate method for both sample interfaces IAccount and IStatement:

__gc __interface IAccount
{
   void Calculate();
};

__gc __interface IStatement
{
   void Calculate();
};

__gc struct CMyStatement: IAccount, IStatement
{
   void IAccount:: Calculate () {};   // OK
   void IStatement:: Calculate () {};   // OK
};

Default Implementation of a Method

Managed Extensions for C++ automatically provide a default implementation for methods that are not defined by the child class. Default implementation can also used to implement ambiguous base interface methods.

For example, the following code sample declares a class (CMyBase) and a managed interface (IMyInterface). Another class (CMyChild) is derived from CMyBase and IMyInterface but does not provide an implementation for the derived method Calculate:

__gc __interface IMyInterface
{
   void Calculate();
};
__gc struct CMyBase
{
   void Calculate(){}
};
__gc struct CMyChild : CMyBase, IMyInterface
{
   // By default, CMyChild uses CMyBase::Calculate to implement
   // IMyInterface::Calculate
};
void main()
{
   IMyInterface* pI = new CMyChild;   // OK: CMyChild is not abstract
   pI->Calculate();   // ok: calls CMyChild::Calculate (via default
                      //implementation)
}

See Also

Introduction to Managed Extensions for C++


Managed Arrays

Using Managed Extensions for C++, a managed array can be declared by using the __gc keyword or by containing a managed object type. Because managed arrays are allocated from the managed heap, these arrays have additional criteria and features for declaration and usage when compared to standard (unmanaged) arrays:

  • The definition of a managed array variable may not specify a size. The array size is given in the call to the managed operator new.
  • All managed arrays must be dynamically allocated using the managed operator new.
  • The indices of a managed array are zero based.
  • Because managed arrays automatically inherit from System::Array, any method from System::Array can be applied directly to the array variable.
  • When accessing static members of an object in a managed array, no bounds checking is performed. This means that accessing past the end of the array will not cause an error.

The following example declares and instantiates a simple managed array of integers:

void main ()
{
   int MyIntArray __gc[]= new int __gc[100];
}

To construct a managed String object from an array of type wchar_t characters, there is no need to zero-terminate the array if it is managed. However, if the wchar_t array is unmanaged, it must be zero-terminated. The following code example demonstrates this:

void main()
{
   String* s = new String(L"ab");

   wchar_t s1 __gc[] = new wchar_t __gc[2];   // array of two wchar_t's
   s1[0] = L'a';
   s1[1] = L'b';
// no zero-termination

   wchar_t s2[3];
   s2[0] = L'a';
   s2[1] = L'b';
   s2[2] = 0;   //must be zero-terminated

   String* str1 = new String(s1);

   if(s->Equals( str1 ))
      Console::WriteLine(S"managed passed");

   if(s->Equals( s2 ))
      Console::WriteLine(S"unmanaged passed");
}

Automatic Array Initialization

When allocating a managed array, the values of the array are automatically initialized to a standard value. This value is determined by the type of the managed array. The following table lists the possible value types and their respective default initialization values.

Value type of array | Default initialization value
C++ primitive data type (int, char, and others) | Zero initialized.
Managed class | Zero initialized.
Value type V (a value array) | The default constructor for the value type is applied to each array element.

Multidimensional Arrays

Managed Extensions also support managed arrays with multiple dimensions. The number of dimensions is equal to the number of commas in the declaration plus one. The following example declares a two-dimensional managed array of type Int32:

Int32 MyArray[,] = new Int32[10,20];   // Two dimensions
for(int row = 0; row < MyArray->GetLength(0); ++row)
{
   for(int col = 0; col < MyArray->GetLength(1); ++col)
      MyArray[row,col] = row+col;
}
Warning The standard C++ comma operator cannot be used inside managed array indices unless it is nested within parentheses.

Array Covariance

For managed arrays, Managed Extensions support the concept of covariance. Array covariance means that, given two types (A and B), an array value of type A can be treated as a reference to an array value of type B, provided there is an implicit reference conversion from B to A. With Managed Extensions, this implicit conversion is available if one class is a direct or indirect base class of the other.

Note Array covariance is not supported for arrays of value class types.

For instance, the following code sample demonstrates this relationship by declaring several classes (Base, Derived, Derived2, and Derived3) and then initializing them in various ways:

__gc struct Base { int i; };
struct Derived : Base {};
struct Derived2 : Base {};
struct Derived3 : Derived {};
__gc struct Other { short s; };
void main()
{
   Derived* d[] = new Derived*[100];
   Base* b[] = d;   // OK by array covariance
   b[0] = new Other;   // Error (compile time)
   b[1] = new Derived2;   // Error (run-time exception)
   b[0] = new Base;   // Error (run-time exception), must be "at least" a Derived.
   b[1] = new Derived;   // ok
   b[0] = new Derived3;   // ok
}

As part of the support for array covariance, assignments to elements of reference type arrays include a run-time check that ensures that the value being assigned to the array element is actually of a permitted type. If the type is not permitted, an exception System::ArrayTypeMismatchException is thrown.

See Also

Introduction to Managed Extensions for C++


String Literals in Managed Extensions for C++

In standard C++ applications, string literals are composed of ASCII characters. However, NGWS objects and applications cannot handle standard ASCII strings. Managed Extensions for C++ solves this problem by allowing string literals to be assigned to a variable of type System::String without casting.

   String *s1 = "a string literal";
   String *s2 = L"a wide string literal";

Managed Extensions support a new type of string literal (prefixed by S) that has type String* and better performance than a C++ string literal.

Note String literals prefixed by S are stored as single-byte characters. This is not the case with string literals prefixed by L, which are stored as double-byte characters.

In addition, all instances of identical string literals (prefixed by S) always point to the same object. This is not true for String* objects constructed from C++ string literals. The following example demonstrates this by comparing the pointer values of two instances (parm_s and loc_s) of the same string literal:

#using <mscorlib.dll>
#include “assert.h”

void MyFunction(String* parm_s)
{
   String* loc_s = S"a NGWS frameworks string literal";
   assert( parm_s == loc_s );   // String pointers are identical
}
void main()
{
   String *s = S"a NGWS frameworks string literal";
MyFunction(s);
};

See Also

Introduction to Managed Extensions for C++


Delegates in Managed Extensions for C++

Delegates provide the underlying mechanism for events in the NGWS Component Model.

Delegates are implemented as abstract classes within the NGWS frameworks library. There are two types of delegates: single cast and multicast. The single-cast delegate (implemented by System::Delegate) enables binding a function pointer to only one method. The multicast delegate (implemented by System::MultiCastDelegate) may bind a function pointer to a single method or many methods. Delegates differ from C++ function pointers in that they may only point to members of managed classes and may bind to an object to support calling methods of that type of instance.

Note For simplicity, the term "delegate" will refer to both the single-cast and multicast versions. If only one of these classes is intended, it will be explicitly stated.

Under Managed Extensions for C++, delegates are supported by the __delegate keyword. The __delegate keyword defines a single-cast delegate type with a specific method signature. A variant of the __delegate keyword, __delegate(multicast), declares a multicast delegate type with a specific method signature.

Single-Cast Delegates

The single-cast delegate only binds the delegate to one method. The following example declares a single-cast delegate GetDayOfWeek.

__delegate int GetDayOfWeek();

Single-cast delegate objects are implemented by the NGWS frameworks base class Delegate.

Multicast Delegates

Another version of a delegate is the multicast delegate. This delegate is able to bind to multiple methods. Multicast delegates are declared by using a variant of the __delegate keyword, __delegate(multicast). The following example declares a multicast delegate DayOfWeekChanged.

__delegate(multicast) void DayOfWeekChanged();

Multicast delegate objects are implemented by the NGWS frameworks base class MultiCastDelegate.

Note Multicast delegates are not permitted to return a value or out parameters. This limitation is due to the properties of return values and out parameters being supplied by one callee and a multicast delegate having many callees.

Although the syntax for the __delegate keyword is similar to the syntax of the standard C++ typedef keyword, the compiler actually generates a definition of a managed class. The managed class has the following characteristics:

  • It inherits from either System::Delegate (single-cast delegates) or System::MulticastDelegate (multicast delegates).
  • The constructor takes two arguments: a managed reference or NULL, and a fully qualified method of the specified type.
  • It has a method called Invoke whose signature matches the declared signature of the delegate. This method makes the actual call to the bound method to all delegates (clients).

The following example declares a single-cast delegate and illustrates that the delegate is actually implemented by the NGWS frameworks base class Delegate:

__delegate int GetDayOfWeek();

__gc class MyCalendar
{
 public:
   int MyGetDayOfWeek()
   {
        //Function implementation
   }
};

void UsesDelegate ()
{
   MyCalendar* pCal = new MyCalendar;
   GetDayOfWeek* pGetDayOfWeek = new GetDayOfWeek(pCal, &MyCalendar::MyGetDayOfWeek);
   int dayOfWeek = pGetDayOfWeek->Invoke();
}

Managed Extensions support a special case for a delegate that uses a single argument constructor where the syntax can be automatically constructed to include both the object reference and method. The previous statement, creating a GetDayOfWeek delegate, could be written as:

GetDayOfWeek* pGetDayOfWeek = new GetDayOfWeek(pcal->MyGetDayOfWeek);

See Also

Introduction to Managed Extensions for C++


Properties of Managed Objects

In Managed Extensions for C++, you can implement a standard NGWS runtime property for a managed class using the __property keyword.

To client code, a property has the appearance of an ordinary data member and can be written to or read from using the same syntax as a data member. However, instead of declaring an actual data member, you declare a pair of methods that implement the property. The compiler then generates a pseudo–data member, corresponding to the property methods. This pseudo–data member can be referenced in your source code as if it were an actual data member of the containing class.

Note You cannot take the address of a pseudo–data member.

The naming convention for a NGWS runtime property has the following properties:

  • The identifier of the Get method must begin with “get_”.
  • The identifier of the Set method must begin with “set_”.

The following example declares a Size property for the CMyClass class and then manipulates the property using the declared accessor functions:

__gc class MyClass
{
public:
   __property int get_Size() { ... };
   __property void set_Size(int i) { ... };
   // Pseudo–data member Size generated by compiler
};

void main()
{
   CMyClass* pC = new CMyClass;
   pC->Size = 10;   // calls set_Size
   int i = pC->Size;   // calls get_Size
}

The following usage notes apply to the __property keyword:

  • The name of the Get and Set methods are the same except for the prefix.
  • The virtual keyword can be applied to either the Get or Set method.
  • The accessibility of the Get and Set methods may differ.
  • It is not necessary for a property to have both a Get and Set method.
  • A property can be made pure virtual by appending “=0” to the end of the Get and Set method declarations (like an ordinary method).
  • The definition of a Get or Set method can appear outside the class body (like an ordinary method).

Some restrictions apply for managed properties:

  • In a managed class, any member whose identifier follows the NGWS runtime property-naming convention (as described above) must define either a Get or a Set property method.
  • If the static keyword is applied to either the Get or Set method, it must also be applied to the other method.
  • The last argument of the Set method must match the return type of the Get method.

Property Types in Managed Extensions

Managed Extensions for C++ support two types of NGWS runtime properties: scalar and indexed.

Scalar Properties

A property is scalar if the get and set methods have the following characteristics:

  • The get method has no parameters and has a return type T.
  • The set method has a single parameter of type T, and a void return type.

Indexed Properties

A property is indexed if its get and set methods have the following characteristics:

  • The get method has a parameter list (p1, … ,pn) and has return type T.
  • The set method has a parameter list (p1, … ,pn, T) and a void return type.

Given the previous information, a pseudo–data member array is generated with the following form (assuming a property name of Dimension):

/*  T Dimension[p1, … ,pn];  */

This property provides array-like access to the pseudo-member. However, because it is implemented using method calls, any parameter type can be used to index the pseudo–data member array.

The following example demonstrates this access. First, two classes are declared (Employee and Manager). Second, an instance of the Manager class (Ed) and two instances of the Employee class (Bob and Gus) are created. The Report property (implemented by class Manager) is then accessed for both Bob and Gus:

#using <mscorlib.dll>
__gc class Employee
{
 public:
   String* name;
...
};
__gc class Manager
{
 public:
__property Employee* get_Report(String*) { ... }
__property void set_Report(String*, Employee*) { ... }
// Pseudo–array member
/*   Employee* Report[ String* ]; */
};

void main()
{
   Manager* Ed = new Manager;
   Employee* Bob = new Employee(S"Bob");
   Employee* Gus = new Employee(S"Gus");

   // Track Ed’s reports
   Ed->Report[ Bob->name ] = Bob;   // indexed by String* type
   Ed->Report[ Gus->name ] = Gus;   // indexed by String* type
}

See Also

Introduction to Managed Extensions for C++


Handling Exceptions Using Managed Extensions for C++

In addition to structured exception handling (SEH) and C++ exception handling, Managed Extensions for C++ extend this feature by supporting the handling of managed exceptions. A managed exception is any exception thrown by a managed type. The System::Exception class provides many useful methods for processing managed exceptions and is recommended as a base class for user-defined exception classes.

Throwing Exceptions Using Managed Extensions

The C++ throw expression is extended to throw a pointer to any managed object. The following example creates a custom exception type and then throws an instance of that type:

#using <mscorlib.dll>
__gc struct MyStruct : public System::Exception { int i; };

void GlobalFunction()
{
   MyStruct* pMyStruct = new MyStruct;
   throw pMyStruct;
}

Value classes must be boxed before they can be thrown:

#using <mscorlib.dll>
__value struct MyValueStruct { int i; };

void GlobalFunction()
{
   MyValueStruct v = {11};
   throw __box(v);
}

Try/Catch Blocks Using Managed Extensions

The same try/catch block structure can be used for catching both managed and unmanaged exceptions. The following example demonstrates a simple try/catch block with managed and unmanaged structures:

#using <mscorlib.dll>
__gc struct MyStruct : public System::Exception { int i; };
struct CMyClass { double d; };
void GlobalFunction()
{
   MyStruct * pMyStruct = new MyStruct;
   pMyStruct->i = 11;
   throw pMyStruct;
}
void GlobalFunction2()
{
   MyClass c = {2.0}; throw c;
}
void main()
{
   for(int i = 1; i >= 0; --i)
   {
    try
    {
     if( i==1) GlobalFunction2();
     if( i==0) GlobalFunction();
    }
    catch(CMyClass& catchC)
    {
     Console::WriteLine(catchC.d);
    }
    catch(MyStruct* catchException)
    {
     Console::WriteLine(catchException->i);
    }
   }
}

Program Output

2
11

Order of Unwinding for C++ Objects

As usual, unwinding occurs for any C++ objects with destructors that may be on the run-time stack between the throwing function and the handling function. Because garbage-collected classes are allocated on the heap, unwinding does not apply to them.

Catching Unmanaged C++ Types

When an unmanaged C++ object type is thrown, it is wrapped with a NGWS runtime exception of type System::Runtime::InteropServices::SEHException. When searching for the appropriate catch clause, there are two possibilities.

If an unmanaged C++ type is encountered, the exception is unwrapped and compared to the type encountered. This comparison allows an unmanaged C++ type to be caught in the normal way.

However, if a catch clause of type SEHException or any of its base classes is examined first, the clause will intercept the exception. Therefore, you should place all catch clauses that catch unmanaged C++ types first before any catch clauses of managed types.

Managed Extensions and the __finally Keyword

In addition to try and catch clauses, Managed Extensions support a __finally clause. The semantics are identical to the __finally block in structured exception handling (SEH). A __finally block may follow a try or catch block.

The purpose of the __finally block is to clean up any resources left after the exception occurred. Note that the __finally block is always executed, even if no exception was thrown. The catch block is only executed if a managed exception is thrown within the associated try block.

The following example demonstrates a simple __finally block:

#using <mscorlib.dll>
__gc class MyException : public System::Exception
{
};
void ThrowMyException()
{
   throw new MyException;
}

void main()
{
   try
   {
    ThrowMyException();
   }
   catch (MyException *e)
   {
    Console::WriteLine("in catch");
    Console::WriteLine(e->GetType());
   }
   __finally
   {
    Console::WriteLine("in finally");
   }
}

Program Output

in catch
MyException
in finally

See Also

Introduction to Managed Extensions for C++ | _try_cast | Exception Handling


Adding Support for Managed Extensions for C++ to an Existing Application

One of the strongest reasons for using Managed Extensions for C++ is the ease in converting existing C++ applications to Managed Extensions applications. The procedure is simple and straightforward and consists of three steps:

  • Modifying the Existing Project Settings
  • Employing New Managed Extensions Functionality in Existing Applications
  • Building and Testing for Regression

Modifying the Existing Project Settings

The first step is to modify the compiler options by adding the /com+ option and recompile the target application. The /com+ option enables support for Managed Extensions and forces a link to the proper library.

To modify the project settings

  1. Load the target project into Visual Studio.
  2. From the Solution Explorer, right-click the project node and click Property Pages.
  3. Click the C/C++ folder in the left pane
  4. Click General folder under C/C++
  5. Set the Enable NGWS Runtime property to Assembly Support (/com+)
  6. Click OK and rebuild the project.

Once the project has been rebuilt, support for Managed Extensions is now available.

Employing New Managed Extensions Functionality in Existing Applications

Once the target application has been built with Managed Extensions support, all NGWS runtime features, from managed objects to NGWS frameworks base classes (such as String), can be easily added. For a full list of these features, see Managed Extensions for C++.

For the purposes of this article, it is sufficient to demonstrate this step using the NGWS frameworks base classes String and Console.

The following code declares two instances of the String class and a managed array of int type:

String MyLiteral= L"Current array values";
String MyLiteral2= L"Current array values (after initialization)";
__gc int a1[] = new __gc int[20];
Note Because the a1 array is a managed array the managed operator new is used to declare and initialize the memory to 0.

After the variables have been declared, an instance of the NGWS frameworks Console class is created and the current values (all equal to 0) in the array is printed using the Write method of the Console class and the Length method of the Array class:

Console::Write(MyLiteral);
Console::Write('\n');
for (i=0; i < a1->Length; ++i)   // Use the Length member
{
   Console::Write(a1[i]);
   Console::Write(L' ');
}

Finally, the array is reinitialized and the values are again printed:

for (i=0; i < 20; ++i)
   a1[i] = i;

for (i=0; i < a1->Length; ++i)   // Use the Length member
{
   Console::Write(a1[i]);
   Console::Write(L' ');
}

Examining the example code reveals some of the benefits of using Managed Extensions in a C++ application:

  • Single-dimensional arrays are dynamic until they are created.
  • The array is automatically destroyed and all resources freed by the managed heap.
  • The array values are automatically initialized to 0.
  • NGWS frameworks base classes are easily accessible and managed classes themselves.

Building and Testing for Regression

The final step is achieving an error-free build of the application and testing of the new functionality.

See Also

Managed Extensions for C++


Using Global Attributes in Managed Extensions for C++

Most attributes are attached to specific language elements, such as classes or methods. However, some attributes are global — they apply to an entire assembly or module. Global attributes can appear in multiple source files in a single compilation.

Assembly-level attributes are specified as follows:

[assembly::attribute]

Module-level attributes are specified as follows:

[module::attribute]
attribute
An applicable global attribute.

The following NGWS attributes let you modify the information in an assembly:

  • System::Reflection::AssemblyConfigurationAttribute
  • System::Runtime::CompilerServices::AssemblyCultureAttribute
  • System::Reflection::AssemblyDescriptionAttribute
  • System::Runtime::CompilerServices::AssemblyKeyFileAttribute
  • System::Runtime::CompilerServices::AssemblyKeyNameAttribute
  • System::Runtime::CompilerServices::AssemblyDelaySignAttribute
  • System::Reflection::AssemblyTitleAttribute
  • System::Runtime::CompilerServices::AssemblyVersionAttribute

If you do not want an assembly created for a compilation, use the compiler option /com+:noassembly.

To specify multiple assembly or module-level attributes in a single attribute block, each attribute must be separated by a comma. For instance, the following sample specifies two assembly-level attributes:

[assembly::System::CLSCompliant(true), assembly::System::Expando];

Example

[assembly::System::CLSCompliant(true)];

See Also

Global Attributes


Compiler Options

CL.exe is a 32-bit tool that controls the Microsoft C and C++ compilers and linker. The compilers produce Common Object File Format (COFF) object (.obj) files. The linker produces executable (.exe) files or dynamic-link libraries (DLLs).

To find a particular compiler option, see one of the following lists:

  • Compiler options listed alphabetically
  • Compiler options by category

For information on specifying options, see:

  • Setting Compiler Options
  • Fast Compilation
  • CL Invokes the Linker

Use NMAKE to build your output file.

Use BSCMAKE to support class browsing.

Linker options also affect how your program is built.

To compile without linking, use /c on the command line or click the Compile command on the Build menu.

See Also

Building a C/C++ Program | Setting Compiler Options


Compiler Options Listed Alphabetically

The following is a comprehensive alphabetic list of compiler options. Click any option name for specific information about it. Also see the compiler options listed by category of purpose.

Option name and arguments | Purpose
@ | Specifies a response file.
/? | Lists the compiler options.
/C | Preserves comments during preprocessing
/c | Compiles without linking
/com+ | Enables Managed Extensions for C++ and produce an output file to run on the Universal Runtime.
/D | Defines constants and macros
/E | Copies preprocessor output to standard output
/EH | Specifies the model of exception handling
/EP | Copies preprocessor output to standard output
/F | Sets stack size
/FA | Creates a listing file
/Fa | Sets listing file name
/Fd | Renames program database file
/Fe | Renames the executable file
/FI | Preprocesses the specified include file
/Fm | Creates a map file
/Fo | Creates an object file
/Fp | Specifies a precompiled header file name
/FR /Fr | Generate browser files
/Fx | Merges injected code with source file
/G3 | Optimizes code to favor the 386 processor. Phased out in Visual C++ 5.0, the compiler will ignore this option.
/G4 | Optimizes code to favor the 486 processor. Phased out in Visual C++ 5.0, the compiler will ignore this option.
/G5 | Optimizes code to favor the Pentium processor
/G6 | Optimizes code to favor the Pentium Pro, Pentium II, and Pentium III processors
/GA | Optimizes code for Windows application
/GB | Optimizes code to favor the Pentium processor. Blends optimizations for the 80386 (/G3), 80486 (/G4), Pentium (/G5), and Pentium Pro, Pentium II, and Pentium III (/G6) options
/GD | Optimizes code for Windows DLL
/Gd | Uses the __cdecl calling convention
/Ge | Activates stack probes
/GF /Gf | Enable string pooling
/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
/GS | Buffer security check
/Gs | Controls stack probes
/GT | Supports fiber safety for data allocated using static thread-local storage
/GX | Enables synchronous exception handling
/Gy | Enables function-level linking
/GZ | Same as /RTC1
/Gz | Uses the __stdcall calling convention
/H | Restricts the length of external (public) names
/HELP | Lists the compiler options
/I | Searches a directory for include files
/J | Changes the default char type
/LD | Creates a dynamic-link library
/LDd | Creates a debug dynamic-link library
/link | Passes the specified option to LINK
/MD | Creates a multithreaded DLL, using MSVCRT.lib
/MDd | Creates a debug multithreaded DLL, using MSVCRTD.lib
/ML | Creates a single-threaded executable file, using LIBC.lib
/MLd | Creates a debug single-threaded executable file, using LIBCD.lib
/MT | Creates a multithreaded executable file, using LIBCMT.lib
/MTd | Creates a debug multithreaded executable file, using LIBCMTD.lib
/noBool | Suppress the C++ bool, true, and false keywords
/noHRESULT | Suppresses implicit compiler support for HRESULT variables
/nologo | Suppresses display of sign-on banner
/noWchar_t | Turns wchar_t off as a native data type
/O1 | Creates small code
/O2 | Creates fast code
/Oa | Assumes no aliasing
/Ob | Controls inline expansion
/Od | Disables optimization
/Og | Uses global optimizations
/Oi | Generates intrinsic functions
/Op | Improves floating-point consistency
/Os | Favors small code
/Ot | Favors fast code
/Ow | Assumes aliasing across function calls
/Ox | Uses maximum optimization (/Ob1gity /Gs)
/Oy | Omits frame pointer
/QI0f | Performs Pentium 0x0f erratum fix
/QIfdiv | Performs Pentium FDIV erratum fix
/QIfist | Suppresses _ftol when a conversion from a floating-point type to an integral type is required
/P | Writes preprocessor output to a file
/RTC | Enables run-time error checking
/showIncludes | Displays a list of include files during compilation
/Tc /TC | Specifies a C source file
/Tp /TP | Specifies a C++ source file
/U | Removes a predefined macro
/u | Removes all predefined macros
/V | Sets the version string
/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
/W | Sets warning level
/w | Disables all warnings
/Wall | Enables all warnings, including warnings that are disabled by default.
/WL | Enables one-line diagnostics for error and warning messages when compiling C++ source code from the command line
/Wp64 | Detects 64-bit portability problems.
/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 | Places complete debugging information in all object files
/Yl | Inject a PCH reference when creating a debug library.
/Yu | Uses a precompiled header file during build
/YX | Automates precompiled header
/Z7 | Generates C 7.0–compatible debugging information
/Za | Disables language extensions
/Zc (Conformance) | Specifies standard behavior under /Ze
/Zd | Generates line numbers
/Ze | Enables language extensions
/Zg | 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
/Zm | Sets the compiler's memory allocation limit
/Zp | Packs structure members
/Zs | Checks syntax only

See Also

Building a C/C++ Program | Compiler Options | Setting Compiler Options


Compiler Options by Category

The following is a comprehensive categorical list of compiler options. Click any option name for specific information about it. Also see the compiler options listed alphabetically.

Optimization

Option name and arguments | Purpose
/O1 | Creates small code
/O2 | Creates fast code
/Oa | Assumes no aliasing
/Ob | Controls inline expansion
/Od | Disables optimization
/Og | Uses global optimizations
/Oi | Generates intrinsic functions
/Op | Improves floating-point consistency
/Os | Favors small code
/Ot | Favors fast code
/Ow | Assumes aliasing across function calls
/Ox | Uses maximum optimization (/Ob1gity /Gs)
/Oy | Omits frame pointer

Code Generation

Option name and arguments | Purpose
/com+ | Enables Managed Extentions for C++ and produce an output file to run on the Universal Runtime.
/EH | Specifies the model of exception handling
/G3 | Optimizes code to favor the 386 processor. Phased out in Visual C++ 5.0, the compiler will ignore this option
/G4 | Optimizes code to favor the 486 processor. Phased out in Visual C++ 5.0, the compiler will ignore this option
/G5 | Optimizes code to favor the Pentium
/G6 | Optimizes code to favor the Pentium Pro, Pentium II, and Pentium III
/GA | Optimizes code for Windows application
/GB | Optimizes code to favor the Pentium processor. Blends optimizations for the 80386 (/G3), 80486 (/G4), Pentium (/G5), and Pentium Pro, Pentium II, and Pentium III (/G6) options.
/Gd | Uses the __cdecl calling convention
/Ge | Activates stack probes
/GF /Gf | Enable string pooling
/Gh | Calls hook function, __penter
/GH | Calls hook function, __pexit
/GL | Enables whole program optimization.
/Gm | Enables minimal rebuild
/GR | Enables run-time type information (RTTI)
/Gr | Uses the __fastcall calling convention
/Gs | Controls stack probes
/GT | Supports fiber safety for data allocated using static thread-local storage
/GX | Enables synchronous exception handling
/Gy | Enables function-level linking
/Gz | Uses the __stdcall calling convention
/MD | Creates a multithreaded DLL, using MSVCRT.lib
/MDd | Creates a debug multithreaded DLL, using MSVCRTD.lib
/ML | Creates a single-threaded executable file, using LIBC.lib
/MLd | Creates a debug single-threaded executable file, using LIBCD.lib
/MT | Creates a multithreaded executable file, using LIBCMT.lib
/MTd | Creates a debug multithreaded executable file, using LIBCMTD.lib
/noWchar_t | Turns wchar_t off as a native data type

Output Files

Option name and arguments | Purpose
/FA /Fa | Creates a listing file Sets listing file name
/Fd | Renames program database file
/Fe | Renames the executable file
/Fm | Creates a map file
/Fo | Creates an object file
/Fp | Specifies a precompiled header file name
/FR /Fr | Generate browser files
/Fx | Merges injected code with source file

Debugging

Option name and arguments | Purpose
/GS | Buffer security check
/GZ | Same as /RTC1
/noHRESULT | Suppresses implicit compiler support for HRESULT variables.
/RTC | Enables run-time error checking
/Wp64 | Detects 64-bit portability problems
/Yd | Places complete debugging information in all object files
/Yl | Inject a PCH reference when creating a debug library.
/Z7 | Generates C 7.0–compatible debugging information
/Zd | Generates line numbers
/Zi | Generates complete debugging information

Preprocessor

Option name and arguments | Purpose
/C | Preserves comments during preprocessing
/D | Defines constants and macros
/E | Copies preprocessor output to standard output
/EP | Copies preprocessor output to standard output
/Fl | Preprocesses the specified include file
/I | Searches a directory for include files
/P | Writes preprocessor output to a file
/U symbol | Removes a predefined macro
/u | Removes all predefined macros
/X | Ignores the standard include directory
/ZI | Includes debug information in a program database compatible with Edit and Continue.

Language

Option name and arguments | Purpose
/noBool | Suppress the C++ bool, true, and false keywords.
/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
/Za | Disables language extensions
/Zc (Conformance) | Specifies standard behavior under /Ze
/Ze | Enables language extensions
/Zg | Generates function prototypes
/Zl | Removes default library name from .obj file
/Zp n | Packs structure members
/Zs | Checks syntax only

Linking

Option name and arguments | 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
/MD | Compiles to create a multithreaded DLL, using MSVCRT.lib
/MDd | Compiles to create a debug multithreaded DLL, using MSVCRTD.lib
/ML | Compiles to create a single-threaded executable file, using LIBC.lib
/MLd | Compiles to create a debug single-threaded executable file, using LIBCD.lib
/MT | Compiles to create a multithreaded executable file, using LIBCMT.lib
/MTd | Compiles to create a debug multithreaded executable file, using LIBCMTD.lib

Precompiled Header

Option name and arguments | Purpose
/Y- | Ignores all other precompiled-header compiler options in the current build.
/Yc | Creates a precompiled header file
/Yd | Places complete debugging information in all object files
/Yu | Uses a precompiled header file during build
/YX | Automates precompiled header

Miscellaneous

Option name and arguments | Purpose
@ | Specifies a response file.
/? | Lists the compiler options.
/c | Compiles without linking
/H | Restricts the length of external (public) names
/HELP | Lists the compiler options
/J | Changes the default char type
/nologo | Suppresses display of sign-on banner
/QI0f | Ensures no problems with Pentium 0F instructions
/QIfdiv | Workaround for the Intel Pentium microprocessors with flawed FDIV, FPREM, FPTAN, and FPATAN instructions
QIfist | Suppresses the call of the helper function, _ftol, when a conversion from a floating-point type to an integral type is required
/showIncludes | Displays a list of all include files during compilation
/Tc /TC | Specifies a C source file
/Tp /TP | Specifies a C++ source file
/V | Sets the version string
/W | Sets warning level
/w | Disables all warnings
/Wall | Enables all warnings, including warnings that are disabled by default.
/WL | Enables one-line diagnostics for error and warning messages when compiling C++ source code from the command line
/Zm | Sets the compiler's memory allocation limit

See Also

Building a C/C++ Program | Compiler Options | Setting Compiler Options


@ (Specify a Compiler Response File)

@response_file

A response file can contain any commands that you would specify on the command line. This can be useful if you are working on a Win9x machine and your command-line arguments exceed 127 characters.

A response file cannot be specified from within the development environment, only at the command line. It is also 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 wish.

See Also

Compiler Options | Setting Compiler Options


/C (Preserve Comments During Preprocessing)

/C

This option preserves comments during preprocessing. It requires the /E, /P, or /EP option. If you specify the /C option as well, the preprocessor passes source-file comments to its output file.

See Also

Compiler Options | Setting Compiler Options


/c (Compile Without Linking)

/c

This option prevents the automatic call to LINK. 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.

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

Compiler Options | Setting Compiler Options


/com+ (NGWS Runtime Compilation)

/com+[:noAssembly]

where,

:noAssembly (optional)
Specifies that an assembly manifest should not be inserted into the output file.
By default, an assembly manifest is inserted into the output file. You can cause an assembly to not be created with the /NOASSEMBLY linker option.

Remarks

The /com+ compiler option enables the use of Managed Extensions for C++ and to create an output file that will require the NGWS runtime at run time. There may or may not be managed data in the application.

/com+ does not imply that classes, interfaces, or structs are managed; use __gc to explicitly specify when you want a construct to be managed.

/com+ does imply that all functions will be managed. To make specified functions unmanaged, use the managed pragma.

Code compiled with /com+ must also use the #using <mscorlib.dll> statement.

Managed code is code that can be inspected and managed by the NGWS runtime. Managed code can access managed objects.

By default, the /com+ compiler option is not in effect.

See the /ASSEMBLY linker option for information about how you can create a NGWS assembly when you compile and link your Managed Extensions for C++ program.

Note the following restrictions on the use of /com+:

  • The use of Run-time Error Checks is not valid with the /com+ compiler option.
  • When inline assembly code is found in in a managed function, the compiler will try to complete the compilation by compiling the function as unmanaged native code. Inline assembly will not appear in a managed function.

    When /com+ is used to compile a program that does not use Managed Extensions for C++, 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 machine 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 /com+.
    • Inline assembly code in module-static functions are not supported:
      static void TestInlineAsmInStaticFunc(void) {
    __asm { nop }
}
    • Inline assembly code in functions that pass copy-constructed function parameters are not supported:
      class CMyClass {
public:
    int a, b, c;
    CMyClass() { a = b = c = 1; }
    CMyClass(const CMyClass & mSrc) { a = b = c = mSrc.a + 1; }
};

void TestCopyCtors(void) {
    CMyClass m;
    f(3, m, 4);
    __asm { nop };
}
  • The vprintf Functions cannot be called from a program compiled with /com+.
  • The naked __declspec modifier is ignored under /com+.
  • The use of dllexport or dllimport on classes is not permitted under /com+.
  • The use of C++ Exception Handling is not permitted under /com+. The translator function set by _set_se_translator will affect only catches in unmanaged code. See Handling Exceptions in MX for more information.
  • The comparison of function pointers is not permitted under /com+.
  • The use of setjmp longjmp is not permitted under /com+.
  • The use of functions that are not fully prototyped is not permitted under /com+.
  • /LTCG linker option is not supported with /com+.
  • /Zd compiler option is not supported with /com+.

See Also

Compiler Options | Setting Compiler Options


/D (Preprocessor Definitions)

/Dname[= | # [{string | number}] ]

This option defines symbols or constants for your source file. This option has much the same effect as using a #define preprocessor directive at the beginning of your source file. However, /D strips quotes on the command line while #define retains them. A constant remains defined until an #undef directive in the source file removes the definition or the compiler reaches the end of the file.

You can use constants created by this option with #if or #ifdef to compile source files conditionally.

This option can define a keyword, identifier, or numeric constant that is also defined in a source file. The option definition remains in effect until a redefinition is encountered in the source file.

To undefine a previous definition, use /D option with a keyword, identifier, or numeric constant followed by the equal sign and a space.

Examples

The following command defines the symbol DEBUG in TEST.c:

CL /DDEBUG  TEST.C

The following command removes all occurrences of the keyword __far in TEST.c:

CL /D__far=  TEST.C

You cannot set the CL environment variable to a string that contains an equal sign. To use /D with the CL environment variable, you must specify a number sign instead of an equal sign:

SET CL "/DTEST#0"

See Also

Compiler Options | Setting Compiler Options | Undefine Symbols (/U | /u)


/E (Preprocess to stdout)

/E

This option preprocesses C and C++ source files and copies the preprocessed files to the standard output device. 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 option along with /E.

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

To suppress #line directives, use the /EP option instead.

To send the preprocessed output to a file instead of to stdout, use the /P 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 When preprocessing to a separate file, spaces are not emitted after tokens. This can result in an illegal program or have unintended side-effects. Consider the following program:
#define m(x) x
m(int)main()
{
   return 0;
}

This program compiles successfully. However, if you compile with:

cl -E test.cpp > test2.cpp

int main in test2.cpp will incorrectly be intmain.

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

Compiler Options | Setting Compiler Options


/EH (Exception Handling Model)

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

This option specifies the model of exception handling to be used by the compiler.

  • Use /EHs to specify the synchronous exception handling model. If you use /Ehs, do not rely on the compiler to catch asynchronous exceptions.
  • Use /EHa to specify the asynchronous exception handling model.

The /EHc option requires that /EHs, /EHa, or /GX is specified. It tells the compiler to assume that extern C functions never throw an exception.

The option can be cleared by the symbol -. For example: /EHsc- is interpreted as /EHs /EHc- , and is equivalent to /EHs.

See Synchronous Exception Handling for more information.

See Also

Compiler Options | Setting Compiler Options


/EP (Preprocess to stdout Without #line Directives)

/EP

This option preprocesses C and C++ source files and copies the preprocessed files to the standard output device. 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 option along 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.

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 instead. The /E option adds #line directives to the output for this purpose.

To send the preprocessed output, adds #line directives, to a file, use the /P option instead.

To send the preprocessed output to a file, with #line directives, use /P and /EP together.

You cannot use precompiled headers with the /EP option.

Example

The following command line creates preprocesses file ADD.C, preserves comments, and displays the result on the standard output device:

CL /EP /C ADD.C

See Also

Compiler Options | Setting Compiler Options


/F (Set Stack Size)

/F[ ]number

This option sets the program stack size in bytes. 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.

Other ways to set the stack size

  • Using the /STACK linker option.
  • Using EDITBIN on the .exe file.

See Also

Compiler Options | Setting Compiler Options


Output-File (/F) Options

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. They include:

  • /Fd (Name the Program Database and Incremental Compilation State File)
  • /Fe (Name the Executable File)
  • /Fm (Generate a Map File)
  • /Fo (Name the Object File)
  • /Fp (Name or Use a Precompiled Header File)
  • /Fx (Merge Injected Code)

Other output-file options are available in the Listing Files category on the C/C++ tab of the Project Settings dialog box. They include:

  • Generate Browse Info (/FR)
  • Exclude Local Variables (/Fr)
  • Intermediate Browse Info File Destination (/FR[filename] or /Fr[filename])
  • Listing File Type (/FA[c|s])
  • Listing File Name(/Fa[filename ])

See Also

Compiler Options | Setting Compiler Options


/FA, /Fa (Listing File)

/FA[c|s|cs]
/Fapathname

The /FA option creates a listing file containing assembly code. The arguments control the generation of source code and machine code and the extension of the listing file.

By default, the listing file gets the same base name as the source file. You can change the name of the listing file and the directory where it is created using the /Fa option.

Command-line option | Project settings | Listing contents; filename extension
/FA | Assembly-Only Listing | Assembly code; .asm
/FAc | Assembly With Machine Code | Machine and assembly code; .cod
/FAs | Assembly With Source Code | Source and assembly code; .asm
/FAcs | Assembly, Machine Code, and Source | Machine, source, and assembly code; .cod

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 | Compiler Options | Setting Compiler Options | Specifying the Pathname


Specifying the Pathname

Each output-file option accepts a pathname argument, which 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 map file to the printer:

CL /FmPRN HELLO.CPP

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options


/Fd (Name PDB File)

/Fdpathname

This option specifies a file name for the program database (PDB) file created by /Zi. Without /Fd, the PDB file name defaults to VC60.pdb.

If you specify a pathname that does not include a file name (the path ends in backslash, the compiler creates a PDB file named VC60.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.

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 | Compiler Options | Setting Compiler Options | Specifying the Pathname


/Fe (Name EXE File)

/Fepathname

This option specifies a name and directory for the .exe file or DLL created by the compiler. Without this option, the compiler gives the file a default name using 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, to compile without linking, /Fe has no effect.

Examples

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:\BIN.

CL /FeC:\BIN\PROCESS *.C

The following command line creates an executable in C:\BIN same base name as the first source or object file:

CL /FeC:\BIN\ *.C

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options | Specifying the Pathname


/FI (Name Forced Include File)

/FI[ ]pathname

This option causes the preprocessor to process the specified header file. This option has the same effect as specifying the file with double quotes in an #include directive on the first line of every source file specified on the command line, in the CL environment variable, or in an command file. If you use multiple /FI options, files are included in the order they are processed by CL.

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options | Specifying the Pathname


/Fm (Name Map File)

/Fmpathname

This option tells the linker to produce a map file containing a list of segments in the order in which they appear in the corresponding .exe file or DLL. By default, the map file 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 linker option.

If you specify /c to suppress linking, /Fm has no effect.

Global symbols in a map file usually have one or more leading underscores because the compiler adds a leading underscore to variable names. Many global symbols that appear in the map file are used internally by the compiler and the standard libraries.

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options | Specifying the Pathname


/Fo (Name Object File)

/Fopathname

This option specifies an object (.obj) file name or directory to be used instead of the default. 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.

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 | Compiler Options | Setting Compiler Options | Specifying the Pathname


/Fp (Name .pch File)

/Fppathname

Use this option with /YX, /Yc, or /Yu to provide a pathname for a precompiled header instead of using the default pathname. You can also use /Fp with /Yc to specify the use of a precompiled header file that differs from the /Yc filename argument and from the base name of the source file.

If you do not specify an extension as part of the pathname, an extension of .pch is assumed. If you specify a directory without a filename, the default filename is VC60.pch.

You can also use the /Fp option with the /Yu and /YX options.

Examples

The following command renames the precompiled header file created and used by /YX:

CL /YX /FpMYPCH.PCH PROG.CPP

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

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

The following command assumes the existence of a hdrstop pragma in PROG.cpp and creates a precompilation of all code up to the hdrstop pragma. The precompiled code is stored in a file called DPROG.pch. If you need a release version in parallel, you simply change the compilation command to:

CL /Yc /FpRPROG.PCH PROG.CPP

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options | Specifying the Pathname


/FR, /Fr (Create .sbr File)

/FR[pathname]
/Fr[pathname]

These options create .sbr files. 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 a filename, the .sbr file gets the same base name as the source file.

CAUTION Do not change the .sbr extension. BSCMAKE requires the intermediary files to have that extension.

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options | Specifying the Pathname


/Fx (Merge Injected Code)

/Fx

/Fx produces a copy of each source file with injected code merged into the source.

To distinguish a merged source file from an original source file, /Fx adds a .mrg extension between the filename and file extension. For example, suppose you have a file named MyCode.cpp that contains attributed code, building the project with /Fx creates a file named MyCode.mrg.cpp that contains 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 a .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 a .mrg file, which allows for the compilation of the .mrg file without text being reinjected.

You should be aware that .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 .mrg.h file for that header. /Fx does not merge include files that do not use injected code.

See Also

Output-File (/F) Options | Compiler Options | Setting Compiler Options


/G (Optimize for Processor) Options

/G{3|4|5|6|B}

These options tell the compiler to optimize code generation for the specified processor.

/G5 optimizes code for the Intel Pentium processor. It sets the value of the _M_IX86 preprocessor macro to 500.

/G6 optimizes code for the Intel Pentium Pro, Pentium II, and Pentium III processors. It sets the value of the _M_IX86 preprocessor macro to 600.

/GB, which is the default option, blends optimizes optimizations for the 80386, 80486, and Pentium processors. It sets the value of _M_IX86 to 600, indicating that the Pentium is the dominant processor in the blending.

/G3 and /G4 optimized for 80386 and 80486 processors. The compiler accepts these options for compatibility reasons, but they have no effect.

See Also

Compiler Options | Setting Compiler Options


/GA (Optimize for Windows Application)

/GA

This option speeds access to data declared with __declspec(thread in a Windows program. When this option is set, the __tls_index macro is assumed to be 0.

See Also

Compiler Options | Setting Compiler Options


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

/GD (Optimize for Windows DLL)

/GD

Reserved for future use.

See Also

Compiler Options | Setting Compiler Options


/Gd, /Gr, /Gz (Calling Convention)

/Gd
/Gr
/Gz

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.
  • The name-decorating convention that the compiler uses to identify individual functions.

/Gd, the default setting, specifies the C calling convention for all functions, except C++ member functions and functions marked __stdcall or __fastcall.

/Gr specifies the __fastcall calling convention for all functions, except C++ member functions and functions marked __cdecl or __stdcall. All __fastcall functions must have prototypes.

/Gz specifies the __stdcall calling convention for all prototyped C functions, except for functions that take a variable number of arguments and functions marked __cdecl or __fastcall. All __stdcall functions must have prototypes.

Note x86 Specific —>By default, C++ member functions use a calling convention in cases where the member function’s this pointer is passed in the ECX register. All other arguments are pushed onto the stack from right to left, and the called routine pops the member function’s arguments from the stack. END x86 Specific A member function that is explicitly marked as __cdecl, __fastcall, or __stdcall uses the specified calling convention. A member function that takes a variable number of arguments always uses the __cdecl calling convention.

__cdecl Specifics

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 on decorated names, see Decorated Names.

__fastcall Specifics

Some of a __fastcall function’s arguments are passed in registers x86 Specific —> ECX and EDX END x86 Specific, 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.

Important Be careful when using the __fastcall calling convention for any function 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 the following template for the naming convention:

@function_name@number
Note Microsoft does not guarantee the same implementation of the __fastcall calling convention between compiler releases. For example, the implementation differs between the 16-bit and 32-bit compilers.

When using 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 the following template for the naming convention:

_functionname@number

x86 Specific —>This option has 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 on decorated names, see Decorated Names. END x86 Specific

See Also

Compiler Options | Setting Compiler Options


/Ge (Enable Stack Probes)

/Ge

This option activates stack probes for every function call that requires storage for local variables. This mechanism is useful if you rewrite the functionality of the stack probe. It is recommended that you use /Gh instead of rewriting the stack probe.

/Gs0 has the same effect.

See Also

Compiler Options | Setting Compiler Options


/Gf, /GF (Eliminate Duplicate Strings)

/Gf
/GF

These options enable the compiler to create a single copy of identical strings in the .exe file and in memory during execution, resulting in smaller programs—an optimization called “string pooling.”

/Gf pools strings.

/GF pools strings and places them in read-only memory.

If you use /GF to place pooled strings in read-only memory, the operating system does not swap that portion of memory and can read the strings back from the image file. You cannot modify strings in read-only memory. If you try to modify them, an Application Error results.

If you use /Gf, your program must not write over pooled strings.

If you use identical strings to allocate string buffers, the /Gf option pools the strings. What were intended as multiple pointers to multiple buffers end up as multiple pointers to a single buffer. In the following code, s and t are initialized with the same string. Compiling the code with /Gf causes the 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. This means that strings will be pooled and placed in read-only memory even if you specify /Gf manually.

See Also

Compiler Options | Setting Compiler Options


/GH (Enable __pexit Hook Function)

/GH

This option calls the __pexit function at the end of every method or function. The __pexit function is not part of any library and it is up to you to provide a definition for __pexit. Use assembly language to write the function.

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 for an example of how to write a __pexit function.

See Also

Compiler Options | Setting Compiler Options


/Gh (Enable __penter Hook Function)

/Gh

This option causes a call to the __penter function at the start of every method or function. The __penter function is not part of any library and it is up to you to provide a definition for __penter. Use assembly language to write the function.

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

The following code, when compiled with /Gh shows how __penter is called twice; once when entering function main and once when entering function x.

#include "stdio.h"

void x(){ }

void main() {
   x();
}

void __declspec(naked) _cdecl _penter( void ) {
    _asm {
        push eax
        push ebx
        push ecx
        push edx
        push ebp
        push edi
        push esi
    }

   printf("\nIn a function!");

    _asm {
        pop esi
        pop edi
        pop ebp
        pop edx
        pop ecx
        pop ebx
        pop eax
        ret
    }
}

See Also

Compiler Options | Setting Compiler Options


/GL (Whole Program Optimization)

/GL

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.

With information on all modules, the compiler can:

  • Optimize the use of registers across function boundaries.
  • Inline a function in a module even when the function is defined in another module.

For more information on the optimizations available with whole program optimization, see /LTCG.

.obj files produced with /GL will not be available to such linker utilities as the EDITBIN and DUMPBIN.

If you compile your program with /GL and /c, you should use the /LTCG linker option to create the output file.

The following compiler options cannot be used with /GL:

  • /YX
  • /ZI
  • /com+

See Also

Compiler Options | Setting Compiler Options


/Gm (Enable Minimal Rebuild)

/Gm

This option enables minimal rebuild, which determines whether C++ source files that include changed C++ class definitions (stored in header (.h) files) need to be recompiled. 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.

See Also

Compiler Options | Setting Compiler Options


/GR (Enable Run-Time Type Information)

/GR

This option (/GR) adds code to check object types at run time. When this option is specified, the compiler defines the _CPPRTTI preprocessor macro. The option is cleared (/GR–) by default.

For more information on run-time type checking, see Run-Time Type Information in the C++ Language Reference.

See Also

Compiler Options | Setting Compiler Options


/GS (Generate Security Check)

/GS

The /GS option is used inject security checks into the compiled code. Currently this works by detecting buffer overruns that have wiped out the return address: a common technique for hijacking code that does not enforce buffer size restrictions correctly. This is presently only done for the x86 platform, since the IA64 architecture does not suffer from the same problem. Accordingly, some of the following details are x86-specific.

On functions subject to buffer overrun problems, the compiler will allocate a variable before the return address. On function entry, that variable is loaded with a security cookie that is computed once at module load. Then, on function exit, a compiler helper is called to make sure the variable still has the same value as the security cookie.
If the value is not the same, an overwrite of the return address has potentially occurred, and so an error will be reported and the process (or at least the thread) terminated.
Unless an alternative handler has been supplied with __set_security_violation_handler, a MessageBox alerting the user to a potential security problem will be displayed and ExitProcess called.
When statically linking the CRT, each module will have its own handler. When dynamic linking is used, every component will share a common handler.

See Also

Compiler Options | Setting Compiler Options


/Gs (Control Stack Checking Calls)

/Gsn

Where n is the number of bytes that local variables can occupy before a stack probe is activated.

This option is an advanced feature to control stack probes. A stack probe is a sequence of code the compiler inserts into every function call. When activated, a stack probe reaches benignly into memory by the amount of space required to store the associated function’s local variables.

If a function requires more than n bytes of stack space for local variables, its stack probe is activated. The default value of n is the size of one page (4K for 80x86 processors). This value allows a carefully tuned interaction between an application for Win32 and the Windows NT virtual-memory manager to increase the amount of memory committed to the program stack at run time.

Warning The default value of size is carefully chosen to allow the program stack of applications for Win32 to grow at run time. Do not change the default setting of /Gs unless you know exactly why you need to change it.

Some programs, such as virtual device drivers, do not require this default stack-growth mechanism. In such cases, the stack probes are not necessary. You can stop the compiler from generating stack probes by setting size to a value that is larger than any function will require for local variable storage. No space is allowed between /Gs and size.

/Gs0 has the same effect as /Ge.

You can turn stack probes on or off by using #pragma check_stack. Note that the /Gs option and the check_stack pragma have no effect on standard C library routines; they affect only the functions you compile.

See Also

Compiler Options | Setting Compiler Options


/GT (Support Fiber-Safe Thread-Local Storage)

/GT

This option supports fiber safety for data allocated using static thread-local storage, that is, data allocated with __declspec( thread ).

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, it must not be cached or optimized as a common subexpression across a function call (see the /Og option for details). /GT prevents such optimizations.

See Also

Compiler Options | Setting Compiler Options


/GX (Enable Exception Handling)

/GX

This option enables synchronous exception handling with the assumption that extern C functions never throw an exception. It is equivalent to /EHsc.

/GX is in effect, by default, when you compile from within the development environment. By default, /GX- is enabled when using command-line tools.

For more information, see C++ Exception Handling.

See Also

Compiler Options | Setting Compiler Options


/Gy (Enable Function-Level Linking)

/Gy

This option allows the compiler to package individual functions in the form of packaged functions (COMDATs). 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:REF to exclude unreferenced packaged functions from the .exe file.

You can use the linker option /ORDER to place packaged functions in a specified order within the .exe file.

Inline functions are always packaged if they are instantiated as calls (which occurs, for example, if inlining is turned off or you take a function address). In addition, C++ member functions defined within the class declaration are automatically packaged; other functions are not, and selecting this option is required to compile them as packaged functions.

Note The /ZI option, used for Edit and Continue, automatically sets the /Gy option.

See Also

Compiler Options | Setting Compiler Options


/GZ Enable Stack Frame Run-Time Error Checking

/GZ

The /GZ compiler option now performs the same operations as the /RTC1 option.

See Also

Compiler Options | Setting Compiler Options


/H (Restrict Length of External Names)

/Hnumber

By default, the length of external (public) names is 2047 characters. This is true for C and C++ programs. The /H option restricts the length of these names. 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 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:

/* When compiled with /H5, the following code will produce either
   *   error L2025: _func : symbol defined more than once
   *   -or-
   *   error LNK2005: _func already defined in '.obj file'
   *   fatal error LNK1169: one or more multiply defined symbols found
   */

   void func1(void);
   void func2(void);

   void main(void)
   {
      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.

See Also

Compiler Options | Setting Compiler Options


/HELP (Compiler Command-Line Help)

/HELP
/help
/?

This option displays a listing of compiler options to standard output.

IDE Settings (Project Settings dialog box)

This command cannot be used in the IDE. You must type /HELP, /help, or /? as a command-line argument to cl.

See Also

Compiler Options | Setting Compiler Options


/I (Additional Include Directories)

/I[ ]directory

This option adds a directory to the list of directories searched for include files. 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 Ignore Standard Include Paths (/X) option.

The compiler searches for directories in the following order:

  1. Directories containing the source file.
  2. Directories specified with the /I option, in the order that CL encounters them.
  3. Directories specified in the INCLUDE environment variable.

Example

The following command looks for the include files requested by MAIN.c in the following order: first in the directory containing MAIN.c, then 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

Compiler Options | Setting Compiler Options


/J (Default char Type is unsigned)

/J

This option changes the default char type from signed char to unsigned char, and the char type is zero-extended when widened to an int type. If a char value is explicitly declared signed, the /J option does not affect it, and the value is sign-extended when 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.

See Also

Compiler Options | Setting Compiler Options


/link (Pass Options to Linker)

/link linkeroptions

This option passes one or more linker options to the linker. The /link option and its linker options must appear after any file names and CL options. A space is required between /link and linkeroptions. See Set Linker Options for a complete list.

See Also

Compiler Options | Setting Compiler Options


/MD, /ML, /MT, /LD (Use Run-Time Library)

/MD[d]
/ML[d]
/MT[d]
/LD[d]

These options select either single-threaded or multithreaded run-time routines, indicate if a multithreaded module is a DLL, and select retail or debug versions of the runtime library.

Caution Do not mix static and dynamic versions of the run-time libraries. Having more than one copy of the run-time libraries in a process can cause problems, because static data in one copy is not shared with the other copy. The linker prevents you from linking with both static and dynamic versions within one .exe file, but you can still end up with two (or more) copies of the run-time libraries. For example, a dynamic-link library linked with the static (non-DLL) versions of the run-time libraries can cause problems when used with an .exe file that was linked with the dynamic (DLL) version of the run-time libraries. (You should also avoid mixing the debug and non-debug versions of the libraries in one process.)
Command Line | Project Settings | Description
/MD | Multithreaded DLL | Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. This option also 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 allows the linker to resolve external references. The actual working code is contained in MSVCRT.dll, which must be available at run time to applications linked with MSVCRT.lib.
/MDd | Debug Multithreaded DLL | Defines _DEBUG, _MT, and _DLL so that debug multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. It also causes the compiler to place the library name MSVCRTD.lib into the .obj file.
/ML | Single-Threaded | Causes the compiler to place the library name LIBC.lib into the .obj file so that the linker will use LIBC.lib to resolve external symbols. This is the compiler’s default action. LIBC.lib does not provide multithread support.
/MLd | Debug Single-Threaded | Defines _DEBUG and causes the compiler to place the library name LIBCD.lib into the .obj file so that the linker will use LIBCD.lib to resolve external symbols. LIBCD.lib does not provide multithread support.
/MT | Multithreaded | Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files. This option also 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. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
/MTd | Debug Multithreaded | Defines _DEBUG and _MT. Defining _MT causes multithread-specific versions of the run-time routines to be selected from the standard .h files. 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. Either /MTd or /MDd (or their non-debug equivalents /MT or MD) is required to create multithreaded programs.
/LD | Not applicable | 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 as naming a DLL rather than an .exe file; the default program name becomes basename.dll instead of basename.exe. Changes default run-time library support to /MT if you have not explicitly specified one of the /M options
/LDd | Not applicable | Creates a debug DLL. Defines _DEBUG.

For more information on using the debug versions of the run-time libraries, see Run-Time Library Reference.

Knowledge Base article Q140584 also discusses how to choose the appropriate C run-time library.

For further discussion of DLLs, see DLL Topics.

See Also

Compiler Options | Setting Compiler Options


/no options (Override Defaults)

The folllowing options suppress various compiler actions.

Syntax | Description
/noBool | Suppresses the C++ bool, true, and false keywords.
/noHRESULT | Suppresses implicit compiler support for HRESULT variables. HRESULT values will display as a number rather than a symbol. For example, you will see 0 in the debugger for variables of type HRESULT instead of S_OK.
/nologo | Suppresses display of the sign-on banner when the compiler starts up and display of informational messages during compiling.
/noWchar_t | Disables the wchar_t native data type. You can now use typedefs to create a wchar_t data type.

See Also

Compiler Options | Setting Compiler Options


/O options (Optimize Code)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.

The /O options control various optimizations that help you create code for maximum speed or minimum size.

  • /O1 optimizes code for minimum size.
  • /O2 optimizes code for maximum speed.
  • /Oa tells the compiler to assume your program does not use aliasing.
  • /Ob controls inline function expansion.
  • /Od disables optimization, speeding compilation and simplifying debugging.
  • /Og enables global optimizations.
  • /Oi generates intrinsic functions for appropriate function calls.
  • /Op disables optimizations that could change the precision of floating-point numbers.
  • /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.
  • /Ow tells the compiler that your program does not use aliasing within functions but may use aliasing across functions calls.
  • /Ox selects full optimization.
  • /Oy suppresses the creation of frame pointers on the call stack for quicker function calls.

IDE Settings (Project Settings dialog box)

To set these optimization options in the development environment, open the Project Settings dialog box, choose the C/C++ tab, and choose Optimizations in the Category box. In the in the Optimizations list box, select an optimization setting—Default, Disable (Debug), Maximize Speed, Minimize Size, or Customize. If you select Customize, you can select specific optimizations in the area below the list box.

See Also

Compiler Options | Setting Compiler Options


/O1, /O2 (Minimize Size, Maximize Speed)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/O1
/O2

These options select a predefined set of options that affect the size and speed of files as follows:

Option | Equivalent to | Comment
/O1 (Minimize Size) | /Og /Os /Oy /Ob1 /Gs /Gf /Gy | Creates the smallest code in the majority of cases.
/O2 (Maximize Speed) | /Og /Oi /Ot /Oy /Ob1 /Gs /Gf /Gy | Creates the fastest code in the majority of cases. (Default setting for release builds)

x86 Specific —>

You can use other options to improve the size or speed of many applications (for example, the /G5 option to generate code optimized for the Pentium processor).

These options imply the use of the Frame-Pointer Omission (/Oy) option.

END x86 Specific

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options | /EH


/Oa, /Ow (Assume No Aliasing, Assume Aliasing Across Function Calls)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Oa
/Ow

Aliasing (the use of multiple names that refer to the same memory location) can prevent some optimizations, such as register storage of variables and loop optimizations.

/Oa tells the compiler that your program does not use aliasing.

Ow tells the compiler that your program does not use aliasing within functions but may use aliasing across function calls. As a result, pointer variables must be reloaded from memory after each function call.

Rules for using /Oa and /Ow

If you use /Oa or /Ow, you must follow these rules. The following rules apply for any variable not declared as volatile:

  • No pointer can reference a variable that is used directly (a variable is referenced if it is on either side of an assignment or if a function uses it in an argument).
  • No variable can be used directly if a pointer to the variable is being used.
  • No variable can be used directly if its address is taken within a function.
  • No pointer can be used to access a memory location if another pointer modifies the same memory location.

Failing to follow these rules can cause corrupted data. If variables seem to take on random values, compile the program with Disable (/Od). If the problem goes away, try compiling with optimization but without /Oa or /Ow.

The following code can cause an aliasing problem:

i = -100;
while( i < 0 )
{
    i += x + y;
    *p = i;
}

Without /Oa or /Ow, the compiler assumes that the assignment to *p can modify x or y, so it does not assume that x + y is constant for each iteration. If you specify /Oa or /Ow, the compiler assumes that modifying *p does not affect x or y and the calculation of x + y can be removed from the loop.

Note You can disable optimizations around code that uses aliasing (for individual functions) by using #pragma optimize with the a or w option.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Ob (In-line Function Expansion)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Ob{0|1|2}

The In-line Function Expansion (/Obn) options control inline expansion of functions, where n is one of the following:

Command line | Project settings | Description
/Ob0 | Disable | Disables inline expansion (default)
/Ob1 | Only __inline | Expands only functions marked as inline or __inline or, in a C++ member function, defined within a class declaration (default with /O1, /O2, and /Ox)
/Ob2 | Any Suitable | Expands functions marked as inline or __inline and any other function that the compiler chooses (expansion occurs at compiler discretion—often referred to as “auto-inlining”). This option requires that you enable optimizations using /O1, /O2, /Ox, /Ot, or /Og.

The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function.

You can also use #pragma auto_inline to exclude functions from being considered as candidates for inline expansion. Also see #pragma intrinsic.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Od (Disable (Debug))

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Od

This option turns off all optimizations in the program and speeds compilation. This option is the default. Because /Od suppresses code movement, it simplifies the debugging process. For information on the compile-for-debugging options, see /Zi, /Z7, and /Zd.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Og (Global Optimizations)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Og

This option provides local and global optimizations, automatic-register allocation, and loop optimization.

  • 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 Assume No Aliasing (/Oa) or Assume Aliasing Across Function Calls (/Ow).

Note You can enable or disable global optimization on a function-by-function basis using the optimize pragma with the g option.

For related information, see Generate Intrinsic Functions (/Oi), Improve Float Consistency (/Op), and Full Optimization (/Ox).

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Oi (Generate Intrinsic Functions)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Oi

This option replaces some function calls with intrinsic or otherwise special forms of the function that help your application run faster. 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 #pragma intrinsic for related information.

x86 Specific

This option replaces the following function calls with their intrinsic (inline) forms:

_disable | _outp | abs | memset
_enable | _outpw | fabs | strcat
_inp | _rotl | labs | strcmp
_inpw | _rotr | memcmp | strcpy
_lrotl | _strset | memcpy | strlen
_lrotr |  |  |
Note The _alloca and setjmp functions are always generated inline; this behavior is not affected by /Oi.

The floating-point functions listed below do not have true intrinsic forms. If you use the Generate Intrinsic Functions option, the listed functions are replaced with versions that pass arguments directly to the floating-point chip rather than pushing them onto the program stack:

acos | cosh | pow | tanh
asin | fmod | sinh |

The floating-point functions listed below have true intrinsic forms when you specify both /Oi and /Og (or any option that includes /Og: /Ox, /O1, and /O2):

atan | exp | sin
atan2 | log | sqrt
cos | log10 | tan

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 Improve Float Consistency (/Op) or Disable Language Extensions (/Za) 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 #pragma intrinsic to create intrinsic functions, or #pragma function to explicitly force a function call.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Op (Improve Float Consistency)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Op[-]

This option improves the consistency of floating-point tests for equality and inequality by disabling optimizations that could change the precision of floating-point calculations.

By default, the compiler uses the coprocessor’s 80-bit registers to hold the intermediate results of floating-point calculations. This increases program speed and decreases program size. However, because the calculation involves floating-point data types that are represented in memory by less than 80 bits, carrying the extra bits of precision (80 bits minus the number of bits in a smaller floating-point type) through a lengthy calculation can produce inconsistent results.

With /Op, the compiler loads data from memory prior to each floating-point operation and, if assignment occurs, writes the results back to memory upon completion. Loading the data prior to each operation guarantees that the data does not retain any significance greater than the capacity of its type.

A program compiled with /Op may be slower and larger than one compiled without /Op.

Note The /Op option disables inline generation of floating-point functions. The standard run-time library routines are used instead. For more information, see the /Oi option.

Selecting /Za (ANSI compatibility) selects /Op by default. Using /Op improves the consistency of floating-point tests for equality and inequality, which is required for strict ANSI conformance. The /Op– option overrides this default.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options | IEEE Floating-Point Representation and Microsoft Languages | Why Floating Point Numbers May Lose Precision


/Os (Favor Small Code)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Os

This option minimizes the size of executable files 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 (Favor Fast Code) options allow you to specify a preference for one over the other:

Note The /Os and /Ot options have their greatest effect when used with /Og (Global Optimizations).

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Ot (Favor Fast Code)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Ot

This option maximizes the speed of .exe files 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 trade-offs of size versus speed.

x86 Specific

The following example code demonstrates the difference between the Favor Small Code (/Os) options and the Favor Fast Code (/Ot) option:

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

Alternatively, 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

Note The /Ot option is implied by the Maximize Speed (/O2) option. The /O2 option combines several options to produce very fast code. The /Os and /Ot options have their greatest effect when used with Global Optimizations (/Og).

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Ox (Full Optimization)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Ox

This option combines optimizing options to produce the fastest possible program. The effect is the same as using the following options:

Command line | Development environment
/Ob1 | In-line Function Expansion
/Og | Global Optimizations
/Oi | Generate Intrinsic Functions
/Ot | Favor Fast Code
/Oy | Frame-Pointer Omission
/Gs | Control Stack Probes
Note The use of Full Optimization implies the use of the Frame Pointer Omission (/Oy) option.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/Oy (Frame-Pointer Omission)

Feature Only in Professional and Enterprise Editions Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
/Oy

This option suppresses creation of frame pointers on the call stack. This option speeds function calls, since no frame pointers need to be set up and removed. It also frees one more register, x86 Specific —>EBP on the Intel 386 or later, END x86 Specific for storing frequently used variables and subexpressions.

x86 Specific —> If your code requires EBP-based addressing, you can specify the /Oy– option after the /Ox option or use #pragma optimize with the "y" and off arguments to gain maximum optimization with EBP-based addressing. The compiler detects most situations where EBP-based addressing is required (for instance, with the _alloca and setjmp functions and with structured exception handling). END x86 Specific

The /Ox (Full Optimization) and /O1 and /O2 (Fast Code) options imply /Oy. Specifying /Oy– after the /Ox, /O1, or /O2 option disables /Oy, whether it is explicit or implied.

See Also

/O options (Optimize Code) | Compiler Options | Setting Compiler Options


/P (Preprocess to a File)

/P

This option preprocesses C and C++ source files and writes the preprocessed output to a file. The file has the same base name as the source file and a .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 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 as well as /E.

The /P option suppresses compilation. It does not produce an .obj file, even if you use /Fo. You must resubmit the preprocessed file for compilation. /P also suppresses the output files from the /FA, /Fa, and /Fm options.

To send the preprocessed output, with #line directives, to the standard output device of to a file, use the /E option instead of /P.

To send the preprocessed output, without #line directives, to the standard output device, use the /EP without /P.

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

Compiler Options | Setting Compiler Options


/Q options (Low-level Operations)

The /Q compiler options let you perform low-level compiler operations.

  • /QI0f (Enable Pentium 0x0f Fix)
  • /QIfdiv (Enable Pentium FDIV Fix)
  • QIfist (Suppress _ftol)


/QI0f (Enable Pentium 0x0f Fix)

/QI0f[-]

As part of its regular Pentium Processor Specification Update process, Intel has disclosed an erratum in the Pentium processor that in rare circumstances causes incorrect decoding of certain 0F instructions. Additional information can be obtained in the Pentium Processor Specification Update, available from Intel.

Microsoft has enhanced Visual C++ to optionally generate code that is immune to the erratum. If you observe this erratum or are concerned that your code may be susceptible, include the /QI0f option on the command line or in the Projects Options box on the C/C++ tab in the Project Settings dialog box.

Intel recommends the use of this option for all code.

See Also

/Q options (Low-level Operations) | Compiler Options | Setting Compiler Options


/QIfdiv (Enable Pentium FDIV Fix)

/QIfdiv[-]

The /QIfdiv option offers a workaround for the Intel Pentium microprocessors with flawed FDIV, FPREM, FPTAN, and FPATAN instructions. Microsoft has implemented helper routines in the run-time library that perform more accurate FDIV and FPREM calculations and has provided hooks so that you can write your own helper functions for the FPTAN and FPATAN instructions.

By default, the workaround is disabled (/QIfdiv–), and the code generator emits code that is unsafe on a flawed Pentium.

If the workaround is enabled (/QIfdiv), the code generator emits fatter, safe code that tests for the processor bug and calls run-time routines instead of using the native instructions of the processor to generate correct floating-point results.

For related information, see /Op. Also see Why Floating Point Numbers May Lose Precision.

Note that replacing your processor is another solution to the computation flaws. Contact Intel Corporation for more information.

Most people need not worry about this situation, either because they do not use floating-point at all, or because they do not need an extremely high degree of accuracy. Those who need to be concerned are urged to make sure they understand the issues rather than simply assume that the tools will "just work."

Performance testing of this workaround indicates a worst case penalty is approximately 10% on a Pentium without the flaw, 2x on a flawed Pentium; and the realistic penalty is <1% on a Pentium without the flaw, and 10% on a flawed Pentium. As always, the results may vary. That is, you may see no slowdown in a realistic program, or you may see 2x in a realistic program. If performance is an issue for you, measure it and see what your actual results are. For more information, see Optimizing Your Code.

This fix has been tested extensively. However, as with all software, there is always a possibility that errors remain. You should rigorously test your applications to ensure correctness.

Accuracy of floating-point operations is complex. Even with an accurate set of “atomic” operations, such as +, -, *, /, a program can give unexpected results. The C/C++ standard does not, in general, guarantee a specific order of evaluation for expressions, nor does it guarantee that intermediate results will be forced to a particular precision, so two programs that are logically equivalent on the surface may yield different results.

See Also

/Q options (Low-level Operations) | Compiler Options | Setting Compiler Options


/QIfist (Suppress _ftol)

/QIfist

/QIfist suppresses the call of the helper function, _ftol, when a conversion from a floating-point type to an integral type is required.

In addition to converting from a floating point type to integral type, the _ftol function ensures the rounding mode of the 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 the /QIfist switch, 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 _controlfp C Run-Time function to modify the rounding behavior of the FPU. The default rounding mode of the CRT is "Round toward nearest." Using the /QIfist compiler switch 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.

Caution This switch is not active by default because the rounding bits also affect FP to FP rounding (which occurs after every calculation), so when you set the flags for C-style (toward zero) rounding, your FP calculations might be different. This switch 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 this switch.

See Also

/Q options (Low-level Operations) | Compiler Options | Setting Compiler Options


/RTC (Run-time error checks)

/RTC1
/RTCs
/RTCc
/RTCu

Run-time error checks is a way for you to find problems in your running code; see Run-Time Error Checks for a full description of this feature. The run-time error checks feature is enabled and disabled by the /RTC group of compiler options and the runtime_checks pragma.

Note 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.
Options | Description
/RTC1 | Equivalent of /RTCsu.
/RTCs Enables stack frame run-time error checking,
  • Initialization of local variables to a non-zero value. This helps identify bugs that do not appear when running in debug mode. It is more likely that variables on the stack will not be initialized to zero in release mode than debug mode because of optimizations like stack packing, which allows stack cells to be shared by non-overlapping variables. It is common for uninitialized variables to be zero in a debug build, but nonzero in release builds.
  • Enables detection of overruns and underruns of local variables such as arrays.

    /RTCs will not detect overruns when accessing memory that results from compiler padding within a structure. Padding could occur by using align, /Zp, pack, or if you order structure elements in such as 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. 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.
/RTCc | Reports when a value is assigned to a smaller data type that results in a data loss. For example, if a value of type short 0x101 is assigned to a variable of type char.
/RTCu Reports when a variable is used without having been initialized. For example, an instuction that generates C4701 may also generate a run-time error under /RTCu. Any instruction that generates C4700 will generate a run-time error under /RTCu.

Note that in 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 /RTCu.

The following preprocessor directives will be defined when you use the compiler option(s) noted.

Preprocessor directive | Compiler option
__MSVC_RUNTIME_CHECKS | Any /RTC option or /GZ

As with all compiler options, you can preface the option with either a backslash or a hyphen. For example /RTC or –RTC are equivalent.

See Also

Compiler Options | Setting Compiler Options | RTC sample


/showIncludes

/showIncludes

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

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.

See Also

Compiler Options | Setting Compiler Options


/Tc, /Tp, /TC, /TP (Specify Source File Type)

/Tcfilename
/Tpfilename
/TC
/TP

The /Tc option specifies that filename is a C source file, even if it doesn’t have a .c extension. The /Tp option specifies that filename is a C++ source file, even if it doesn’t have a .cpp or .cxx extension. A space between the option and 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 via /Tc or /Tp.

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.

Examples

The following 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

The following CL command line specifies that FOO1.c, FOO2.cxx, FOO3.huh, and FOO4.o are compiled as C++ files, and FOO5.z is compiled as a C file.

CL FOO1.C FOO2.CXX FOO3.HUH FOO4.O /Tc FOO5.Z /TP

See Also

Compiler Options | Setting Compiler Options


/U, /u (Undefine Symbols)

/U[ ]symbol
/u

These options undefine previously defined symbols. /U undefines the specified symbol. /u undefines all previously defined symbols.

Neither option can undefine symbols created with the #define directive.

/u undefines the following Microsoft-specific macros. /U can undefine these options also.

Symbol | Function
_CHAR_UNSIGNED | Default char type is unsigned. Defined when /J is specified.
_CPPRTTI | Defined for code compiled with the /GR (Enable Run-Time Type Information) option.
_CPPUNWIND | Defined for code compiled with the /GX (Enable Exception Handling) option.
_DLL | Defined when /MD is specified.
_M_IX86 | 1Defined as 500 for Blend (/GB), 300 for 80386 (/G3), 400 for 80486 (/G4), 500 for Pentium (/G5), and 600 for Pentium Pro, Pentium II, and Pentium III (/G6).
_MSC_VER | Defines the compiler version. Defined as 1200 for Microsoft Visual C++ version 6.0 or later. Always defined.
_WIN32 | 1Defined for applications for WIN32. Always defined.
_MT | Defined when /MD or /MT is specified.

1 x86 specific

See Also

Compiler Options | Setting Compiler Options


/V (Version Number)

/Vstring

This option embeds a text string in the .obj file. This string can 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 #pragma comment with the compiler comment-type argument to place the name and version number of the compiler in the .obj file.

See Also

Compiler Options | Setting Compiler Options


/vd (Disable Construction Displacements)

/vdn

These options apply only to C++ code that uses virtual bases:

Command line | Project settings | Description
/vd0 | Disable Construction Displacements (check box selected) | 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.
/vd1 | (Check box cleared) | Enables the creation of hidden vtordisp constructor/destructor displacement members. This choice is the default.

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 #pragma vtordisp to suppress and then re-enable vtordisp fields on a class-by-class basis.

See Also

Compiler Options | Setting Compiler Options


/vmb, /vmg (Representation Method)

/Vmb
/Vmg

These options select the method that the compiler uses to represent pointers to class members. You can also use #pragma pointers_to_members or inheritance keywords in your code to specify a pointer representation.

Command line | Project settings | Description
/vmb | Best-Case Always | Use this option if you always define a class before you declare a pointer to a member of the class.
/vmg | General-Purpose Always | Use this option if you need 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. You must then choose an inheritance model from the General Purpose Representation drop-down list box.

See Also

Compiler Options | Setting Compiler Options


/vmm, /vms, /vmv (General Purpose Representation)

/Vmm
/Vms
/Vmv

If you select General-Purpose Always (/vmg) as the representation method, you must also specify an option to indicate the inheritance model of the not-yet-encountered class definition. You can select one of the following three options.

Command line Project settings Description
/vmm Point to Single- and Multiple-Inheritance Classes
  • Specifies the most general representation of a pointer to a member of a class to be one that uses 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.
  • The corresponding inheritance keyword and argument to #pragma pointers_to_members is multiple_inheritance.
/vms Point to Single-Inheritance Classes
  • 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.
  • 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.
  • The corresponding inheritance keyword and argument to #pragma pointers_to_members is single_inheritance.
/vmv Point to Any Class
  • Specifies the most general representation of a pointer to a member of a class to be one that uses virtual inheritance.
  • This option requires a larger pointer and additional code to interpret the pointer than the other options.
  • It never causes an error and is the default.
  • The corresponding inheritance keyword and argument to #pragma pointers_to_members is virtual_inheritance.

On the command line, use any one of these options with /vmg.

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.

See Also

/vmb | /vmg (Representation Method) | Compiler Options | Setting Compiler Options


/Wn, /WX, /Wall, /wnn, /wdn, /wen, /won (Warning Level)

/Wn
/WX
/Wall
/wnn
/wdn
/wen
/won

These options specify how the compiler generates warnings for a given compilation.

/Wn
Specifies the highest level of warning generated by the compiler. Valid warning levels for n range from 0 to 4:
  • Level 0 disables all warnings.
  • Level 1 displays severe warnings.
  • Level 2 displays all level 1 warnings and warnings less severe than level 1. Level 2 is the default warning level at the command line.
  • Level 3 displays all level 2 warnings and all other warnings recommended for production purposes.
  • Level 4 displays all level 3 warnings plus informational warnings, which in most cases can be safely ignored. This option should be used only to provide "lint" level warnings and is not recommended as your usual warning level setting.
/Wall
Enables all warnings, including those disabled by default.
/WX
Treats all warnings as errors.
/wnn
Specifies the level for a particular warning. The first parameter sets the warning level (same as /Wn) and the second parameter is the actual warning number.

For example, /w14326 causes C4326 to be generated as a level 1 warning.

/wdn
Disables the specified compiler warning where n is the compiler warning number.

For example, /wd4326 disables compiler warning C4326.

/wen
Treats the specific compiler warning as an error.

For example, /we4326 flags warning number C4326 as an error.

/won
Reports the error only once where n is the number for the desired compiler warning.

For example, /wo4326 will cause warning C4326 to be reported only once.

If you create a precompiled header (/Yc) with one of the /w options, any use of the precompiled header (/Yu) will cause those same /w options to be in effect again. You can override the /w setting in the precompiled header with another /w option at the command line.

Pragma directives in source code are unaffected by the /w option.

You can also use #pragma warning() to control the level of warning reported at compile time.

The Build Errors documentation describes the warnings, indicates each warning’s level, and indicates potential problems (rather than actual coding errors) with statements that may not compile as you intend.

See Also

Compiler Options | Setting Compiler Options


/WL (Enable One-Line Diagnostics)

/WL

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 (C2440) that has an additional line of information; it will let you test the effect when you use /WL.

void func1()
{
   int *p;
   char *q;
   p = q;      // Conversion error
}
main(){}

See Also

Compiler Options | Setting Compiler Options


/Wp64 (Detect 64-Bit Portability Problems)

/Wp64

/Wp64 detects 64-bit portability problems on either Win32 or Win64 platforms. Any difference in the number of portability warnings generated between Win32 and Win64 can be corrected by using the __w64 qualifier on Win32. The __w64 qualifier tells the compiler what types are defined as 64-bit on Win64.

Variables of the following types are tested on a 32-bit operating system as if they were 64 bits:

  • int
  • long
  • pointer

See Also

Compiler Options | Setting Compiler Options


/X (Ignore Standard Include Paths)

/X

This option prevents the compiler from searching for include files in directories specified in the PATH and INCLUDE environment variables. You can use this option with the Additional Include Directories (/Idirectory) option.

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

Compiler Options | Setting Compiler Options


/Y- (Ignore Precompiled Header Options)

/Y-

The /Y- compiler option causes all other /Y compiler options to be ignored (and cannot itself be overridden).

See Also

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options


/Yc (Create Precompiled Header File)

/Yc[filename]

This option instructs the compiler to create a precompiled header (.pch) file that represents the state of compilation at a certain point.

Command line | Project settings | Description
/Yc Create Precompiled Header File The compiler compiles all code up to the end of the base source file, or to the point in the base file where a #pragma hdrstop occurs.

The resulting .pch file has the same base name as your base source file unless you specify a different filename using the hdrstop pragma or the /Fp option.

Note If the /Ycfilename and /Yufilename options occur on the same command line and both reference the same filename, /Ycfilename takes precedence, precompiling all code up to and including the named file. This feature simplifies the writing of makefiles.
/Ycfilename | Through Header | The compiler compiles all code up to and including the .h file specified in the Through Header text box (filename).

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 option to specify a name for the precompiled header file.

If you use /Ycfilename (Through Header), the compiler compiles all code up to and including the specified file for subsequent use with the /Yu option.

Note If the options /Ycfilename and /Yu filename 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.

Example

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

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

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options | Creating Precompiled Header Files


/Yd (Place Debug Info in Object File)

/Yd

This option, when used with the /Yc and /Z7 options, places complete debugging information in all object files created from a precompiled header (.pch) file. Unless you need to distribute a library containing debugging information, use the /Zi option rather than /Z7 and /Yd. The /Yd option takes no argument.

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.

Note The /Yd option is implied with use of the Automatic Use Of Precompiled Headers (/YX) option.

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.

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

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options


/Yl (Inject PCH Reference for Debug Library)

/Ylsymbol

When you compile a module with /Yc and /Ylsymbol, the compiler creates a symbol similar to __@@_PchSym_@00@...@symbol, where the ellipsis (...) represents a linker-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.

This option is useful if you attempt to create a debugging library that uses precompiled headers and the build fails. You may generate LNK1211. When you specify the /Yc and /Z7 options, the compiler creates a precompiled header file that contains debugging information. An error can occur when you store the precompiled header in a library, use the library to build an object module, and the source code does not refer to any of the functions the precompiled header file defines.

To solve the problem, specify /Ylsymbol, where symbol is the name of an arbitrary symbol in the library, when you create a precompiled header file that does not contain any function definitions. This option directs the compiler to store the debugging information in the precompiled header file.

See Also

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options


/Yu (Use Precompiled Header File)

/Yu[filename]

This option instructs the compiler to use an existing precompiled header in the current compilation.

Command line | Project settings | Description
/Yu | Use Precompiled Header File | This option specifies using a precompiled header (.pch) file during builds. The PCH must have been created using Create Precompiled Header File (/Yc).
/Yufilename Through Header 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.

The filename argument is the name of a header file, which is included in the source file using an #include preprocessor directive. 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, filename specifies 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.

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 (not precompiled header file). In this case, the compiler will use the precompiled header (.pch file) named by /Fp. 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.

Note If the /Ycfilename and /Yufilename options occur on the same command line and both reference the same filename, /Ycfilename takes precedence, precompiling all code up to and including the named file. This feature simplifies the writing of makefiles.

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

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options


Consistency Rules for Per-File Use of Precompiled Headers

When you use a PCH, the compiler assumes the same compilation environment—using consistent compiler options, pragmas, and so on—that was in effect when you created the PCH, unless you specify otherwise. If the compiler detects an inconsistency, it issues a warning and identifies the inconsistency where possible. Such warnings do not necessarily indicate a problem with the PCH; they simply warn you of possible conflicts. The consistency requirements for PCHs are explained in the following list:

Compiler Option Consistency
The following compiler options can trigger an inconsistency warning when using a PCH:
  • Macros created using the Preprocessor (/D) option must be the same between the compilation that created the PCH and the current compilation. The state of defined constants is not checked, but unpredictable results can occur if these change.
  • PCHs do not work with the /E and /EP options.
  • PCHs must be created using either the Generate Browse Info (/FR) option or the Exclude Local Variables (/Fr) option before subsequent compilations that use the PCH can use these options.
C 7.0-Compatible (/Z7)
If this option is in effect when the PCH is created, subsequent compilations that use the PCH can use the debugging information.

If the C 7.0-Compatible (/Z7) option is not in effect when the PCH is created, subsequent compilations that use the PCH and that option trigger a warning. The debugging information is placed in the current .obj file, and local symbols defined in the PCH are not available to the debugger.

Include Path Consistency
A PCH does not contain information about the include path that was in effect when it was created. When you use a .pch file, the compiler always uses the include path specified in the current compilation.
Source File Consistency
When you specify the Use Precompiled Header File (/Yu) option, the compiler ignores all preprocessor directives (including pragmas) that appear in the source code that will be precompiled. The compilation specified by such preprocessor directives must be the same as the compilation used for the Create Precompiled Header File (/Yc) option.
Pragma Consistency
Pragmas processed during the creation of a PCH usually affect the file with which the PCH is subsequently used. The comment and message pragmas do not affect the remainder of the compilation.

The following pragmas are retained as part of a PCH. They do affect the remainder of a compilation that uses the PCH.

alloc_text | include_alias | pack
auto_inline | init_seg | pointers_to_members
check_stack | inline_depth | setlocale
code_seg | inline_recursion | vtordisp
data_seg | intrinsic | warning
function | optimize

See Also

/Yu (Use Precompiled Header File) | Compiler Options | Setting Compiler Options


/YX (Automatic Use of Precompiled Headers)

/YX[filename]

This option instructs the compiler to use a precompiled header file (PCH) if one exists or to create one if none exists. The file is created in the current directory. You can use the /Fp option to change the default name and location of the precompiled header.

Command line Project settings Description
/YX Automatic Use of Precompiled Headers
  • Creates a file named VCx0.pch, where x is the major version of Visual C++, if it doesn’t already exist, and compiles only header files into this .pch file.
  • If you have no project open, it creates a file named VCx0.pch, where x is the major version of Visual C++ in use.
  • The inclusion of .h files stops when the compiler encounters the first declaration, definition, hdrstop pragma, or #line directive in the source file being compiled with the option, or after the .h file specified in the Through Header text box.
  • In subsequent compilations, the PCH is used after the compiler makes its final consistency check.
  • See Consistency Rules for /YX.
/YXfilename Through Header
  • When creating a PCH, the compiler compiles all code up to and including the .h file specified in the Through Header text box (filename).
  • When using a PCH, the compiler treats all code occurring before the specified .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.

Using the /YX option limits precompilation to header files only. The precompiled header is created when the compiler encounters the first declaration, definition, hdrstop pragma, or #line directive that occurs in the source file. In a subsequent compilation, the precompiled header is used at the point in a source file where the compiler makes its final consistency check. For more information, see Consistency Rules for /YX.

The header files precompiled by /YX are determined by the compiler, which may elect to use a subset of header files available to improve the number of cases where the resulting precompiled header can be used.

Although it is usually best to let the compiler determine which header files to use, you can selectively precompile header files by placing a hdrstop pragma in the source file between two #include directives. All header files before the hdrstop pragma are precompiled; those after are not. When used with /YX, any filename specified with the hdrstop pragma is ignored. If any subsequent compilation using the precompiled header does not contain an identical hdrstop pragma at the same point in the source file, the compiler builds a new precompiled header.

Note If either /Yc or /Yu is specified with /YX, a warning is issued. In such cases, /YX is ignored, and /Yc or /Yu takes precedence.

Use of the /YX option implies use of the /Yd option (duplicate debugging information in all object files).

Example

The following command line uses /YX to create or use a precompiled header named VCx0.pch:

CL /YX MYPROG.CPP

The following command line creates a precompiled header named MYPROG.pch and places it in the \PROJPCH directory:

CL /YX /Fp\PROJPCH\MYPROG.PCH MYPROG.CPP

See Also

Compiler Options | Setting Compiler Options | Precompiled Header Compiler Options


Consistency Rules for /YX

If a precompiled header file exists (either MSVC.pch or one specified by /Fp), it is compared with the current compilation for consistency. The following requirements must be met; otherwise, a new precompiled header file is created, and the new file replaces the old.

  • The current compiler options must match those specified when the precompiled header was created. However, if a significant portion of the source code of the currently compiled module matches the module for which the PCH was created, the compiler can create a new PCH for the matching part. This subsetting action increases the number of modules for which a PCH can be used.
  • The current working directory must match that specified when the PCH was created.
  • The order and values of all #include and #pragma directives must match those specified when the precompiled header was created. These, along with #define directives, are checked one by one as they appear during subsequent compilations that use the precompiled header. The values of #define directives must match. However, a sequence of #define directives need not occur in exactly the same order because there are no semantic order dependencies for #define directives. The #pragma directives must be nearly identical, with a few exceptions; for example, multiple spaces outside of strings are treated as a single space to allow for different programming styles.
  • The values of #define directives must match. However, a group of #define directives in sequence need not occur in exactly the same order since there are no semantic order dependencies for #define directives.
  • The value and order of include paths specified on the command line with /I (Additional Include Directories) options must match those specified when the precompiled header was created.
  • The timestamps of all header files (all files specified with #include directives) used to build the precompiled header must match those that existed when the precompiled header was created.

See Also

/YX (Automatic Use of Precompiled Headers) | Compiler Options | Setting Compiler Options


/Z7, /Zd, /Zi, /ZI (Debug Info)

/Z{d|7|i|I}

The Debug Info options select the type of debugging information created for your program and whether this information is kept in object (.obj) files or in a program database (PDB).

Command line | Project settings | Description
None of these options | None | Produces no debugging information, so compilation is faster.
/Zd | Line Numbers Only | Produces an .obj file or executable (.exe) file containing only global and external symbol and line-number information (no symbolic debugging information). Use this option if you want to reduce the size of the .exe file, or if you don’t want to use the debugger’s expression evaluator (requires symbolic information).
/Z7 | C 7.0- Compatible | Produces an .obj file and an .exe file containing line numbers and full symbolic debugging information for use with the debugger. The symbolic debugging information includes the names and types of variables, as well as functions and line numbers.
/Zi | Program Database | Produces a program database (PDB) that contains type information and symbolic debugging information for use with the debugger. The symbolic debugging information includes the names and types of variables, as well as functions and line numbers.
/ZI | Program Database for Edit and Continue | Produces a program database, as described above, in a format that supports the Edit and Continue feature. If you want to use Edit and Continue debugging, you must use this option. Because most optimizations are incompatible with Edit and Continue, using /ZI disables any #pragma optimize statements in your code. /ZI causes /Gy to be used in your compilation.

The compiler names the program database project.pdb. If you compile a file without a project, the compiler creates a database named VCx0.pdb., where x is the major version of Visual C++ in use. The compiler embeds the name of the PDB in each .obj file created using this option, pointing the debugger to the location of symbolic and line-number information. When you use this option, your .obj files will be smaller, because debugging information is stored in the .pdb file rather than in .obj files.

If you create a library from objects that were compiled using this option, the associated .pdb file must be available when the library is linked to a program. Thus, if you distribute the library, you must distribute the PDB.

Note To create a library that contains debugging information without using .pdb files, you must select the compiler’s C 7.0-Compatible (/Z7). 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. The /Yd option is ignored when the Program Database option is specified.

See Also

Compiler Options | Setting Compiler Options


/Za, /Ze (Disable Language Extensions)

/Za
/Ze

The Visual C++ compiler offers a number of features beyond those specified in either the ANSI C or ANSI C++ standards. These features are collectively known as Microsoft’s extensions to the C and C++ languages. These extensions are available when the /Ze option, the default, is specified and are not available when the /Za option is specified. See Microsoft Extensions to C and C++ for more information.

Command line | Project settings | Description
/Za | Disable Language Extensions (check box selected) | Language constructs not compatible with either ANSI C++ or ANSI C are flagged as errors.
/Ze | (Check box cleared) | Enables Microsoft extensions.
Note If you use the Disable Language Extensions (/Za) option, the Improve Float Consistency (/Op) option is used to improve the consistency of floating-point tests for equality and inequality. This use of /Op with /Za is for strict ANSI conformance and is the only situation under which /Op is selected by default. The /Op– option is provided to override the default selection of /Op with /Za. Specify /Op– in the Common/Project/Source File Options text box (or on the command line), after /Za, to disable /Op. For more information, also see Generate Intrinsic Functions (/Oi).

Disable language extensions if you plan to port your program to other environments. The compiler treats extended keywords as simple identifiers, disables the other Microsoft extensions, and automatically defines the __STDC__ predefined macro for C programs.

See Also

Compiler Options | Setting Compiler Options


Microsoft Extensions to C and C++

The following are Visual C++ extensions to the ANSI C and ANSI C++ standards:

Keywords

Microsoft extends the C++ language with several additional keywords. For a complete list, see C++ Keywords in the C++ Language Reference. Keywords with two leading underscores are Microsoft extensions.

Out of Class Definition of static const Integral (or enum) Members

Under the standard (/Za), you need to make an out-of-class definition for data members. For example,

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 inside a class; the initializing expression must be a const expression.

To avoid errors when an out-of-class definition is provided (when the out-of-class definition is provided in a header file and the header file is included in multiple source files), you should use selectany. For example,

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

Casts

The compiler supports the following two non-ANSI casts:

  • Use of non-ANSI casts to produce l-values:
    char *p;
(( int * ) p )++;

    The preceding example could be rewritten to conform with the ANSI C standard as follows:

    p = ( char * )(( int * )p + 1 );
  • Non-ANSI casting of a function pointer to a data pointer:
    int ( * pfunc ) ();
int *pdata;
pdata = ( int * ) pfunc;

    To perform the same cast while maintaining ANSI compatibility, you must cast the function pointer to an int before casting it to a data pointer:

    pdata = ( int * ) (int) pfunc;

Variable-Length Argument Lists

The compiler supports use of 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 with 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 );
}
void main( void )
{
    func2( 4 );    //  /Ze passes 4 as type double
}                  //  /Za passes 4 as type int
  • Use of block-scope variables initialized with nonconstant expressions:
    int clip( int );
int bar( int );
void 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 with base types other than unsigned int or signed int.
  • Declarators without either a storage class or a type:
    x;
void 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

The compiler supports inline generation of the x86 Specific —> atan, atan2, cos, exp, log, log10, sin, sqrt, and tan functions END x86 Specific when the Generate Intrinsic Functions (/Oi) option is specified. For C, 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++. The following 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'
}

new Operator Does Not Throw Exception

When the new operator fails to allocate the requested memory, no exception will be thrown; a null pointer is returned instead.

Scope of Variable in for Loop Stays in Effect After Loop

The following code will compile under /Za. However, to keep compatibility with older code bases, it will not compile under /Ze:

int main () {
   for (int i = 0; i<1; ++i);
   for (int i = 0; i<1; ++i);
   return 0;
}

Use /Zc:forScope if you want to enable Microsoft extensions (/Ze) and standard behavior for for loops.

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)

See Also

/Za | /Ze (Disable Language Extensions) | Compiler Options | Setting Compiler Options


/Zc (Conformance)

The /Zc compiler option lets you specify standard behavior with /Ze. The following is a list of the current /Zc compiler options:

  • /Zc:forScope

See Also

Compiler Options | Setting Compiler Options


/Zc:forScope

/Zc:forScope

If you want standard behavior of for loops and Microsoft extensions (/Ze), use /Zc:forScope with /Ze, which is on by default.

Standard behavior is to let a for loop's initializer go out of scope after the for loop finishes. Under /Ze, the for loop's initializer remains in scope until the local scope ends.

The following code will compile under /Ze but not under /Za:

void main() {
// 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, you will get a warning 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 above code to declare int i.

You can modify the run-time behavior of /Zc:forScope with the conform pragma.

If you use /Zc:forScope in a project with an existing .pch file, /Zc:forScope is ignored (with a warning) and compilation continues with the existing .pch files. If you want a new .pch file generated, use /Yc.

See Also

/Zc (Conformance)


/Zg (Generate Function Prototypes)

/Zg

This option creates a function prototype for each function defined in the source file, but does not compile the source file.

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.

See Also

Compiler Options | Setting Compiler Options


/Zl (Omit Default Library Name)

/Zl

This option omits the default library name from the .obj file. By default, CL puts the name of the library into the .obj file to direct the linker to the correct library. 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.

See Also

Compiler Options | Setting Compiler Options


/Zm (Specify Memory Allocation Limit)

/Zmnumber

/Zmnumber determines the compiler's memory allocation limit. number is a scaling factor with a default value of 100, which specifies a memory allocation of 105MB. The maximum number is 2000. The following table demonstrates how number modifies the memory allocation:

number | memory allocation
10 | 10.5 MB
100 | 105 MB
200 | 210 MB
1000 | 1050 MB
2000 | 2100 MB

The compiler uses a number of discrete heaps, each of which has a finite limit. The total of the size limits for all heaps is about 105 MB, but when any one heap is exhausted, the compiler cannot continue. Memory is allocated only as needed; the 105-MB limit prevents using too much memory. Exceeding any one of the discrete-heap size limits occurs only in rare circumstances involving very large or very complex programs. Should your program exceed one of these limits, use /Zm to scale the total size of all the limits.

Note In most cases, use of this compiler option is not necessary. Use it if compiling your program causes error message C1076.

See Also

Compiler Options | Setting Compiler Options


/Zp (Struct Member Alignment)

/Zp[1|2|4|8|16]

The Struct Member Alignment (/Zpn) option controls how the members of a structure are packed into memory and specifies the same packing for all structures in a module. When you specify this 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.

You should not use this option unless you have specific alignment requirements.

Command line | Project settings | Result
/Zp1 | 1 Byte | Packs structures on 1-byte boundaries
/Zp2 | 2 Bytes | Packs structures on 2-byte boundaries
/Zp4 | 4 Bytes | Packs structures on 4-byte boundaries
/Zp8 | 8 Bytes | Packs structures on 8-byte boundaries (default)
/Zp16 | 16 Bytes | Packs structures on 16-byte boundaries
/Zp | Not applicable | Specifies the same packing for all structures in a module.

You can also use #pragma pack to control structure packing.

See Also

Compiler Options | Setting Compiler Options


/Zs (Syntax Check Only)

/Zs

This option tells the compiler to check only the syntax of the source files on the command line. No output files are created. 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.

See Also

Compiler Options | Setting Compiler Options


Fast Compilation

How can I compile faster?

To increase the speed of your compiles:

  • Use minimal rebuild, in which the C++ compiler recompiles a source file only if it is dependent on changes to a class in a header file.
  • Create Precompiled Header Files and use the precompiled header options.

See Also

Compiler Options | Setting Compiler Options


CL Invokes the Linker

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 Linker Option Reference.

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 and scanf.
  • 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 and scanf 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

Compiler Options | Setting Compiler Options


Linker Options

LINK is a 32-bit tool that links Common Object File Format (COFF) object files and libraries to create a 32-bit executable (.exe) file or dynamic-link library (DLL).

Following is a comprehensive list of options for LINK.exe. This section also includes information on Compiler-Controlled LINK Options, LINK Input Files, and LINK Output.

Linker options specified on the command line are not case sensitive: /base and /BASE mean the same thing.

You can also specify some linker options via comment pragma.

Option | Purpose
@ | Specifies a response file.
/ALIGN | Specifies the alignment of each section.
/ALLOWBIND | Specifies that a DLL cannot be bound.
/ASSEMBLYMODULE | Specifies that a Microsoft Intermediate Language (MSIL) module should be imported into the assembly.
/ASSEMBLYRESOURCE | Links a NGWS resource file to an assembly.
/BASE | Sets a base address for the program.
/DEBUG | Creates debugging information.
/DEBUGTYPE | Creates particular formats of debugging information.
/DEF | Passes a module-definition (.def) file to the linker.
/DEFAULTLIB | Searches specified library when resolving external references.
/DELAY | Controls the delayed loading of DLLs.
/DELAYLOAD | Causes the delayed loading of the specified DLL.
/DLL | Builds a DLL.
/DRIVER | Creates a Windows NT kernel mode driver.
/ENTRY | Sets the starting address.
/EXETYPE | Builds a virtual device driver.
/EXPORT | Exports a function.
/FIXED | Creates a program that can be loaded only at its preferred base address.
/FORCE | Forces link to complete in spite of unresolved or multiply defined symbols.
/HEAP | Sets the size of the heap in bytes.
/IDLOUT | Specifies the name of the .IDL file and other MIDL output files.
/IGNOREIDL | Prevents processing attribute information into a .idl file.
/IMPLIB | Overrides the default import library name.
/INCLUDE | Forces symbol references.
/INCREMENTAL | Controls incremental linking.
/LARGEADDRESSAWARE | Tells the compiler that the application supports addresses larger than two gigabytes.
/LIBPATH | Allows the user to override the environmental library path.
/LTCG | Specifies link-time code generation.
/MACHINE | Specifies the target platform.
/MAP | Creates a map file .
/MAPINFO | Includes the specified information in the map file.
/MERGE | Combines sections.
/MIDL | Specifies MIDL command line options.
/NOASSEMBLY | Suppresses the creation of a NGWS assembly.
/NODEFAULTLIB | Ignores all (or specified) default libraries when resolving external references.
/NOENTRY | Creates a resource-only DLL.
/NOLOGO | Suppresses startup banner.
/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.
/PDBSTRIPPED | Create a program database (PDB) file with no private symbols.
/RELEASE | Sets the checksum in the .exe header.
/SECTION | Overrides the attributes of a section.
/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 running it.
/TLBID | Allows you to specify the resource ID of the linker-generated type library.
/TLBOUT | Specify the name of the .TLB file and other MIDL output files.
/TSAWARE | Creates an application that is specifically designed to run under Terminal Server.
/VERBOSE | Prints linker progress messages.
/VERSION | Assigns a version number.
/VXD | Creates a virtual device driver (VxD).
/WS | Aggressively trim process memory.

For related information, see Compiler-Controlled LINK Options.

See Also

Building a C/C++ Program | Setting Linker Options | FAQ: Building Your Program


Compiler-Controlled LINK Options

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.

Compiler-Controlled LINK Options

CL command-line 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, /ML, or /MT | Places a default library name in the .obj file.
/MDd, /MLd, or /MTd | Places a default library name in the .obj file. Defines the symbol _DEBUG.
/nologo | Passes /NOLOGO.
/Zd | Passes /DEBUG /DEBUGTYPE:COFF.
/Zi or /Z7 | Passes /DEBUG /DEBUGTYPE:CV.
/Zl | Omits default library name from .obj file.

For more information on compiler options, see Compiler Option Reference.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


LINK Input Files

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.

Note LINK no longer takes a semicolon (or any other character) as the start of a comment in response files and order files. Semicolons are recognized only as start of comments in module-definition files (.def).

LINK uses the following types of input files:

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


.obj Files as Linker Input

LINK accepts .obj files that are either Common Object File Format (COFF) or 32-bit Object Module Format (OMF). Microsoft’s compiler creates COFF .obj files.

LINK automatically converts 32-bit OMF objects to COFF. However, there are limitations to OMF to COFF conversions. OMF can represent some things that cannot be represented in COFF. If there are errors when the linker converts from OMF to COFF, then you will need to use COFF .obj files instead of OMF .obj files as input to the linker.

See Also

LINK Input Files | Linker Options | FAQ: Building Your Program


.lib Files as Linker Input

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.

See Also

LINK Input Files | Linker Options | FAQ: Building Your Program


.exp Files as Linker Input

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 | Linker Options | FAQ: Building Your Program


.def Files as Linker Input

See Module-definition (.def) files for more information. Use the /DEF option to specify the .def file name.

See Also

LINK Input Files | Linker Options | FAQ: Building Your Program


.pdb Files as Linker Input

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 .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 | Linker Options | FAQ: Building Your Program


.res Files as Linker Input

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 | Linker Options | FAQ: Building Your Program


.exe Files as Linker Input

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 | Linker Options | FAQ: Building Your Program


.txt Files as Linker Input

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 | Linker Options | FAQ: Building Your Program


.ilk Files as Linker Input

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 .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 | Linker Options | FAQ: Building Your Program


LINK Output

Link output includes .exe files, DLLs, map files, 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 map file.

If the Generate Debug Info (/DEBUG) and Microsoft Format (/DEBUGTYPE:CV) options are 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 is also used by LIB, DUMPBIN, and EDITBIN.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


Reserved Words

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 The linker ignores this word but emits no warning.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


@ (Specify a Linker Response File)

@response_file

See @ (Specify a Compiler Response File) for more information.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/ALIGN (Section Alignment)

/ALIGN[:number]

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/ALLOWBIND (Prevent DLL Binding)

/ALLOWBIND{:NO}

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | BindImage | BindImageEx


/ASSEMBLYMODULE (Add an MSIL Module to the Assembly)

/ASSEMBLYMODULE:filename

where,

filename
The module you want to include in this assembly.

Remarks

You can import NGWS metadata into a program with the #using directive. If you specify a module, which is a file that does not contain an assembly, you also have to specify /ASSEMBLYMODULE for that module.

By specifying a module with #using, you imply that you need to use the types in that module for your program. However, it is possible that you would want to include a module in your assembly to be used by other programs. In that case, you would specify /ASSEMBLYMODULE for that module.

Other linker options that affect assembly generation are:

  • /ASSEMBLYRESOURCE
  • /NOASSEMBLY

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/ASSEMBLYRESOURCE (Link to a NGWS Runtime Resource)

/ASSEMBLYRESOURCE:filename

where,

filename
The NGWS resource you want to link to this assembly.

Remarks

This option makes an assembly reference to a NGWS resource file.

Other linker options that affect assembly generation are:

  • /ASSEMBLYMODULE
  • /NOASSEMBLY

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/BASE (Base Address)

/BASE:{address | @filename,key}

This option sets a base address for the program, overriding the default location for an .exe file (at 0x400000) or a DLL (at 0x10000000). 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.

Type the preferred base address in the Base Address text box (or in the address argument on the command line). The linker rounds the specified number up to the nearest multiple of 64K.

On the command line, another way to specify the base address is by using the filename preceded by an at sign (@), and a key into the file. The filename is a text file that contains the locations and sizes of all the DLLs your program will use. The linker looks for filename in either the specified path or, if no path is specified, in 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 a 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

You can reduce paging and improve performance of your program by assigning base addresses so that DLLs do not overlap in the address space.

Another way to set the base address is with the BASE argument in a NAME or LIBRARY statement. The /BASE and /DLL options together are equivalent to the LIBRARY statement.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DEBUG (Generate Debug Info)

/DEBUG

This option creates debugging information for the .exe file or DLL. When specifying this option, you automatically get a DEBUGTYPE of CV.

The linker puts the debugging information into a program database (PDB). It updates the PDB during subsequent builds of the program.

An .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 the Use Program Database linker option (/PDB:filename on the command line) and specify a different file name in the Program database name text box.

The compiler’s Line Numbers Only (/Zd) or 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.

If the Use Program Database option is not selected, the linker does not create a PDB, but instead puts the debugging information into the .exe file or DLL.

The Generate Debug Info (/DEBUG) option changes the defaults for the /OPT option from REF to NOREF and from ICF to NOICF.

See Knowledge Base articles Q121366 for more information on .PDB and .DBG files.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DEBUGTYPE (Debugging Format)

/DEBUGTYPE:[option]

option is available when the /DEBUG (Generate Debug Info) option is used. There is currently only one option: CV, which indicates Microsoft Format debugging information.

If /DEBUG is specified, the default type is /DEBUGTYPE:CV; if /DEBUG is not specified, /DEBUGTYPE is ignored.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DEF (Specify Module-Definition File)

/DEF:filename

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

Do not specify this option within the development environment; this option is used only on the command line. To specify a .def file, add it to the project along with other files.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DEFAULTLIB (Specify Default Library)

/DEFAULTLIB:library

This 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 on the command line and before default libraries named in .obj files.

The Ignore All Default Libraries (/NODEFAULTLIB) option overrides /DEFAULTLIB:library. The Ignore Libraries (/NODEFAULTLIB:library) option overrides /DEFAULTLIB:library when the same library name is specified in both.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DELAY (Delay Load Import Settings)

/DELAY:UNLOAD
/DELAY:NOBIND

This 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. When this happens, the DLL is said to be bound. 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 do 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | Peering Inside the PE: A Tour of the Win32 Portable Executable File Format


/DELAYLOAD (Delay Load Import)

/DELAYLOAD:dllname

This option causes delayed loading of DLLs. The dllname specifies a DLL to delay load. You can use this option as many times as necessary to specify as many DLLs as you choose. You must link your program with Delayimp.lib or implement your own delay-load helper function.

The /DELAY option specifies binding and loading options for each delay-loaded DLL.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DLL (Build a DLL)

/DLL

This 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. The __declspec(dllexport) keyword 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 select either MFC AppWizard (DLL) or Dynamic-Link Library on the Projects tab of the New dialog box.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/DRIVER (Windows NT Kernel Mode Driver)

/DRIVER[:UPONLY |:WDM]

Use this linker option to build a Windows NT kernel mode driver.

The UPONLY keyword 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.

The WDM keyword causes the linker to set the IMAGE_DLLCHARACTERISTICS_WDM_DRIVER bit in the optional header's DllCharacteristics field. WDM video capture was designed to resolve the problems inherent in the Video for Windows architecture.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/ENTRY (Entry-Point Symbol)

/ENTRY:function

The Entry-Point Symbol option sets the starting address for an .exe file or DLL.

Type a function name in the Entry-Point Symbol text box (or in the function argument on the command line). The function must be defined with the __stdcall calling convention. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .exe file) or DllEntryPoint (for 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 using /SUBSYSTEM:CONSOLE; calls main (or wmain).
WinMainCRTStartup (or wWinMainCRTStartup) | An application using /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined with __stdcall.
_DllMainCRTStartup | A DLL; calls DllMain, which must be defined with __stdcall, if it exists.

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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/EXETYPE (Executable File Type)

/EXETYPE[:DYNAMIC | :DEV386]

/EXETYPE (Executable File Type) is used when building a virtual device driver (VxD). A VxD is linked using the /VXD option.

Parameters

DYNAMIC
Creates a dynamically-loaded virtual device driver.
DEV386
Creates a statically-loaded virtual device driver. This is the default for /EXETYPE.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/EXPORT (Exports A Function)

/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

With this option, you can export a function from your program so that other programs can call the function. You can also export 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 three 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

All three 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 Names 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/FIXED (Fixed Base Address)

/FIXED[:NO]

This option tells the operating system to load the program only at its preferred base address. If the preferred base address is unavailable, the operating system will not load the file. For more information, see /BASE (Base Address).

By default, /FIXED:NO is the default when building a DLL and /FIXED 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 that address, it issues an error message and does not load the program.

Specify /FIXED:NO to generate a relocation section in the program.

Do not use /FIXED when building device drivers for Windows NT.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/FORCE (Force File Output)

/FORCE:{MULTIPLE|UNRESOLVED}

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

On the command line, 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 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/HEAP (Set Heap Size)

/HEAP:reserve[,commit]

This 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 is subject to interpretation by the operating system. In Windows NT, 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 heap space but increases the memory requirements and possibly the startup time.

Specify the reserve and commit values in decimal or C-language notation.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/IDLOUT (Name MIDL Output Files)

/IDLOUT:[path\]filename

where,

filename
Specifies the name of the .idl file created by the MIDL compiler. No file extension is assumed; specify filename.idl if you want a .idl extension.
path
An absolute or relative path specification. By specifying a path, you only affect the location of .idl file; all other files are placed in the project directory.

Remarks

/IDLOUT specifies the name and extension of the .idl file.

The MIDL compiler is called by the Visual C++ 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | /IGNOREIDL | /MIDL | Building an Attributed Program


/IGNOREIDL (Don't Process Attributes into MIDL)

/IGNOREIDL

Specifies that any IDL attributes in source code should not be processed into a .idl file.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | /IDLOUT | /TLBOUT | /MIDL | Building an Attributed Program


/IMPLIB (Name Import Library)

/IMPLIB:filename

This 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
  • An 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/INCLUDE (Force Symbol References)

/INCLUDE:symbol

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/INCREMENTAL (Link Incrementally)

/INCREMENTAL[:NO]

This option 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 nonincrementally linked. However, because it is prepared for subsequent incremental links, an incrementally linked executable (.exe) file or dynamic-link library (DLL):

  • Is larger than a nonincrementally linked program because of padding of code and data. (Padding allows the linker to increase the size of functions and data without recreating the .exe 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 nonincrementally.

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 nonincrementally. 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).
  • /DEBUGTYPE is selected.
  • /OPT:REF is selected.
  • /OPT:ICF is selected.
  • /ORDER is selected.

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 nonincrementally.)
  • 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.
  • An object that was compiled with the /Yu /Z7 option is changed.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/LARGEADDRESSAWARE (Handle Large Addresses)

/LARGEADDRESSAWARE[:NO]

Tells the linker that the application can handle addresses larger than 2 gigabytes.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/LIBPATH (Additional Libpath)

/LIBPATH:dir

Use this linker 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/LTCG (Link-time Code Generation)

/LTCG

Tells the linker to call the compiler and perform whole program optimization. /LTCG is called for you when you use the /GL compiler option.

If you use /GL with /c, you can use /LTCG when you link your .obj files and create the output file for the fastest possible output-file creation time.

/LTCG is not valid for use with:

  • /INCREMENTAL:YES.
  • /com+

When /LTCG is used with either /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
  • stack double alignment
  • improved memory disambiguation (better interference info for global variables)

Using /LTCG and /Ogt will result in double alignment optimization.

If /LTCG and /Ogs are specified, double alignment will not be 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 would double align these functions that are optimized for size if they call functions that need double-alignment.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/MACHINE (Specify Target Platform)

/MACHINE:{ARM|CEE|IA64|IX86|MIPS|MIPS16|MIPSFPU|MIPSFPU16|
MIPSR41XX|PPC|SH3|SH4|THUMB}

This option specifies the target platform for the program.

Usually, you do not need 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.

CEE refers to the NGWS execution engine.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/MAP (Generate Mapfile)

/MAP[:filename]

This option tells the linker to create a mapfile.

Command line | Project settings | Description
/MAP | Generate Mapfile | The linker names the mapfile with the base name of the program and the extension .map.
/MAP:filename | Mapfile Name | This option overrides 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 map file.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/MAPINFO (Include Information in Mapfile)

/MAPINFO:{EXPORTS|FIXUPS|LINES}

This option tells the linker to include the specified information in a map file, which is created if you specify the /MAP option.

  • EXPORTS tells the linker to include exported functions.
  • FIXUPS tells the linker to include base-relocation information in the mapfile if relocation information exists in the image. Base relocations will be present in the image if you link with /FIXED:NO.
  • LINES includes line-number information.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/MERGE (Combine Sections)

/MERGE:from=to

This option combines the first section (from) with the second section (to), naming the resulting section to. 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/MIDL (Specify MIDL Command Line Options)

/MIDL:@file

You can indicate the file that contains MIDL command line options.

All options for the conversion of an IDL file to a TLB file must be given in this 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | /IDLOUT | /IGNOREIDL | /TLBOUT | Building an Attributed Program


/NOASSEMBLY (Create an MSIL Module)

/NOASSEMBLY

This option tells the linker to create an image for the current output file without a NGWS assembly.

By default, an assembly is created.

Other linker options that affect assembly generation are:

  • /ASSEMBLYMODULE
  • /ASSEMBLYRESOURCE

See Also

Setting Linker Options | Linker Options | FAQ: Building Your


/NODEFAULTLIB (Ignore Libraries)

/NODEFAULTLIB[:library]

This option tells the linker to remove one or more default libraries from the list of libraries it searches when resolving external references.

Command line | Project settings | Description
/NODEFAULTLIB:library | Ignore Libraries | This option removes the specified library or libraries from the list of libraries it searches when resolving external references.
/NODEFAULTLIB | Ignore All Default Libraries | This option removes all default libraries from the list of libraries it searches when resolving external references.

The linker resolves references to external definitions by searching first in libraries specified in the Object/Library Modules text box in the Project Settings dialog box (or on the command line), then in default libraries specified with the /DEFAULTLIB option, and then in default libraries named in .obj files.

To specify multiple libraries, use /NODEFAULTLIB:library more than once.

The Ignore Libraries (/NODEFAULTLIB:library) option overrides /DEFAULTLIB: library when the same library name is specified in both.

If you use /NODEFAULTLIB linker option, 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/NOENTRY (No Entry Point)

/NOENTRY

This option is required for creating a resource-only DLL.

Use this option to prevent LINK from linking a reference to _main into the DLL.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/NOLOGO (Suppress Startup Banner)

/NOLOGO

This option prevents display of the copyright message and version number.

The Suppress Startup Banner 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


Object/Library Modules

To pass an object file or standard library (either static or import) to the linker, specify the file name in the Object/library modules text box, or type the file name on the command line. You can specify an absolute or relative path with the file name, and you can use wildcards in the file name. If you omit the dot (.) and file name extension, the linker assumes .obj for the purpose of finding the file. The linker does not use file name 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.

For additional information, see LINK Input Files.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/OPT (Optimizations)

/OPT:REF | NOREF
/OPT:ICF[=iterations] | NOICF]
/OPT:WIN98 | NOWIN98

/OPT controls the optimizations that LINK performs during a build. Optimizations generally decrease the image size and increase the program speed, at a cost of increased link time.

REF | NOREF
/OPT:REF eliminates functions and/or data that are never referenced while /OPT:NOREF keeps functions and/or data that are never referenced. /OPT:REF is the default.

LINK removes unreferenced packaged functions by default. An object contains packaged functions (COMDATs) if it has been compiled with the /Gy option. This optimization is called transitive COMDAT elimination. 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 the /DEBUG option is specified, the default for /OPT changes from REF to NOREF, and all functions are preserved in the image. To override this default and optimize a debugging build, specify /OPT:REF. The /OPT:REF option disables incremental linking.

You have to explicitly mark data as a COMDAT; use __declspec(selectany).

If /OPT:REF is specified, /OPT:ICF is on by default. If you want /OPT:REF but not /OPT:ICF, you must specify the following:

link /opt:ref /opt:noicf

Specifying /OPT:ICF does not activate the /OPT:REF option.

ICF[=iterations] | NOICF
Use /OPT:ICF[=iterations] to perform identical COMDAT folding. Redundant COMDATs can be removed from the linker output. iterations specifies the number of times to traverse the symbols for duplicates. The default number of iterations is two. Additional iterations may locate more duplicates uncovered through folding in the previous iteration.

Functions are placed in COMDATs with the /Gy compiler option and const data is placed in COMDATs. See selectany for an example of how to specify data for folding.

ICF is on by default if REF is on and needs to be explicitly turned on in a debug build.

/OPT:WIN98 | NOWIN98
WIN98 and NOWIN98 control the section alignment in the final image - for WIN98 apps it is optimal to align sections on a 4K boundary to improve load time. This is ON by default in the linker, so you need to specify /opt:nowin98 to get a trimmed-down (but slower on Win98) version of the app.

If you build images intended to run on Windows 98, especially those that are redistributable, you should use the WIN98 option. This allows the Windows 98 memory manager to cache executable images with a minimum of wasted space. Specifically, WIN98 aligns sections on a 4K boundary to improve load time. WIN98 is on by default. WIN98 is not on when,

  • /ALIGN is used.
  • /MACHINE does not target x86.
  • /SUBSYSTEM specifies something other than WINDOWS or CONSOLE.
/OPT:WIN98 is not enabled by default for small images; you should enable /OPT:WIN98 explicitly to ensure that you are not affected by this tuning. Specify /opt:nowin98 to get a smaller, but slower on Win98, version of your application.

The enhancements in Windows 98 only work when the sections in a portable executable image begin on a page boundary. The /OPT:WIN98 option performs the necessary file alignment.

If you are building components that run only on NT, you should use /OPT:NOWIN98.

This change impacts neither Windows NT's or Windows 95's loading of images nor the working set of the process. The only impact is to the on-disk size. The average wasted space for 4096-byte file alignment can be characterized by:

count-of-sections-in-image * 4096/2

The average for the current 512-byte file alignment is:

count-of-sections-in-image * 512/2

The growth is therefore:

cbGrowth = count-of-sections-in-image * (4096/2 - 512/2)

average count-of-bytes-Growth = count-of-sections-in-image * 1792 + 3584

maximum count-of-bytes-Growth = count-of-sections-in-image * 4095 + 3584

To get the count of sections, use dumpbin on an executable. The summary will give you a list of sections in that image. Typically, you will see from 3 to 5 sections and you need to add one to that value, because it does not account for the portable executable header.

The only time you should not use /OPT:WIN98 is when your portable executable image is very small. Even if an image is slated for downloads, the wasted space is zero-filled and compresses well.

You can use /VERBOSE to see the functions removed by /OPT:REF and the the functions that are folded by /OPT:ICF.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/ORDER (Put Functions in Order)

/ORDER:@filename

This option tells LINK to optimize your program by placing certain COMDATs into the image in a predetermined order. LINK places the functions in the specified order within each section in the image.

Specify the order in filename, which is a text file that lists the COMDATs in the order you want to link them. Each line in filename contains the name of one COMDAT. An object contains COMDATs if it has been compiled with the /Gy option. Function names are case sensitive.

LINK uses decorated forms of identifiers. The compiler decorates an identifier when it creates the .obj file. If the name of the COMDAT 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 form of an identifier when you need to specify it to the linker. For more information on decorated names, see Decorated Names.

Note Do not specify the decorated form of C identifiers that are declared __cdecl or __stdcall.

If more than one /ORDER specification is used, the last one specified takes effect.

Ordering allows you to optimize your program’s paging behavior through swap tuning by grouping a function with the functions it calls. You can also group frequently called functions together. These techniques increase the probability that a called function is in memory when it is needed and will not have to be paged from disk.

The /ORDER option disables 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 file, that is either static or not found.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/OUT (Output File Name)

/OUT:filename

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

The Output File Name option controls the default base name for a .map file or import library. For details, see Generate Mapfile (/MAP) and /IMPLIB.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/PDB (Use Program Database)

/PDB:filename

By default, when the Generate Debug Info (/DEBUG) option is specified, the linker creates a program database (PDB), which holds debugging information. If Generate Debug Info (/DEBUG) is not specified, the Use Program Database (/PDB) option is ignored.

Command line | Project settings | Description
/PDB:filename | Use program database, Program database name | The linker creates a program database file with the given file name.

The default file name for the PDB has the base name of the program and the extension .pdb. To override the default name, type a file name in the Program database name text box, or specify /PDB:filename on the command line.

Debugging information in a PDB must be in Microsoft Format (/DEBUGTYPE:CV).

Incremental linking is suppressed if the Use program database check box is not selected in the IDE.

A PDB file can be up to 2GB.

If you create the PDB file with the /Zi) compiler option, it will create a PDB with a 4K page size. The linker's /PDB option creates a PDB file with a 1K page file size.

For more information, see .pdb Files as Linker Input.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/PDBSTRIPPED (Strip Private Symbols)

/PDBSTRIPPED:pdb_file_name

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

pdb_file_name is the name you specify for the stripped PDB file. The file extension is .pdb.

The full PDB file will still be generated when you use /PDBSTRIPPED.

If you do not create a PDB file, /PDBSTRIPPED is ignored.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/RELEASE (Set the Checksum)

/RELEASE

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/SECTION (Specify Section Attributes)

/SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#]

This 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 roughly equivalent to a segment or the resources in a new executable (NE) file. Sections contain either code or data. Unlike segments, sections are blocks of contiguous memory with no size constraints. 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 librarian and contain information vital to the operating system. For more information on NE files, see Knowledge Base article "Executable-File Header Format" (Q65122). You can find Knowledge Base articles on the MSDN Library CD, or at http://support.microsoft.com/support/.

Specify a colon (:) and a section name. The name is case sensitive.

Do not use the following names, as they will 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, and executable status remains unchanged.

The meanings of the attribute characters are shown below.

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.
L | Preload | VxD only; marks the section as preload.
P | Pageable | Marks the section as not pageable.
X | Memory-resident | VxD only; marks the section as memory-resident.

K and P are peculiar in that the section flags that correspond to these are in the negative sense. So if you specify one of these on the .text section (/section:.text,K), there will be no difference in the section flags of a dumpbin /headers; it was already implicitly cached. To remove the default, specify /section:.text,!K and a dumpbin will reveal 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=# lets you specify an alignment value for a particular section. See /ALIGN for more information.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/STACK (Stack Allocations)

/STACK:reserve[,commit]

This option sets the size of the stack in bytes. This option is only for use when building a .exe.

This option specifies the total stack allocation in virtual memory. The default stack size is 1 MB. The linker rounds up the specified value to the nearest 4 bytes.

The optional value specified in the Commit text box (or in the commit argument on the command line) is subject to interpretation by the operating system. In Windows NT, 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.

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 after the .exe file is built by using the EDITBIN tool.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/STUB (MS-DOS Stub File Name)

/STUB:filename

This 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 to be sure that it is a valid MS-DOS executable file, and issues an error message if the file is not valid. 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 filename that contains an IMAGE_DOS_HEADER structure (defined in WINNT.H) to be used in the VXD, rather than the default header.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/SUBSYSTEM (Specify Subsystem)

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

/SUBSYSTEM:{CONSOLE|WINDOWS|NATIVE|POSIX|WINDOWSCE}[,major[.minor]]

where,

CONSOLE
Win32 character-mode application. Console applications are given a console by the operating system. If main or wmain is defined, CONSOLE is the default.
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, WINDOWS is the default.
NATIVE
Device drivers for Windows NT.
POSIX
Application that runs with the POSIX subsystem in Windows NT.
WINDOWSCE
Application that runs on a Windows CE device.
major and minor (optional)
Specify the minimum required version of the subsystem:
  • The arguments are decimal numbers in the range 0 through 65,535.
  • The default is version 4.00 for CONSOLE, WINDOWS, and NATIVE; and version 19.90 for POSIX.
  • For /subsystem:windows and /subsystem:console, the version number must be 3.10 or higher.
  • For /subsystem:windowsce, the version must at least be 1.0.

    There are no upper bounds for version numbers.

The choice of subsystem affects the default starting address for the program. For more information, see the Entry-Point Symbol (/ENTRY:function) option.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/SWAPRUN (Load Linker Output to Swap File)

/SWAPRUN:{NET|CD}

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

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/TLBID (Specify Resource ID for TypeLib)

/TLBID:id

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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/TLBOUT (Name .TLB File)

/TLBOUT:[path\]filename

where:

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.
path
An absolute or relative path specification for where the .tlb file should be created.

Remarks

/TLBOUT specifies the name and extention of the .tlb file.

The MIDL compiler is called by the Visual C++ 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | /IGNOREIDL | /MIDL | Building an Attributed Program


/TSAWARE (Create Terminal Server Aware Application)

/TSAWARE[:NO]

The /TSAWARE linker 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:yes 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:yes, otherwise you need to use /TSAWARE:NO option.

The /TSAWARE linker option is enabled by default for Windows 2000 and later, for Windows and console applications. See /SUBSYSTEM and /VERSION for information.

/TSAWARE is not valid for drivers, VxDs, or DLLs.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program | Storing User-Specific Information | Legacy Applications in a Terminal Services Environment


/VERBOSE (Print Progress Messages)

/VERBOSE[:LIB]

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.

Command line | Description
/VERBOSE | Displays details about the linking process.
/VERBOSE:LIB | Displays progress messages indicating 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.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/VERSION (Version Information)

/VERVERSION:major[.minor]

This option tells the linker to put a version number in the header of the .exe file or DLL.

The major and minor arguments are decimal numbers in the range 0 through 65,535. The default is version 0.0.

Another way to insert a version number is with the VERSION module-definition statement.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/VXD (Create Virtual Device Driver)

/VXD

This option creates a virtual device driver (VxD). When this option is specified, the default file name extension changes to .vxd. For details on VxDs, see the Microsoft Windows NT Device Driver Kit.

A .vxd file is not in Common Object File Format, and it cannot be used with DUMPBIN or EDITBIN. It does not contain debugging information. However, you can create a map file when you link a .vxd file.

A .vxd file cannot be incrementally linked.

For related information, see /EXETYPE.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


/WS (Aggressively Trim Process Memory)

/WS:AGGRESSIVE

Use this linker option to add the WS_AGGRESSIVE attribute to your application's image. The Windows NT 4.0 loader will recognize this attribute and aggressively trim the working set of the process when it is not active. Using this option is similar to adding the following call throughout your application.

SetProcessWorkingSetSize(hThisProcess, -1, -1)

/WS:AGGRESSIVE can be used for applications that must have a low impact on the system's memory pool.

If the speed of your application is important, do not use /WS:AGGRESSIVE without testing the resulting performance implications. Ideal candidates are processes that tend to operate in the background, such as services and screen savers.

See Also

Setting Linker Options | Linker Options | FAQ: Building Your Program


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Warnings and Errors

© 2000 Microsoft Corporation. All rights reserved.


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

This error usually means that you have error files (.err) from a different version of the compiler. Try reinstalling the product.


Fatal Error C1001

INTERNAL COMPILER ERROR
(compiler file file, line number)

Possible causes

  • The first compiler failed while attempting to recover its state following the detection of a syntax error. Fixing the syntax errors in your code should solve the problem.
  • The code generator cannot generate correct code for a construct, probably due the combination of an expression and an optimization option. Try removing one or more optimization options and recompiling the function containing the line indicated in the error message.

If the compiler emits no error messages prior to this internal compiler error, determine which compiler pass emitted the internal error by recompiling the application with /Bd. The /Bd option causes each compiler pass to print its name and arguments. Look for the last pass invoked before C1001 occurs.

If the last pass is P1, then the likely cause is recovery from a syntax error, which the compiler cannot print before the internal error occurs. Examine the line where the internal error occurs and the previous line. Those lines may contain a syntax error. Fixing any errors you find. If you cannot find an error, contact Microsoft Technical Support.

If the last pass is P2, you can probably fix the problem by removing one or more optimization options (or using a different code generator). 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, /Oi, and /Oa. Once you determine which option is responsible, you can disable it using the optimize pragma for the function where the error occurs and continue to use the option for the rest of the module.

A C1001 error in the P2 pass occurs rarely at low optimization levels or when optimization is disabled. If this happens, try rewriting the line where the error is reported, or several lines of code surrounding that line. If that doesn’t work, contact Microsoft Technical Support.


Fatal Error C1002

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.

Possible solutions

  • Divide the source file into several smaller files.
  • Break expressions into smaller subexpressions.
  • Remove other programs or drivers that consume memory.


Fatal Error C1003

error count exceeds number; stopping compilation

Errors in the program are too numerous to allow recovery. The compiler must terminate.


Fatal Error C1004

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

Other possible causes

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

#if TEST
// uncomment the next line
// #endif

void main() {
}
// C1004


Fatal Error C1005

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 C1006

write error on compiler-generated file

The compiler was unable to create intermediate files.

Possible causes

  • Disk-media error.
  • Open floppy-drive door.


Fatal Error C1007

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

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

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

unexpected end of file while looking for precompiled header directive

A precompiled header did not contain a precompiled header directive.

Possible causes

  • Incorrect file specified as a header file.
  • An include file specified with /Yu (Use Precompiled Header) is not listed in the source file.
  • The source file is compiled with /Yufilename but doesn’t contain a #include "filename" directive with the same filename.

The following sample generates C1010:

// compile with /Yufilename to resolve
//
void main(void) {
}
// C1010


Fatal Error C1011

compiler limit : 'identifier' : macro definition too big, exceeds: number bytes

The macro definition was too long. Try to split the definition.


Fatal Error C1012

unmatched parenthesis : missing character

The parentheses in a preprocessor directive do not match.


Fatal Error C1013

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

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

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

#ifdef   // C1016
// try ...
// #ifdef X
#define FC1016
#endif

void main() {
}


Fatal Error C1017

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 code produces error C1017:

#define CONSTANT_NAME "YES"
#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.

#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

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:

// uncomment the line below to resolve the error
// #if 1
#elif   // C1018
#endif

void main() {
}


Fatal Error C1019

unexpected #else

The #else directive appears outside an #if, #ifdef, or #ifndef construct. Use #if only within one of these constructs. The following sample generates C1019:

// uncomment the line below to resolve the error
// #if 1
#else      // C1019
#endif

void main() {
}


Fatal Error C1020

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:

// uncomment the below line to resolve the error
// #if 1
#endif   // C1020

void main() {
}


Fatal Error C1021

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:

#BadPreProcName   // C1021, delete line
void main() {
}


Fatal Error C1022

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:

#define   true 1

#if (true)

#else

#else   // C1022
// replace the else with endif
// #endif

void main() {
}


Fatal Error C1026

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.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Fatal Error C1033

cannot open program database pdb

Possible cause

Disk error.


Fatal Error C1034

file: no include path set

The INCLUDE environment variable is not set.

To set the INCLUDE variable in Visual C++

  1. From the Tools Menu, click Options.
  2. In the Options dialog box, select the Directories tab.
  3. In the Show Directories For box, select Include Files.
  4. In the Directories box, enter the path for include files.

To set the INCLUDE variable from the command line

  • Run the VCVARS32.bat batch file.


Fatal Error C1035

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 C1036

cannot overwrite earlier program database format, delete filename and recompile

Possible cause

  • Upgrading from a very old version of Visual C++ (such as version 1.1).


Fatal Error C1037

cannot open object file filename

The object file specified by /Fo cannot be opened.

Possible causes

  • Invalid filename.
  • Insufficient memory to open the file.
  • Another process is using the file.
  • A read-only file has the same name.


Fatal Error C1038

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 C1039

decl/defn not complete, cannot create precompiled header at this point

The last declaration or definition in the file is incomplete; a precompiled header file cannot be created.


Fatal Error C1040

ILStore error for program database file: filename

Error writing to the .pdb file, possibly due to lack of disk space or a disk error.


Fatal Error C1044

out of disk space for compiler intermediate file

The compiler could not create intermediate files for use in the compilation process because no space was available.

Make more space available on the disk pointed to by the TMP environment variable and then recompile.


Fatal Error C1045

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

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

limit of option exceeded at 'argument'

The option is specified too many times. The message gives the option argument that caused the error. Check the CL environment variable for uses of the option.


Fatal Error C1048

unknown option 'character' in 'option'

The character is not valid for the option.

Consider the following line:

#pragma optimize( "*", on )

The * causes the following error:

unknown option '*' in '#pragma optimize'


Fatal Error C1049

invalid numerical argument 'string'

The compiler found a string in place of a numerical argument.

Possible causes

  • A hexadecimal number lacking the \x prefix.
  • A malformed floating-point number.


Fatal Error C1051

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.


Fatal Error C1052

compiler limit : #if or #ifdef blocks nested too deeply

The program exceeds the nesting limit (32 levels) for #if and #ifdef directives.

Possible cause

  • Preprocessor directives in include files.


Fatal Error C1053

'<identifier>' : function too large

The function is too large to compile.

Possible solutions

  • Try compiling without optimizations.
  • Divide the function into smaller functions.
  • Reduce calls to inline functions.


Fatal Error C1054

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

Possible solutions

  • Simplify the data types being initialized to reduce nesting.
  • Initialize variables in separate statements after the declaration.


Fatal Error C1055

compiler limit : out of keys

The source file contains too many symbols. The compiler ran out of hash keys for the symbol table.

Possible solutions

  • Split the source file into smaller files.
  • Eliminate unnecessary header files.
  • Reuse temporary and global variables instead of creating new ones.


Fatal Error C1056

compiler limit : out of macro expansion space: number bytes, when expanding token: 'token'

An internal buffer overflowed during macro expansion.

Possible solutions

  • Split macros into simpler macros.
  • Remove unnecessary space and tab characters from macro definitions.


Fatal Error C1057

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 C1058

compiler limit : too many formal arguments

A function declaration has too many formal arguments. Reduce the number of arguments by passing structures or pointers to structures.


Fatal Error C1059

compiler is out of near heap space

The compiler ran out of space in its near default data-segment (near) heap.

Possible solutions

  • Eliminate unnecessary include files.
  • Split the current function into smaller functions.
  • Split the current file into smaller files.


Fatal Error C1060

compiler is out of heap space

The operating system or run-time library cannot fill a request for memory.

Possible solutions

  • Use /Zm to increase memory allocation limit.
  • Increase the size of the Windows swap-file.
  • Close other running programs.
  • Eliminate unnecessary include files.
  • Eliminate unnecessary global variables, for example, by allocating memory dynamically instead of declaring a large array.
  • Eliminate unused declarations.
  • Split the current file into smaller files.


Fatal Error C1061

compiler limit : blocks nested too deeply

Nesting of code blocks exceeds the limit of 128 nesting levels. Simplify nesting.


Fatal Error C1062

error while writing to preprocessor output file

The compilation command includes the /P option, but the disk does not have enough space to hold the preprocessor output file.

Possible solutions

  • Free up disk space.
  • Choose another disk.
  • Remove the /P option.


Fatal Error C1063

compiler limit : compiler stack overflow

The program was too complex, possibly due to recursive include files. Split the code into smaller source files and recompile.


Fatal Error C1064

compiler limit : token overflowed internal buffer

An identifier exceeds the length of the internal buffer used for identifiers. Shorten the name.


Fatal Error C1065

compiler limit : out of tags

The source file contains too many symbols. Split the file into smaller files.


Fatal Error C1067

compiler limit : debug information module size exceeded

This error could occur if a symbol has a decorated name exceeding 247 characters. Shorten the symbol name.

It could also mean that you have many symbols with long names or that a class, struct, or union has too many members.


Fatal Error C1068

cannot open file 'filename'

The file does not exist, cannot be opened, or cannot be found. Check that the environment settings are valid and specify the correct path.

If error number C1086 appears without an error message, the compiler has run out of file handles.


Fatal Error C1069

write error on file 'filename'

An error occurred writing to the file. Check available disk space.


Fatal Error C1070

mismatched #if/#endif pair in file 'filename'

An #if, #ifdef, or #ifndef directive has no corresponding #endif. The following sample generates C1070:

#define TEST

#ifdef TEST
// use the line below to resolve the error
// #endif

#ifdef TEST

#endif

void main() {
}


Fatal Error C1071

unexpected end of file found in comment

The compiler reached the end of the file while scanning a comment.

Possible causes

  • Missing comment terminator (*/).
  • Missing newline character after a comment on the last line of a source file.

The following sample generates C1071:

void main() {
}

/* this comment is fine */
/* forgot the closing tag         // C1071


Fatal Error C1072

'filename' : cannot read file

An error occurred reading a file.

Possible causes

  • Disk error.
  • File-sharing conflict.


Fatal Error C1073

Internal error involving incremental compilation (compiler file 'filename', line number)

Recompile the file without using incremental compilation.


Fatal Error C1074

'IDB' is illegal extension for PDB file: filename

The compiler expects program databases to have the .pdb extension.


Fatal Error C1075

end of file found before the left token at 'filename(linenumber)' was matched

The compiler expected matching token before it reached the end of file.

Possible cause

  • Unmatched bracket, curly brace, or other paired character.


Fatal Error C1076

compiler limit : internal heap limit reached; use /Zm to specify a higher limit

Probable cause

  • Too many symbols.

Possible solutions

  • Use the /Zm option to set the compiler memory limit.
  • Eliminate unnecessary include files.
  • Eliminate unnecessary global variables, for example, by allocating memory dynamically instead of declaring a large array.
  • Eliminate unused declarations.
  • Split large functions into smaller functions.
  • Split large classes into smaller classes.
  • Split the current file into smaller files.

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

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


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Fatal Error C1079

compiler limit : PCH file size limit exceeded

The PCH file exceeds the 4 GB size limit.


Fatal Error C1080

compiler limit : command line option exceeded limit of number characters

An argument passed to the compiler exceeds 256 characters.


Fatal Error C1081

'symbol': file name exceeds number bytes in length

The length of a file pathname exceeds _MAX_PATH (defined by STDLIB.h as 260 characters).

Possible cause

  • 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

Cannot close filetype file: 'file': message

Possible cause

  • If the message says "bad file number", the file may have been closing in the foreground while compiling in the background.


Fatal Error C1083

Cannot open filetype file: 'file': message

Possible causes

  • File does not exist.
  • File, subdirectory, or disk is read-only.
  • No access permission for file or directory.
  • Not enough file handles. Close some applications and recompile.
  • The INCLUDE environment variable is set incorrectly.
  • An #include directive uses double quotation marks around a path specification, which causes the standard directories to be skipped.
  • You did not specify /com+ and your program uses managed constructs.

The following sample generates C1083:

#include "test.h"   // C1083, test.h does not exist

void main() {
}


Fatal Error C1084

Cannot read filetype file: 'file': message

Possible cause

  • If the message says "bad file number", the file may have been closing in the foreground while compiling in the background.


Fatal Error C1085

Cannot write filetype file: 'file': message

Possible cause

  • Drive is read-only.
  • Drive is full.
  • Sharing violation.
  • If the message says "bad file number", the file may have been closing in the foreground while compiling in the background.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Fatal Error C1086

Cannot seek filetype file: 'file': message

The compiler cannot complete an I/O operation.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Fatal Error C1087

Cannot tell filetype file: 'file': message

The compiler cannot complete an I/O operation.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Fatal Error C1088

Cannot flush filetype file: 'file': message

The compiler cannot complete an I/O operation.


Fatal Error C1089

Cannot truncate filetype file: ‘file’: message

The compiler cannot shrink a file to zero length.


Fatal Error C1090

data allocation exceeds 64K

The specified segment has grown beyond the maximum for data segments. Reduce the size of the segment.

Inline functions in your source may increase code size.


Fatal Error C1091

compiler limit: string exceeds 'length' bytes in length

A string constant exceeded the current limit on the length of strings.

You may want to split the static string into two (or more) variables and use strcpy to join the result as part of the declaration or during run time.


Fatal Error C1092

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 vc60.pdb, 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 Limitations of Edit and Continue.


Fatal Error C1093

API call 'function name' failed 'location of call' : 'text from run-time'

A call to a NGWS function failed. text from run-time may or may not be supplied by the COM runtime.


Fatal Error C1094

too many 'flag' flags, 'string'

You used flag too often. The last use had the parameter string.


Fatal Error C1098

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

Edit and Continue engine terminating compile

Edit and Continue loaded a precompiled header file in preparation for compiling code changes, but sequent 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

unable to initialize OLE : system error message

The compiler cannot initialize the Component Object Model (COM) library. See CoInitialize.


Fatal Error C1108

unable to find DLL: 'dll'

Either Mspdb60.dll or Mspdb70.dll was not in the path causing a call to LoadLibrary to fail. To resolve C1108, reinstall Visual C++ or copy the appropriate .dll file from the installation CD to somewhere in the path.


Fatal Error C1126

'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 swapable functions) exceeds the limit.

Possible solution

  • Use malloc or new to allocate large amounts of data.


Fatal Error C1128

object file format limit exceeded : more than 32K sections

While compiling with /Gy, the compiler encountered more than 32,727 functions in one source file. Split the source file into multiple source files and recompile.

/Gy is added to your compilation if you used /ZI.


Fatal Error C1189

#error : user supplied error message

Generated by an #error directive in the program. For example:

#undef _WIN32

#if !defined(_WIN32)
#error _WIN32 must be defined //error
#endif

int main() {
   return 0;
}


Fatal Error C1190

NGWS runtime targeted code requires '#using <mscorlib.dll>' and /com+

You are using Managed Extensions for C++ constructs and the /com+ compiler option, but you did not explicitly include Mscorlib.dll.

The following sample generates C1190:

// uncomment the following line to resolve error
// #using <mscorlib.dll>
__gc class A {
};

void main() {
}


Fatal Error C1191

'mscorlib.dll' can only be imported at global scope

The instruction to import mscorlib.dll into a program that uses Managed Extensions for C++ cannot appear in a namespace or function, but must appear at global scope.

The following sample generates C1191:

// uncomment the following line to resolve
// #using <mscorlib.dll>
namespace sample {
#using <mscorlib.dll>   // C1191, not at global scope
}
void main() {
}


Fatal Error C1192

#using failed on 'file'

Only a file in the Microsoft Intermediate Language (MSIL) format can be passed to a #using directive. The /com+ compiler option lets you create an MSIL output file. Other Visual Studio languages also produce MSIL files.

The following sample generates C1192:

#using <mscorlib.dll>
#using "stdio.h"   // C1192
// The following line resolves the error.
// #include <stdio.h>

void main() {
}


Fatal Error C1200

unexpected internal error handling template inline functions

Note the circumstances of the error, try to isolate the problem and create a reproducible test case, then consult Microsoft Technical Support.


Fatal Error C1201

unable to continue after syntax error in template class definition

An unexpected error occurred while parsing a template class 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 consult Microsoft Technical Support.


Fatal Error C1202

recursive type or function dependency context too complex

A template definition was recursive or exceeded complexity limits. For example:

template<int n> class Factorial : public Factorial<n-1>
{
public:
    operator int ()
    {
        return Factorial <n-1>::operator int () * n;
    }
};

Factorial<7> facSeven; // error on this line


Fatal Error C1203

'keyword' : disabled in this compiler

The Windows NT SDK compiler does not support this feature.


Fatal Error C1350

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

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 the DLL from your product CD.


Fatal Error C1502

inline member-function definition missing '}'

The compiler reached the end of file and did not find a matching brace. Make sure that curly braces match.


Fatal Error C1503

default parameter definition missing ',' or ')'

After a default parameter definition, you must use a comma to continue the parameter list, or a right parenthesis to end the list. Check for missing commas and parentheses.


Fatal Error C1504

type still ambiguous after parsing number tokens, unable to recover

The compiler cannot resolve the type, even after looking ahead.

Possible solutions

  • Simplify the code to make the statement clearer.
  • Use an explicit type cast.


Fatal Error C1505

unrecoverable parser look-ahead error

The compiler cannot evaluate the code. Simplify the code by splitting classes or functions.


Fatal Error C1506

unrecoverable block scoping error

The block was too large to compile.

Possible causes

  • Mismatched curly braces.
  • Unusually large function or class.


Fatal Error C1507

previous user errors and subsequent error recovery halt further compilation

There are too many errors to continue. Fix some of the errors and compile again.


Fatal Error C1508

compiler limit : 'function' : more than 65535 argument bytes

The formal parameters to the function exceed the limit of 65535 bytes.


Fatal Error C1509

compiler limit : too many exception handler states in function 'function'. simplify function

The code exceeds an internal limit on exception handler states (1,920 states).

Most common cause

  • The function contains a complex expression of user-defined class variables and arithmetic operators.

Possible solutions

  • Simplify expressions by assigning common subexpressions to temporary variables.
  • Split the function into smaller functions.


Fatal Error C1603

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 C1700

compiler compiler is out of far heap space

The compiler ran out of storage in its far heap, probably because of too many symbols.

Possible solutions

  • Eliminate some global variables.
  • Split the current file into smaller files.
  • Remove other programs or drivers running on the system.
  • Check CONFIG.sys and AUTOEXEC.bat files for device drivers that are not needed.


Fatal Error C1852

'filename' is not a valid precompiled header file

The file is not a precompiled header.

Possible causes

  • Invalid file specified with /Yu or #pragma hdrstop.
  • The compiler assumes a file extension of .pch if you do not specify otherwise.


Fatal Error C1853

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

  • The precompiled header was compiled with a previous compiler version. Recompile the header with the current compiler.
  • The precompiled header is C++ and you are using it from C.


Fatal Error C1854

cannot overwrite information formed during creation of the precompiled header in object file: 'filename'

You specified the /Yu (use precompiled header) option after specifying the /Yc (create precompiled header) option for the same file. Certain declarations (such as declarations including __declspec dllexport) make this illegal.


Fatal Error C1900

Il mismatch between 'tool1' version 'number1' and 'tool2' version 'number2'

The two tools do not match. Install and use the current version of each tool.


Fatal Error C1902

program database manager mismatch; please check your installation

A program database file (.pdb) was created using a newer version of DBI.dll than the one found while compiling. Install the latest version of DBI.dll on your system.


Fatal Error C1903

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

bad provider interaction: 'file'

Reinstall Visual C++. If that does not correct the problem, consult Microsoft Technical Support.


Fatal Error C1999

UNKNOWN FATAL ERROR
Choose the Technical Support command on the Visual C++
Help menu, 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 consult Microsoft Technical Support.


Compiler Error C2001

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. For example:

printf("Hello,             // error
    world");
printf("Hello,\n          //  error
    world");
printf("Hello,\           //  OK
 world");
printf("Hello,"            // OK
    " world");

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:

printf("Hello,\n\
world");
printf("Hello,\
\nworld");
printf("Hello,\n"
    "world");
printf("Hello,"
 "\nworld");


Compiler Error C2002

invalid wide-character constant

The multibyte-character constant was not legal.

Possible causes

  • The wide-character constant contains more bytes than expected.
  • The standard header STDDEF.h is not included.
  • Wide characters are supported in C.
  • Wide characters cannot be concatenated with ordinary string literals.
  • A wide-character constant must be preceded by the character 'L':
    L'mbconst'


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2003

expected 'defined id'

An identifier must follow the preprocessor keyword.


Compiler Error C2004

expected 'defined(id)'

An identifier must appear in the parentheses following the preprocessor keyword.


Compiler Error C2005

#line expected a line number, found 'token'

The #line directive must be followed by a line number. The following sample generates C2005:

void main() {
   int i = 0;
   #line i   // C2005

   // try ...
   // #line 0
}


Compiler Error C2006

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

#include stdio.h   // C2006
// requires quotes or angle brackets
// #include <stdio.h>

void main() {
}


Compiler Error C2007

#define syntax

No identifier appears after a #define. To resolve the error, use an identifier. The following sample generates C2007:

#define            // C2007
#define true 1      // ok

void main() {
}


Compiler Error C2008

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

#define TEST1"mytest1"   // C2008
#define TEST2 "mytest2"   // ok

void main() {
}


Compiler Error C2009

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. The following sample generates C2009:

#define macro1(a,a) (a*a)   // C2009
// try ..
// #define macro2(a)   (a*a)
// #define macro3(a,b) (a*a)

void main() {
}


Compiler Error C2010

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

#define mymacro(a|) (2*a)   // C2010, remove the |

void main() {
}


Compiler Error C2011

'identifier' : 'type' type redefinition

The identifier was already defined as type. You may also get C2011 if you import a type library more than once into the same file.

For example:

struct S;
union S;    // Error C2011


Compiler Error C2012

missing name following '<'

An #include directive lacks the required filename. The following sample generates C2012:

#include <            // C2012, include the filename to resolve
#include <stdio.h>   // ok

void main() {
}


Compiler Error C2013

missing '>'

An #include directive lacks a closing angle bracket. Add the closing bracket to resolve the error. The following sample generates C2013:

#include <stdio.h      // C2013
#include <stdio.h>   // ok

void main() {
}


Compiler Error C2014

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:

int k; #include <stdio.h>   // C2014
/* try ...
int k;
#include <stdio.h>
*/

void main() {
}


Compiler Error C2015

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. The following sample generates C2015:

char test1='error';   // C2015
// try ..
// char test2='e';      // ok

void main() {
}


Compiler Error C2016

no closing single quotation mark

A character constant did not end with a single quote before a newline character.


Compiler Error C2017

illegal escape sequence

An escape sequence, such as \t, appears outside of a character or string constant. The following sample generates C2017:

char test1='a'\n;   // C2017
// try ...
// char test2='a\n';   // ok

void main() {
}


Compiler Error C2018

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. The following sample generates C2018:

void main(){
   int i™ = 1;   // C2018, remove the extended ascii character
}


Compiler Error C2019

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:

#!define TRUE 1   // C2019, remove the ! to resolve the error

void main() {
}


Compiler Error C2020

'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

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. The following sample generates C2021:

float test1=1.175494351E;   // C2021
// try ...
// float test2=1.175494351E8;

void main() {
}


Compiler Error C2022

'number' : too big for character

The octal number following a backslash (\) in a character or string constant is too big to represent a character.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2023

divide by 0

The expression results in division by zero.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2024

mod by 0

The expression results in a modulo-zero operation.


Compiler Error C2025

'identifier' : enum/struct/union type redefinition

The identifier has already been used for an enumeration, structure, or union tag.


Compiler Error C2026

string too big, trailing characters truncated

The string was longer than the limit of 2048 characters.

Prior to adjacent strings being concatenated, a string cannot be longer than 2048 characters.

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

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. The following sample generates C2027:

class D;

/* resolve the error by defining the class
class D {
public:
   void func() {
   }
};
*/

void main() {
   D *pD;
   pD->func();   // C2027
}


Compiler Error C2028

struct/union member must be inside a struct/union

Structure or union members must be declared within the structure or union.


Compiler Error C2030

'identifier' : struct/union member redefinition

A structure or union uses the same identifier for more than one member.


Compiler Error C2032

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

struct z {
   int i;
   void func();   // C2032, delete this declaration
};

void main() {
}


Compiler Error C2033

'identifier' : bit field cannot have indirection

The bit field was declared as a pointer, which is not allowed. For example:

struct S
{
   int *b : 1;  // error
};


Compiler Error C2034

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

struct A {
   char test : 9;   // C2034, char has 8 bits
   // try ...
   // char test : 8;
};

void main() {
}


Compiler Error C2036

'identifier' : unknown size

An operation on identifier requires the size of the data object, which cannot be determined. For example:

struct A* pA;
struct B { int i; };
B* pB;
void main()
{
   pA++;   // error, size of A not known
   pB++;   // OK, B has been declared
}


Compiler Error C2039

'identifier1' : is not a member of 'identifier2'

The code incorrectly uses a nonmember of a structure or union. For example:

struct S
{
   int mem0;
} *pS;
void main()
{
   pS->mem1 = 0;       // error, mem1 is not a member
   pS->mem0 = 0;       // OK
}


Compiler Error C2040

'operator' : 'identifier1' differs in levels of indirection from 'identifier2'

An expression involving the operators has inconsistent levels of indirection.

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 operator is converted to the nonarithmetic type.


Compiler Error C2041

illegal digit 'character' for base 'number'

The specified character is not a legal digit for the base (such as octal or hex). The following sample generates C2041:

int i = 081; // error, 8 is not a legal digit
int i = 071; // OK


Compiler Error C2042

signed/unsigned keywords mutually exclusive

The keywords signed and unsigned are used in a single declaration. The following sample generates C2042:

unsigned signed int i;      // error


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2043

illegal break

A break is legal only within a do, for, while, or switch statement.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2044

illegal continue

A continue is legal only within a do, for, or while statement.


Compiler Error C2045

'identifier' : label redefined

The label appears before multiple statements in the same function. The following sample generates C2045:

void main() {
// to resolve, delete one of the label: blocks
   label: {
   }
   goto label;
   label: {
   }
}


Compiler Error C2046

illegal case

The keyword case can appear only in a switch statement. The following sample generates C2046:

void main() {
   int i = 0;

   case 0:      // C2046, delete case to resolve error

   switch(i) {
      case 0:   // ok
      break;

      case 1:    // ok
      break;

      default:   // ok
      break;
   }
}


Compiler Error C2047

illegal default

The keyword default can appear only in a switch statement. The following sample generates C2047:

void main() {
   int i = 0;

   default:      // C2047, delete default to resolve error

   switch(i) {
      case 0:
      break;

      case 1:
      break;

      default:   // ok
      break;
   }
}


Compiler Error C2048

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:

void main() {
   int a = 1;
   switch (a)
    {
      case 1:
         a = 0;
      default:
         a = 2;
      default:   // C2048, delete one default label
         a = 3;
   }
}


Compiler Error C2049

case value 'value' already used

The case value was used more than once in this switch statement.

Possible cause

  • Enumerations or macros that evaluate to the same value.


Compiler Error C2050

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:

void main() {

   int a = 1;

   switch ("a") {   // C2050
   // try ..
   // switch (a) {
      case 1:
         a = 0;
      default:
         a = 2;
   }
}


Compiler Error C2051

case expression not constant

Case expressions must be integer constants. The following sample generates C2051:

class X {
   public:
   operator const int() {
      return 1;
   }
};

void fail() {
}

void main() {
   static X x;
   int i = 0;

   switch (i) {
      case x:      // C2051, use constant expression to resolve error
      // try ...
      // case 1:
         break;
      default:
         fail();
         break;
   }
}


Compiler Error C2052

case expression not integral

Case expressions must be integer constants. The following sample generates C2052:

void main() {
   int a = 1;
   switch (a) {
      case 1.01:   // C2052
      // try ...
      // case 1:
         a = 0;
      default:
         a = 2;
   }
}


Compiler Error C2053

'identifier' : wide string mismatch

The wide string is assigned to an incompatible type. The following sample generates C2053:

char array[] = L"Rika";    // error


Compiler Error C2054

expected '(' to follow 'identifier'

The function identifier is used in a context that requires trailing parentheses.

Possible cause

  • Omitting an equal sign (=) on a complex initialization.

The following sample generates C2054:

int array1[] { 1, 2, 3 };   // error, missing =
int array2[] = { 1, 2, 3 }; // OK


Compiler Error C2055

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:

void func(int, char) {   // C2055
// use the line below to resolve the error
// void func (int i, char c) {
}

void main() {
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2056

illegal expression

An expression was illegal because of a previous error.


Compiler Error C2057

expected constant expression

The context requires a constant expression. The following sample generates C2057:

int i;
// use the line below to resolve the error
// const int i = 8;

int b[i];   // C2057

void main() {
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2058

constant expression is not integral

The context requires an integer constant expression.


Compiler Error C2059

syntax error : 'token'

The token caused a syntax error.

To determine the cause, examine not only the line listed in the error message, but also the lines above it. The following example generates an error message for the line containing the open curly brace, but the true source of the error appears on the line just above it.

void main )             // No opening parenthesis.
{
}

If examining the lines yields no clue to what the problem might be, try commenting out the line listed in the error message and possibly several lines above it.

If the error message occurs on a symbol immediately following a typedef variable, check that the variable is defined in the source code.

One specific reason you can get C2059 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, such as that used to initialize a structure, is not an expression. The following example generates C2059:

// compile with /c
struct ag_type {
   int a;
   float b;
};
void func(ag_type arg = {5, 7.0});

The resolution is to define a constructor to perform the required initialization.

// compile with /c
struct ag_type {
   int a;
   float b;
   ag_type(int aa, float bb) : a(aa), b(bb) {}
};
void func(ag_type arg = ag_type(5, 7.0));

You can also get C2059 if you define a member template class or

function outside the class. See Knowledge Base article Q241949 for more information.


Compiler Error C2060

syntax error : end of file found

At least one more token was expected.

Possible causes

  • Missing semicolons:
    int *p    // error
  • Missing closing brace on the last function:
    main()
{         // error


Compiler Error C2061

syntax error : identifier 'identifier'

The compiler found identifier where it wasn’t expected. An initializer may be enclosed by parentheses. To avoid this problem, enclose the declarator in parentheses or make it a typedef.


Compiler Error C2062

type 'type' unexpected

The compiler did not expect a type name. The following sample generates C2062:

class A {
   public:
      int i;   // ok
   protected:
      int j;   // ok
   private:
      int k;   // ok
   :
      int l;   // C2062
};

void main() {
}


Compiler Error C2063

'identifier' : not a function

The identifier is used as a function but not declared as a function. The following sample generates C2063:

int i, j;
j = i();    // error, i is not a function


Compiler Error C2064

term does not evaluate to a function

A call is made to a function through an expression. The expression does not evaluate to a function pointer. The following sample generates C2064:

int i, j;
char* p;
void func()
{
   j = i();    // error, i is not a function
   p();        // error, p doesn't point to a function
}


Compiler Error C2065

'identifier' : undeclared identifier

A variable’s type must be specified in a declaration before it can be used. The parameters that a function uses must be specified in a declaration, or prototype, before the function can be used.

Possible causes

  • You may be calling a function in an SDK header file that is currently not supported in your build environment; see Header File Requirements.
  • Omitting necessary include files, especially if you define VC_EXTRALEAN, WIN32_LEAN_AND_MEAN, or WIN32_EXTRA_LEAN. These symbols 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.)
  • Identifier name is misspelled.
  • Identifier uses the wrong uppercase and lowercase letters.
  • Missing closing quote after a string constant.
  • A newline character in a string constant without a continuation character:
    #include <stdio.h>
main() {
   printf("\n %s
      %s   // error: 's' : undeclared identifier
      %s",
      "this", "is", "it");
}

    Take special care when you split a constant string over several lines. One method is to change the format string. Strings separated only by whitespace (spaces, tabs, newlines) are concatenated:

    #include <stdio.h>
main() {
   printf("\n %s"
       " %s"
       " %s",
       "this", "is", "it");
 }

    A less-preferable method uses a backslash at the end of a line. The spaces at the beginning of each continued line become part of the string:

       printf("\n %s\
       %s\
       %s",
       "this", "is", "it");
  • Improper namespace scope. To resolve ANSI C++ Standard Library functions and operators, for example, you must specify the std namespace with the using directive. The following example fails to compile because the using directive is commented out and cout is defined in the std namespace:
    #include <iostream>
// using namespace std;
void main()
{
     cout << "Hello" << endl;
}


Compiler Error C2066

cast to function type is illegal

In ANSI C, it is not legal to cast between a function pointer and a data pointer.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2067

cast to array type is illegal

An object was cast to an array type.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2068

illegal cast from 'type1' to 'type2'

A type used was not legal for this cast.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2069

cast of 'void' term to non-'void'

Type void cannot be cast to any other type.


Compiler Error C2070

illegal sizeof operand

The sizeof operator requires an expression or type name. The following sample generates C2070:

void func() {
}
void main() {
   int a;
    a = sizeof(func);   // C2070
   // try ...
   // a = sizeof(a);
}


Compiler Error C2071

'identifier' : illegal storage class

identifier was declared with an illegal storage class. The following sample generates C2071:

struct C {
extern int i;   // C2071, remove extern to resolve error
};

void main() {
}


Compiler Error C2072

'identifier' : initialization of a function

A function initializer was illegally specified.


Compiler Error C2073

'identifier' : partially initialized array requires 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:

class A
{
public:
   A( int );              // constructor for ints only
};
A a[3] = { A(1), A(2) };  // error, no default constructor
class B
{
public:
   B();                   // default constructor declared
   B( int );
};
B b[3] = { B(1), B(2) };  // OK


Compiler Error C2074

'identifier' : 'class-key' initialization needs curly braces

There were no curly braces around the specified class, structure, or union initializer.


Compiler Error C2075

'identifier' : array initialization needs curly braces

There were no curly braces around the specified array initializer. The following sample generates C2075:

int i[] = 1, 2, 3 };     // error
int i[] = { 1, 2, 3 };   // OK


Compiler Error C2077

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

too many initializers

The number of initializers exceeds the number of objects to be initialized.

The following sample generates C2078:

#include <stdio.h>

void main() {

char a[]={"a", "b"};// c2078, try char *b[]={"a", "b"};

char c[2]={"a", "b"};// c2078, try char *d[2]={"c", "d"};

}


Compiler Error C2079

'identifier' uses undefined class/struct/union 'name'

The specified identifier is an undefined class, structure, or union.

Possible cause

  • Initializing an anonymous union.


Compiler Error C2081

'identifier' : name in formal parameter list illegal

The identifier caused a syntax error.

Possible cause

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

void func( int i, j )  // error, no type specified for j
{
}


Compiler Error C2082

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:

void func(int i) {
   int i;      // C2082, remove this line to resolve error
}

void main() {
}


Compiler Error C2083

struct/union comparison illegal

A structure or union is compared directly with another user-defined type. This is now allowed unless a comparison operator has been defined or a conversion to a scalar type exists. The following sample generates C2083:

struct A
{
   int i;
} a, b;
void func()
{
   if( a == b );   // error, structure comparison
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2084

function 'function' already has a body

The function has already been defined.


Compiler Error C2085

'identifier' : not in formal parameter list

The identifier was declared in a function definition but not in the formal parameter list. (ANSI C only)

Possible cause

  • Missing semicolon at the end of a function prototype:
    void func1( void )
void 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

'identifier' : redefinition

The identifier is defined more than once, or a subsequent declaration differs from a previous one. The following sample generates C2086:

int a;
char a;
main()
{
}
main()
{
  int a;
  int a;
}

// The following example is an error in C++, but not in ANSI C:

int a;
int a;
main()
{
}


Compiler Error C2087

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

int func(a)
    char a[10][];         // error
    { }
int func(a)
    char a[][5];          // OK
    { }


Compiler Error C2088

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

// compile /Tc
struct S {
   int m_i;
} s;

void function() {
    int i = s * 1;
    struct S s2 = +s;
    s++;
}


Compiler Error C2089

'identifier' : 'class-key' too large

The specified structure or union exceeds the 64K limit.


Compiler Error C2090

function returns array

A function cannot return an array. Return a pointer to an array instead. The following sample generates C2090:

int[] func1(void) {   // C2090
}
int* func2(int * i) {   // ok
   return i;
}

void main() {
}


Compiler Error C2091

function returns function

A function cannot return a function. Return a pointer to a function instead.


Compiler Error C2092

'array name' array element type cannot be function

Arrays of functions are not allowed. Use an array of pointers to functions. The following code example generates C2092.

typedef void (F) ();   // OK
typedef F AT[10];      // Error

void main()
{
}


Compiler Error C2093

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

void func() {
    int li;   // an implicit auto variable
    int * s[]= { &li };   // C2093, address is not a constant
}

void main() {
}


Compiler Error C2094

label 'identifier' was undefined

The label used by a goto statement does not exist in the function. The following sample generates C2094:

void main() {
   goto test;

   // uncomment the following to resolve
   /*
   test: {
   }
   */
}


Compiler Error C2095

'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

illegal initialization

Possible causes

  • Initialization of a variable using a nonconstant value.
  • Initialization of a short address with a long address.
  • Initialization of a local structure, union, or array with a nonconstant expression when compiling with /Za.
  • Initialization with an expression containing a comma operator.
  • Initialization with an expression that is neither constant nor symbolic.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2098

expression is not an address

An address was expected as the initialization expression.


Compiler Error C2099

initializer is not a constant

Example ( C )

int i, j;
int *p;
j = i();    // error, i() is not constant
j = *p;     // error, *p is not a constant


Compiler Error C2100

illegal indirection

Indirection operator ( * ) is applied to a nonpointer value. The following sample generates C2100:

void main() {
   int r = 0, *s = 0;
   *r = 200;   // C2100
   // try
   // *s = 200;
}


Compiler Error C2101

'&' on constant

The address-of operator ( & ) must have an l-value as operand. The following sample generates C2101:

void main() {
   char test;
   test = &'a';  // C2101, remove the & to resolve
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2102

'&' requires l-value

The address-of operator ( & ) must have an l-value as operand.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2103

'&' on register variable

You cannot take the address of a register.


Compiler Error C2104

'&' on bit field ignored

You cannot take the address of a bit field.

The following sample generates C2104:

struct X {
   int b : 1;
   int sb : 1;
};

void main() {
   X x;
   &x.sb;   // C2104, remove the & to resolve the error
}


Compiler Error C2105

'operator' needs l-value

The operator must have an l-value as operand. The following sample generates C2105:

main() {
   int a[10] = {0};
   int b[10] = {0};

   ++(a , b);   // C2105
   // try ..
   // ++(a[0] , b[0]); // ok
   // ++a[0];
}


Compiler Error C2106

'operator' : left operand must be l-value

The operator must have an l-value as its left operand. The following sample generates C2106:

void main() {
   int a;
   1 = a;   // C2106
   // try ..
   // a = 1;
}


Compiler Error C2107

illegal index, indirection not allowed

A subscript is applied to an expression that does not evaluate to a pointer.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2108

subscript is not of integral type

The array subscript is a noninteger expression.


Compiler Error C2109

subscript requires array or pointer type

The subscript was used on a variable that was not an array. The following sample generates C2109:

void main() {
   int a, b[10] = {0};
   a[1] = 0;   // C2109
   b[0] = 1;   // ok
}


Compiler Error C2110

'+' : cannot add two pointers

An attempt was made to add two pointer values using the plus ( + ) operator. The following sample generates C2110:

void main() {
   int a = 0;
   int *pa;
   int *pb;
   a = pa + pb;   // C2110
}


Compiler Error C2111

'+' : 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:

void main() {
   int *a = 0, *pa = 0, b = 0;
   double d = 0.00;

   a = pa + d;   // C2111

   // try ...
   // a = pa + b;
}


Compiler Error C2112

'-' : pointer subtraction requires integral or pointer operand

An attempt was made to subtract pointers that point to different types.


Compiler Error C2113

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

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


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2115

'identifier' : incompatible types

An expression contained incompatible types.


Compiler Error C2116

function parameter lists differed

The parameters in the default parameter list do not match the formal parameter list.


Compiler Error C2117

'identifier' : array bounds overflow

An array has too many initializers.

Possible causes

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

void main() {
   char abc[4] = "abcd";   // C2117
   // try ...
   // char abc[4] = "abd";
}


Compiler Error C2118

negative subscript or subscript is too large

The value defining the array size is larger than the maximum array size or smaller than zero. The following sample generates C2118:

void main() {
   int array1[-1];   // C2118
   int array2[3];      // ok
}


Compiler Error C2119

typedef types both define indirection

Two typedef types declare an item, and both typedef types have indirection.

The following sample generates C2119:

typedef int *p_int;
typedef short *p_short;
p_short p_int p;        // error


Compiler Error C2120

'void' illegal with all types

The void type is used in a declaration with another type. The following sample generates C2120:

void main() {
   void int i;
   // try ...
   // int i;
}


Compiler Error C2121

'#' : invalid character : possibly the result of a macro expansion

An illegal # character may have been inserted by an incorrect macro that uses the token-pasting operator (##) instead of the stringizing operator (#).


Compiler Error C2122

'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

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:

void main() {
  int i = 1 / 0;   // C2124, do not divide by zero to resolve the error
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2125

'identifier' : allocation exceeds 64K

The given item exceeds the 64K size limit.


Compiler Error C2126

'operator' : incorrect operand

The operator (usually ++ or --) was incorrectly applied to an enumeration.


Compiler Error C2127

parameter allocation exceeds 32K

The storage space for parameters to a function exceeds the 32K limit.


Compiler Error C2128

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

void func();

/* use this function declaration to resolve the error
extern "C" {
void func();
}
*/

#pragma alloc_text("my segment", func)   // C2128

void main() {
}

void func() {
}


Compiler Error C2129

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

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

void main() {
   #line 1000 test   // C2130
   // try ...
   // #line 1000 "test"
}


Compiler Error C2131

more than one memory attribute

More than one memory attribute ( __near, __far, __huge, or __based ) is applied to an item.

The following sample generates C2131:

typedef int __near nint;
nint __far a;              // error


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2132

syntax error : unexpected identifier

An identifier appears in an illegal context.


Compiler Error C2133

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

struct X
{
   int a[0]; // error, unsized array
};


Compiler Error C2134

'identifier' : struct/union too large

The size of a structure or union exceeds the 64K limit.


Compiler Error C2135

'bit operator' : illegal bit field operation

The address-of operator (&) cannot be applied to a bit field.

The following sample generates C2135:

struct S
{
   int i : 1;
   int j;
};
void main()
{
   &S::i;      // error, address of a bit field
   &S::j;      // OK
}


Compiler Error C2136

'function' : prototype must have parameter types

A function prototype has formal parameter names but no types for the parameters. Each formal parameter must have a type or an ellipsis (...) to indicate a variable number of parameters and turn off type checking.

Possible cause

  • Misspelled type name in a prototype that does not provide the formal parameter names.


Compiler Error C2137

empty character constant

The empty character constant ( ' ' ) is illegal. The following sample generates C2137:

void main() {
   char c = '';   // C2137
   // try ...
   // char d = ' ';   // ok
}


Compiler Error C2138

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

type following 'identifier' is illegal

Two types were used in the same declaration.

The following sample generates C2139:

int double a;    // error


Compiler Error C2140

parameter cannot be function type

A formal parameter of is declared as a function. Use a pointer to a function instead.


Compiler Error C2141

value out of range for enum constant

An enumeration constant has a value outside the range of an integer type.


Compiler Error C2142

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:

void func();
void func( int, ... );    // error


Compiler Error C2143

syntax error : missing 'token1' before 'token2'

The compiler expected a specific token (a language element other than whitespace) and found another token instead.

Possible causes

  • The first non-whitespace character following an if statement should be a left parenthesis. The compiler cannot translate anything else:
    void main() {
   int j = 0;
   if (j < 25)   // C2143, missing semicolon
}
  • Missing closing brace, parenthesis, or semicolon on the line where the error is detected or a few lines above:
    class X
{
   int member
} x;          // error, missing ; on previous line
  • Invalid tag in a class declaration:
    class X
{
   int member;
} x;
class + {};   // error, + is an invalid tag name
  • A label 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:
    void func1()
{
   end:      // error
}            // this line is not a statement
void func2()
{
   end:      // OK
    ;        // this label attached to null statement
}
  • Single-line comments with /Za (ANSI compatibility).
    int i;    // syntax error : missing ';' before 'division operator'
int j;    /* no error */
  • Invalid attribute syntax. Although the following instruction is valid in a MIDL file:
    typedef [public] long MEMBERID;

    it is not valid in a C++ source code file. Instead, you would need to issue:

    [public] typedef long MEMBERID;

See Knowledge Base article Q241706 for information on this error when using a function-try block.

Check the C++ Language Reference to determine where code is syntactically incorrect. Since the compiler may report this error after the line that causes the problem, check the few lines of code that precede the error.


Compiler Error C2144

syntax error : 'type' should be preceded by 'token'

The compiler expected token and found type instead.

Possible cause

  • Missing closing brace, right parenthesis, or semicolon.


Compiler Error C2145

syntax error : missing 'token' before identifier

The compiler expected token and found identifier instead.

Possible cause

  • Missing semicolon after the last declaration in a block.


Compiler Error C2146

syntax error : missing 'token' before identifier 'identifier'

The compiler expected token and found identifier instead.

Probable cause

  • A typographical error. Error C2065 usually precedes this error.

The following sample generates C2146:

void main(void)
{
   intt x; //Syntax error: missing semicolon before 'x'
}


Compiler Error C2147

'identifier' : const automatic array must be fully initialized

The specified array is declared as const but not all elements are initialized when the array is defined.

The following sample generates C2147:

void func(void) {
const int arr[10] = { 1, 2};   // C2147
// This is not an error if the array is declared global...
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2148

array too large

An array exceeds the 64K limit. Reduce the size of the array.


Compiler Error C2149

'identifier' : named bit field cannot have zero width

Bit fields can have zero width only if unnamed. The following sample generates C2149:

struct C {
   int i : 0;   // C2149
   // try ...
   // int j : 2;   // ok
};

void main() {
}


Compiler Error C2150

'identifier' : bit field must have type 'int', 'signed int', or 'unsigned int'

ANSI C (/Za) requires bit fields to be int, signed int, or unsigned int. The following sample generates C2150:

struct A {
   float a : 8;   // C2150
   // try ...
   // int i : 8;   // ok
};

void main() {
}


Compiler Error C2151

more than one language attribute

A function has more than one keyword ( __cdecl, __stdcall, or __fastcall) specifying a calling convention.


Compiler Error C2152

'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

hex constants must have at least one hex digit

Hexadecimal constants 0x, 0X, and \x are illegal. At least one hex digit must follow x or X. The following sample generates C2153:

void main() {
   int a= 0x;   // C2153
   int b= 0xA;   // ok
}


Compiler Error C2154

'segment' : does not refer to a segment name

When you declare a based variable, you must allocate a segment, unless the variable is extern and uninitialized.


Compiler Error C2155

'?' : 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

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:

#pragma optimize( "l", on )      // ok

void main() {
   #pragma optimize( "l", on )   // C2156
}


Compiler Error C2157

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

// uncomment the following function declaration to resolve
// extern "C" void func();

#pragma alloc_text( "func", func)   // C2157

void main() {
}


Compiler Error C2158

'identifier' : is a function

The identifier specified in the variable list of a same_seg pragma is declared as a function.


Compiler Error C2159

more than one storage class specified

A declaration contains more than one storage class.

The following sample generates C2159:

extern static int i;      // error


Compiler Error C2160

'##' cannot occur at the beginning of a macro definition

A macro definition began with a token-pasting operator (##).

The following sample generates C2160:

#define mac(a,b) ##a    // error


Compiler Error C2161

'##' cannot occur at the end of a macro definition

A macro definition ended with a token-pasting operator (##).

The following sample generates C2161:

#define mac(a,b) a##    // error


Compiler Error C2162

expected macro formal parameter

The token following a stringizing operator (#) is not a formal parameter name.

The following sample generates C2162:

#define print(a) printf(#b)    // error


Compiler Error C2163

'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 Managed Extensions for C++.


Compiler Error C2164

'function' : intrinsic function not declared

An intrinsic pragma uses an undeclared function (only occurs with /Oi).


Compiler Error C2165

'keyword' : cannot modify pointers to data

The __stdcall, __cdecl, or __fastcall keyword attempts to modify a pointer to data.

The following sample generates C2165:

char __cdecl *p;   // error


Compiler Error C2166

l-value specifies const object

Code attempts to modify an item declared const. The following sample generates C2166:

void main() {
   int j = 0;
   const int i = 4;   // i is const
   j = i;   // ok
   i = 5;   // C2166
}


Compiler Error C2167

'function' : too many actual parameters for intrinsic function

A reference to an intrinsic function has too many parameters.


Compiler Error C2168

'function' : too few actual parameters for intrinsic function

A reference to an intrinsic function has too few parameters.


Compiler Error C2169

'function' : intrinsic function, cannot be defined

A function definition appears for a function already declared intrinsic.


Compiler Error C2170

'identifier' : not declared as a function, cannot be intrinsic

Possible causes

  • Pragma intrinsic is used for an item other than a function.
  • Pragma intrinsic is used for a function with no intrinsic form.


Compiler Error C2171

'operator' : illegal operand

A unary operator is used with an illegal operand type.

The following sample generates C2171:

double d, d1;
d = ~d1;      // error


Compiler Error C2172

'function' : actual parameter is not a pointer : parameter number

Parameter number is not a pointer. The function expects a pointer.


Compiler Error C2173

'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

'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

'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

constant too big

A constant value is too large for the variable type it is assigned. The following sample generates C2177:

void main() {
   int a=18446744073709551616; // C2177
   // try ...
   // int b=18446744073709551615; // ok
}


Compiler Error C2178

'identifier' : storage class for same_seg variables must be extern

A variable specified in a same_seg pragma is not declared extern.


Compiler Error C2179

'identifier' : was used in same_seg, but storage class is no longer extern

The variable is specified in a same_seg pragma but redeclared with a storage class other than extern.


Compiler Error C2180

controlling expression has type 'void'

The controlling expression in an if, while, for, or do statement is a function with return type void or an expression cast to void. The following sample generates C2180:

void test() {
}

int test2() {
   return 0;
}

void main() {
   if (test())   // C2180
      ;
   // try ..
   /*
   if (test2())
      ;
   */
}


Compiler Error C2181

illegal else without matching if

Each else must have a matching if. The following sample generates C2181:

void main() {
   int i = 0;

   /* use an if to resolve the error
   if(i)
      i = 0;
   */

   else      // C2181
      i = 1;
}


Compiler Error C2182

'identifier' : illegal use of type 'void'

A variable is declared type void. The following sample generates C2182:

int i = 10;
void &ir = i;   // C2182, cannot have a reference to type void

void main() {
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2183

syntax error: translation unit is empty

Preprocessing produced an empty source file.


Compiler Error C2184

illegal return of a 'void' value

The function return type is not void, but the return statement does not return a value.


Compiler Error C2185

'identifier' : illegal based allocation

A register variable or automatic (local) variable is declared __based. Only global variables can be declared __based.


Compiler Error C2186

'operator' : illegal operand of type 'void'

The operator has a void operand.

The following sample generates C2186:

void func1( void );
int  func2( void );
int i = 2 + func1();   // error, func1() is type void
int j = 2 + func2();   // OK, both operands are type int


Compiler Error C2188

'number' : too big for wide character

The number exceeds the size limit for the wide-character type. Choose a larger type.


Compiler Error C2189

#error : string

The compiler encountered an #error directive and output the user-specified string.


Compiler Error C2190

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:

// compile with /Za
void func( int, float );
void func( int  );        // error, different parameter list


Compiler Error C2191

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.

The following sample generates C2191:

// compile with /Za
void func( int );
void func( int, float ); // error, different parameter list


Compiler Error C2192

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:

// compile with /Za
void func( float, int );
void func( int, float ); // error, different parameter list


Compiler Error C2193

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

extern "C" void foo();
#pragma alloc_text(MYCODE, foo)
#pragma code_seg("MYCODE2")
extern "C" void foo()
{               // error
}


Compiler Error C2194

'identifier' : is a text segment

The data_seg pragma uses a segment name used with code_seg.

The following sample generates C2194:

#pragma code_seg("MYCODE")
#pragma data_seg("MYCODE")   // error


Compiler Error C2195

'identifier' : is a data segment

The code_seg pragma uses a segment name used with the data_seg pragma.

The following sample generates C2195:

#pragma data_seg("MYDATA")
#pragma code_seg("MYDATA")   // error


Compiler Error C2196

case value 'value' already used

A switch statement uses the same case value more than once.

The following sample generates C2196:

void f()
{
    int i;
    switch( i )
    {
    case 0:
        break;
    case 0:    // error, case value '0' already used
        break;
    }
}


Compiler Error C2197

'function' : too many actual parameters

Possible causes

  • Too many parameters for a call to the function.
  • Incorrect function declaration.

The following sample generates C2197:

// compile with /Za
void func( int );
main()
{
   func( 1, 2 );   // error, two actual parameters
}


Compiler Error C2198

'function' : too few actual parameters

Possible causes

  • Too few parameters for a call to the function.
  • Incorrect function declaration.

The following sample generates C2198:

void func( int, int );
main()
{
   func( 1 );   // error, only one actual parameter
}


Compiler Error C2199

syntax error : found 'identifier (' at global scope (was a declaration intended?)

The specified context caused a syntax error. There may be incorrect declaration syntax.


Compiler Error C2200

'function' : function has already been defined

An alloc_text pragma uses a function name already defined.


Compiler Error C2201

'identifier' : must have external linkage in order to be exported/imported

The exported identifier is static.

Example

__declspec(dllexport) static void func() {}  // error, func() is static
__declspec(dllexport) void func() {}         // OK


Compiler Error C2203

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.

Example

delete [4] ArrayOfObjects;   // error


Compiler Error C2204

'type' : type definition found within parentheses

The type is defined as an operand or in prototype scope.

Example

( struct S {}; );  // error


Compiler Error C2205

'identifier' : cannot initialize extern variables with block scope

An extern variable cannot be initialized in a function.


Compiler Error C2206

'function' : typedef cannot be used for function definition

A typedef is used to define a function type.

Example

typedef int functyp();
functyp func1 {};        // error


Compiler Error C2207

'member' in struct/union 'tag' has a zero-sized array

The member of the structure or union tag contains an array with no subscript or a zero subscript. This kind of array is legal only as the last member of a structure or union.


Compiler Error C2208

'type' : no members defined using this type

An enumeration, structure, or union is defined without members. This error occurs when you compile for C++ with the ANSI compatibility (/Za).

Possible cause

  • Porting C code with nested structs to C++. Rewrite the code to use C++ mechanisms.

    The following code uses C-style structs. When compiled for C++, the first struct declares a nested structure, Struct::ToBeIncluded. This is not the same as ::ToBeIncluded.

    struct ToBeIncluded {
    int i;
};

struct Struct {     //C struct defined using /Ze extensions
    float x;
    struct ToBeIncluded;     // C-style struct injection
    float y;
};                           // error under /Za ANSI compatibility

    The following code shows the structures rewritten for C++:

    struct ToBeIncluded {
    int i;
};

struct Intermediate {        // revised C++ struct
    float x;
};

struct Struct                // C++ style
    :   public Intermediate,
        public ToBeIncluded
{
    float y;
};                           // Always OK for C++
#endif


Compiler Error C2212

'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

'modifier' : illegal argument to __based

The argument modifying __based is invalid.

Example

int i;
char __based(i) *p;      // error


Compiler Error C2217

'attribute1' must be used with 'attribute2'

The first function attribute requires the second attribute.

Possible causes

  • Interrupt (__interrupt) function declared as near. Interrupt functions must be far.
  • Interrupt function declared with __stdcall, or __fastcall. Interrupt functions must use C calling conventions.


Compiler Error C2218

type in __based construct must be 'void'

Only types based on void are legal in 32-bit code.


Compiler Error C2219

syntax error : type qualifier must be after '*'

Type qualifier (const or volatile) appears where it is not permitted.

Example

int (const *p);    // error


Compiler Error C2220

warning treated as error - no object file generated

/WX tells the compiler to treat all warnings as errors.

Possible solutions

  • Fix the problem that caused the warning.
  • Compile at a lower warning level.
  • Compile without /WX.


Compiler Error C2221

'.' : left operand points to class/struct/union. use '–>'

The left operand is a pointer rather than a class, struct, or union. To access a member, you must use the -> operator rather than the period (.) operator.


Compiler Error C2222

'->' : left operand has class/struct/union type, use '.'

The left operand is a class, struct, or union rather than a pointer. To access a member, you must use the period (.) operator rather than the -> operator.


Compiler Error C2223

left of '->identifier' must point to class/struct/union

The operand to the left of -> is not a pointer to a class, structure, or union.

Possible cause

  • Left operand is an undefined variable (therefore type int).


Compiler Error C2224

left of '.identifier' must have class/struct/union type

The operand to the left of the period (.) is not a class, structure, or union.

Possible cause

  • Left operand is an undefined variable (therefore type int).


Compiler Error C2226

syntax error : unexpected type 'type'

A syntax error occurs before or in the type specifier.

Example

int func1( int, ... , float ); // error, misplaced ellipsis
int func2( int, float, ... );  // OK


Compiler Error C2227

left of '->identifier' must point to class/struct/union

The operand to the left of -> is not a pointer to a class, structure, or union.

Example

int  *pInt;
struct S
{
public:
    int member;
} *pS;
void main()
{
    pInt->member = 0;   // error, pInt points to an int
    pS->member = 0;     // OK, pS points to a structure S
}


Compiler Error C2228

left of '.identifier' must have class/struct/union type

The operand to the left of the period (.) is not a class, structure, or union.

Example

int i;
struct S
{
public:
    int member;
} s, *ps;
void main()
{
   i.member = 0;   // error, i is not a class type
   ps.member = 0;  // error, ps is a pointer to a structure
   s.member = 0;   // OK, s is a structure type
   ps->member = 0; // OK, ps points to a structure S
}


Compiler Error C2229

type 'identifier' has an illegal zero-sized array

A member of a structure or bit field contains a zero-sized array.

Example

struct S
{
   int a[0];  // error, zero-sized array
   int b[1];  // OK
};


Compiler Error C2230

'operator' : indirection to different types

The operator is used with pointer expressions that have different base types, without conversion. (Warning in ANSI C; error in C++.)

Example

struct ts1 *s1;
struct ts2 *s2;
s2 = s1;   // error


Compiler Error C2231

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

Example

struct S
{
public:
    int member;
} s, *ps;
void main()
{
   ps.member = 0;  // error, ps points to structure S
   ps->member = 0; // OK, ps points to a structure S
   s.member = 0;   // OK, s is a structure type
}


Compiler Error C2232

'–>' : 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.

Example

struct X
{
    int member;
} x, *px;
void main()
{
    x->member = 0;   // error, x is not a pointer
    px->member = 0;  // OK, px is a pointer to an X
    x.member = 0;    // OK
}


Compiler Error C2233

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

class A {
   char zeroarray[];
   // try declaring the array as follows ...
   // char somearray[1];
};

A array[100];   // C2233

void main() {
}


Compiler Error C2234

'name' : arrays of references are illegal

Because pointers to references are not allowed, arrays of references are not possible. The following sample generates C2234:

main() {
   int i,j,k,l;

   int &array[4] = {i,j,k,l};   // C2234, delete the & to resolve the error
}


Compiler Error C2235

';' in formal parameter list

A formal parameter list contains a semicolon.

Possible cause

  • Using a semicolon instead of a comma to separate parameters.

Example

void func( int i; float f );   // error, uses semicolon
void func( int i, float f );   // OK, uses comma


Compiler Error C2236

unexpected 'class-key' 'identifier'

The identifier is already defined as a type and cannot be overridden by a user-defined type. The following sample generates C2236:

int class A {   // C2236, delete int to resolve the error
};

void main() {
}


Compiler Error C2238

unexpected token(s) preceding 'token'

An incorrect token was found.

Possible cause

  • Invalid name in a bit-field declaration.

Example

struct bits
{
   int field1 : 16;
   int 9      : 16;  // error, 9 is not a valid name
};


Compiler Error C2239

unexpected token 'token' following declaration of 'identifier'

An incorrect token was found in the declaration.

Example

int i 8;   // error, missing =
int j = 7; // OK


Compiler Error C2240

unexpected 'token' following formal list (only modifiers are allowed)

An incorrect token was found after a formal parameter list.

Example

void func() int;  // error
void func();      // OK


Compiler Error C2241

'identifier' : member access is restricted

Code attempts to access a private or protected member.

Possible solutions

  • Change the access level of the member.
  • Declare the member a friend of the accessing function.


Compiler Error C2242

typedef name cannot follow class/struct/union

A typedef name appears at the end of a qualified name.


Compiler Error C2243

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

Example

class B {};
class D : private B {};

D d;
B *p = &d;      // error


Compiler Error C2244

'identifier' : unable to match function definition to an existing declaration

An unusual use of the unary + operator and was used in front of a function call that did not have parenthesis.

This error only occurs in C++ projects.

Solution

Reconcile the function signatures (return type, name, and argument list) in the definition and the declaration.

- or -

Add the missing declaration.

The following sample generates C2244:

int func(char) {
   return 0;
}

int func(int) {
   return 0;
}

void main() {
   +func;   // C2244

   // the following line resolves the error
   // +func(0);
}


Compiler Error C2245

nonexistent function 'Identifier' specified as friend

Identifier is not a function, so it can be a friend.

Example

class C
{
public:
   int i;                  // i is not a function
   void func();
};
class S
{
public:
   friend void C::i();     // error
   friend void C::func();  // OK
};


Compiler Error C2246

'identifier' : illegal static data member in locally defined class

A member of a class, structure, or union with local scope is declared static.

Example

void func( void )
{
   class A
   {
 static int i;    // error, i is local to func
   };
};
class B
{
   static int i;       // OK
};


Compiler Error C2247

'Identifier' not accessible because 'class' uses 'specifier' to inherit from 'class'

Identifier is inherited from a class declared with private or protected access.

Example

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;               // error, i not accessible


Compiler Error C2248

'member' : cannot access access member declared in class 'class'

Members of a derived class cannot access private members of a base class. Objects created from a class cannot access protected or private members of that class.

See Knowledge Base article Q243351 for more information on C2248.

The following sample generates C2248:

#include <stdio.h>
class X {
public:
   int  m_pubMemb;
   void setPrivMemb( int i ) {
      m_privMemb = i;
      printf("\n%d", m_privMemb);
   }

protected:
   int  m_protMemb;

private:
   int  m_privMemb;

} x;

void main() {
   x.m_pubMemb = 4;
   printf("\n%d", x.m_pubMemb);
   x.setPrivMemb(0);   // OK, uses public access function

   x.m_protMemb = 2;   // error, m_protMemb is protected
   x.m_privMemb = 3;   // error, m_privMemb is private
}

You may also see this error when using Managed Extensions for C++:

#using <mscorlib.dll>
__gc class Base {
protected:
void Method() {
Console::WriteLine("protected");
}
};

__gc class Der : public Base {
void Method() {
((Base*)this)->Method(); // C2248
// try ...
// Base::Method();
}
};
void main() {
}


Compiler Error C2249

'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

class A
{
private:
   void privFunc( void ) {};
public:
   void pubFunc( void ) {};
};
class B : virtual public A {} b;
void main( void )
{
   b.privFunc();        // error, private member of A
   b.pubFunc();         // OK
}


Compiler Error C2250

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

Example

struct V { virtual void vf(); };
struct A : virtual V { void vf(); };
struct B : virtual V { void vf(); };
struct D : A, B {};                   //error


Compiler Error C2251

'destructor' : defined but not declared

The destructor is defined but not declared in the class body.

Example

class C
{
  C();     // only a constructor is declared
};

C::C() {}  // OK, constructor is defined

C::~C()    // undeclared destructor definition
{          // error on this line
}


Compiler Error C2252

'Identifier' : pure specifier can only be specified for functions

Identifier is a nonfunction specified as pure virtual. Only virtual member functions can be declared with a pure specifier.

Example

class A
{
   virtual int i = 0;          // error, i is an int
   virtual void func() = 0;    // OK, func is a function
};


Compiler Error C2253

'function' : pure specifier only applies to virtual function – specifier ignored

A nonvirtual function is specified as pure virtual.

Example

class A
{
public:
  void func1() = 0;          // error, not virtual
  virtual void func2() = 0;  // OK
};


Compiler Error C2254

'function' : pure specifier not allowed on friend functions

A friend function is specified as pure virtual.

Example

class A
{
public:
   friend void func1() = 0;   // error, 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

'function' : a friend function can only be declared in a class

A nonmember function is declared a friend.

Example

class A
{
private:
   void func1();
   friend void func2();
};
friend void func1() {};    // error
void func2() {};           // OK


Compiler Error C2256

illegal use of friend specifier on 'destructor'

The destructor is specified as a friend.

Example

class C
{
public:
   friend ~C(); // error
   ~C();        // OK
};


Compiler Error C2258

illegal pure syntax, must be '= 0'

A pure virtual function is declared with incorrect syntax.

Example

class A
{
public:
   void virtual func1() = 1; // error, not = 0
   void virtual func2() = 0; // OK
};


Compiler Error C2259

'class' : cannot instantiate abstract class due to following members:

Code declares an instance of an abstract class or structure. One or more C4259 warnings follow for the abstract members.

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.

Example

class V
{
public:
   void virtual func() = 0;
};
class A : public V {};
class B : public V
{
public:
   void func();
};
V v;  // error, V is an abstract class
A a;  // error, A inherits func() as pure virtual
B b;  // OK, B defines func()


Compiler Error C2260

function pointer cast to a data pointer

ANSI C does not allow you to cast a function pointer to a data pointer.

Possible solutions

  • Use C++.
  • Use /Ze.


Compiler Error C2261

data pointer cast to a function pointer

ANSI C does not allow you to cast a data pointer to a function pointer.

Possible solutions

  • Use C++.
  • Use /Ze.


Compiler Error C2262

'identifier' : cannot be destroyed

The object cannot be instantiated because the appropriate destructor, though defined, is not accessible.

Example

class B
{
   ~B();
};
class D : public B {};
D d;         // error, B's destructor is private


Compiler Error C2264

'function' : error in function definition or declaration; function not called

The function cannot be called due to an incorrect definition or declaration.

Example

class C
{
public:
   operator int( int = 10 );    // incorrect declaration here
};
void main()
{
   int i;
   C c;
   i = c;                       // error
}


Compiler Error C2265

'identifier' : reference to a zero-sized array is illegal

A reference is declared for an array with zero size. The array must have nonzero, constant bounds.


Compiler Error C2266

'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

'function' : static functions with block scope are illegal

A local function is declared static. Static functions must have global scope.

Example

void main()
{
    static int func1();    // error
}


Compiler Error C2268

'operation' : different const or volatile qualifiers

An operation is performed on a variable defined as const or volatile. The const or volatile item cannot be modified.

Possible cause

  • A pointer to an item declared const or volatile is assigned to a pointer not declared as pointing to const or volatile.

Example

const  char *p = "abcde";
int    str( char *s );
str( p );                // error


Compiler Error C2270

'function' : modifiers not allowed on nonmember functions

A nonmember function is declared with const, volatile, or another memory-model modifier.

Example

void func1(void) const;     // error, nonmember function
// try the following declaration instead:
// void func1(void);
class CMyClass {
   public:
      void func2(void) const;  // OK
   };

void main() {
}


Compiler Error C2271

'operator' : new/delete cannot have formal list modifiers

The operator (new or delete) is declared with a memory-model specifier.

For example, the following sample generates C2271:

void* operator new(size_t) /*const*/   // Global operator new
{
   return 0;
}
struct X {
/*static*/ void* operator new(size_t) const;
};
void * X::operator new(size_t) const   // static member operator new
{
   return 0;
}

void main() {
}


Compiler Error C2272

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

Example

class CMyClass {
   public:
      static void func1() const volatile;  // error, func1 is static
      void func2() const volatile;         // OK
   };

void main() {
}


Compiler Error C2273

'type' : illegal as right side of '->' operator

A type appears as the right operand of a -> operator.

Possible cause

  • Trying to access a user-defined type conversion. Use the keyword operator between -> and type.

Example

i = ClassPtr->int( a );           // error
i = ClassPtr->operator int( a );  // OK


Compiler Error C2274

'type' : illegal as right side of '.' operator

A type appears as the right operand of a member-access (.) operator.

Possible cause

  • Trying to access a user-defined type conversion. Use the keyword operator between the period and type.

Example

i = ClassName.int( a );           // error
i = ClassName.operator int( a );  // OK


Compiler Error C2275

'identifier' : illegal use of this type as an expression

An expression uses the -> operator with a typedef identifier.

Example

typedef struct S
{
    int mem;
} *S_t;
void func1( int *parm );
void func2()
{
    func1( &S_t->mem );   // error: S_t is a typedef
}


Compiler Error C2276

'operator' : illegal address of bound member function expression

You cannot take the address of a virtual function.

Example

class A
{
public:
   virtual int func();
} a;
int (*pf)() = &a.func;   // error
class B
{
public:
   void mf()
   {
  &this->mf;       //error
   }
};


Compiler Error C2277

'identifier' : cannot take address of this member function

You cannot take the address of a member function.

Example

class A
{
public:
   A();
};
(*pctor)() = &A::A;   // error


Compiler Error C2278

'function' : no function with C linkage found

The function was not found.

Possible cause

  • File containing the function definition does not appear in project list or makefile
  • Function not defined within the file scope
  • Keyword extern missing from the function prototype


Compiler Error C2279

cannot use braces to initialize default arguments

For more information on resolving this error, see C2059.

Example

struct Point
{
   int x, y;
};
int f( Point p = { 1, 2 } );  // error C2279


Compiler Error C2280

missing '{' before identifier 'identifier'?

Example

int int_var;
void func( int a     // missing opening brace
   t_var = 1;        // error is called on this line
}


Compiler Error C2281

'identifier1' : is not a function, but contains <function returning>; 'identifier2' is unexpected

The declaration of the identifier has incorrect syntax.

Example

int (*f)() a;      // error


Compiler Error C2282

'identifier1' is followed by 'identifier2' (missing ','?)

Missing comma between identifier1 and identifier2.

Example

int *f g;          // error


Compiler Error C2283

'identifier' : pure specifier not allowed on unnamed class-key

A member function of an unnamed class or structure is illegally declared with a pure specifier.

Example

struct
{
   virtual void func() = 0;   // error
};
struct S
{
   virtual void func() = 0;   // OK
};


Compiler Error C2284

unbalanced parenthesis found while processing a member function

A member-function definition ended with a parenthesis instead of a brace.

Example

class C {
public:
   void func()
   {
   );            // error, parenthesis instead of brace
};


Compiler Error C2285

pointers to members representation has already been determined - pragma ignored

Two different representations exist for class.

Example

class  __single_inheritance X;
class  __multiple_inheritance X;   // error


Compiler Error C2286

pointers to members of 'identifier' representation is already set to 'inheritance' – declaration ignored

Two different pointer-to-members representations exist for class.

Example

class  __single_inheritance X;
class  __multiple_inheritance X;   // error


Compiler Error C2287

'class': inheritance representation: 'representation1' is less general than the required 'representation2'

A class is declared with a simpler representation than required.

Compiling the following code with /vmg ("General-purpose always" representation) causes C2287.

Example

class __single_inheritance X;

struct A { };
struct B { };
struct X : A, B { };  // error, X uses multiple inheritance


Compiler Error C2289

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

Example

volatile volatile int i;   // error


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2290

C++ asm syntax ignored. Use __asm.

The asm syntax is reserved for future use.


Compiler Error C2292

'identifier': best case inheritance representation: 'representation1' declared but 'representation2' required

Example

Compiling the following code with /vmb ("Best-case always" representation) causes C2292.

class __single_inheritance X;

struct A { };
struct B { };
struct X : A, B { };  // error, X uses multiple inheritance


Compiler Error C2293

'identifier': illegal to have a member variable as a __based specifier

Specifiers for __based modifier must be nonmember pointers.

Example

class A
{
   static int *i;
   void __based(i) *bp; // error
};


Compiler Error C2294

'identifier': illegal argument to intrinsic function, parameter number

The parameter is invalid for the given function.


Compiler Error C2295

escaped 'character' : is illegal in macro definition

A macro definition cannot contain an escape sequence with the specified character.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2296

'operator' : bad left operand

The left operand used with operator is illegal.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2297

'operator' : bad right operand

The right operand used with operator is illegal.


Compiler Error C2298

'operation' : illegal operation on pointer to member function expression

A pointer to member-function expression must call the member function.

Example

struct X {
    int mf() { return 0; }
};

X x;
int (X::*pmf)() = &X::mf;

int main()
{
    int (*pf)();
    pf = x.*pmf;   // error
    +(x.*pmf);     // error
    return 0;
}


Compiler Error C2299

'name' : globally qualified name illegal as right hand side of operator 'operator'

The right operand of operator must be a member of a class, structure, or union.


Compiler Error C2300

'identifier' : class does not have a destructor called '~identifier'

The class does not have a destructor with the required name.


Compiler Error C2301

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

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 C2303

left of '.identifier' must be an l-value

An l-value must appear to the left of the period (.) operator.


Compiler Error C2304

'type symbol' : unexpected tokens following type

An incorrect token appears after the type. This error is similar to C2239, but C2304 occurs within a function body.


Compiler Error C2305

'pdbfile' does not contain debugging information for this module

The program database does not contain current debugging information for the module. Delete the file and recompile.


Compiler Error C2306

'pdbfile' does not contain the most recent debugging information for this module

The program database is not current. Delete it and recompile.


Compiler Error C2307

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

concatenating mismatched wide 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

catch handler expected a parenthesized exception declaration

A catch handler has no parenthesized type.

Example

#include <eh.h>
class C;
void main()
{
    try
    {
        throw "ooops!";
    }
    catch C  {}   // error
    catch( C ) {} // OK
}


Compiler Error C2310

catch handlers must specify one type

A catch handler specified no type or multiple types.

Example

#include <eh.h>
int main()
{
    try
    {
        throw "Out of memory!";
    }
    catch( int ,int)  // error, two types
    {
    }
    return 0;
}


Compiler Error C2311

'exception' : is caught by '...' on line number

The catch handler for the ellipsis (...) must be the last handler for a throw.

Example

#include <eh.h>
//...
void main()
{
    try
    {
        throw "ooops!";
    }
    catch( ... ) {}  // ellipsis handler is not last catch for this throw
    catch( int ) {}
}


Compiler Error C2312

'exception1' : is caught by 'exception2' on line number

Two handlers catch the same exception type.

Example

#include <eh.h>
//...
void main()
{
    try
    {
        throw "ooops!";
    }
    catch( signed int ) {}
    catch( int ) {}  // error
}


Compiler Error C2313

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

Example

#include <eh.h>
class C;
void main()
{
    try
    {
        throw "ooops!";
    }
    catch( C& ) {}
    catch( C ) {}   // error
}


Compiler Error C2315

'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 C2317

'try' block starting on line 'number' has no catch handlers

A try block must have at least one catch handler.

Example

#include <eh.h>
void main()
{
    try
    {
        throw "ooops!";
    }
        // error: no catch handler
}


Compiler Error C2318

no try block associated with this catch handler

A catch handler is defined but not preceded by a try block.

Example

#include <eh.h>
void main()
{
        // no try block
    catch( int )   // error
    {
        cout << "Integer exception raised.";
    }
}


Compiler Error C2319

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

Example

#include <eh.h>
class C;
void main()
{
    try
    {
        throw "ooops!";
    }
    catch( C ) ;    // error, missing block
    catch( C ) {}   // OK
}


Compiler Error C2320

expected ':' to follow access specifier 'specifier'

The keyword public, protected, or private must be followed by a colon.


Compiler Error C2321

syntax error: unexpected 'identifier'

A qualified name occurs in the wrong place.

Example

struct A { struct B { }; };

void f()      // note missing '{'
A::B x;      // error
}


Compiler Error C2322

'identifier' : address of dllimport 'dllimport' is not static

A nonstatic value is given as the address of a function declared with dllimport.


Compiler Error C2323

compiler limit: out of local keys compiling function 'function'

Too many local variables prevent compiling the function. Divide the function into smaller functions.


Compiler Error C2324

'identifier' : unexpected to the right of 'name'

A destructor is called using an incorrect identifier.

Example

class A {};
typedef A* pA_t;
int i;

void f()
{
    pA_t *ppa = new pA_t;
    ppa->~i;              // error
}


Compiler Error C2325

'type' : unexpected type to the right of 'name'

A call is made to a destructor of incorrect type.

Example

class A {};
void f()
{
    A** ppa = new A *;
    ppa->~A*;          // error
}

To avoid the error, do this:

typedef A* pA_t;
void g()
{
    pA_t *ppa = new pA_t;
    ppa->~pA_t();     // ok
}


Compiler Error C2326

'declarator' : function cannot access 'name'

The code tries to modify a member variable, which is probably from a friend function, without specifying an object.

Example

class X
{
    int a;
    friend void f(X *p) { a = 10; } // error
};


Compiler Error C2327

'symbol' : member from enclosing class is not a type name, static, or an 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.

Example

int x;
class enclose
{
public:
   int x;
   static int s;
   class inner
   {
      void f()
      {
         x = 1;      // error; enclose::x is not static
         s = 1;      // ok; enclose::s is static
         ::x = 1;    // ok; ::x refers to global
      }
   };
};


Compiler Error C2329

'identifier' : __ptr64 not available for pointers to functions

On MIPS and DEC ALPHA platforms, the __ptr64 modifier can be applied only to data pointers.

Example

typedef void (__ptr64 *pf) (int);   //error


Compiler Error C2332

‘tag’: missing tag name

You must specify a variable name for the class, structure, union, or enumeration.

Example

int struct;   //error


Compiler Error C2333

'function' : error in function declaration; skipping function body

This error occurs after another error, for member functions defined inside their class.

Example

struct s1 {
   s1(s1) {   //error
   }
};


Compiler Error C2334

"unexpected token(s) preceding ': or {'; skipping apparent function body"

This error occurs after another error, for member functions defined inside their class.

Example

struct s1 {             // in a cpp file
   s1(s1 func hello) {  // error
   }
};


Compiler Error C2337

'attribute name' : attribute is not supported

You have used an attribute that is not supported in this version of Visual C++. For example:

[emitidl];
[module(name="x")];
[grasshopper]   // not a supported attribute
class a{};


Compiler Error C2340

'argument' : illegal allocate specifier

A __declspec(allocate("segname")) statement has an invalid argument. Valid arguments are "_CODE", "_DATA" and "_FAR_DATA".


Compiler Error C2341

section name : segment must be defined using #pragma data_seg or code_seg prior to use

A #pragma or __declspec(allocate()) statement refers to a segment not yet defined #pragma code_seg or #pragma data_seg.

Example

The following #pragma appears in a source file before "MYSEG" is defined:

#pragma alloc_text (MYSEG, MyLocal) // error

To fix this error, define the segment before referring to it. For this example, use #pragma code_seg to define MYSEG before alloc_text:

#pragma code_seg("MYSEG")
   .
   .
   .
#pragma alloc_text (MYSEG, MyLocal)


Compiler Error C2344

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:

// compile with cl /c
__declspec(align(3)) int a;


Compiler Error C2345

align(value) : illegal alignment value

You passed a value to the align keyword that is outside the allowable range.

For example, the following code generates C2345 because 1 is the smallest allowable number you can pass:

// compile with cl /c
__declspec(align(0)) int a;


Compiler Error C2346

'member function' : cannot have overloaded methods in embedded-IDL

When generating an IDL from an interface, overloaded member functions are not allowed. For example, the following interface definition will generate this error:

interface IFst {
   HRESULT fst(BSTR b);
   HRESULT fst(long l);
};


Compiler Error C2347

'__w64' : cannot be used with type 'type'

__w64 only applies to variables of the int and long data types. For example, you will get C2347 if you issue,

__w64 short i;

A short integer can only be 32 bits.


Compiler Error C2348

'type name' : illegal type in embedded-IDL

To place a struct in a .idl file with the export attribute, the struct must contain only data.

The following code shows how this error could occur because variables of type _bstr_t and _variant_t have contructors.

#include <comdef.h>

[emitidl];
[ module(name="SimpleMidlTest", uuid="38f23b6e-2721-11d2-a97e-00c04fa37ddb", version=1.0) ];

[export]
struct SomeStruct {
   DWORD m_dword;
   _bstr_t m_bstring;
   _variant_t m_var;
};

__interface IMyInterface {
   HRESULT func([in, out] stuff *pStuff);
};


Compiler Error C2349

'function' cannot be compiled using /com+: 'text'; compile without /com+

There are restrictions when using inline assembly with Managed Extensions for C++. For example, static functions cannot contain inline assembly. The following sample generates C2349:

#using <mscorlib.dll>
// remove static, the asm, or compile without /com+ to resolve
static void TestInlineAsmInStaticFunc(void) {    // C2349
   __asm {
      nop
   }
}

void main() {
   TestInlineAsmInStaticFunc();
}


Compiler Error C2350

'identifier' is not a static member

Nonstatic members of a class or structure cannot be defined.

Example

class C
{
public:
   int i;
   static int s;
};
void main()
{
   int C::i = 0;  // error, nonstatic member
   int C::s = 0;  // OK, static member
   C.c;
   c.i = 0;       // OK, member of instance of C
}


Compiler Error C2351

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.

Example

class B
{
public:
   B();
   B( int );
};
class D : public B
{
public:
   D( int i ) : ( i ) {}   // error, B was not named
   D( int i ) : B( i ) {}  // OK
};


Compiler Error C2352

'class::function' : illegal call of non-static member function

A static member function calls a nonstatic member function.

Example

class X
{
public:
   static void func1();
   void func2();
   static void func3()
   {
   func1();          // OK, calls static func1
   func2();          // error, calls nonstatic func2
   }
};


Compiler Error C2353

'constructor' : improper use of constructor initializers

Constructor initializer syntax is incorrect.

Possible cause

  • Missing constructor definition in a constructor initializer.

Example

class C
{
public:
   C() : i( 10 );   // error, missing definition
   C() : i( 10 ){}; // OK
private:
   int i;
};


Compiler Error C2354

'reference' : initialization of reference member requires a temporary variable

A constructor initializes a reference to a member instead of initializing the member.

It is illegal to initialize a reference member of a class in the class's constructor with a temporary variable. An attempt to do so generates the C2354 error, as illustrated by this sample code:

   int temp() { return 1; }

   class Test
   {
   public:
       int member;
       int& ref_member;
       Test();
   };

   Test::Test() : ref_member( temp() )
   {
   }

When this error is encountered, the solution is to change the code so that the reference member is not initialized to a temporary variable. The reference must be initialized to an object that will exist for the lifetime of the reference member.


Compiler Error C2355

'this' : can only be referenced inside non-static member functions

The this pointer is valid only within nonstatic member functions.

Example

char *p = this;     // error


Compiler Error C2356

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.

Move the segment initialization code to the beginning of the module. If multiple areas must be initialized, move them to separate modules.


Compiler Error C2357

'identifier' : must be a function of type 'type'

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


Compiler Error C2360

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

Example

void func( void )
{
   int x;
   switch ( x )
   {
   case 0 :
      int i = 1;       // error, skipped by case 1
      { int j = 1; }   // OK, initialized in enclosing block
   case 1 :
      int k = 1;       // OK, initialization not skipped
   }
}


Compiler Error C2361

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

Example

void func( void )
{
   int x;
   switch (x)
   {
   case 0 :
      int i = 1;       // error, skipped by default
      { int j = 1; }   // OK, initialized in enclosing block
   default :
      int k = 1;       // OK, initialization not skipped
   }
}


Compiler Error C2362

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.

Example

void func()
{
   goto label1;
   int i = 1;         // error, initialization skipped
   {
      int j = 1;      // OK, this block is never entered
   }
label1:;
}


Compiler Error C2363

'arg': cannot evaluate argument 'custom attribute' of custom attribute

A custom attribute can only have arguments that can be evaluated at compile time.

The following sample generates C2363:

#using <mscorlib.dll>
using namespace System;

int func() {
   return 0;
}

[attribute(All)]
__gc class A {
public:
   A(int) {
   }
};

[A(func())]
// try the following line
// [A(0)]
__gc class B {   // C2363
};

void main() {
}


Compiler Error C2364

cannot initialize pointer to code-based object 'identifier'

Pointers to code-based object cannot be statically initialized.

Example

__declspec(allocate("_CODE")) int i ;
int *p = &i ;

To fix this example, rewrite the statements to initialize the pointer dynamically:

__declspec(allocate("_CODE")) int i ;
int *p ;
main() {
   p = &i ;
   .
   .
   .
}


Compiler Error C2365

'class member' : redefinition; previous definition was a 'class member'

You attempted to redefine a class member.

The following sample generates C2365.

Example

// compile with cl /c
//
class   C1   {
   int    CFunc();
   char   *CFunc;      // already exists as a member function

   int    CMem;
   char   *CMem();   // already exists as a member
   };


Compiler Error C2368

'identifier' : redefinition; different allocation specifiers

The declaration and definition of the symbol specify different __declspec attributes.


Compiler Error C2369

'array' : redefinition; different subscripts

The array is already declared with a different subscript.

Example

int a[10];
int a[20];  // error


Compiler Error C2370

'identifier' : redefinition; different storage class

The identifier is already declared with a different storage class.

Example

extern int i;
static int i;  // error


Compiler Error C2371

'identifier' : redefinition; different basic types

The identifier is already declared.

Example

void main(void)
{
    int i;
    float i;    // error, redefinition
}


Compiler Error C2372

'identifier' : redefinition; different types of indirection

The identifier is already defined with a different derived type.

Example

extern int *fp;
extern int fp[];  // error


Compiler Error C2373

'identifier' : redefinition; different type modifiers

The identifier is already defined with a different type modifier.

Example

void __stdcall func( void );
void __cdecl func( void );  // error


Compiler Error C2374

'identifier' : redefinition; multiple initialization

The identifier is initialized more than once.

Example

int i = 0;
int i = 1;  // error


Compiler Error C2375

'function' : redefinition; different linkage

The function is already declared with a different linkage specifier.

Example

extern void func( void );
static void func( void );  // error


Compiler Error C2376

'function' : redefinition; different based allocation

The function is already declared with a different based allocation.

Example

int func();
int _based(_segname("S1")) func();
int _based(_segname("S2")) func();  // error


Compiler Error C2377

'identifier' : redefinition; typedef cannot be overloaded with any other symbol

A typedef identifier is redefined.

Example

typedef int i;
int i;  // error


Compiler Error C2378

'identifier' : redefinition; symbol cannot be overloaded with a typedef

The identifier was redefined as a typedef.

Example

int i;
typedef int i;  //error


Compiler Error C2379

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

Example

void func();
void func(char);     // error, char promotes to int


Compiler Error C2380

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.

Example

class C
{
public:
   int C();  // error, specifies an int return
   int C;    // error, redefinition of i
   C();      // OK
};


Compiler Error C2381

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

void f1();

void __declspec(noreturn) f1() {   // C2381
}

void main() {
}


Compiler Error C2385

ambiguous access of 'member' in 'class'

The member can derive from more than one object (it is inherited from more than one object).

Possible solutions

  • Make the member unambiguous by providing a cast.
  • Rename the ambiguous members in the base classes.

Warning C4385 provides additional information about the ambiguity.

Example

struct A { int x; };
struct B { int x; };
struct C : A, B {};
void func ()
{
   C aC;
   aC.x = 9;        // error
}


Compiler Error C2386

ambiguous conversion from 'type1*' to 'type2*'

The conversion can be done more than one way.

Possible solutions

  • Provide an explicit type conversion.
  • Change the organization of classes so that conversion is no longer ambiguous.

Warning C4386 provides additional information about the ambiguity.

Example

struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
void bup ()
{
   D *pD;
   A *pA;
   pA = pD;            // error
}


Compiler Error C2387

ambiguous conversion from 'type1&' to 'type2&'

The conversion can be done more than one way.

Possible solutions

  • Provide an explicit type conversion.
  • Change the organization of classes so that conversion is no longer ambiguous.


Compiler Error C2390

'identifier' : incorrect storage class 'specifier'

The storage class is not legal for the global-scope identifier. The default storage class is used in place of the illegal class.

Possible solutions

  • 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

register int i;        //error
void main ()
{
   register int j;     //OK
}


Compiler Error C2391

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

Example

class D { void func( int ); };

class A {
   friend class B { int i; };   // error
   friend class C;              // OK
   friend void D::func(int);    // OK
};


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2398

'name' is not yet implemented

This message is not used.


Compiler Error C2400

inline assembler syntax error in 'context'; found 'token'

The token caused a syntax error in the specified context.

Possible cause

  • Specifying a Pentium instruction. Choosing the Pentium option (/G5) causes the compiler to generate instruction sequences optimized for the Pentium, but does not allow Pentium-specific instructions.

The following sample generates C2400:

void main() {
   __asm {
      heh ax,bx;   // C2400
      // try..
      // mov ax,bx;
   }
}


Compiler Error C2401

'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

'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

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


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2404

'identifier' : illegal register in 'context'

This register is illegal in this context.


Compiler Error C2405

illegal short forward reference with offset

Short forward references must refer to a label only. An additional offset cannot be used.


Compiler Error C2406

'identifier' : name undefined in 'context'

An undefined identifier is used with the SIZE, LENGTH, or member-selection (.) operator.


Compiler Error C2407

illegal 'float' register in 'context'

An NDP register was specified in an illegal context.


Compiler Error C2408

illegal type on PTR operator in 'context'

The first parameter of the PTR operator is not a legal type specification.


Compiler Error C2409

illegal type used as operator in 'context'

The type is not legal as an operator in this context


Compiler Error C2410

'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

'identifier' : illegal struct/union member in 'context'

Possible causes

  • The identifier is not a member of a visible structure or union in this context.
  • The identifier is not a member of the structure or union specified with the member-selection (.) operator.


Compiler Error C2412

'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

'token' : illegal align size

The size used with the ALIGN directive is missing or outside the valid range.


Compiler Error C2414

illegal number of operands

Possible causes

  • The opcode does not support the number of operands used. Check an assembly-language reference manual to determine the correct number of operands.
  • A newer processor supports the instruction with a different number of operands. Adjust the /G option to use the later processor.


Compiler Error C2415

improper operand type

The opcode does not use operands of this type.

Possible causes

  • The opcode does not support the number of operands used. Check an assembly-language reference manual to determine the correct number of operands.
  • A newer processor supports the instruction with additional types. Adjust the /G option to use the later processor.


Compiler Error C2416

'identifier' : illegal opcode for processor

The specified opcode is not valid in this context.

Possible causes

  • The instruction requires a newer processor. A newer processor supports the instruction with additional types. Adjust the /G option to use the later processor.
  • Using an opcode that is valid for the processor but that is not handled by the compiler.


Compiler Error C2417

divide by zero in 'context'

The parameter to the right of the division operator is zero in this context.


Compiler Error C2418

cannot delete browser file: filename

The compiler could not delete the browser file.

Possible causes

  • File is read-only.
  • File is in use by another process.


Compiler Error C2419

mod by zero in 'context'

The parameter to the right of the MOD operator is zero in this context.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2420

'identifier' : illegal symbol in context

The identifier is illegal in this context.


Compiler Error C2421

PTR operator used with register in 'context'

The PTR operator cannot be used with a register operand.


Compiler Error C2422

illegal segment override in 'operand'

Inline assembly code incorrectly uses a segment override operator (semicolon) on an operand.

Possible causes

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

Example

_asm
{
  mov    AX, [BX:ES]        //Error
  mov    AX, ES:[BX]        //OK
}


Compiler Error C2423

'number' : illegal scale

Inline assembly code uses a number other than 1, 2, 4, or 8 to scale a register.

Example

_asm
{
  lea    EAX, [EAX*3]            //Error
  lea    EAX, [EAX+EAX*2]        //OK
}


Compiler Error C2424

'token' : improper expression in 'context'

The token forms part of an incorrect expression in this context.


Compiler Error C2425

'token' :non-constant expression in 'context'

The token forms part of a nonconstant expression in this context. The following sample generates C2425:

main() {
   int i = 3;
   __asm   {
      mov     eax,    [ebp - i]   // C2425
      // try..
      // mov eax, [ebp - 3]
        }
}


Compiler Error C2426

'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

'identifier' : jump referencing label is out of range

A branch to the specified label contains code that cannot be jumped over.

Example

        jz label1
        inc EAX

label1: inc ECX

In this example, you can fix the error by removing extra code between the branch and the label or by inverting the jump:

        jnz label2
        jmp label1
label2: inc EAX

label1: inc ECX


Compiler Error C2428

'operation' : not allowed on operand of type 'bool'

You cannot apply a decrement operator to objects of type bool.

Example

void g(bool fFlag) {
   --fFlag;   //Error
   fFlag--;   //Error
}


Compiler Error C2429

'label' : illegal far label reference

You cannot use FAR PTR on jumps or calls to labels. Far references to functions are allowed only if the function has been declared.


Compiler Error C2430

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

_asm mov eax, [ebx*2+ecx*4]


Compiler Error C2431

illegal index register in 'identifier'

The ESP register is scaled or used as both index and base register. The SIB encoding for the 80386 processor does not allow either.

Example

_asm mov ax, [ESI+2*ESP]
_asm mov ax, [esp+esp]


Compiler Error C2432

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.

Example

_asm mov eax, DWORD PTR [bx]


Compiler Error C2433

'identifier' : 'modifier' not permitted on data declarations

The friend, virtual, and inline modifiers cannot be used for data declarations. The following sample generates C2433:

class A {
   virtual static int b;   // C2433, remove virtual to resolve the error
};

void main() {
}


Compiler Error C2434

'identifier' : cannot convert default argument from 'type1' to 'type2'

A default parameter could not be converted to the type specified in the formal parameter list. If you encounter this error on code that compiled with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++ for more information.

Possible cause

  • Incorrect function prototype.
  • Wrong value for a default parameter. (Define a conversion operator or a constructor that takes a single parameter of the same type as the specified default parameter.)

Example

class A
{
public:
   int i;
} a;
class B
{
public:
   operator int() { return i; }    // conversion operator
   int i;
} b;
void func1( int j = a ) {}  // error, can't convert a to int
void func2( int j = b ) {}  // OK

If the conversion operator in A is supplied, there is no error.


Compiler Error C2435

'identifier' : function called before default arguments were resolved

The function is declared or defined with default arguments, but called before the default arguments are defined.

Example

class C
{
public:
   void a(void)
   {
      b();                   // error caught here
   }
   void b(void* ptr = sp);   // move this line above the definition
   static void *sp;          // a() to avoid error
};


Compiler Error C2436

'identifier' : member function or nested class in constructor initializer list

Member functions or local classes in the constructor initializer list cannot be initialized.

Example

struct S{
   int f();
   struct Inner{
      int I;
   };
   S():f(10), Inner(0){}   //Error
};


Compiler Error C2437

'identifier' : already initialized

An object can be initialized only once. The following sample generates C2437:

class A {
public:
   A(int i) {
   }
};

class B : A {
   B() : A(1), A(2) {   // C2437
   // try ..
   // B() : A(1) {
   }
};

void main() {
}


Compiler Error C2438

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

Example

class X   // correct
{
public:
   static const int i;
   static int j;
};
const int X::i = 1;
int X::j = 2;


Compiler Error C2439

'identifier' : member could not be initialized

A class, structure, or union member cannot be initialized.

Possible cause

  • Trying to initialize an indirect base class or structure.
  • 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

'conversion' : cannot convert from 'type1' to 'type2'

The compiler cannot cast from ‘type1’ to ‘type2’. Several situations can generate C2440.

class CMyClass {
public:
   explicit CMyClass( int iBar)
      throw()   {
      }
   };

void main() {

   CMyClass myclass = 2; // conversion required
   // try the following
   // CMyClass myclass(2);
   // or
   // CMyClass myclass = (CMyClass)2;

   int *i;
   float j;
   j = (float)i; // cannot cast from pointer to int to float
}

If you encounter this error on code that compiled with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++.


Compiler Error C2443

operand size conflict

The instruction requires operands to be the same size.

Example

short var;
void main()
{
   __asm xchg ax,bl            // error
   __asm mov al,red            // error
   __asm mov al,BYTE PTR var   // OK
}


Compiler Error C2444

'identifier' : used ANSI prototype, found 'type', expected '{' or ';'

The function prototype is followed by a type.

Possible cause

  • Missing semicolon.


Compiler Error C2446

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

If you encounter this error on code that was compiled with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++.

Example

The following code has two conversion problems:

  1. Converting an int to a pointer to char has no meaning.
  2. Converting a pointer to a const object into a pointer to a non-const object is not allowed, since it would enable you to modify the const object, violating the semantics of const.
    int i;
char *p;
int *j;
const int *cj;

void main()
{
   p = i;  // ERROR #1: conversion has no meaning
   j = cj; // ERROR #2: pointer to const obj
}


Compiler Error C2447

'{' : missing function header (old-style formal list?)

An open brace occurs at global scope without a corresponding function header.

Possible cause

  • Old-style C-language formal list.

Example

int c;
{}       // error


Compiler Error C2448

'identifier' : function-style initializer appears to be a function definition

The function definition is incorrect.

Possible cause

  • Old-style C-language formal list.

Example

void func(c)
   int c;
{}             // error


Compiler Error C2449

found '{' at file scope (missing function header?)

An open brace occurs at file scope.

Possible cause

  • A semicolon between a function header and the opening brace of the function definition.

Example

int __stdcall func(void);  // extra semicolon on this line
{                         // error detected here


Compiler Error C2450

switch expression of type 'type' is illegal

The switch expression evaluates to an illegal 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.

Example

class X
{
public:
   int i;
} x;
class Y
{
public:
   int i;
   operator int() { return i; }  // conversion operator
} y;
void main()
{
   int j = 1;
   switch ( x )              // error, x is not type int
   {
 default:  ;
   }
   switch ( y )              // OK
   {
 default:  ;
   }
}


Compiler Error C2451

conditional expression of type 'type' is illegal

The conditional expression evaluates to an integer type. The following sample generates C2451:

class B {
};

main() {
   B b1;
   int i = 0;
   if (b1)   // C2451
      ;
   /*
   // try
   // if (i)
      ;
   */
}


Compiler Error C2452

array bound expression of type 'type' is illegal

An array is declared with a bound expression that cannot be converted to type int.

Example

class C { int a; } aC;
class D { public: int a; operator int() { return a; } } aD;
class E { public: double a; operator double() { return a; } } aE;
int (*pf)();

void func()
{
   char *buf;
   int *pi;

   buf = new char[aC];  // error, no conversion from C to int
   buf = new char[pi];  // error, int * is illegal type for array bound
   buf = new char[pf];  // error, int (*)() is illegal for array bound
   buf = new char[10L]; // OK
   buf = new char[aD];  // OK, conversion by D::operator int()
   buf = new char[aE];  // OK, conversion by E::operator double()
}


Compiler Error C2453

array bound expression uses function name

An array is declared with a bound expression that is a function name. Array bounds must be a type that can be converted to type int.

Example

int func();

void bunc()
{
    char *buf;

    buf = new char[10];     // OK
    buf = new char[func];   // error, array bound is function name
    buf = new char[bunc];   // error
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2454

improper operand type for processor

The operand is not valid for the target processor.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2455

improper operand type in instruction

The instruction contains an invalid operand type.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2456

illegal opcode for processor

The opcode is not valid for the target processor.


Compiler Error C2457

'macro': predefined macro cannot appear outside of a function body

You attempted to use a predefined macro, such as __FUNCTION__, in a global space. The following sample generates C2457:

#include <stdio.h>
__FUNCTION__;   // C2457, cannot be global

void main() {
   // try ...
   // printf("\n%s",__FUNCTION__);
}


Compiler Error C2458

'identifier' : redefinition within definition

A class, structure, union, or enumeration is redefined in its own declaration.

Example

class C
{
    enum i { C };   // error
};


Compiler Error C2459

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

Example

class C
{
    union { int C; };   // error
};


Compiler Error C2460

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

Example

class C
{
   C aC;    // error
};


Compiler Error C2461

'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. (The list can be null.)

Add a pair of parentheses after class::class.

Example

class C
{
    C::C;        // error
    C::C();      // OK
};


Compiler Error C2462

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

Example

void main()
{
    new struct S { int i; };     // error
}


Compiler Error C2463

cannot define an anonymous type in a 'new-expression'

You cannot define an anonymous type in the operand field of the new operator. Create a named type definition in a separate statement, then use the new operator.

Example

void main()
{
    new struct { int x; };  // error
}


Compiler Error C2464

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

Example

void main()
{
    new ( int& ir );   // error
}


Compiler Error C2465

cannot define an anonymous type inside parentheses

An anonymous structure, union, or enumerated type is defined inside a parenthetical expression. This is illegal in C++ because the definition is meaningless in function scope.


Compiler Error C2466

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

Example

int *p = new X[0];        // error
C *aC = new [int_var] C;  // error
int[0]                    // error


Compiler Error C2467

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.

Example

int main()
{
   struct X
   {
      union { int i; };  // error, nested declaration
   };
   return 0;
}


Compiler Error C2468

'new' : cannot allocate 'const'/'volatile' objects (type is 'type')

The new operator is incorrectly used to create a const or volatile object.

Example

void main(void)
{
   new int * const;       // error
   new int * volatile;    // error
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2469

‘operator’: cannot allocate ‘type’ object

Example

int *i = new void;


Compiler Error C2470

'function' : looks like a function definition, but there is no formal parameter list; skipping apparent body

A function definition is missing its argument list. The following sample generates C2470:

int MyFunc {
// ...
};

void main(){
MyFunc();
}

This error may also be issued on a brace-enclosed initialization that is missing an =.

int arr[] { 1, 2, 3, 4, 5 };

Instead, you should use:

int arr[] = { 1, 2, 3, 4, 5 };


Compiler Error C2471

cannot update program database 'file'

The compiler cannot write to the database file.

Possible causes

  • Insufficient disk space.
  • Volume is read-only.
  • Sharing violation.


Compiler Error C2475

'member_name' : forming a pointer-to-member requires explicit use of the address-of operator (‘&’) and a qualified name

Accessing a member of a class from outside the class requires the scope resolution operator (::) and the address of (&) operator. The following sample generates C2475:

#include <stdio.h>

struct A {
   void f() {
      printf("test");
   }
   void g();
};

void A::g() {
   void (A::*p1)() = f;      // ok in -Ze; error in -Za (C2475)
   void (A::*p5)() = this->f;   // error: C2475

   // the following line shows how to call a function from outside the class
   // void (A::*p4)() = &A::f;
}

int main() {
   A *ap = new A;
   A a;
   void (A::*p5)() = a.f;       // error: C2475

   // the following line shows how to call a function from outside the class
   void (A::*p4)() = &A::f;

   // the following line shows how to call a member function
   (ap->*p4)();
   return 0;
}


Compiler Error C2479

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

#pragma section("mycode", read)
__declspec(allocate("mycode"))  int i = 0;   // proper use of allocate
static __declspec(allocate("mycode")) void DoNothing() {   // C2479
}

void main() {
}


Compiler Error C2480

'identifier' : 'thread' is only valid for data items of static extent

You cannot use the thread attribute with an automatic variable, nonstatic data member, or function parameter. Use the thread attribute for global variables, static data members, and local static variables only.


Compiler Error C2481

'identifier1' : cannot be initialized using address of 'thread' variable 'identifier2'

The address of variable identifier2 is a dynamic value that can be determined only in the context of a particular thread. Because it is not static, it cannot be used to initialize identifier1.


Compiler Error C2482

'identifier' : dynamic initialization of 'thread' data not allowed

Variables declared with the thread attribute cannot be initialized with an expression that requires run-time evaluation. A static expression is required to initialize thread data.


Compiler Error C2483

'identifier' : object with constructor cannot be declared 'thread'

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.


Compiler Error C2484

'identifier' : attribute 'attribute' doesn't match previous declaration

The identifier is already declared with a different attribute.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2485

'identifier' : unrecognized extended attribute

The declaration attribute is not valid.


Compiler Error C2486

'__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:

void __declspec(naked) main() {
// try ...
// void __declspec(naked) main() {
   __asm {
      mov     eax,    __LOCAL_SIZE   // C2486
   }
}


Compiler Error C2487

'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

'identifier' : 'naked' can only be applied to non-member function definitions

The naked attribute was applied to a function declaration.

Example

__declspec( naked )  int func();  // error, declaration, not definition
__declspec( naked ) int i;        // error, i is not a function


Compiler Error C2489

'identifier' : initialized auto or register variable not allowed at function scope in 'naked' function

Example

__declspec( naked ) int func()
{
   int i = 1;            // error
   register int j = 1;   // error
}


Compiler Error C2490

'keyword' not allowed in function with 'naked' attribute

A function defined as naked cannot use structured exception handling.

Example

__declspec( naked ) int func()
{
   __try{}     // error, structured exception handling
}


Compiler Error C2491

'identifier' : definition of dllimport identifier not allowed

Data, static data members, and functions can be declared as dllimports but not defined as dllimports. The following sample generates C2491:

// function definition
void __declspec(dllimport) funcB() {   // C2491
}

// function declaration
void __declspec(dllimport) funcB();      // ok

void main() {
}


Compiler Error C2492

'variable' : 'thread' data may not have dll interface

The variable is declared with the thread attribute and with 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:

class C {
public:
   char   ch;
};

__declspec(dllexport) __declspec(thread) C c_1;   // C2492
// try ...
// __declspec(thread) C c_1;

void main() {
}


Compiler Error C2493

illegal form of __based

A __based expression must be based on a pointer.

Example

char * mybase;
int __based(mybase) * ptr; // correct


Compiler Error C2494

'keyword' may not appear in termination block

You cannot use keyword in a __finally block.


Compiler Error C2495

'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 code generates this error.

Example

__declspec(nothrow) class X {
   int m_data;
} x;


Compiler Error C2496

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

Example

// OK
__declspec(selectany) int x1 = 1;

// error - x2 is not externally visible
const __declspec(selectany) int x2 = 2;

// OK
extern const __declspec(selectany) int x3 = 3;

// OK
__declspec(selectany) int x4;

// OK .. dynamic initialization of x5
int f();
__declspec(selectany) int x5 = f();

// error - x6 is not externally visible
static __declspec(selectany) int x6 = 6;

extern const int x7;
// OK - redeclaration of x7 that is extern
const __declspec(selectany) int x7 = 7;


Compiler Error C2498

'function' 'novtable' can only be applied to class declarations

Possible cause

  • Using __declspec(novtable) with a function.

Example

void __declspec(novtable) f() { } // error


Compiler Error C2499

'class' : a class cannot be its own base class

You attempted to specify the class that you are defining as a base class.

For example:

// compile with cl /c
//
class CMyClass : public CMyClass {
};


Compiler Error C2500

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

Example

class A { };
class B : public A, public A { };    // error
class C : public A { };
class D : public A { };
class E : public C, public D { };    // OK, contains two As


Compiler Error C2501

'identifier' : missing storage-class or type specifiers

The identifier is declared without specifying its type.

Possible causes

  • Spelling or capitalization error.
  • Missing type specifier in the declaration of the identifier.

Example

// Header file for the CUndeclared has been omitted:
class CMyClass {
private:
   CUndeclared m_myClass;  // Error: Class unknown
} ;


Compiler Error C2502

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

Example

class A { };
class B { };
class C : private public A { };     // error
class D : private A { };            // OK
class E : public A, private B { };  // OK


Compiler Error C2503

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

class A {
   public:
   int array [];
   // try ...
   // int array [10];
};

class B:A {   // C2503
   int i;
};

int main() {
}


Compiler Error C2504

'class' : base class undefined

The base class is declared but never defined.

Possible cause

  • Missing include file.
  • External base class not declared with extern.

Example

class A;                 // error, A is undefined
class A {};              // OK, A is defined
class B : public A {};   // the error is detected here


Compiler Error C2505

'identifier' : is not a legal base class

The identifier is not a class or structure but was used to derive a class.

Possible cause

  • Variable or type name in the base class list.

Example

class B { };
class D : public B { };  // OK, D is derived from B
typedef int I;
class E : public I { };  //  error, I is not a class


Compiler Error C2506

'class::identifier' : ambiguous

The name refers to more than one class member. An expression used to access a base class or structure must refer to a unique function, object, type, or enumerator. The scope-resolution operator (::) can be used to resolve the ambiguity.

Ambiguity is checked before access control. A private base class containing only private members can cause ambiguity as well as a public class.

Example

class A
{
public:
   int a;
};
class B
{
private:
   int a;
};
class C : public A, private B { };
C c;
int j = c.a;          // error, could be A::a or B::a
int i = c.A::a;       // OK, resolved ambiguity


Compiler Error C2507

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

Example

class A {};
class B : virtual virtual public A {}; // error
class C : virtual public A {};         // OK


Compiler Error C2508

'identifier' : access denied

A nonpublic class member cannot be accessed. A private or protected class, structure, or union member can be accessed only by members of that class.


Compiler Error C2509

'identifier' : member function not declared in 'class'

The function is not declared in the specified class.

Possible cause

  • Specifying the wrong class when calling the function.


Compiler Error C2510

'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

'identifier' : overloaded member function not found in 'class'

No version of the function is declared with the specified parameters.

Possible causes

  • Wrong parameters passed to function.
  • Parameters passed in wrong order.
  • Incorrect spelling of parameter names.

The following sample generates C2511:

class C {
   int c_2;
   int Func(char *, char *);
};

int C::Func(char *, char *, int i) {   // C2511
// try ...
// int C::Func(char *, char *) {
   return 0;
}

void main() {
}


Compiler Error C2512

'identifier' : no appropriate default constructor available

No default constructor is available for the specified class, structure, or union. The compiler supplies a default constructor if user-defined constructors are not provided. If you provide a constructor that takes a nonvoid parameter, you must also provide a default constructor. The default constructor can be a constructor with default values for all parameters.

The following sample generates C2512:

class B {
public:
   B (char *);
   /* add the folling constructor
    B() {
   };
   */
};

void main() {
   B b;   // C2512
}


Compiler Error C2513

'type' : no variable declared before '='

The type specifier appears in declaration with no variable identifier. The following sample generates C2513:

void main() {
   int = 9;     // C2513
   // try ...
   // int i = 9;
}


Compiler Error C2514

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


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2515

'identifier' : not in class 'class'

The identifier is not a member of the class.


Compiler Error C2516

'name' : is not a legal base class

The class is derived from a type name defined by a typedef statement.

Example

typedef   unsigned long ulong;
class C   : public ulong {}; // error


Compiler Error C2517

'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

keyword 'keyword' illegal in base class list; ignored

The keywords class and struct should not appear in a base class list.

Example

class B {};
class C   : public class B {}; // error
class C   : public B {};       // OK


Compiler Error C2519

cannot convert 'Type1 *' to 'Type2 *'

Type1 does not derive from type2, so implicit conversion is impossible. Pointers cannot generally be converted implicitly from one type to another. Conversion to void* is possible if the size of void is greater than the size of the original pointer.

Possible solution

  • Explicit conversion.


Compiler Error C2520

conversion from unsigned __int64 to double not implemented, use signed __int64

See int64 or data type ranges.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2521

destructors do not take arguments

You attempted to use arguments with a destructor.


Compiler Error C2522

'name' : cannot be constructed because it cannot be destroyed in this context

This message is not used.


Compiler Error C2523

'class::~identifier' : destructor 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:

class A {
   ~B();   // C2523
   // the line below resolves the error
   // ~A();
};

void main() {
}


Compiler Error C2524

'destructor' : destructors must have a 'void' parameter list

The destructor had a parameter list that is not void. Other parameter types are not allowed. The following code reproduces C2524:

class A {

   A() {
   }

   ~A(int i) {
   // use the line below to resolve the error
   // ~A() {
   }

};


Compiler Error C2525

'identifier' : explicit destructor is named but not called

A member selection uses an explicit destructor without a function call operator (matched parentheses).

Example

struct C
{
   ~C();
};

void func( CpC )
{
   pC->~C;       // error
   pC->~C();     // OK
}


Compiler Error C2526

'identifier1' : C linkage function cannot return C++ class 'identifier2'

A function defined with C linkage cannot return a user-defined type.


Compiler Error C2527

'identifier' : array of references must be fully initialized

Elements of the specified array are not initialized. You must supply an initializer for every element in an array of references.

Example

int a, b, c;
int &ai[3];               // error, elements not initialized
int &ai[3] = { a, b, c }; // OK


Compiler Error C2528

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

int i;
int &ir = i;
int & (*irptr) = ir;   // C2528

main() {
}


Compiler Error C2529

'name' : reference to reference is illegal

Possible solution

  • Use pointer syntax and declare a reference to a pointer.

The following sample generates C2529:

int i;
int &ri = i;
int &(&rri) = ri;   // C2529

main() {
}


Compiler Error C2530

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

void main(){
   int i = 0;
   int &j;
   // try ...
   // int &j = i;
}


Compiler Error C2531

'identifier' : reference to a bit field illegal

References to bit fields are not allowed. The following sample generates C2531:

class P {
   int &b1 : 10;   // C2531, remove the & to resolve the error
};

void main() {
}


Compiler Error C2532

'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

'identifier' : constructors not allowed a return type

A constructor cannot a value or have a return type (not even a void return type).

Example

class X
{
public:
   void X( void ) { ... };  // error, return type declared
   X( void ) { ... };       // OK, no return type declared
};


Compiler Error C2534

'identifier' : constructor cannot return a value

A constructor cannot return a value or have a return type (not even a void return type).

Possible solution

  • Remove the return statement from the constructor definition.

The following sample generates C2534:

class A {
public:
   int i;
   A() {
      i = 1;
      return i;   // C2534, remove the return to resolve the error
   }
};

void main() {
}


Compiler Error C2535

'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 are compiling an ATL project, see Knowledge Base article Q241852.

The following sample generates C2535:

class C {
public:
   void func();   // forward declaration
   void func() {   // C2535, delete the forward declaration to resolve
   }
};

void main() {
}


Compiler Error C2536

'class::identifier' : cannot specify explicit initializer for arrays

A member of a class, structure, or union could not be initialized.

Possible causes

  • A constructor is not available to initialize one or more members of an array. If the size of the array is greater than the number of initializers, a default constructor must be defined.
  • A nonstatic array declared with the const specifier. This kind of array cannot be explicitly initialized.

The following sample generates C2536:

class C {
   int i;
   int j;
   int k;
};

class D   {
   C aC[5];
   D() : aC(1,2,3,4,5) {   // C2536
   // try ...
   // D() {
   }
};

void main() {
}


Compiler Error C2537

'specifier' : illegal linkage specification

Possible causes

  • The linkage specifier is not supported. Only the "C" linkage specifier is supported.
  • "C" linkage is specified for more than one function in a set of overloaded functions. This is not allowed.

The following sample generates C2537:

extern "c" void func(); // C2537
// try ...
// extern "C" void func();

void main() {
}


Compiler Error C2538

new : cannot specify initializer for arrays

An initializer is given for an array created with the new operator. The new operator creates arrays of objects by calling the default constructor for each element of the array. The elements of the array cannot be initialized to distinct values.


Compiler Error C2539

new : 'class' : no default constructor to initialize arrays of objects

Initializing an array of objects requires a default constructor (a constructor with no parameters), which is called separately for each object in the array. The constructor was not available. If any constructor is defined, the compiler does not generate a default constructor and you must supply one.


Compiler Error C2540

non-constant expression as array bound

An array must have a constant bound.

Example

int i;
int A[i];        // error, i is nonconstant
const j = 20;
int A[j];        // OK, j is constant
int B[32];       // OK, 32 is a literal


Compiler Error C2541

'delete' : delete : cannot delete objects that are not pointers

The delete operator was used on an object that is not a pointer.

Example

void main()
{
   int i;
   delete i;            // error, i is not a pointer
   intip = new int;
   delete ip;           // OK
}


Compiler Error C2542

'identifier' : class object has no constructor for initialization

There is no constructor with a parameter list that matches the initialization.

Possible cause

  • Incorrect parameters in initialization.


Compiler Error C2543

expected ']' for operator '[]'

The subscripting operator is missing a left bracket.

Possible cause

  • Macro expansion.


Compiler Error C2544

expected ')' for operator '()'

The function call operator is missing a left parenthesis.

Possible cause

  • Macro expansion.


Compiler Error C2545

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

Possible cause

  • Operands have incorrect type.

Possible solution

  • Define a conversion operator or constructor that takes a single parameter.


Compiler Error C2546

'operator' : illegal mix of 'void' pointer with pointer to type

The operator is called with incompatible pointer types.

Possible cause

  • Arithmetic operator used on a void pointer. Pointer arithmetic requires pointers to objects. If you must use the operator with a void pointer, you must overload the operator or cast the void pointer to a type accepted by the operator.


Compiler Error C2547

illegal cast of overloaded function

A pointer to a function is converted to an overloaded type. This is not allowed.

Example

int func();
int func( int );
( int (*)() )func;      // error, func is overloaded
int func2();
( void (*)() )func2;    // OK, func2 is not overloaded


Compiler Error C2548

'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

void func( int = 1, int, int = 3);  // error
void func( int, int, int = 3);      // OK
void func( int, int = 2, int = 3);  // OK


Compiler Error C2549

user-defined conversion cannot specify a return type

Example

class X
{
public:
   int operator int() { return value; }   // error
   operator int() { return value; }       // OK
private:
   int value;
};


Compiler Error C2550

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

Example

class C
{
public:
   C();
};

class D : public C
{
public:
   D();
   void func();
};

void D::func() : C() {}  // error
D::D() : C() {}          // OK


Compiler Error C2551

'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

'identifier' : non-aggregates cannot be initialized with initializer list

The aggregate identifier was incorrectly initialized.

Aggregates are defined as follows:

  • Arrays.
  • Classes, structures, and unions that do not have constructors, private or protected members, base classes, or virtual functions.

In addition, Visual C++ does not allow data types in an aggregate that themselves contain constructors.

The following code generates error C255:

#include <string>
#include <iostream>
using namespace std;

struct Pair {
string name;   // could use char * name
   double val;
};

int main() {
string s("Test");
// could use
// char* s = new char[5];
// strcpy(s, "Test");

Pair p = { s, 0 };

return 0;
}


Compiler Error C2553

no legal conversion of return value to return type 'type'

The return value cannot be converted to the required type. If encounter this error on code that compiled correctly with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++.

Possible solution

  • Supply a user-defined conversion operator to cast the return value.

The following sample generates C2553:

struct X {
private:
   X(const X&) {
   }
};

struct Y : X {
};

Y retY(Y y) {   // C2553
// try ...
// Y* retY(Y *y) {
   return y;
}

void main() {
}


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2554

'name' : __based is illegal on references to functions

This message is not used.


Compiler Error C2555

'function1' of 'class1' : overriding virtual function differs from 'class2::function2' only by return type or calling convention

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.

Possible solution

  • Cast the return value after the virtual function has been called.

For more information on C2555, see Knowledge Base article Q240862.

Example

struct X
{
   virtual void func();
};
struct Y : X
{
   char func();  // error
};

Visual C++ does not support overriding a virtual function with a return type that differs in any way from the overridden function. The Visual C++ compiler does not support covariant return types. For example, the following two examples are not allowed in Visual C++,

// Example 1
class A {
public:
   virtual A* func();
};

class B : public A {
public:
   virtual B* func();
};

//Example 2
class C {
public:
   virtual A* func();
};
class D : public C {
public:
   virtual B* func();
};

You can mimic the behavior with a run-time performance loss by:

  1. Enable RTTI (/GR)
  2. Derive from a common base for the return type.
  3. Return the correct class type; do not use c-style cast or reinterpret_cast.
  4. Caller uses dynamic_cast to cast to the correct class
// Example 3
class X {};
class A : public X {
public:
   virtual X* func() { return new A; }
};
class B : public A {
public:
   virtual X* func() { return new B; }
};
void test() {
   X* p;
   A a, *pa;
   B b, *pb;
   p = a.func();
   pa = dynamic_cast<A*>(p);
   if (pa == 0) { /* error */ }
   p = b.func();
   pb = dynamic_cast<B*>(p);
   if (pb == 0) { /* error */ }
}


Compiler Error C2556

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

class C {
   int    func();   // first declaratioin
   double   func();   // C2556
   int func(int i);   // ok, parameter lists differ
};

void main() {
}


Compiler Error C2557

'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

'identifier' : no copy constructor available

A copy constructor initializes an object from another object of the same type. (It makes a copy of the object.) compiler generates a default copy constructor if you do not define any constructors.

Possible cause

  • Trying to copy a class whose copy constructor is with a private. In most cases, a class with 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 properly.

Possible solution

  • If you determine that it is safe to use a class with a private copy constructor, derive a new class from the class with the a private constructor and make a public or protected copy constructor available in the new class. Use the derived class in place of the original.

See Also

Compiler Errors when Implementing a CObject-Derived Class.


Compiler Error C2559

'identifier' : no match for specified operator

The new operator tried to call the constructor for identifier, but no constructor corresponded to the given ambient memory model or distance. Check that an appropriate constructor has been defined for each memory model and distance used.


Compiler Error C2560

'function' : overloaded function differs only by calling convention/memory model

Declarations of the overloaded function did not specify different formal parameter types. Overloaded functions cannot differ by calling convention or memory model alone.

Example

void _cdecl  func();
void _pascal func();       // error
void _pascal func( int );  // OK


Compiler Error C2561

'identifier' : function must return a value

The function was declared as returning a value, but the function definition does not contain a return statement.

Possible cause

  • Incorrect function prototype.

Possible solutions

  • If the function does not return a value, declare the function with return type void.
  • Check that all possible branches of the function return a value of the type declared in the prototype.
  • 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.

Example

The following sample generates C2561:

int test_1(int x) {

   if (x) {
//      test_2();
      return;   // C2561
   }
else
  return;   // C2561
}

void main(){}


Compiler Error C2562

'identifier' : 'void' function returning a value

The function is declared as void but returns a value.

Possible cause

  • Incorrect function prototype.

Possible solutions

  • Specify the return type in the function declaration.

The following sample generates C2562:

void testfunc() {
   int i;
   return i;   // C2562, delete the return to resolve the error
}

int main() {
}


Compiler Error C2563

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.

Example

void func( int );
void func( int, int );
main()
{
   void *fp();
   fp = func;                // error
   fp = func( int, int );    // OK
}


Compiler Error C2564

'type' : a function-style conversion to a built-in type can only take one argument

Function-style type casts of built-in types take a single argument.

Example

void g(float f, double d) {
   int j=int(f, d);   //error
}


Compiler Error C2565

'::identifier' was previously declared as a global function

The member function has the same name as a function declared earlier with global scope.


Compiler Error C2566

overloaded function in conditional expression

An overloaded function in a conditional expression cannot be evaluated.

Example

int f( int );
int f( double );
void main()
{
   if( f );      // error, which f?
   if( f(1) );   // OK
}


Compiler Error C2567

'identifier' : intrinsic function must have prototype when using C++

The intrinsic function is not prototyped.

Example

#include <string.h>
#pragma intrinsic( abs )     // error, no prototype for abs()
#pragma intrinsic( strcpy )  // OK, prototyped in string.h


Compiler Error C2568

'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

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

union ubase {
};

class cHasPubUBase : public ubase {   // C2569
// try ...
// class cHasPubUBase {
};

void main() {
}


Compiler Error C2570

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

class base {
};

union hasPubBase : public base {   // C2570
// try ...
// union hasPubBase {
};

void main() {
}


Compiler Error C2571

'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 solutions

  • Change the union to a class or structure.
  • Make the function nonvirtual.

The following sample generates C2571:

union A {
   virtual void func1();   // C2571, remove virtual to resolve the error
};

void main() {
}


Compiler Error C2572

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

void f(int i = 1);   // function declaration

// function definition
void f(int i = 1) {   // C2572
// try ...
// void f(int i) {
}

void main() {
}


Compiler Error C2573

'identifier' : simple type cast must have exactly one expression

The conversion has the wrong number of actual parameters.

Example

void func() {
  int i = int();     // error, no actual parameters
  int j = int( 1.0 ) // OK
}


Compiler Error C2574

'destructor' : constructors and destructors cannot be declared static

Neither destructors nor constructors can be declared static. The following sample generates C2574:

class A {
   virtual static ~A();   // C2574, remove static to resolve error
};

void main() {
}


Compiler Error C2575

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

virtual void func() {   // C2575, remove virtual to resolve error
}

void main() {
}


Compiler Error C2576

'identifier' : virtual used for static member function

A static member function is declared as virtual. The object that calls a function must determine which virtual function is used. This is not possible for static functions, so they cannot be declared virtual.

The following sample generates C2576:

struct X {
   static virtual void func() {   // C2576, remove virtual to resolve error
   }
};

void main() {
}


Compiler Error C2577

'destructor' : destructor cannot return a value

A destructor cannot return a value of void or any other type. Remove the return statement from the destructor definition.

The following sample generates C2577:

class A {
   public:
      A() {
}
      ~A() {
         return 0;   // C2577, remove to resolve the error
      }
};

void main() {
}


Compiler Error C2578

'function' : static member function cannot hide interface method

Overloaded methods cannot contain matching signatures and differ only by the static keyword.

The following sample generates C2578:

#using <mscorlib.dll>
__gc __interface IFace {
   public:
   void Test();
};

__gc class CMyClass : public IFace {
   public:
   static void Test()   {   // C2578 hides IFace::Test
   }
};

void main(){
}


Compiler Error C2579

'class::function(params)' : parameter list not sufficiently different from 'class::function(params)'

The formal parameter lists of overloaded functions must be distinct.


Compiler Error C2580

redefinition of class name 'identifier'

A class, structure, or union is defined more than once. The following sample generates C2580:

class C {
   C::C;   // C2580, remove to resolve the error
};

void main() {
}


Compiler Error C2581

'identifier' : static 'operator =' function is illegal

The assignment (=) operator is incorrectly declared as static. Assignment operators cannot be static.


Compiler Error C2582

'operator =' function is unavailable in 'class'

No assignment (=) operator is defined for the class. If you define any assignment operator that takes the class as a parameter, the compiler cannot generate a default assignment operator for that class.

Assignment operators are not inherited by derived classes. You must explicitly define an assignment operator for each class.

The following sample generates C2582:

class A {
   private:
        A& operator=(const A& a){}
};

class B : public A {
   public:
      // try the following line to resolve the error
      // void operator=(const B& b){}
};

void main() {
   B b1;
   B b2;
   b1 = b2;   // C2582
}

See also

Compiler Errors when Implementing a CObject-Derived Class.


Compiler Error C2583

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

class A {
   public:
      int i;
      A() const;   // C2583, remove const to resolve
};

void main() {
}


Compiler Error C2584

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

The following sample generates C2584:

struct A1 {
   virtual int foo();
};

struct A2 {
    virtual int foo();
};

struct B1: public virtual A1, virtual A2 {
    virtual int foo();
};

struct B2: public virtual A2, virtual A1 {
    virtual int foo();//{return 1;};
};

struct C: virtual B1, B2 {
    virtual int foo();
};

struct Z : virtual B2, virtual C  {   // remove virtual B2 to resolve this C2584
    virtual int foo();
};

void main(){
}


Compiler Error C2585

explicit conversion to 'type' is ambiguous

The type conversion can produce more than one result. If you encounter this error on code that compiled successfully with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++.

Possible causes

  • 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.
  • A conversion operator and a constructor have been defined making the same conversion.


Compiler Error C2586

incorrect user-defined conversion syntax : illegal indirections

Indirection of a conversion operator is not allowed.

Example

class C
{
   operator int();   // error, indirection on the operator
};

typedef int pINT_t;
class D
{
   operator pINT_t();  // correct
};


Compiler Error C2587

'identifier' : illegal use of local variable as default parameter

Local variables are not allowed as default parameters.

Example

int i;
void func();
{
   int j;
   extern void func2( int k = j );  // error, local variable
   extern void func2( int k = i );  // OK
}


Compiler Error C2588

'::~identifier' : illegal global destructor

The destructor is defined for something other than a class, structure, or union. This is not allowed.

Possible causes

  • Missing class, structure, or union name on the left side of the scope resolution (::) operator.

Example

~F();  // error


Compiler Error C2589

'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 following sample generates C2589:

class A {
};

void operator :: ();   // C2589

void main() {
}


Compiler Error C2590

'identifier' : ambiguous user-defined conversions in switch expression

The specified switch expression cannot be unambiguously converted to an integer type.

Possible cause

  • A conversion operator and a constructor make the same conversion.


Compiler Error C2591

'identifier' : ambiguous user-defined conversions in conditional expression

A conditional expression could not be unambiguously converted to an integer type.

Possible cause

  • A conversion operator and a constructor make the same conversion.


Compiler Error C2592

no legal conversion of initialization expression to type 'type'

If you encounter this error on code that compiled successfully with an earlier version of Visual C++, see Technote: Improved Conformance to ANSI C++.

Possible solution

  • Supply a conversion operator to make the required cast.


Compiler Error C2593

'operator identifier' is ambiguous

More than one possible operator is defined for an overloaded operator.

Possible solution

  • Use an explicit cast on one or more actual parameters.

Example

struct A {};
struct B : A {};
struct X {};
struct D : B, X {};
void operator+( X, X );
void operator+( A, B );
D d;
void main()
{
   d +  d;         // error, D has an A, B, and X
   (X)d + (X)d;    // OK, uses operator+( X, X )
}

Possible cause

  • 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 CArchive's member function CArchive::Write().

    The following example shows how to archive a floating-point variable (f) to archive ar:

    ar.Write(&f, sizeof( float ));


Compiler Error C2594

'operator' : ambiguous conversions from 'type1' to 'type2'

No conversion from type1 to type2 was more direct than any other. One possible solution is to define or specify an explicit conversion.

The following sample generates C2594:

// compile with /c
struct A{};
struct I1 : A {};
struct I2 : A {};
struct D : I1, I2 {};

A *f (D *p) {
return (A*) (p);   // C2594
// return reinterpret_cast<A*> (p);   // try this instead
}


Compiler Error C2595

'identifier' : qualified name already has a constructor

A constructor was already defined for the nested class, structure, or union. Only one constructor is allowed.


Compiler Error C2596

'identifier' : qualified name already has a destructor

A destructor was already defined for the nested class, structure, or union. Only one destructor is allowed.


Compiler Error C2597

illegal reference to non-static member 'identifier'

Possible causes

  • A nonstatic member is specified in a static member function. To access the nonstatic member, you must create an instance of the class and use a member-access operator (. or ->).
  • The specified identifier is not a member of a class, structure, or union.
  • A member access operator refers to a nonmember function.

Example

struct s1 {  // in cpp file
   static void   func();
   int   i;
};

void s1::func()
{
   i = 1;   // error C2597 here
}


Compiler Error C2598

linkage specification must be at global scope

The linkage specifier is declared at local scope.

Example

void func()
{
   extern "C" int func2();   // error, linkage declared in
   .                         //   block at local scope
   .
   .
}
extern "C" int func( int i );  // OK


Compiler Error C2599

'function' : local functions are not supported

A function is defined inside the body of another function.

Possible cause

  • Missing closing curly brace in a function definition.

Example

void func1()
{
                  // Missing a closing curly brace here
void func2() {}   // Error detected on this line

void func3()
{
void func4() {}   // Error detected on this line
}                 // Local functions not allowed


Compiler Error C2600

'name' : uses 'identifier' in local class 'class' causing compiler-generated special member functions

The declaration of the member identifier caused the compiler to generate an assignment operator, default constructor, or other member function for the class. Because local classes cannot define member functions, an error results.

Members that are references or const can be initialized but cannot be assigned new values. They require the compiler to generate an assignment operator and a default constructor.

Example

void f()
{
   class C         // local class
   {
      const int i; // error: const member
   };

   C c;  // constructor needed to initialize c.i
}


Compiler Error C2601

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

Example

int main()
{
   int i = 0;

   int funcname(int j)  // error
   {
      j++;
      return j;
   }

   i = funcname(i);
   return 0;
}


Compiler Error C2602

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

Example

struct X
{
   int x;
};
struct A
{
   int a;
};
struct B : public A
{
   X::x;       // error, B is not derived from X
   A::a;       // OK
};


Compiler Error C2603

'function' : Too many block scope static objects with constructor/destructors in function

There is a limit of 31 on the number of static objects you can have in an externally visible inline function.

The following code generates C2603:

struct C { C() {} };
extern inline void f1() {
   static C C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C14,C15,C16;
   static C C17,C18,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32;
   static C C33;   // Comment this line out to avoid error
}


Compiler Error C2605

overloaded functions 'class::function' do not have same access

Overloaded functions named in an access declaration have different access levels (public, private, or protected). As a result, access levels cannot be adjusted.

Example

struct X
{
private:
   int f();
protected:
   int f(int);
public:
   int f(int,int);
};
struct A : public X
{
protected:
   X::f;       // error
public:
   X::f;       // error
};
struct B : protected X
{
protected:
   X::f;       // error
public:
   X::f;       // error
};
struct C : private X
{
protected:
   X::f;       // error
public:
   X::f;       // error
};


Compiler Error C2606

'class::identifier': illegal private access declaration

The public or protected part of a derived class can adjust access to a member of a base class. The private part cannot.

Example

struct X
{
private:
   int priv;
protected:
   int prot;
public:
   int pub;
};
struct A : public X
{
private:
   X::priv;    // error
   X::prot;    // error
   X::pub;     // error
};
struct B : protected X
{
private:
   X::priv;    // error
   X::prot;    // error
   X::pub;     // error
};
struct C : private X
{
private:
   X::priv;    // error
   X::prot;    // error
   X::pub;     // error
};


Compiler Error C2607

'identifier' : cannot implicitly convert a 'type1' to a 'type2' that is not const

In C++, you can create a reference to another object by initializing the reference using the & operator. You can modify the original object by changing the reference object. This is similar to modifying a variable through a pointer in C, but you do not need to dereference the pointer. If you try to initialize a reference to an object of another type (an int reference to a float variable, for example), error C2607 results.

The reference to type2 must be:

  • An l-value of type type2, or
  • A type derived from type2 for which type2 is an accessible base.

Example

float f;
int& ri2 = f; // error, f is not an int l-value


Compiler Error C2608

illegal reference cast - operand not an l-value

The reference cannot be cast because a temporary copy of the referenced value cannot be generated.

Example

struct C
{
   int mem;
   operator int();
};
struct D
{
   operator C();
   void memfunc();
};
D aD[10];
void D::memfunc()
{
   C aC = ( C& )( aD + 1 );   // error
}


Compiler Error C2609

'conversion' : cannot implicitly convert a non-lvalue 'type1' function return to a 'type2' that is not const

A reference cannot be initialized from a function return value that is not an l-value.

This is an error under ANSI compatibility (/Za) and a warning under Microsoft extensions (/Ze).

Example

struct X
{
    X( int );
};
X f();
X& r = f();   // error


Compiler Error C2610

identifier 'class' can never be instantiated; user-defined constructor is required

The class cannot be properly initialized because a constructor cannot be created for the class. Define a constructor.


Compiler Error C2611

'token' : illegal following '~' (expected identifier)

The token is not an identifier.

Example

class C
{
   C::~operator int();    // error
   ~C();                  // OK, destructor declaration
};


Compiler Error C2612

trailing ',' illegal in base/member initializer list

A comma appears after the last base or member in an initializer list.

Example

class A
{
public:
   int i;
   A( int ia ) : i( ia ), {}; // error, extra comma
};
class B
{
public:
   int i;
   B( int ib ) : i( ib ) {};  // OK
};


Compiler Error C2613

trailing ',' illegal in base class list

A comma appears after the last base in a base class list.

Example

class A {};
class B : public A, {};  // error, extra comma
class C : public A {};   // OK


Compiler Error C2614

'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

class A
{
public:
   int i;
   A( int ia ) : B( i ) {};  // error, B is not a member of A
};


Compiler Error C2616

'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

'function' : inconsistent return statement

The specified function does not have a declared return type, and a previous return statement did not supply a value.

Example

int i;
func()                   // no return type prototype
{
   if( i ) return;       // no return value
   else return( 1 );     // error detected on this line
}


Compiler Error C2618

local classes cannot have base classes

A local class cannot have a base class, even if the base class itself has file scope.

Example

class A { };
void f()
{
    class B : public A {};   // error
}


Compiler Error C2619

union 'union' : cannot have static member variable 'identifier'

A union member is declared static.

Example

void func()
{
   union
   {
   static int j; // error, j is static
   int i;        // OK
   };
}


Compiler Error C2620

member 'identifier' of union 'union' has user-defined constructor or non-trivial default constructor

A union member cannot have a default constructor.

Example

class A
{
   A();      // A has a default constructor
};
union U
{
   A a;      // error
};


Compiler Error C2621

member 'identifier' of union 'union' has copy constructor

A union member cannot have a copy constructor.

Example

class A
{
   A( const A& );  // A has a copy constructor
};
union U
{
   A a;            // error
};


Compiler Error C2622

member 'identifier' of union 'union' has assignment operator

A union member cannot have an assignment operator.

Example

class A
{
   A& operator= ( const A& );  // A's assignment operator
};
union U
{
   A a;                        // error
};


Compiler Error C2623

member 'identifier' of union 'union' has destructor

A union member cannot have a destructor.

Example

class A
{
   ~A();    // A has a destructor
};
union U
{
   A a;     // error
};


Compiler Error C2624

local classes cannot be used to declare 'extern' variables

A local class or structure cannot be used to declare extern variables.

Example

void main(void)
{
struct C {...};
extern C ac;   //error
}


Compiler Error C2625

anonymous union did not declare any non-static data members

Unions cannot have static data members.

Example

static union {};         // error
static union { int i; }; // OK


Compiler Error C2626

anonymous union defines protected/private member 'identifier'

A member of an anonymous union must have public access.

Example

void main()
{
   union
   {
   public:
      int i;     // OK, i is public
   protected:
      int j;     // error, j is protected
   private:
      int k;     // error, k is private
   };
}


Compiler Error C2627

'identifier' : member function defined in unnamed class

An anonymous union cannot have member functions.

void main()
{
    union {
       int i;
       void func( void );     // Error, union is anonymous.
    };
    union U {
       void func2( void );    // OK.
    };
}


Compiler Error C2628

'type1' followed by 'type2' is illegal (did you forget a ';'?)

A section of code between the two types is incorrect.

Possible cause

  • Missing semicolon.

Example

class C
{
public:
   void func( void ) {;}
}                         // semicolon is missing here
void main() {}            // error detected on this line


Compiler Error C2629

unexpected 'token ('

A syntax error made the statement ambiguous.

Possible cause

  • Mixing declaration and expression syntax.

Example

class B
{
   B( &B );  // error, misplaced &
   B( B& );  // OK
};


Compiler Error C2630

'symbol' found in what should be a comma-separated list

The symbol appears in a context that requires a comma.

Example

class D
{
   public:
   D(int);
};
class E
{
   public:
   E(int);
};
class C : public D, public E   // OK
{
   C();
};
C::C() : D(0) ; E(0) { }       // error


Compiler Error C2631

'class' : destructors not allowed a return type

A destructor is incorrectly declared with a return type.

Example

class C
{
   int ~C();   // error, returns int
   void ~C();  // error, returns void
   ~C();       // OK
};


Compiler Error C2632

'type1' followed by 'type2' is illegal

Possible cause

  • Missing code between two type specifiers.

Example

int float i;   // error


Compiler Error C2633

'identifier' : 'inline' is the only legal storage class for constructors

A constructor is declared as a storage class other than inline.

Example

class C
{
   extern C();  // error, not inline
};


Compiler Error C2634

'&class::member' : pointer to reference member is illegal

A pointer to a reference member is declared.

Example

int mem;
struct S
{
   S() : rf(mem) { }
   int &rf;
};
int (S::*pdm) = &S::rf;  // error


Compiler Error C2635

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 followings sample generates C2635:

class B {
};

class D : virtual public B {   // remove virtual to resolve the error
};

void main() {
    B b;
    D d;

    D * pD = &d;

    pD = (D*)&b;      // C2635
}


Compiler Error C2636

'identifier' : pointer to reference member is illegal

A pointer to a reference member was declared.

Example

struct S {};
int &S::*prs;       // error


Compiler Error C2637

'identifier' : cannot modify pointers to data members

A pointer to a data member was modified.

Example

struct S {};
int __stdcall S::*pms;     // error


Compiler Error C2638

'identifier' : __based modifier illegal on pointer to member

The __based modifier cannot be used for pointers to members.

Example

void *a;

class C
{
public:
   int i;
   int j;
   int func();
};
int __based (a) C::* cpi = &C::i;  // error
int (__based (a) C::* cpf)() = &C::func; // error


Compiler Error C2639

compiler generated default constructor required by unnamed class

An unnamed class, structure, or union requires a default constructor. A name is required for a constructor to be generated.

Example

class A
{
public:
   A();      // default constructor declaration
};

class C
{
public:
   struct    // unnamed struct
   {
      A a;
   } s1;     // error detected here
   struct S  // named struct
   {
      A a;
   } s2;     // OK
};


Compiler Error C2640

'identifier' : __based modifier illegal on reference

The __based modifier can be used on pointers only.

Example

void f(int i)
{
    void *vp;
    int _based(vp) &vr = I;  // error
}


Compiler Error C2641

illegal pointer to member cast across virtual inheritance path

A pointer to a member is cast to a base class inherited through virtual inheritance.

Example

struct V {};
struct A : virtual V {};
int A::*pma;
int V::*pmv = (int V::*)pma;      // error


Compiler Error C2643

illegal cast from pointer to member

A pointer to a member of a class, structure, or union is cast to a different type.

Example

class C
{
public:
   int i;
   operator int*() { return &i; }
};
int C::* cpi = (int*)&C::i; // error
int C::* cpi2 = &C::i;      // OK


Compiler Error C2644

basis class 'class' for pointer to member has not been defined

A pointer points to a class that was declared but not defined.

Example

class C;
int C::* cp; // error, C has not been defined
class D {};
int D::*dp;  // OK


Compiler Error C2645

no qualified name for pointer to member (found ':: *')

The declaration of a pointer to a member does not specify a class.

Example

class A {};
int ::* cp;    // error, class not specifed
int B::* bp    // error, B not defined
int A::* ap;   // OK


Compiler Error C2646

global anonymous unions must be declared static

An anonymous union has global scope but is not declared static.

Example

union { int i; };         // error, not static
static union { int j; };  // OK
union U { int i; };       // OK, not anonymous


Compiler Error C2647

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

Example

class C {};
class D {};

void main()
{
   D d, *pd;
   C c, *pc;
   int C::*pmc;

   pd->*pmc = 0;   // error
   d.*pmc = 0;   // error
   pc->*pmc = 0;   // okay
   c.*pmc = 0;   // okay
}


Compiler Error C2648

'identifier' : use of member as default parameter requires static member

A nonstatic member is used as a default parameter.

Example

class C
{
public:
   int i;
   static int j;
   void func1( int i = i );  // error, i is not static
   void func2( int i = j );  // OK, uses static j
};


Compiler Error C2649

'identifier' : is not a 'class-key'

A class, structure, or union declaration uses an incorrect tag.

Example

struct S
{
   int i;
};
class S::i c;   // error


Compiler Error C2650

'operator' : cannot be a virtual function

A new or delete operator is declared virtual. These operators are static member functions and cannot be virtual.

Example

class A
{
   virtual void* operator new( unsigned int ); // error
};


Compiler Error C2651

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

The following sample generates C2651:

template<typename T, T::PMF pmf>
struct X1 {
};

struct Y1 {
   typedef void (Y1::*PMF)();

   void mf() {
   }
};

void f1()
{
   X1<int, 0>      x11;      // Fails
//   X1<Y1, &Y1::mf>   x12;   // Works
}
void main(){}


Compiler Error C2652

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

Example

class A
{
   A( A );     // error, takes an A
};
class B
{
   B( B& );    // OK, reference to B
};


Compiler Error C2653

'identifier' : is not a class or namespace name

Syntax requires a class, structure, union, or namespace name.

Example

int x;
int main()
{
   return x::i; // error
}


Compiler Error C2654

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

Possible cause

  • Trying to initialize variables in a declaration. Use a constructor for this purpose.

Example

class A
{
   int i;
   int j = i;  // error, access outside function
   void setj( void ) { j = i ; }  // OK, access in function
   A( int ai )
   {
      i = ai;  // OK, initializes i and j
      j = i;
   }
} a( 1 );


Compiler Error C2655

'identifier' : definition or redeclaration illegal in current scope

An identifier can be redeclared only at global scope.

Example

class A {};
class B
{
public:
   static int i;
};
void main()
{
   A B::i;  // error
}


Compiler Error C2656

'function' : function not allowed as a bit field

A function is declared as a member of a bit field.

Possible cause

  • Syntax error in a constructor initializer list.


Compiler Error C2657

'class::*' found at the start of a statement (did you forget to specify a type?)

The line began with a pointer-to-member identifier.

Possible cause

  • Missing type specifier in the declaration of a pointer to a member.

Example

class C {};
void main() {
   C::* pmc1;        // error
   void C::* pmc2;   // OK
}


Compiler Error C2658

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

struct X {
   union { // can be struct too
      int i;
   };
   union {
      int i; // C2658 with /Za; ignored silently otherwise
      // 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
      // void *ii;
   };
};

void main() {
}


Compiler Error C2659

'operator' : overloaded function as left operand

An overloaded function was on the left side of the specified operator.

Example

int func( int );
int func( double );
void main()
{
   func = 10;  // error
}


Compiler Error C2660

'function' : function does not take number parameters

The function is called with an incorrect number of parameters.

Possible causes

  • Incorrect number of actual parameters:
    void func( int, int );
void main()
{
   func( 1 );     // error, func( int ) not declared
   func( 1, 0 );  // OK, func( int, int ) was declared
}
  • Accidentally calling 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.


Compiler Error C2661

'function' : no overloaded function takes number parameters

Possible cause

  • Incorrect actual parameters in function call.
  • Missing function declaration.

Example

void func( int );
void func( int, int );
void main()
{
   func( );      // error, func( void ) was not declared
   func( 1 );    // OK, func( int ) was declared
}


Compiler Error C2662

'function' : cannot convert 'this' pointer from 'type1' to 'type2'

The compiler could not convert the this pointer from type1 to type2.

Possible cause

  • Invoking a non-const member function on a const object.

Possible solutions

  • Remove the const from the object declaration.
  • Add const to the member function.

Example

class C
{
public:
   void func1();
   void func2() const;
} const c;

void main()
{
   c.func1();  // error
   c.func2();  // no error
}


Compiler Error C2663

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

Possible cause

  • Invoking a non-const member function on a const object.

Possible solutions

  • Remove the const from the object declaration.
  • Add const to one of the member function overloads.

Example

class C {
public:
   void foo() volatile;
   void foo(); // adding const here would fix problem
};

const C *pcc;

void main()
{
   pcc->foo();      // error
}


Compiler Error C2664

'function' : cannot convert parameter number from 'type1' to 'type2'

A parameter cannot be converted to the required type. This might happen if you create an instance of a class and attempt an implicit conversion on a constructor marked with the explicit keyword.

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 called with a parameter that is not of the type that the function expects, a temporary object is created 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 previous versions of the language, all references were able to be initialized by temporary objects. This behavior is now being phased out, hence the error given by the Microsoft C/C++ compiler.

The code below demonstrates this error by calling Test with a string literal. Because the parameter is a 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.

Example 1

class A {} a;
func( int, A );
void main()
{
   func( 1, 1 );  // error, no conversion from int to A
}

Example 2

#include <iostream.h>
#include <string.h>

class szString
{
  int slen;
  char *str;

public:
  szString(const char *);
  int len() const { return slen; }
};

void Test(szString &a) { cout << a.len();}

szString::szString(const char * newstr)
{
  slen=strlen(newstr);
  str = new char[slen + 1];
  strcpy(str, newstr);
}

void main(void)
{
  Test("hello");
}

Possible solutions

  • Recheck the prototype for the given function and correct the argument noted in the error message.
  • Supply an explicit conversion if necessary.

If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.


Compiler Error C2665

'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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Possible solutions

  • Supply a conversion operator.
  • Use explicit conversion.


Compiler Error C2666

'identifier' : number overloads have similar conversions

An overloaded function or operator is ambiguous. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Possible cause

  • Formal parameter lists are too similar to resolve ambiguity.

Possible solution

  • Explicitly cast one or more of the actual parameters.

Example

void func( int, float ) {};
void func( float, int ) {};
func( 1, 1 );        // error, same conversion for each func
func( 1, (float)1 )  // OK


Compiler Error C2667

'function' : none of number overloads have a best conversion

An overloaded function call is ambiguous and cannot be resolved. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

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.

See Knowledge Base article Q240869 for more information on partial ordering of function templates.


Compiler Error C2668

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

See Knowledge Base article Q240869 for more information on partial ordering of function templates.

If you are building an ATL project containing a COM object supporting ISupportErrorInfo, see Knowledge Base article Q243298.

Example

struct A {};
struct B : A {};
struct X {};
struct D : B, X {};

void func( X, X );
void func( A, B );
D d;
void main()
{
   func( d, d );        // error, D has an A, B, and X
   func( (X)d, (X)d );  // OK, uses func( X, X )
}

If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.


Compiler Error C2669

member function not allowed in anonymous union

Anonymous unions cannot have member functions. The following sample generates C2669:

struct X {
   union {
      int i;
      void f() {   // C2669, remove function
         i = 0;
      }
   };
};

void main() {
}

See Also

Anonymous Unions


Compiler Error C2670

'identifier' : the template function cannot convert parameter number from type 'type'

A parameter could not be converted to the required type.

Possible solution

  • Create an explicit conversion.


Compiler Error C2671

'function' : static member functions do not have 'this' pointers

A static member function tried to access this.

Example

struct S
{
   static S* const func() { return this; }  // error
};


Compiler Error C2672

'function' : new/delete member functions do not have 'this' pointers

A new or delete tried to access this.

Example

class C
{
   void* operator new( unsigned int )
   {
      this = 10;      // error  return 0;
   }
};


Compiler Error C2673

'function' : global functions do not have 'this' pointers

A global function tried to access this.

Example

void main()
{
   this = 0;  // error
}


Compiler Error C2674

'operator' : no acceptable conversions from 'type1' to 'type2'

No conversion is defined from type1 to type2. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Possible solutions

  • Define a constructor or conversion operator.

Example

class C
{
   public:
   C();       // no constructor with an int argument
} c;
class D
{
   public:
   D( int );
   D();
} d;
void main()
{
   c = 10;    // error
   d = 10;    // OK
}


Compiler Error C2675

unary '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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Example

class C
{
   public:
   C();
} c;

class D
{
   public:
   D();
   operator !();
} d;

void main()
{
   !c;   // error
   !d;    // OK, operator !() defined
}


Compiler Error C2676

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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Example

class C
{
   public:
   C();
} c;

class D
{
   public:
   D();
   D operator <<( C& );
} d;
void main()
{
   d >> c;   // error
   d << c;   // OK, operator << defined
}


Compiler Error C2677

binary 'operator' : no global operator defined 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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Example

class C
{
   public:
   C();
} c;

class D
{
   public:
   D();
   operator int();
} d;

void main()
{
   1 >> c;   // error
   1 >> d;   // OK, operator int() defined
}


Compiler Error C2678

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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Example

class   C
{
   public: C();
};

void main()
{
   C   aC;
   aC + 12;      // error
   }


Compiler Error C2679

binary 'operator' : no operator defined 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. If you encounter this error while porting code from Visual C++ 2.0 or earlier, see Technote: Improved Conformance to ANSI C++.

Example

class C
{
   public:
   C();       // no constructor with an int argument
} c;
class D
{
   public:
   D( int );
   D();
} d;
void main()
{
   c = 10;    // error
   d = 10;    // OK
}


Compiler Error C2680

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

Example

class A { virtual void f(); };
class B : public A {};

void g(B b)
{
    A a;
    a = dynamic_cast<A>(b);  // error
}


Compiler Error C2681

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

Example

class A { virtual void f(); };

void g(int i)
{
    A* pa;
    pa = dynamic_cast<A*>(i);  // error
}


Compiler Error C2682

cannot use name 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.

Example

class A { virtual void f(); };
class B: public A {};

void g(A* pa)
{
    B& rb = dynamic_cast<B&>(pa); // error
}


Compiler Error C2683

dynamic_cast : 'class' 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.

Example

class B { };
class D : public B {  };

void f(B* pb)
{
    D* pd1 = dynamic_cast<D*>(pb);  // error
}


Compiler Error C2687

cannot define a nested UDT of a template class out of line

A nested UDT (user-defined type) was implemented (defined) outside of its class, which is not supported by the Visual C++ compiler.

The following sample generates C2687:

template <class T>
struct A {
   struct B;
};
template <class T>
struct A<T>::B {   // C2687
};
/*
// uncomment this class and delete other code in this sample to resolve
template <class T>
struct A {
        struct B {
        };
};
*/

void main() {
}


Compiler Error C2690

'operator' : cannot perform pointer arithmetic on managed NGWS frameworks array

In the managed environment of NGWS, the variable that you declare for a managed array is not a pointer such that you can increment it. For example, the following sample generates C2690:

void main(){

int i, j;

// A simple dynamically allocated array.
int a1[] = new int[2];
for (i=0; i < 2; ++i)
    a1[i] = i;

for (i=0; i < a1.Length; ++i)   // Use the Length member
{
    Text.Out.Write(a1[i]);
    Text.Out.Write(' ');
}
Text.Out.WriteLine();
Text.Out.WriteLine(a1.GetRank());

a1++;      // C2690
}


Compiler Error C2691

'date type' : invalid type for managed array element

A managed array can include managed types and native types, but some types are not allowed, such as pointers to unmanaged types.

The following sample generates C2691:

#using <mscorlib.dll>

void main() {
   int * a1[] = new __gc int * [20];   // C2691

   // try the code below to resolve the error
   // int * a1 = new int [20];
}


Compiler Error C2692

'function_name' : fully prototyped functions required in NGWS runtime C compiler

When compiling for NGWS managed code, the C compiler requires function declarations. In addition, if a function takes no parameters, it must explicitly declare void as the parameter type.

For example, the following code generates C2692:

// compile with /com+
// to resolve one C2692, uncomment the following declaration
// int func1(int);

// to resolve the other C2692, remove the comments
int func2(/* void */) {
   return 1;
}

void main() {
   int x = func1(1);
   int y = func2();
}
int func1(int n)
{
   return n;
}


Compiler Error C2693

'operator' : illegal comparison for references to managed NGWS frameworks array

You cannot test a managed 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.

For example, the following sample generates C2693:

#define MANAGED __gc

int func1(MANAGED int a[], MANAGED int b[]) { return a==b; }  // OK
int func2(MANAGED int a[], MANAGED int b[]) { return a!=b; }  // OK
int func3(MANAGED int a[], MANAGED int b[]) { return a<b; }  // C2693


Compiler Error C2694

Cannot declare gc pointer to 'void'

Garbage-collected pointers cannot be pointers to type void. To resolve the error, be sure managed pointers point to managed objects. The following sample generates C2694:

#using <mscorlib.dll>

__gc struct A {
};

void main() {
   void __gc* ptr;   // C2694

   // try..
   // A __gc* ptr;
}


Technote: Improved Conformance to ANSI C++

Because of improved C++ conformance, some constructs that compiled in older versions of Visual C++ now produce errors. The errors affected are:

C2434 | C2440 | C2446 | C2553 | C2585 | C2592
C2664 | C2665 | C2666 | C2667 | C2668 | C2674
C2675 | C2676 | C2677 | C2678 | C2679 |

Overload Resolution Changes

Visual C++ versions 4.0 and later bring overload resolution rules closer to the C++ standard. This allows some code to work that did not work previously, but can result in ambiguities in code that compiled cleanly with earlier versions of Visual C++.

Dereferencing a Reference is an Identity Conversion

Versions of Microsoft Visual C++ prior to 4.0 did not consider dereferencing a reference, or binding to a reference, to be an exact match. Visual C++ versions 4.0 and later considered the conversions trivial, as specified by the Annotated C++ Reference Manual.

Example

void foo(const int);
void foo(int&);

void bar(void)
{
    int i;
    int &ri = i;
    foo(i);  // Accepted by VC2.0, VC1.x, rejected by VC4.0, error C2668
    foo(ri);  // Accepted by VC2.0, VC1.x, rejected by VC4.0, error C2668
}

User-Defined Conversions (UDCs) are Selected by 'this' Pointer Types

Versions of Visual C++ prior to 4.0 selected a user-defined conversion to call by determining the required conversion from the UDC result type to the required type, ignoring the conversion required for the this pointer of the UDC. Later versions select a UDC based on the quality of match on the this pointer. If two conversions have identical this pointers, a Microsoft extension uses the quality of the conversion from the UDC result to the target type to determine the UDC. (This extension is not disabled by /Za.)

The new behavior catches some errors not previously detected.

Example

struct C {
    // some class
};

struct D {
    // A class which wraps a C
    C myC;

    // Two user-defined conversion functions, one for
    //  using myC, and the other for modifying it
    operator C () { return myC; }   // conversion #1
    operator C& () { return myC; }   // conversion #2
};

// A function that takes a C
void func1(C);

// A function that has a D
void func2()
{
    D aD;

    func1(D);  // Error diagnosed in VC4.0: error C2664
}

In this example, the user-defined conversion is ambiguous because the conversions for the this pointers are identical and the the UDC results have identical conversions. The following code (which follows the previous code) shows another error:

// A function that wants to modify a C
void func3(C&);

// Some function that gets a D&
void func4(const D& aD)
{
    func3(aD);  // Error diagnosed in VC4.0: error C2664
}

This time, neither UDC can be called. The D object is const, but neither UDC takes a const this pointer.

To correct both these problems, rewrite conversion #1 as follows:

operator C () const { return myC; }  // conversion #1a

or:

operator const C& () const { return myC; }  // conversion #1b

Both conversions take a const this pointer and can be called for const objects. Conversion #1b returns a reference to a const object, avoiding copy construction, but still ensuring that the original object cannot be modified.

An additional, more subtle effect of this change is that user-defined conversions can silently change behavior:

Example

void foo(int);

struct C {
    operator int () const;
    operator long ();
};

void main(void)
{
    C aC;
    const C acC;

    foo(acC);  // calls "operator int() const"
    foo(aC);   // calls "operator int() const" in VC2.0,
               // but "operator long()" in VC4.0
}


Compiler Error C2700

'identifier' : cannot be thrown (use –W4 for more info)

The object cannot be thrown. Compile with /W4 for more diagnostic information.


Compiler Error C2702

__except may not appear in termination block

An exception handler (__try/__except) cannot be nested inside a __finally block.

Error

int Counter;
void main ()
{
   __try {}
   __finally
   {
      __try {}
      __except( Counter ) {}    // error
   }
}


Compiler Error C2703

illegal __leave statement

A __leave statement must be inside a __try block.

Example

void main ()
{
   __leave;   //error
   __try
   {
      __leave;   //OK
   }
   __finally {}
}


Compiler Error C2704

'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

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

Example

void main ()
{
goto trouble;
   __try {
   trouble: ;   //error
   }
   __finally {}
}


Compiler Error C2706

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:

int main() {
   __try {
      void f();
   // C4706  } missing here
   __except(GetExceptionCode() == 0x0) {
   }
}


Compiler Error C2707

'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. The following sample generates C2707:

#include <windows.h>

LONG MyFilter() {
   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()) {
      return(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?   // ok
      EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
   }
}

void main() {
}


Compiler Error C2708

'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

'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

cannot delete a pointer to a const object

You cannot use the delete operator on a pointer to a const object.

Example

const int* pci;
const int i = 0;
void main()
{
   pci = &i;
   delete pci;  // error, pci points to a const
}


Compiler Error C2711

cannot delete a pointer to a function

You cannot use the delete operator on a pointer to a function.

Example

void (*pf)();
void func();
void main()
{
   pf = func;
   delete pf;   // error, pf points to a function
}


Compiler Error C2712

cannot use __try in functions that require object unwinding

With /GX, a function with structured exception handling cannot have 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 using /GX-.


Compiler Error C2713

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

'function' : function with inline assembly is not allowed to have NGWS runtime EH constructs

NGWS exception handling is not allowed in a function that also contains an __asm block.

The following sample generates C2714:

#using <mscorlib.dll>
#include <stdio.h>

int nakedfunc(void) {
   try {
      __asm {
         mov eax, 10h
      }
   } __finally {
      printf("Test\n");
   }
}   // C2714

void main() {
   printf("Return value is %d\n", nakedfunc());
}


Compiler Error C2720

'identifier' : 'specifier' storage-class specifier illegal on members

The storage class cannot be used on class members.

Example

struct S
{
   static int i;
};
static S::i;   // error


Compiler Error C2721

'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

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

'function' : 'specifier' storage-class 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.

Example

struct X
{
   virtual void f();
   virtual void g();
};
virtual void X::f() {} // error, virtual specifier
void X::g() {}         // OK


Compiler Error C2724

'identifier' : 'static' should not be used on member functions defined at file scope

Static member functions should be declared with external linkage. Static member functions at file scope cause an error under ANSI compatibility (/Za) and a warning under Microsoft extensions (/Ze).

Example

class C
{
   static void func();
};

static void C::func(){};    // error


Compiler Error C2725

value out of range for intrinsic constant argument

Some intrinsics require a constant argument. This error is generated when the argument is out-of-range. Check the documentation and only pass in-range argument values when invoking the intrinsics. The following sample generates C2725:

#include <mmintrin.h>

__m128 x1, x2;

void val_is_out_of_range(){
   x1 = _mm_shuffle_ps(x1, x2, -1);      // C2725
   x1 = _mm_shuffle_ps(x1, x2, 256);   // C2725

   /* use the below lines to resolve the error
   x1 = _mm_shuffle_ps(x1, x2, 0);
   x1 = _mm_shuffle_ps(x1, x2, 255);
   */
}


Compiler Error C2730

'class' : cannot be a base class of itself

Recursive base classes are illegal. Specify another class as the base class.


Compiler Error C2731

'identifier' : function cannot be overloaded

The functions main, WinMain, and LibMain cannot be overloaded.

Example

extern "C" void WinMain(int, char *, char *);
void WinMain(int, short, char *, char*);       // error


Compiler Error C2732

linkage specification contradicts earlier specification for 'function'

The function is already declared with a different linkage specifier.

Possible cause

  • Include files with different linkage specifiers.

Change the extern statements so that the linkages agree.

Example

extern void func( void );      // implicit C++ linkage
extern "C" void func( void );  // error


Compiler Error C2733

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:

extern "C" {
   void F1(int);
}

extern "C" {
   void F1(void);
}   // C2733, delete one of the external linkages to resolve

void main() {
}


Compiler Error C2734

'identifier' : const object must be initialized if not extern

The identifier is declared const but not initialized or extern.

Example

const int j;           // error
extern const int i;    // OK, declared as extern


Compiler Error C2735

'keyword' keyword is not permitted in formal parameter type specifier

The keyword is illegal in this context.

Example

void main()
{
   int *myint;
   myint = new static int;     // error
   myint = new typedef int;    // error
   myint = new auto int;       // error
   myint = new register int;   // error
}


Compiler Error C2736

'keyword' keyword is not permitted in cast

The keyword is illegal in a cast.

Example

int main()
{
   return (virtual) 0;   // error
}


Compiler Error C2737

'class1' : base class 'class2' must be exported

If a derived class is exported, its base class must also be exported.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2750

'operator' : 'type'1 to 'type2'

The conversion is illegal.


Compiler Error C2751

'parameter' : the name of a function parameter cannot be qualified

You cannot use a qualified name as a function parameter. For example, the parameter in function f is qualified and generates C2751.

namespace std {
   template<typename T>
   class list {
      // ...
   };
}

#define list std::list

void f(int &list)
{
}


Compiler Error C2758

'const' : must be initialized in constructor base/member initializer list

The constructor does not initialize the const variable in an initializer list. The compiler leaves the constant undefined. Reference and const member variables must be given a value when initialized or in the constructor.

The following sample generates C2758:

struct A {
   const int i;

   A(int i){   // C2758
   // try ...
   // A(int i) : i(0) {
   };

};

void main() {
}


Compiler Error C2760

syntax error : expected 'name1' not 'name2'

A casting operator is used with an invalid operator.

Example

class B { };
class D : public B {  };

void f(B* pb)
{
    D* pd1 = static_cast<D*>(pb);
    D* pd2 = static_cast<D*>=(pb); // error
    D* pd3 = static_cast<D*=(pb);  // error
}


Compiler Error C2762

'class' : invalid expression as a template argument for 'argument'

When using /Za, the compiler will not convert an integral to a pointer.

template<typename T, T *pT>
class X2 {
};

void f2()
{
   X2<int, 0> x21;                         // Fails with /Za
   // X2<int, static_cast<int *>(0)> x22;  // Works with /Za
}

void main(){}


Compiler Error C2764

'parameter' : illegal use of template type-parameter

Your code should use a function return type or the type of a user-defined conversion.

For example, the following code generates this error:

template<typename T>
class X3 {
   T() {      // C2764
   }

/* any of the following will work
   T f() {   // works
   }

   operator T() {
   }
*/
};

void main(){}

Depending on what is intended, one way to fix this would be:

operator const T() const;


Compiler Error C2765

"filename" : cannot open binary header at this point

A #import of a binary header may only appear at external scope; it can appear neither inside a class or function definition nor inside an initialization. A future version of Visual C++ is expected to incorporate this functionality.


Compiler Error C2769

'function' : deduced template arguments do not match explicit template arguments

The compiler first looks at the relationship between the types between the <> and how they are used in the function arguments. Then it looks at your specialization to see if the relationship there is the same.

For example, the following code generates C2769:

template<typename T>
void f(const T &);

template void f<int>(const char &);


Compiler Error C2771

#import only permitted at global or namespace scope

The #import directive is not allowed in, for example, a function or structure.


Compiler Error C2773

#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

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

Example

struct A {
   __declspec(property(get=GetProp)) int prop;
   int GetProp(void);
};

void f(A* pa, int val)
{
    pa->prop = val;      // error C2774
    pa->prop++;      // error C2774
}


Compiler Error C2775

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

Example

struct A {
   __declspec(property(put=PutProp)) int prop;
   int PutProp(void);
};

int f(A* pa)
{
   int x = pa->prop;   // error C2775
   return x;
}


Compiler Error C2776

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.

Example

struct A {
   __declspec(property(get=GetProp,get=GetPropToo))
      int prop;      // error C2776
   int GetProp(void);
   int GetPropToo(void);
};


Compiler Error C2777

only one 'put' method can be specified per property

Example

struct A {
   __declspec(property(put=PutProp,put=PutPropToo))
      int prop;      // error C2777
   int PutProp(void);
   int PutPropToo(void);
};


Compiler Error C2778

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:

// Correct:
struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) A { };
struct __declspec(uuid("{00000000-0000-0000-0000-000000000000}")) B { };

Example

// error C2778:
struct __declspec(uuid(" 00000000-0000-0000-0000-000000000000 ")) C { };
struct __declspec(uuid("00000000000000000000000000000000")) D { };

The uuid extended attribute accepts strings recognized by CLSIDFromString, with or without brace delimiters.


Compiler Error C2779

'declaration' : property methods can only be associated with non-static data members

The property extended attribute is incorrectly applied to a static data member.

Example

struct A {
   static __declspec(property(put=PutProp))
      int prop;      // error C2779
   int PutProp(void);
};


Compiler Error C2780

'declaration' : expects value1 arguments - value2 provided

A function template has too few arguments.

Example

template<class T> void f(T, T){ }
f(1);  // error

Function f takes two or more parameters, but only one parameter is provided.


Compiler Error C2781

'declaration' : expects at least value1 argument - value2 provided

A function template with a variable parameter list has too few arguments.

Example

template<class T> void f(T, int, ...){ }
f(1); //error

Function f takes two or more parameters, but only one parameter is provided.


Compiler Error C2782

'declaration' : template parameter 'identifier' is ambiguous

The compiler cannot determine the type of a template argument.

Example

template<class T> void f(T,T){ }
f(1, 'c');

In this example, the compiler cannot determine where type T is int or char.


Compiler Error C2783

'declaration' : could not deduce template argument for 'identifier'

The compiler cannot determine a template argument.

Example

template<class T1, class T2> T1 f(T2){ }
f(1); // error

The compiler cannot determine the type associated with template argument T1.


Compiler Error C2784

'declaration' : could not deduce template argument for 'type' from 'type'

The compiler cannot determine a template argument from the supplied function arguments.

Example

template<class T> class X { };
template<class T> void f(X<T>) {}
f(1); // error

The compiler cannot determine the template argument associated with T from this function call. The following code will work:

X<int> x;
f(x);


Compiler Error C2785

'declaration1' and 'declaration2' have different return types

The return type of function template specialization differs from the return type of the primary function template.

Example

template<class T> void f(T);
template<> int f(int); // error

Check all specializations of the function template for consistency.


Compiler Error C2786

'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

  • The argument is not a user-defined type.
  • _uuidof cannot extract the GUID from the argument.

Example

struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) A {
};

void foo(void)
{
    __uuidof(int);      // error C2786
    __uuidof(int *);   // error C2786
    __uuidof(A **);      // error C2786

// no error
    __uuidof(A);
    __uuidof(A *);
    __uuidof(A &);
    __uuidof(A[]);

    int i;
    int *pi;
    A **ppa;

    __uuidof(i);   // error C2786
    __uuidof(pi);   // error C2786
    __uuidof(ppa);   // error C2786
}


Compiler Error C2787

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

Example

struct F {
};

struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) F2 {
};

void bar(void)
{
    __uuidof(F);   // error C2787
    __uuidof(F *);   // error C2787

    __uuidof(F2);   // OK
}


Compiler Error C2788

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

Example

struct __declspec(uuid("00000001-0000-0000-0000-000000000000")) A { };
struct __declspec(uuid("{00000002-0000-0000-0000-000000000000}")) B { };

template <class T, class U> class Foo { };

typedef Foo<A,B> MyBadFoo;
typedef Foo<A,A> MyGoodFoo;

void bar(void)
{
    __uuidof(MyBadFoo);      // error C2788
    __uuidof(MyGoodFoo);   // OK
}


Compiler Error C2790

'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 code sample shows one way this error could be generated:

// compile with cl /c
void f()
{
   __super::g();
}


Compiler Error C2791

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 code sample shows one way this error could be generated:

struct D {
   void mf() {
      __super::mf();
   }
};


Compiler Error C2792

'super' : this keyword must be followed by '::'

The only token that can follow the keyword super is ::.

The following code sample shows one way this error could be generated:

struct B {
   void mf();
};

struct D : B {
   void mf() {
      __super.();
   }
};


Compiler Error C2793

'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 code sample shows one way this error could be generated:

struct B {
   void mf();
};

struct D : B {
   void mf() {
      __super::();
   }
};


Compiler Error C2794

'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 code sample shows one way this error could be generated:

struct B {
   void mf();
};

struct D : B {
   void mf() {
      __super::f();
   }
};


Compiler Error C2795

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

The following code sample shows one way this error could be generated:

struct B {
   int m_data;
};

struct D : B {
   void mf() {
      super::m_data += 1;
   }
};


Compiler Error C2796

'function' : no function found that matches the signature of the current function

This error message appears whenever the compiler cannot find a base-class method that matches the signature of the current method.

The following code sample shows one way this error could be generated:

struct B1 {
   void mf(int);
};

struct B2 {
   void mf(char);
};

struct D : B1, B2 {
   void mf() {
      __super::mf();
   }
};


Compiler Error C2797

'method' : method after 'super' is ambiguous

This error appears whenever the compiler finds two or more base-class methods that match the signature of the current method.

The following code sample shows one way this error could be generated:

struct B1 {
   void mf();
};

struct B2 {
   void mf();
};

struct D : B1, B2 {
   void mf() {
      __super::mf();
   }
};


Compiler Error C2798

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

For example, the following code shows how this error would be generated.

struct B1 {
   int i;
};

struct B2 {
   int i;
};

struct D : B1, B2 {
   void g() {
      __super::i = 4;
   }
};


Compiler Error C2799

the template parameter list for 'function' is incompatible with the template parameter list for class 'class'

The number of arguments for the template class differs from the number of parameters for the member function definition.

For example, the following code generates C2799:

typedef  unsigned char   wchar_t;

template <typename CHARTYPE>
class DefaultCStringIterator
{
public:
   CHARTYPE* CharNext(const CHARTYPE* pChar);
};

template <>
class DefaultCStringIterator<wchar_t>
{
public:
   wchar_t* CharNext(const wchar_t* pChar)
   {
      return (wchar_t*) pChar++;
   }
};

template <>
class DefaultCStringIterator<char>
{
public:
   char* CharNext(const char* pChar)
   {
      return (char*) pChar++;
   }
};

template <typename CHARTYPE = char,
         class CStringIterator = DefaultCStringIterator<CHARTYPE> >
class CString_t : public CStringIterator
{
public:
// Constructors
   CString_t();
};

template <typename CHARTYPE>
inline CString_t<CHARTYPE>::CString_t()
{
   Init();
}

void main()
{
   CString_t<> myString;
}


Compiler Error C2800

'operator operator' cannot be overloaded

The following operators cannot be overloaded: class member access (.), pointer to member (.*), scope resolution (::), conditional expression (? :), and sizeof.

Example

 class C
 {
    operator:: ();  // error
 };


Compiler Error C2801

'operator operator' must be a nonstatic member

The following operators can be overloaded only as nonstatic members:

  • Assignment =
  • Class member access ->
  • Subscripting []
  • Function call ( )

Possible causes

  • Overloaded operator is not a class, structure, or union member.
  • Overloaded operator is declared static.

Example

operator[]();            // error, not a member
class A
{
   static operator->();  // error, static
   operator()();         // OK
};


Compiler Error C2802

static member 'operator operator' has no formal parameters

An operator declared by a static member function must have at least one parameter.

Example

class A
{
   static operator+ ();     // error, void parameter list
   static operator* ( A& ); // OK
};


Compiler Error C2803

'operator operator' must have at least one formal parameter of class

The overloaded operator lacks a parameter of class type.

Example

int operator+( int, int );  // error


Compiler Error C2804

binary 'operator operator' has too many parameters

The overloaded binary operator is declared with more than one parameter.

Example

class X
{
   X operator+ ( X , X );  // error, two parameters
   X operator+ ( X );      // OK, one parameter
};


Compiler Error C2805

binary 'operator operator' has too few parameters

The binary operator has no parameters.

Example

class X

{
public:
   X operator< ( void );  // error, must take one parameter
   X operator< ( X );     // OK
};


Compiler Error C2806

'operator operator' has too many formal parameters

An overloaded operator has too many parameters.

Example

class X
{
public:
   X operator++ ( int, int ); // error, more than 1 parameter
   X operator++ ( int );      // OK
} ;


Compiler Error C2807

the second formal parameter to postfix 'operator operator' must be 'int'

The second parameter to a postfix operator has the wrong type.

Example

class X
{
public:
   X operator++ ( X );    // error, nonvoid parameter
   X operator++ ( int );  // OK, int parameter
};


Compiler Error C2808

unary 'operator operator' has too many formal parameters

The unary operator has a nonvoid parameter list.

Example

class X
{
public:
   X operator! ( X );     // error, nonvoid parameter list
   X operator! ( void );  // OK
};


Compiler Error C2809

'operator operator' has no formal parameters

The operator lacks required parameters.

Example

int operator+ ();  // error


Compiler Error C2810

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

For example, the following code generates a C2810 error:

// compile with /cl /c
#include <unknwn.h>
#undef interface
#pragma keyword("interface", on)

class CBase1 {
public:
  HRESULT mf1();
  int  m_i;

};

[com, uuid="40719E20-EF37-11D1-978D-0000F805D73B"]
interface IDerived : public CBase1 {  // 2810 : cannot inherit from a class
   HRESULT mf2(void *a);
};

struct CBase2 {
   HRESULT mf1(int a, char *b);
   HRESULT mf2();
};

[com, uuid="50719E20-EF37-11D1-978D-0000F805D73B"]
interface IDerived2 : public CBase2 {  // 2810 : cannot inherit from a struct
   HRESULT mf3(double a);
};


Compiler Error C2813

'operator name' : invalid number of arguments for the managed operator 'operator symbol'

The declaration of an operator specified too many parameters.

The following sample generates C2813:

#using<mscorlib.dll>
using namespace System;

__gc class G {
   Int32 j;
public:
   G(Int32 n) : j(n) {
   };

   static bool op_Equality(G* g1, G* g2, G* g3) {   // C2813, equality operator takes two arguments
   // the following line declares the correct number of arguments
   // static bool op_Equality(G* g1, G* g2) {
      return g1->j == g2->j;
   };
};

void main() {
}


Compiler Error C2815

'operator delete' : first formal parameter must be 'void *', but 'param' was used

Any user-defined operator delete must take a first formal parameter of type void *.

The following sample demonstrates an instance of this error:

// compile cl /c
class CMyClass {
public:
   void mf1(int *a);
   void operator delete(CMyClass *);  // 2815 : First formal must be 'void *'
};


Compiler Error C2817

return type for 'operator delete' must be 'void'

An overloaded delete operator cannot return a value.


Compiler Error C2818

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

type 'type' does not have an overloaded member 'operator ->'

You need to define operator->() to use this pointer operation.

Example

class A {
public:
   int i;
};

class B {
};

void C(B j)
{
   j->i; // error C2819
}

Solution

The following code fixes the problem:

class B {
   A* pA;

public:

   A* operator->()
   {
      return pA;
   }
};


Compiler Error C2821

first formal parameter to 'operator new' must be 'unsigned int'

The first formal parameter of the near or far forms of the operator new must be an unsigned int. The following sample generates C2821:

void * operator new( /* unsigned int,*/ void * ); // C2821
// in the previous line, remove the comments to resolve

void main() {
}


Compiler Error C2823

a typedef template is illegal

Templates are not allowed in typedef definitions.

The following sample generates C2823:

template<class T>
typedef struct x {
   T i;   // can't use T, specify data type and delete template
} x1;

void main() {
}


Compiler Error C2824

return type for 'operator new' must be 'void *'

With nonbased pointers, overloads of operator new must return void *. The following sample generates C2824:

class   A {
   A* operator new(size_t i, char *m);   // C2824
   // use the code below to resolve the error
   // void* operator new(size_t i, char *m);
};

void main() {
}


Compiler Error C2827

'operator operator' cannot be globally overridden with unary form

The operator cannot have a unary form outside of an object.

Possible solutions

  • Make the overloaded operator local to an object.
  • Choose an appropriate unary operator to overload.


Compiler Error C2828

'operator operator' cannot be globally overridden with binary form

The operator cannot have a binary form outside of an object.

Possible solutions

  • Make the overloaded operator local to an object.
  • Choose an appropriate unary operator to overload.


Compiler Error C2829

'operator operator' cannot have a variable parameter list

Only two operators can take variable parameter lists:

  • Function call ()
  • new


Compiler Error C2830

only placement parameters to 'operator new' can have default values

The standard formal parameters for the operator new cannot have default values. Only user-defined placement parameters can specify defaults.


Compiler Error C2831

'operator operator' cannot have default parameters

Only three operators can have default parameters:

  • new
  • Assignment =
  • Left parenthesis (

The following sample generates C2831:

#define BINOP <=
class A {
   public:
      int i;
      int operator BINOP(int x = 1) {   // C2831
      // use the line below to resolve the error
      // int operator BINOP(int x) {
         return i+x;
      };
};

main() {
}


Compiler Error C2832

'modifier' form of 'operator operator' cannot be a member

The huge and based forms form of the operator new or delete cannot class, structure, or union members.

Example

class T
{
public:
   void __huge* operator new ( unsigned long, size_t );      // error
   void __based(void)* operator new ( __segment, size_t );   // error
   void operator delete ( void __huge* );                    // error
   void operator delete ( __segment, void __based(void)* );  // error
};


Compiler Error C2833

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

The following sample generates C2833:

class A {
};

void operator ::* ();   // C2833, remove the * to resolve the error

void main() {
}


Compiler Error C2834

'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

user-defined conversion 'type' takes no formal parameters

User-defined type conversions cannot take formal parameters. The following sample generates C2835:

class A {
   public:
      char v_char;

      A() {
         v_char = 'A';
      };
      operator char(char a) {      // C2825, remove "char a" to resolve
         return v_char + 1;
      };
};

int main() {
   A a;
}


Compiler Error C2836

cannot export 'identifier': a previous declaration did not export it

The given identifier is declared to be exported, but a previous declaration does not export it. Declarations of an identifier must be all external or all nonexternal.

Example

extern int i;         // i not exported
int    __declspec(dllexport) i;    // error, i exported


Compiler Error C2837

'identifier' : illegal local static variable in exported inline function

An external inline function attempts to declare a local static variable. This is not allowed.


Compiler Error C2838

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

Example

class Bellini
{
public:
    Norma();
};
class Bottesini
{
    Bellini::Norma();  // error

};


Compiler Error C2839

invalid return type 'type' for overloaded 'operator ->'

The -> operator must return a class, struct, or union, or a reference to one.


Compiler Error C2841

'function' : invalid template function declaration

You specified an invalid function declaration, such as:

template<typename T>
struct X {
   void mf(const T &);
};

template<>
struct X<char> {
   void mf(const char &);
};

template<char>
void X<char>::mf(const char &)
{
}

To fix the error in this code, change template<char> to template<>.


Compiler Error C2844

'member' : cannot be a member of interface 'interface'

An interface 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:

#using <mscorlib.dll>
__gc __interface IFace {
   int i;   // C2844

   // try the line below to resolve the error
   // __property int Size { get; set; };
};

void main(){
}


Compiler Error C2845

'operator' : cannot perform pointer arithmetic on pointer to managed class 'class'

You cannot increment the pointer to a managed class.

The following sample generates C2845:

#using <mscorlib.dll>

__gc class X {
};

void main() {
   X *pX = new X;

   pX++;   // C2845
}


Compiler Error C2846

'constructor' : an interface cannot have a constructor

A Visual C++ interface cannot have a constructor.

For example, the following sample generates C2846:

__interface C {
C();   // C2846; constructor not allowed in an interface
};

void main(){
}


Compiler Error C2847

cannot apply sizeof to managed class, interface or value type 'class'

The sizeof operator gets the value of an object at compile time. The size of a managed class, interface, or value type is dynamic and so cannot be known at compile time.

The following sample generates C2847:

#using <mscorlib.dll>
__gc class A {
};

void main() {
   A *xA = new A;
   sizeof(xA);   // cannot use sizeof on managed object
}


Compiler Error C2849

'destructor' : an interface cannot have a destructor

A Visual C++ interface cannot have a destructor.

For example, the following sample generates C2849:

__interface C {
~C();   // C2849; destructor not allowed in an interface
};

void main(){}


Compiler Error C2854

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:

#pragma hdrstop( "source\\pchfiles\\myheader.pch" )

Do not use angle brackets.


Compiler Error C2855

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

#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

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

Possible cause

  • A #include statement in a conditional compilation block that is not compiled.


Compiler Error C2858

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

filename is not the pdb 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. Recreate the precompiled header.


Compiler Error C2860

'void' cannot be an argument type, except for '(void)'

Type void cannot be used as an argument type with other arguments.

Example

void profunc1(void, int i);    // error C2860
void profunc2(int i, void);    // error C2860
void profunc3(int, void);      // error C2860
void profunc4(void, ...);      // error C2860
void profunc5(..., void);      // error C2059
void func6(int i, void) {}     // error C2860
void func7(int, void) {}       // error C2860
void func8(void, ...) {}       // error C2860
void func9(..., void) {}       // error C2059
void func10(void) {}           // OK


Compiler Error C2861

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

Example

// Example:
//
#pragma keyword("interface", on)

#include <objbase.h>              //    required for IUnknown definition
#undef interface                  //    required - header #define's interface.

interface IMyInterface : IUnknown {
   HRESULT mf(int a);
};

HRESULT IMyInterface::mf(int a)
{                                  // error
   if (a > 0)
      return S_OK;
   else
      return E_FAIL;
}


Compiler Error C2862

'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 code will generate C2862:

// compile cl /c
#include <unknwn.h>
#undef interface
#pragma keyword("interface", on)

[com, uuid="60719E20-EF37-11D1-978D-0000F805D73B"]
interface IMyInterface {
  HRESULT mf1(void);  // OK
protected:
  HRESULT mf2(int *b);  // 2862 : An interface may only have public methods
private:
  HRESULT mf3(int *c);  // 2862 : An interface may only have public methods
};


Compiler Error C2863

'interface' : an interface cannot have friends

Declaring friends on an interface is not allowed. The following sample demonstrates instances of this error:

// compile : cl /c
#include <unknwn.h>
#undef interface
#pragma keyword("interface", on)

interface IMyInterface1;

class CMyClass {
   void *f();
};

interface IMyInterface {
   void g();
   friend int h();  // 2863 : An interface cannot have friends
   friend interface IMyInterface1;  // 2863 : An interface cannot have friends
   friend void *CMyClass::f();  // 2863 : An interface cannot have friends
};


Compiler Error C2864

'variable' : only const static integral data members can be initialized inside a class or struct"

You attempted to initialize a nonstatic data member.

class B  {
int i = 3;   // C2864;
// try ...
// static const int i = 3;
};


Compiler Error C2865

'function' : illegal comparison for references to managed class 'class'

You can compare references to managed 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 NGWS runtime might move managed objects at any time, changing the outcome of the test.


Compiler Error C2866

'variable' : const static data members of managed class must be initialized at their declarations"

It is illegal to declare an uninitialized, const static data member in a managed class or struct.

For example, the following sample generates C2866:

#using <mscorlib.dll>

__gc class CMyClass {
   public:
   const static double d; // C2866, initialize d to resolve
};

void main() {
}


Compiler Error C2867

'identifier' : is not a namespace

A using-directive is applied to something other than a namespace.

Example

namespace N {
   class X {};
}
using namespace N::X;   //error


Compiler Error C2868

'identifier' : illegal syntax for using-declaration; expected qualified-name

A using-declaration requires a qualified name. Anything else causes this error.

Example

class X {...};

void f() {
   using X;   //Error
}


Compiler Error C2869

'name' : has already been defined to be a namespace

You cannot reuse a name already used as a namespace.

Example

namespace A { int i; };

class A { // error C2869, A is already used
};


Compiler Error C2870

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

Example

void main(void) {
   namespace A { int i; }; // error C2870

}


Compiler Error C2871

'name' : does not exist or is not a namespace

Possible causes

  • Extending an item that is not a namespace.
  • Adding a nonexistent namespace with a using declaration.
  • Adding something that is not a namespace with a using declaration.

Example

int A;
int i;

namespace A { \\ error: cannot extend; A is not a namespace
   using namespace B; \\ error: namespace B does not exist
   using namespace i; \\ error: i is not a namespace
}


Compiler Error C2872

'symbol' : ambiguous symbol

The compiler cannot determine which symbol you are referring to.

Example

namespace A {
   int i;
}

using namespace A;

int i;

void z() {
   ::i++;   // ok
   A::i++;   // ok
   i++;      // error C2872, ::i or A::i?
}


Compiler Error C2873

'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

using-declaration causes a multiple declaration of 'symbol'

The declaration causes the same item to be defined twice.

Example

namespace Z {
   int i;
}

void a() {
   int i;
   using Z::i; // error C2874, i already declared
}


Compiler Error C2875

using-declaration causes a multiple declaration of 'class::identifier'

The declaration causes the same item to be defined twice.

Example

class A {
public:
   int z;
};

class B : public A {
   using A::z;
   using A::z; // C2875, A::z defined more than once
};


Compiler Error C2876

'class::symbol' : not all overloads are accessible

All overloaded functions derived from a base class must be accessible in the derived class.

Example

In the following code, the int version of overloaded function a is not accessible in B.

class A {
public:
   double a(double);
private:
   int a(int);
};

class B : public A {
   using A::a; // error C2876
};


Compiler Error C2877

'symbol' is not accessible from 'class'

All members derived from a base class must be accessible in the derived class.

Example

In the following code, variable a is not accessible in B.

class A {
private:
   int a;
};

class B : public A {
   using A::a; // error C2877
};


Compiler Error C2878

'name' : a namespace or class of this name does not exist

You made reference to a namespace or class that is not defined.

Example

The following code shows namespace B defined as an alias for namespace C, but C does not exist. The code compiles if you use namespace A instead of namespace C.

namespace A {}

namespace B = C;   // error C2878, namespace C doesn't exist


Compiler Error C2879

'symbol' : symbol can not be aliased

You cannot create a namespace alias to a symbol other than a namespace.

Example

int i;

namespace A = i; // error C2879, i is not a namespace


Compiler Error C2880

'symbol' : a symbol of this name already exists in the current scope

You tried to create a namespace alias, but the name you chose already exists.

Example

namespace A {
   int k;
}

int i;

namespace i = A; // error C2880, i already exists


Compiler Error C2881

'namespace1' : is already used as an alias for 'namespace2'

You cannot use the same name as an alias for two namespaces.

Example

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

'name' : illegal use of namespace identifier in expression

You tried to use the name of a namespace in an expression.

Example

namespace A {
   int k;
}

int i = A; // error C2882, can't assign A to i


Compiler Error C2883

'name' : local 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.

Example

namespace A {
   void z(int);
}

void f() {
   using A::z;
   void z(int); // error C2883, z is already defined
}


Compiler Error C2884

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

Example

namespace A {
   void z(int);
}

void f() {
   void z(int);
   using A::z; // error C2884, z is already defined
}


Compiler Error C2885

'class::identifier' : a using-declaration as a member of a class must be a member-declaration

You used a using declaration incorrectly. If you use the using keyword with a class member, C++ requires you to define that member inside another class (a derived class).

Example

class A {
public:
   int i;
};

void z() {
   using A::i; // error C2885, not member declaration
}


Compiler Error C2886

'class::identifier' : symbol cannot be used in a member using-declaration

A using declaration uses a symbol, such a namespace name. A using declaration is for declaring base class members.

Example

namespace Z {
   int i;
}

class A {
   using Z::i; // error c2886, Z::i is a namespace
};


Compiler Error C2888

'identifier' : symbol cannot be defined within namespace 'namespace'

A symbol belonging to namespace A must be defined in a namespace that encloses A.

Example

namspace M {
   namespace N {
      void f1();
      void f2();
   }
   void N::f1() {...   //OK: namspace M encloses N
   }
}

namespace O {
   //Error: namespace O does not enclose M
   void M::N::f2(){...
   }
}


Compiler Error C2890

'class' : managed class can only have one non-interface superclass

A managed class can have only one base class. The following sample generates C2890:

#using <mscorlib.dll>

__gc class A {
};
__gc class B {
};

__gc class C : public A, public B {   // C2890
};

/* to resolve the error use the code below
__gc class C : public A {
};
*/
void main() {
}


Compiler Error C2892

'statement' : reference template parameters are not supported

You cannot use a reference argument in a template parameter. For example, the following sample generates C2892. The comment line in the following example (below the line that gives the error) has code that shows one way to resolve the error.

#include <stdio.h>

void func(int* const n) {
   printf("\ntest\n");
}

template <int*& I = 0>      // error C2892
// template <int* I = 0>
struct  Y
{
   void mf() { func(I); }
};

void mf()
{
  Y<> a;
  a.mf();
}

void main(){mf();}


Compiler Error C2893

Failed to specialize function template 'template name'

The compiler failed to specialize a function template. There can be many causes for this error. Try changing your source code to specialize the function template in a different way.


Compiler Error C2894

templates cannot be declared to have 'C' linkage

Possible cause

  • Template defined inside an extern “C” block.

Example

extern “C” {

   template<class T> class stack {   //error
   };
   template<class T> void f(const T &aT){} //error
}

and

extern “C” template<class T> void f(const T &aT) {} //error


Compiler Error C2895

'function' : cannot explicitly instantiate a function template that has been declared with dllimport

Example

template<class T> void mf(T) {...

};
template void __declspec(dllimport) mf<int>(int); //error

The following code works if the function can be inlined. Otherwise the function in the DLL is called and the error occurs:

template<class T> void mf(T) {...
}
inline template void __declspec(dllimport) mf<int>(int);


Compiler Error C2896

'function1' : cannot use function template 'function2' as argument

A function template cannot be an argument to another function template.

Example

template<class T1, class T2> void f1(void(*)(T1, T2));
template<class T1, class T2> void f2(T1, T2);

void g() {
   f1(f2);
}


Compiler Error C2897

'declaration' : destructors cannot be templates

Destructors cannot be overloaded, so declaring a destructor as a template (which would define a set of destructors) is not allowed.

Example

class X {
public:
   template<typename T> ~X() {...} //Error
};


Compiler Error C2898

'declaration' : member function templates cannot be virtual

Example

class X {
public:

   //Error:
   template<typename T> virtual void f(T t){...}
};


Compiler Error C2899

typename cannot be used outside a template declaration

The typename keyword can be used only in a template definition or declaration. In a template declaration, it can be used in two ways:

// One way
template<typename T> class X {};

// Another way
template<class T> struct X {
   typename T::A a;   // T::A is a type
};

Example

struct Y {
   typedef int B;
   typename Y::B b;   //error
};


Compiler Error C2901

'declaration1' : function differs from 'declaration2' only by return type or calling convention

Under ANSI compatibility (/Za), a function template specialization cannot differ from the primary function template by return type or calling convention only.

Example

template<class T> void __cdecl f(T);
template<> void __stdcall f(int);


Compiler Error C2902

'token' : unexpected token following 'template', identifier expected

The token following the keyword template was not an identifier.

Example

namespace N {
   template<class T> class X {};
   class Y {};
}
void f() {
   N::template X<int> x1; // legal
}
void g() {
   N::template + 1; // error C2902
}


Compiler Error C2903

'identifier' : symbol is neither a class template nor a function template

Code attempts explicit instantiation of something that is not a template.

Example

namespace N {
   template<class T> class X {};
   class Y {};
}
void g() {
   N::template Y y; // error C2903
}


Compiler Error C2904

'identifier' : template-name already defined as 'declaration'

Check the code for duplicate names.

Example

void X(); // X is declared as a function
template<class T> class X{}; // error


Compiler Error C2906

C++ language change: to explicitly specialize class template 'identifier' use the following syntax -

Under ANSI compatibility (/Za), you must use the new syntax for explicit specialization of templates:

template<class T> class X{};   // primary template
class X<int> { }         // old syntax, error with /Za
template<> class X<int> { };   // new syntax


Compiler Error C2907

explicit specialization; 'declaration' is not a member of a class template

Code attempts explicit specialization of a static data member of a non-template class.

Example

class X {
   static int data;
};

template<> int X::data=0; // error


Compiler Error C2908

explicit specialization; 'template' has already been specialized from the primary template

A specialization of the primary template occurs before the explicit specialization.

Example

template<class T> class X {};

void f() {
X<int> x;      //specialization and instantiation
         //of X<int>
}

template<> class X<int> {}   //explicit specialization, error


Compiler Error C2909

'identifier': explicit instantiation of template function requires return type

An explicit instantiation of a function template requires explicit specification of its return type. Implicit return type specification does not work.

Example

template<class T> int f(T);
template f<int>(int);   // error
template int f<int>(int);   // OK


Compiler Error C2912

explicit specialization; 'declaration' is not a function template

You cannot specialize a nontemplate function.

Example

void f();
template<> void f<char>(char); // error


Compiler Error C2913

explicit specialization; 'declaration' is not a class template

You cannot specialize a nontemplate class.

Example

class X{};
template<> class X<int> {}; // error


Compiler Error C2914

'identifier' : cannot deduce template argument as function argument is ambiguous

The compiler cannot determine which overloaded functions to use.

Example

void f(int);
void f(double);

template<class T> void g(void (*) (T));

void h() { g(f); } // error


Compiler Error C2917

'name' : invalid template-parameter

A template parameter list contains an identifier that was not a template parameter.

Example

template<class T> class Vector { void sort(); };

template<class T> void Vector<C>::sort() // error: 'C'
{
}


Compiler Error C2918

'name' : illegal use of local type in template instantiation

You cannot generate a template function (a function from a function template) based on a local type. Types used to instantiate templates must have external linkage.

Example

template<class T> void f(T t) {};

void g()
{
    struct X {};
    X x;

    f(x);          // error
}


Compiler Error C2919

illegal use of anonymous local type in template instantiation

You cannot generate a template function (a function from a function template) based on a local type. Types used to instantiate templates must have external linkage.

Example

template<class T> void f(T t) {};

void g()
{
    struct {} x;

    f(x);         // error
}


Compiler Error C2920

redefinition : 'class' : template class has already been declared as 'identifier'

A class has multiple declarations, which are not equivalent.


Compiler Error C2921

redefinition : 'class' : template class is being redeclared as 'identifier'

A class has multiple declarations, which are not equivalent.


Compiler Error C2922

'symbol' : a friend function of a template class must have been previously declared

A class declaration includes a reference to a friend function that is not defined. A prototype for the friend function must appear before the class declaration (perhaps in an include file).


Compiler Error C2923

'type' : 'identifier' is invalid as template argument 'number', type expected

The argument list is missing a type needed to instantiate the template. Check the template declaration.


Compiler Error C2924

'identifier' : explicit instantiation; name is not a member of a template-class specialization

You cannot explicitly instantiate an identifier that is not a templated class.

Example

template int NotAClass;  // error


Compiler Error C2925

'identifier' : explicit instantiation; class 'member' does not specify a template-class specialization

You cannot explicitly instantiate a member of a nontemplated class.

Example

class C
{
   public: void a(void){};
};
template C::a(void);  // error


Compiler Error C2926

'type' : types with no linkage cannot be used as template arguments

You cannot generate a template class (a class from a class template) based on a local type. Types used to instantiate templates must have external linkage.

Example

template<class T> class X{};

void f()
{
    struct Y{};

    X<Y> x;         // error
}


Compiler Error C2927

'function' : a template function 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

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

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

Example

template A<int>::A();
extern template A<int>::A();  // error


Compiler Error C2930

'class' : template-class-id redefined as an enumerate of 'enum identifier'

You cannot use a templated class as a member of an enumeration.

Possible cause

  • Braces improperly matched.


Compiler Error C2931

'class' : template-class-id redefined as a member function of 'identifier'

You cannot use a templated class as a member function of another class.

Possible cause

  • Braces improperly matched.


Compiler Error C2932

'class' : template-class-id redefined as a data member of 'identifier'

You cannot use a templated class as a data member.


Compiler Error C2933

'class' : template-class-id redefined as a typedef member of 'identifier'

You cannot use a templated class as a typedef member.


Compiler Error C2934

'class' : template-class-id redefined as a nested 'item' of 'identifier'

You cannot use a templated class as a nested item.


Compiler Error C2935

'class' : template-class-id redefined as a global function

You cannot use a templated class as a global function.

Possible cause

  • Braces improperly matched.


Compiler Error C2936

'class' : template-class-id redefined as a global data variable

You cannot use a templated class as a global data variable.

Possible cause

  • Braces improperly matched.


Compiler Error C2937

'class' : template-class-id redefined as a global typedef

You cannot use a templated class as a global typedef.


Compiler Error C2938

'class' : template-class-id redefined as a global 'item'

You cannot use a templated class as an item.


Compiler Error C2939

'class' : template-class-id redefined as a local data variable

You cannot use a templated class as a local data variable.

Possible cause

  • Braces improperly matched.


Compiler Error C2940

'class' : template-class-id redefined as a local typedef

You cannot use a templated class as a local typedef.


Compiler Error C2941

'class' : template-class-id redefined as a local 'item'

You cannot use a templated class as an item.


Compiler Error C2942

'class' : template-class-id redefined as a formal argument of a function

You cannot use a templated class as a formal argument. You cannot pass an argument directly to the constructor of a templated class.


Compiler Error C2943

'class' : template-class-id redefined as a type argument of a template

You cannot use a templated class, instead of a symbol, as a template type argument.

Example

template<class T> class List {};
template<class List<int> > class MyList;   // error


Compiler Error C2944

'class' : template-class-id redefined as a value argument of a template

You cannot use a templated class, instead of a symbol, as a template value argument.


Compiler Error C2945

explicit instantiation does not refer to a template-class specialization

You cannot explicitly instantiate something that is not templated.


Compiler Error C2946

explicit instantiation; 'class' is not a template-class specialization

You cannot explicitly instantiate a nontemplated class.

Example

class C {};
template C;  // error


Compiler Error C2947

'identifier' : cannot specialize a template-class with a reference to a local-extern

A template specialization uses the address of a variable or function whose first declaration occurs in a local extern context.

Example

template<int* p> class X {};
void func ()
{
    extern int i;
    X<&i> object;   // error
}


Compiler Error C2948

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 C2949

'symbol' : explicit instantiation; cannot use 'auto' and 'extern' on the same template-class specialization

A template class is instantiated once using the extern storage-class specifier and once without. If you instantiate a template class more than once, you must use the same storage-class specifier for each declaration.

Example

template <class T> class X {};
extern template X<int>;
template X<int>;   // error


Compiler Error C2950

'symbol' : invalid left delimiter in template declaration : expected '<'

The symbol appears after the keyword template.

Possible cause

  • Improper macro expansion.

Example

template <<class T> class D{};  // error


Compiler Error C2951

template declarations are only permitted at global or namespace scope

You cannot declare a template outside global or namespace scope. If you make your template declarations in an include file, make sure the include file is at global scope.

Example

void main()
{
   template <class T> class A {};  // error
}


Compiler Error C2952

template declaration must specify parameter list

You cannot declare a template without specifying a parameter list. A template declaration is meaningless unless it has a parameter list consisting of one or more types.

Example

template<> class C {};  // error
template<class T> class D {};  // okay


Compiler Error C2953

'identifier' : template class has already been defined

Check the source file and include files for other definitions.

Example

template <class T> class A    {};
template <class T> class A    {};  // error


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2954

template definitions cannot nest

Possible cause

  • Improper matching of braces.


Compiler Error C2955

'identifier' : use of class template requires template argument list

You cannot use a class template as an identifier without a template argument list.

Example 1

template<class T> class X {};
X x;      // C2955

Example 2

The following code is illegal,

#include <string>
int x=std::basic_string.npos;

You may have intended something like,

#include <string>
int x = std::basic_string<char>.npos;
// or
// int x = std::string.npos;


Compiler Error C2956

'<' : unexpected for non-template class 'identifier'; ignoring template argument list

You cannot instantiate a non-templated class.

Possible cause

  • Wrong class name before the angle brackets.

Example

class c{};
c<int> MyClass;  // error


Compiler Error C2957

'symbol' : invalid left delimiter for template class 'identifier' : expected '<'

The symbol appears instead of an opening angle bracket when referring to a templated class.

Possible cause

  • Improper macro expansion.

Example

template <class T> class c {};
c <<int> Instantiation1;  // error


Compiler Error C2958

the left delimiter found at 'location' was not matched correctly

A delimiter is not properly matched.

Possible cause

  • Mismatched parenthesis in a function template declaration.


Compiler Error C2959

'identifier' : an 'enum' may not be declared as a template

Only class, struct, and union specifiers can be used when declaring a templated class.

Example

template <class T> enum E{};  //error


Compiler Error C2960

template 'identifier' requires a tag-name

A union, struct, class, or enum specifier following a template class lacks its own identifier.

Example

template <class T> class D struct; // error


Compiler Error C2961

syntax error : 'token' : unexpected token in template declaration

The token caused a syntax error in a template declaration.

Possible cause

  • Mismatched delimiters.


Compiler Error C2962

syntax error : 'token' : expected template-class member function definition to end with '}'

The token caused a syntax error in a template declaration.

Possible cause

  • Mismatched delimiters.


Compiler Error C2963

string literals are not permitted as parameter to a template specialization

One or more of the template parameter expressions is a string literal.

Possible solution

  • Use a pointer to a string variable.


Compiler Error C2964

invalid expression as template parameter

One or more of the template parameter expressions is not valid as a template parameter. Check the template declaration for parameter types.

Example

class C {};
template<class T, C c> class MyClass {};
template MyStack< int, 4 >;  // error


Compiler Error C2965

'identifier' : invalid overloading of static data member for template class 'class'

You cannot overload an identifier already defined as static.


Compiler Error C2966

'identifier' : adding member function of same name as existing static data member for template class 'class'

There is a naming conflict between a static data member and a function member of a templated class.


Compiler Error C2967

'identifier' : adding static data member of same name as existing member function for template class 'class'

There is a naming conflict between a static data member and a function member of a templated class.


Compiler Error C2968

'identifier' : user specialization of template class has an incomplete definition : expected '}' but found 'symbol'

The compiler was unable to match braces around a templated class while attempting to generate a user specialization. Check the braces in the template definition.


Compiler Error C2969

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:

class A {
   int   i;
   public:
   A(int i) {
   }
};

A anA(1);

class B {
   A a;
   B() : a(anA);   // C2969
   /*
   // try ...
   B() : a(anA) {
      // ...
   }
   */
};


Compiler Error C2970

'class' : template argument 'parameter' : invalid use of static variable 'variable' as non-type argument

You cannot use the name or address of a static variable as a template argument. For example, the following code shows how this error would be generated:

// compile with cl /c
//
static int si;   // cannot use static variable in templates
template <int i> class X {};
template <int *pi> class Y{};
X<si> anX;
Y<&si> aY;


Compiler Error C2971

'class' : template argument 'parameter' : invalid use of local variable 'variable' as non-type argument

You cannot use the name or address of a local variable as a template argument.

The following sample generates C2971:

template <int *pi> class Y {
};

int global_var = 0;

void main() {
   int local_var = 0;

   Y<&local_var> aY;   // C2971

   // use the code below to resolve the error
   // Y<&global_var> aY;
}


Compiler Error C2972

'class' : template argument 'number' : 'token' is not a valid template argument

You use token as a template argument.


Compiler Error C2973

invalid template argument 'number'

Check the template definition to find the correct types.


Compiler Error C2974

invalid template argument 'number', type expected

The template argument does not match the template declaration. A type should appear within the angle brackets. Check the template definition to find the correct types.


Compiler Error C2975

invalid template argument 'number', constant expression expected

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.


Compiler Error C2976

'identifier' : too few template arguments

A template is missing one or more actual arguments. Check the template declaration to find the correct number of template parameters.

Possible cause

  • Missing template arguments in STL components.


Compiler Error C2977

'identifier' : too many template arguments

A template has too many actual arguments. Check the template declaration to find the correct number of template parameters.

Example

template<class T, int i> class MyClass {};
template MyClass< int , 1, 1 >;  // error


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C2980

unexpected token in template declaration

The template declaration has a syntax error.


Compiler Error C2981

one or more missing '>' in template declaration

The compiler could not find a closing brace for the template declaration

Possible causes

  • An expression with an ambiguous right-shift operator.
  • Improper macro expansion.

Example

template <class T>> class D{};  // error


Compiler Error C2982

'identifier' : new template parameter list has fewer parameters than the previous declaration

A template argument list does not match that of the previous declaration.


Compiler Error C2983

'identifier' : new template parameter list has more parameters than the previous declaration

A template argument list does not match that of the previous declaration.


Compiler Error C2984

'identifier' : template parameters 'argument1' and 'argument2' do not match

A template argument list does not match that of the previous declaration.


Compiler Error C2985

'identifier' : invalid static data member; template class 'class' already has a function member of the same name

There is a naming conflict between a static data member and a function member of a templated class.


Compiler Error C2986

'identifier' : invalid function member; template class 'class' already has a static data member of the same name

There is a naming conflict between a static data member and a function member of a templated class.


Compiler Error C2987

'identifier' : redefinition type mismatch for static data member of template class 'class'

There is a type conflict between two static data members. When multiply defining a static variable, you must use equivalent types.


Compiler Error C2988

unrecognizable template declaration/definition

The template declaration does not parse correctly. Check delimiters.


Compiler Error C2989

'class' : template class has already been defined as a non-template class

The template class redefines a non-template class. Check header files for conflicts. If you are using class template partial specializations, see Knowledge Base article Q240866.

Example

class C{};
template <class T> class C{};  // error


Compiler Error C2990

'class' : non-template class has already been defined as a template class

The nontemplate class redefines a template class. Check header files for conflicts.

Example

template <class T> class C{};  // error
class C{};


Compiler Error C2991

redefinition of template parameter 'parameter'

There was a type conflict between two template definitions of parameter. When multiply defining a template parameter, you must use equivalent types.


Compiler Error C2992

'class' : invalid or missing template parameter list

The class is preceded by a template keyword with no parameters.

Example

template<> class A {};  // error


Compiler Error C2993

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

struct MyStruct {
   int a;char b;
};

template <class T, struct MyStruct S>   // C2993
// try
// template <class T, struct MyStruct * S>
class CMyClass {
};

void main() {
}


Compiler Error C2994

unnamed class in template parameter list

You cannot use the class keyword as a template argument without specifying a class name.


Compiler Error C2995

'function' : template function has already been defined

Make sure that there is only one definition for each member function of a templated class.


Compiler Error C2996

'function' : recursive template function definition

A function definition attempts to instantiate its root templated class. Recursive template instantiations are not allowed.


Compiler Error C2997

'function' : function parameter list must use template parameter 'parameter'

In templated functions, all template parameters must be used as function parameters.

Example

template <class T> int max(int x, int y)  // error: T not used
   {return (x>y)?x:y;}


Compiler Error C2998

'identifier' : is not a valid name for a template definition

The compiler cannot understand the syntax used in the template definition.

Example

template <class T> int x = 1018; // error


Compiler Error C2999

UNKNOWN ERROR
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 consult Microsoft Technical Support.


Compiler Error C3100

'property' : property argument expects only one value

A parameter for the property attribute can only have one value. For example, the following code generates C3100:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX1 {
public:
   [ property(get={0, 1}) ]
   int Size;
};


Compiler Error C3101

'value' : invalid value for property argument 'parameter'

You specified an invalid parameter to the property attribute. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX2 {
public:
   [ property(get=3) ]   // 3 is not a valid value to the get parameter
   int Size;
};


Compiler Error C3102

'attribute_name' : a 'positional' argument cannot follow a 'named' argument

A positional, or anonymous, argument cannot follow a named argument. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX3 {
public:
   [ property(get=1, 0) ]   // get is the named argument
   int Size;
};


Compiler Error C3103

'attribute_name' : too many 'positional' arguments

There are too many positional, or anonymous, arguments. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX4 {
public:
   [ property(1, 0, 0, 0, 0, 0) ]
   int Size;
};


Compiler Error C3104

'parameter_name' : illegal argument for attribute 'attribute_name'

You specified an invalid argument to an attribute. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX5 {
public:
   [ property(set=1) ]   // set is not valid to property attribute
   int Size;
};

See Also

property attribute


Compiler Error C3107

'parameter' : already seen this property argument

Parameters to the property attribute are not repeatable.

For example, in the following code the parameter put appears twice on the property attribute.

#pragma keyword("interface", on)

struct IUnknown {
};

interface IMyIF {
   [ property(put=0, put=0) ]
   int data;
};


Compiler Error C3108

'attribute' : this attribute cannot be used in conjunction with the attribute 'attribute'

The use of some attributes is mutually exclusive. For example, in the following code, the attempt to define a variable with the propget and property attributes causes this error.

typedef long HRESULT;

#pragma keyword("interface", on)

__interface IMyIF {
   [ propget, property(put=0) ]
   int data;
};


Compiler Error C3110

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

#include <unknwn.h>
#undef interface
#pragma keyword("interface", on)

[ com, uuid= "4F98A180-EF37-11D1-978D-0000F805D73B" ]
interface ITestInterface {
  HRESULT mf1(void);
  HRESULT mf1(BSTR);
};


Compiler Error C3113

an 'invalid structure name' cannot not be a template

You attempted to make a class template out of an interface or an enum. For example, given,

template<typename T>
__interface IMyInterface {
};

Will generate C3113 because you cannot templatize an interface.


Compiler Error C3116

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

__interface IMyInterface {
static void myFunc();   // C3116
};


Compiler Error C3117

'%$S' : an interface can only have one base class

You declared an interface that inherits from multiple base classes. For example,

__interface I1 {
};

__interface I2 {
};

__interface I3 : I1, I2 {
};

generates this error.


Compiler Error C3118

'interface' : interfaces do not support virtual inheritance

You tried to virtually inherit from an interface. For example,

__interface I1 {
};

__interface I2 : virtual I1 {
};

generates this error.


Compiler Error C3119

cannot have multiple 'module' attributes with different uuid's

Multiple module statements are not allowed. For example, the following code generates C3119:

#include <unknwn.h>
[emitidl];
[module(name="xx", uuid="00000000-0000-0000-0000-111111111111")];
[module(name="xxx")];

int main(void) { return(0); }


Compiler Error C3120

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

__interface A {
int X(int i, ...);
};

int main(void) { return(0); }


Compiler Error C3121

cannot change GUID for class 'class_name'

You attempted to change the class ID with __declspec(uuid).

For example, the following code generates C3121:

[emitidl];
[module(name="MyLibrary")];

[coclass, uuid="00000000-0000-0000-0000-111111111111"]
class __declspec(uuid("00000000-0000-0000-0000-111111111112")) A {
};
void main() {}


Compiler Error C3122

'property' : a parameterized property must have at least one argument

A parameterized property must have at least one parameter. For example:

// compile with cl /c
__interface IX20 {
   [ property ]
   int Data();
};

See Also

property


Compiler Error C3123

NGWS runtime DLL mscoree.dll is not found on system

An attribute was found that is not supported by the NGWS attribute provider.


Compiler Error C3124

Error loading NGWS runtime DLL mscoree.dll

You should reinstall NGWS; one or more required functions in mscoree.dll are missing.


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Error C3125

Error unloading NGWS runtime DLL mscoree.dll

Contact Microsoft technical support.


Compiler Error C3127

'attribute_name' : you cannot use this attribute in conjunction with attribute 'attribute_name'

You can only use one of the following attributes to describe a member method,

  • propget
  • propput
  • propputref

For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX8 {
   [ propget, propput ] int Size([in] int);  // use propget or propput
};


Compiler Error C3128

'function_name' : 'attribute_parameter' method name does not match previously specified method name, 'function_name'

If you define a data member in a class that derives from an interface with the same data member, the accessor method names must be the same. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

interface IX9 {
   [ property(get="GetSize") ]
   int Size;
};

class CX9 : public IX9 {
public:
   [ property(get="getSize") ]     // Should be GetSize
   int Size;                     // Size is also defined in IX9
};

See Also

property attribute


Compiler Error C3129

The compiler cannot automatically generate a '%$M' method if there is no storage specified

Within a class or struct the compiler cannot automatically generate any method implementations if no storage is specified. For example:

#pragma keyword("interface", on)
#pragma warning(disable:4199)

class CX10 {
public:
   [ property(storage_name=0) ]   // specified no automatic storage
   int Size;
};

See Also

property attribute


Compiler Error C3130

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

project must have a 'module' attribute with a 'name' property

The module attribute must have a name parameter.

For example, the following code will cause this error:

[emitidl];
[public] typedef long int LongInt;
int main() { return(0); }

Note that currently, this error is generated during the linker phase because the linker calls a compiler utility to read the IDL information from the .obj files.


Compiler Error C3133

'attribute_name(s)' : these attributes are only used within the context of a COM interface

The following attributes:

  • bindable
  • defaultbind
  • displaybind
  • helpstring
  • id
  • immediatebind
  • requestedit
  • restricted

are only valid within the context of an interface preceded with one of the following attributes:

  • custom
  • dispinterface
  • dual
  • object

For example:

__interface IX11 {
   [ property, id(1), helpstring("Help!") ]   // id and helpstring not valid on property
   int Size;
};


Compiler Error C3134

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

For example, the following code will generate C3134:

#include <unknwn.h>
[module(name="xx")];

[object, helpstringdll(xx.dll), uuid("00000000-0000-0000-0000-000000000001")] // C3144
// try helpstringdll("xx.dll")
__interface IMyI {
   HRESULT xx();
};

void main(){
}

See Also

Attributes by Usage


Compiler Error C3135

'property' : a property cannot have a 'const' or 'volatile' type

The const and volatile keywords are not permitted on properties.

For example, the following code generates C3135:

__interface IMyI {
   [ property ]
   const int Size;
};


Compiler Error C3136

'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 code shows how this error is generated and how you correct it.

// compile with cl /c

#include "unknwn.h"

_interface A {      // could use _interface A : IUnknown {
int a();
};

[com]
__interface B : A {
int aa();
};


Compiler Error C3137

'property' : a property cannot be initialized

A property cannot be initialized in a constructor’s initialization list.

For example, the following code will generate C3137:

// compile with cl /c
class CMyClass {
public:
  [property] int prop;
  CMyClass() : prop(1) {};   // this line causes C3137
};

You can eliminate the error by rewriting the constructor to be

CMyClass() {
   prop = 1;
}


Compiler Error C3138

'interface' : a 'attribute' interface must inherit from IDispatch, or from an interface that inherits from IDispatch

An interface with the dual or dispinterface attriubtes does not have IDispatch as a direct or indirect base interface.

The following code shows how this error would be generated:

// compile with cl /c
#include <unknwn.h>
#pragma keyword("interface", on)

[ com, custom, uuid("77ac9240-6e9a-11d2-97de-0000f805d73b") ]
interface IMyCustomInterface
{
   HRESULT mf1(void);
};

[ com, dispinterface, uuid("3536f8a0-6e9a-11d2-97de-0000f805d73b") ]
interface IMyDispInterface : IUnknown
{
   HRESULT mf2(void);
};

[ com, dual, uuid("34e90a10-6e9a-11d2-97de-0000f805d73b") ]
interface IMyDualInterface : IMyCustomInterface
{
   HRESULT mf3(void);
};


Compiler Error C3139

'struct' : cannot export a UDT without members

You attempted to apply the export attribute to an empty UDT (user-defined type). For example:

#include "unknwn.h"
[emitidl];
[module(name=xx)];

[export] struct MyStruct {   // empty type
};
void main(){}


Compiler Error C3140

cannot have multiple 'module' attributes in the same compilation unit

The module attribute can only be defined once per project. For example, the following sample will generate C3140:

[emitidl];
[module(name=MyLibrary)];
[module(name=MyLibrary2)];   // C3140


Compiler Error C3141

'interface_name' : interfaces only support public inheritance

Interfaces defined with the interface (or __interface) keyword only support public inheritance.

For example, the following code generates C3141:

// compile: cl /c
//
#pragma keyword("interface", on)

interface IBase {};
interface IDerived1 : protected IBase {};  // C3141
interface IDerived2 : private IBase {};    // C3141


Compiler Error C3142

'property_name' : you cannot take the address of a property

The address of a property is not available to the programmer.

The following code sample generates C3142:

#include <stdio.h>
__interface IMyI {
   [ property ] int Property;
};

void main() {
  if (&IMyI::Property == 0) { printf("ptr-to-mbr was null.\n"); }
}


Compiler Error C3145

'object' : cannot declare a global or static managed object or a gc pointer

You can only define NGWS objects within function scope.

The following sample generates C3145:

#using <mscorlib.dll>
Object *o;   // C3145, declaring in main is OK
__gc class X {
public:
   void mf() {
      static X *pX = new X();   // C3145
      // try the following line instead
      // X *pX = new X();
   }
};

void main() {
   Object *p;
}


Compiler Error C3146

'main' : invalid signature for main function

The function main cannot have more than three parameters. For example:

void main(int a1, int a2, int a3, int a4)   { // C3146
}


Compiler Error C3148

illegal __nogc pointer to managed type 'type'

A pointer to a managed type cannot be declared with the __nogc keyword.

The following sample generates C3148:

#using<mscorlib.dll>
__gc  class G {
};

void main() {
   G __nogc *pg;   // C3148
   // try ..
   // G *pg;
   // or
   // G __gc *pg;
}


Compiler Error C3149

'class' : illegal use of managed type 'object type'; did you forget a '*'?

Managed objects have to be declared as pointers.

The following sample generates C3149:

#using <mscorlib.dll>

__gc class A {
};

void main() {
   A a = new A;   // C3149

   // try this to resolve the error
   // A *a = new A;
}


Compiler Error C3150

'element' : 'attribute' can only be applied to a class, interface, array or pointer

The managed attribute can only be used on a class, interface, or array.

The following sample generates C3150:

#using <mscorlib.dll>

__gc void f() {   // C3150; function cannot be managed
}

void main() {
}


Compiler Error C3152

'element' : 'attribute' can only be applied to a class

Certain attributes can only be applied to a C++ class.

The following sample generates C3152:

#using <mscorlib.dll>

__value __interface A {   // C3152;
};

__value class X {
   int f();
};

void main(){
}


Compiler Error C3153

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

#using <mscorlib.dll>
__interface A {
};

void main() {
   A *a = new A;   // C3153
}


Compiler Error C3154

'attribute' : illegal usage of attribute

An attribute was used in an unsupported way. You may have used a managed attribute with a COM attribute. Or you may have applied an attribute to a keyword for which it was not intended.


Compiler Error C3155

in a 'new' expression 'keyword' can only be applied to an array

When creating an object on the managed heap with the new operator, the object must be an array.


Compiler Error C3156

'class' : you cannot have a local definition of a managed class, struct or interface

A function cannot contain the definition of a managed class, struct, or interface.

The following sample generates C3156:

#using <mscorlib.dll>

void f() {
   __gc class X {   // C3156
   };
}

void main() {
}


Compiler Error C3158

'construct' : destructors and copy constructors are not allowed in a value-type

Value type objects are allocated on the stack and have predefined copy constructors that perform binary copy operations. You cannot define copy constructors so that copying is done differently.

The following sample generates C3158:

#using <mscorlib.dll>
__value class C {
   ~C();   // C3158
   C(const C& c);   // C3158
};
void main() {
}


Compiler Error C3159

'pointer' : array of pointers to value type cannot be declared

An array of pointers to a value type cannot be declared.

The following sample generates C3159:

#using <mscorlib.dll>

__value struct B {
};

void f( B*[] );   // C3159

void main() {
}


Compiler Error C3160

'pointer' : cannot declare interior gc pointer as a member of 'class'

Interior garbage collection (GC) pointers may point to the interior of a managed class. Because they are slower than whole-object pointers and require special handling by the garbage collector, you cannot declare GC pointers as members of a class.

The following sample generates C3160:

#using <mscorlib.dll>
int __gc* pg2; // OK

__gc struct A {
   // cannot create interior pointers inside a class
   int __gc* pg; // C3160
};
void main() {
}


Compiler Error C3161

'interface' : interface nesting or nesting in interface is illegal

An __interface can only appear at global scope or within a namespace. A class, struct, or union cannot appear in an interface. The following sample generates C3161:

__interface X {
   __interface Y {
   };   // C3161. A nested interface
};

void main() {
}


Compiler Error C3162

'function' : a pure function cannot be '__sealed'

The __sealed keyword was applied to a pure virtual function. A pure virtual function must be implemented in a derived class; a __sealed method cannot be implemented by a derived class.

The following sample generates C3162:

#using <mscorlib.dll>

__gc class CMyClass {
   __sealed void virtual Function(void) = 0;   // C3162
};

void main() {
}


Compiler Error C3164

Unrecognized symbol inside brackets

When declaring an array, an invalid value was specified inside the brackets.

The following sample generates C3164:

int[10] i;
int[k] j;   // C3164, k is not valid here
void main() {
}


Compiler Error C3167

Unable to initialize COM+: make sure URT is installed

The NGWS run-time library is not installed on this computer; install NGWS.


Compiler Error C3168

'type' : illegal type for managed enum underlying type

The underlying type you specified for the enum type was not valid. The underlying type must be an integral C++ type or a corresponding Managed Extensions for C++ type.

The following sample generates C3168:

#using <mscorlib.dll>

__gc class G {
};

__value enum E : G {e};   // C3168

// use the line below to resolve the error
// __value enum E {e};

void main() {
}


Compiler Error C3169

'function' : cannot declare a managed object or a gc pointer within an unmanaged function

Unmanaged functions cannot declare managed objects or pointers to managed objects.

The following sample generates C3169:

#using <mscorlib.dll>

__gc class A {
};

#pragma unmanaged   // remove this line to resolve

void func() {
   A __gc* a;   // C3169
}

#pragma managed

void main() {
}


Compiler Error C3170

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:

// 1.cpp
[ module(name="MyModule", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f") ];

// 2.cpp
[ module(name="MyModule1", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f") ];

the compiler would generate C3170 (note the different names).


Compiler Error C3171

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

// 1.cpp
[ module(name="MyModule", uuid="373a1a4e-469b-11d3-a6b0-00c04f79ae8f", version="1.0") ];

// 2.cpp
[ 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

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

// 1.cpp
[ idl_module(name="x", dllname="file.dll", version="1.1") ];

// 2.cpp
[ idl_module(name="x", dllname="file.dll", version="1.0") ];

the compiler would generate C3172 (note the different version values).


Compiler Error C3173

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

module attribute was not specified

A program that uses Visual C++ attributes did not also use the module attribute, which is required in any progam that uses attributes.

The following sample generates C3174:

// uncomment the following line to resolve this C3174
// [module(name="x")];
[export]
struct S {
   int i;
};

void main() {
}


Compiler Error C3175

'function1' : cannot call a method of a managed class from unmanaged function 'function2'

Unmanaged functions cannot call member functions of managed classes.

The following sample generates C3175:

#using <mscorlib.dll>

__gc struct A {
   static void func() {
   }
};

#pragma unmanaged      // remove this line to resolve

void func2() {
   A::func();         // C3175
}

#pragma managed

void main() {
   A *a = new A;
   func2();
}


Compiler Error C3176

'type' : cannot declare local value type

A class can only be declared as a value type at global scope.

The following sample generates C3176:

#import <mscorlib.dll>
// Declare the class here to resolve the error.
void main() {
   __value class V {   // C3176
   };
}


Compiler Error C3177

'enum' : can only specify underlying type for managed enum

An enum was declared incorrectly. How this error is resolved depends on whether you are compiling with /com+.

The following sample generates C3177:

#using<mscorlib.dll>   // Delete, if you are not using /com+

enum E : int { e1, e2 };   // C3177
// To resolve for /com+
// __value enum E : int { e1, e2 };
// To resolve without /com+
// enum E { e1, e2 };

void main() {
}


Compiler Error C3178

'type' : unable to initialize a managed object in initializer list

An attempt was made to initialize a member during the creation of an object. Initialize members in a separate instruction.

The following sample generates C3178:

#using<mscorlib.dll>
__value struct V {
   String *s;
};

void main() {
   V v = { S"Hello" };   // C3178
   // The following line resolves the error.
   // V v;
   // v.s = S"Hello";
}


Compiler Error C3179

unnamed managed class/struct is not allowed

All managed classes and structs must have names.

The following sample generates C3179:

#using<mscorlib.dll>
typedef __value struct {
// The following line resolves the error.
// typedef __value struct MyStruct {
   int i;
} V;   // C3179

void main() {
}


Compiler Error C3200

'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. Consider the following code,

template<typename T>
class X {
};

template<template<typename U> class T1, typename T2>
class Y {
};

Calling Y<int, int> aY will generate C3200. The first parameter needs to be a template, for example, Y<X, int> aY.


Compiler Error C3201

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 class template that does not take a template parameter. For example, given:

template<typename T1, typename T2>
class X3 {
};

If you then issue Y<X3, int> aY; you will generate C3201. A more appropriate call would be Y<int, int> aY;.


Compiler Error C3202

'arg name' : invalid default argument for template parameter 'parameter', expected a class template

You passed an invalid default argument for a template parameter. For example, given,

template<typename T>
class X {
};

template<template<typename U> class T1 = int, typename T2>
class Y {
};

Calling Yclass T1 = int will generate C3202. Instead of int, a valid argument would be X.


Compiler Error C3204

you cannot call _alloca from within a catch block

This error occurs when you use a call to _alloca from within a catch block. For example, in the code fragment below, the call to SysAllocString will cause this error:

// compile with /GX
#include <malloc.h>

void ShowError(void)
{
   try
   {
   }
   catch(...)
   {
      _alloca(1);
   }
}


Compiler Error C3206

'function' : member functions of nested classes of a template class cannot be defined outside the class

For inner nested classes inside a template, you must define functions inside the class. Such functions automatically become inline functions.

This error is generated for code allowed by the C++ language, however, not yet supported by Visual C++.

For example, the following sample generates C3206:

template<typename T> class Sequence {
    public:
    class Cursor {
        public:
      Cursor(Sequence*);
// to fix, use the following line instead of the preceding line
//      Cursor(Sequence*){}
    };
};

template<typename T> Sequence<T>::Cursor::Cursor(Sequence<T>*) {  }
// error, remove previous line

void main()
{
   Sequence<int>::Cursor c(0);
}


Compiler Error C3241

'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. For example:

#pragma warning(disable:4199)

__interface IX12A {
   void mf();
};

__interface IX12B {
   void mf(int);
};

class CX12 : public IX12A, public IX12B {
   void IX12A::mf(int);
};


Compiler Error C3242

'function' : you can only explicitly override virtual functions

You tried to explicitly override a nonvirtual method.


Compiler Error C3243

none of the overload functions were introduced by 'interface'

You tried to explicitly override a member that does not exist in the specified interface. For example:

#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()   // Error C3243 occurs here
{
}


Compiler Error C3244

'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. For example:

#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()   // Error C3244 occurs here
{
}


Compiler Error C3246

'class' : cannot inherit from 'class' as it has been marked as 'sealed'

A class that is marked as sealed cannot be the base class for any other classes. For example, the following sample generates C3246:

__sealed class X {
};

class Y : public X {
};

void main(){
}


Compiler Error C3247

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

[module(name="MyLib")];
[coclass]
class a {
};

[coclass]
class b : public a {   // C3247
};
void main() {
}


Compiler Error C3248

'function': function marked as 'sealed' -- cannot be overridden by 'function'

A derived class tried to override a sealed virtual method. For example:

class B {
public:
   __sealed virtual void func();
};
class D:B {
public:
   void func(); // error
};


Compiler Error C3250

'class' : invalid base class for value type 'class'

A value class can only inherit from an interface or from Microsoft.Runtime.Object; any other base class is illegal.

The following sample generates C3250:

valueclass VC1 {
   int i;
};

valueclass VC2 : public VC1 {   // C3250; VC1 not an interface of Object
   int j;
};

If you intend to have VC2 contain an instance of VC1, declare VC1 as a member:

valueclass VC2 {
   VC1 m_vc1;
   int j;
};


Compiler Error C3251

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:

class bug1 {
public:
   int RunTest()    {
      Integer4 i = 2;
      Class c1 = i.GetClass();   // C3251
      return 0;
   }
};


Compiler Error C3252

'function' : cannot change access level of a method in a derived class

Since all methods in an interface are public, it is illegal to define an interface method in the private section of a class.

The following sample generates C3252:

#using <mscorlib.dll>
__gc __interface A {
   void f1();
};

class B : public A {
   private:
   void f1();   // C3252; cannot change access level

   public:
   /* declare here to resolve the error
   void f1();
   */
};

void main() {
}


Compiler Error C3253

'unmanaged class' : a managed class cannot derive from an unmanaged class

You attempted to use an unmanaged class as a base class for a managed class

The following sample generates C3253:

#using <mscorlib.dll>

struct S {   // unmanaged class
};

/* use the code below to resolve the error
__gc struct S {
};
*/

__gc class C : public S   {   // C3253
};

void main() {
}


Compiler Error C3254

'function' : can only apply __transient to a data member

The __transient keyword can only be applied to class data members.

The following sample generates C3254:

#using<mscorlib.dll>

__gc __serializable class X {
   __transient func();   // C3254
};

void main() {
}


Compiler Error C3256

'member' : must be a member of serializable class or struct; 'class/struct' is not marked as __serializable

For a member to be marked as __transient, the class must be marked as __serializable.

The following sample generates C3256:

#using<mscorlib.dll>

__gc class X {
// The follow line resolves the error.
// __gc __serializable class X {
   __transient int A;   // C3256
};

void main() {
};


Compiler Error C3257

'object' : cannot create a temporary of a managed class

You cannot create temporary, stack-based objects for managed classes. The compiler attempted to create a temporary object that is not directly mentioned in the code. This temporary object is created on the stack because there is no call to new.

The following sample generates C3257:

#using <mscorlib.dll>
__gc class X {
   public:
   X();
   X(int i) {
      X();   // C3257
   }
};

void main() {
}


Compiler Error C3258

'class' : operator overloading is not implemented for managed classes

Operator overloading is not allowed with managed classes.

The following sample generates C3258:

#using <mscorlib.dll>

__gc class A {
   public:
   int i;
   A *operator=(const int _i) {   // C3258
      i = _i;
      return(this);
   }
};

void main() {
   A *a = new A;
}


Compiler Error C3259

'class2' : explicitly unmanaged class cannot derive from a managed 'class1'

A class that is explicitly defined as unmanaged cannot inherit from a managed class.

The following sample generates C3259:

#using <mscorlib.dll>

__gc __interface A {
};

__nogc class B : public A { // C3259
};

void main() {
}


Compiler Error C3262

invalid array indexing: '#' dimension(s) specified for '#'-dimensional 'array type'

An array was improperly subscripted: the number of indices does not match the number of dimensions in the array.

The following sample generates C3262:

#using <mscorlib.dll>
void main() {
int iArr __gc[,] = new int __gc[10,20];
iArr[1,2,3]; // error: 3 dimensions specified for 2-dimensional array
}


Compiler Error C3264

'class' : a class-constructor cannot have a return type

Class constructors cannot have return types.

The following sample generates C3264:

#using <mscorlib.dll>

__gc class X {
   public:

   static int X() { // C3264
   }

   /* use the code below to resolve the error
   static X() {
   }
   */
};
void main() {
}


Compiler Error C3265

'managed construct' : cannot have managed entities in an unmanaged context 'unmanaged construct'

You cannot include a managed object in an unmanaged context.

The following sample reproduces C3265:

#using <mscorlib.dll>
__gc class A {
};

__nogc class B {
/* make class B managed to resolve the error
__gc class B {
*/
   A *a;          // C3265
   __gc int b[];   // C3265
};

void main() {
}


Compiler Error C3266

'class' : a class-constructor must have a 'void' parameter list

Constructors in a class using Managed Extensions for C++ cannot take parameters. The following sample generates C3266:

#using <mscorlib.dll>

__gc class X {
   static X(int i) { // C3266
   }

   /* the following code resolves the error
   static X() {
   }
   */
};

void main() {
}


Compiler Error C3267

'class' : a class-constructor must be fully defined within the enclosing class

Class constructors must be fully defined within the enclosing class definition.

The following sample generates C3267:

#using <mscorlib.dll>

__gc class X {
   public:
   static X(); // C3267

   /* use the lines below to resolve the error
   static X() {
   }
   */
};

void main() {
}


Compiler Error C3268

'class' : the 'structlayout' attribute can only be applied to a managed-class or value-type

The layout attribute can only be used with managed classes or value types.

The following sample generates C3268:

#using <mscorlib.dll>

[ structlayout(sequential) ]
class A {      // C3268
};

/* use the following class definition to resolve the error
__gc class A {
};
*/

void main() {
}


Compiler Error C3269

'function' : a member-function of a managed class cannot be declared with '...'

Managed-class member functions cannot declare variable-length parameter lists.

The following sample generates C3269:

#using <mscorlib.dll>

__gc struct A {
   void func(int i, ...) {   // C3269, remove ', ...' to resolve
   }
};

void main() {
}


Compiler Error C3273

'__finally' : not allowed on C++ try block

__finally can be used after all exception blocks.


Compiler Error C3274

__finally without matching try

A __finally statement was found without a matching try. To resolve, either delete the __finally statement or add a try statement for the __finally.

The following sample generates C3274:

#using <mscorlib.dll>
void main(int argc, char** argv) {
   try {
      try {
         throw new ApplicationException();
      }
      catch(...) {
         Console::Error->WriteLine(L"Caught an exception");
      }
      __finally {
         Console::WriteLine(L"In finally");
      }
   } __finally {
      Console::WriteLine(L"In finally");
      }
/*
      try {
         throw new ApplicationException();
      }
*/
      // resolve by commenting out the following __finally
      // or by uncommenting the previous try
      __finally {   // C3274
         Console::WriteLine(L"In finally");
      }

   Console::WriteLine(L"**FAIL**");
   }


Compiler Error C3275

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

The following sample shows the two situations in which C3275 could be generated:

#using <mscorlib.dll>
__value enum Jewelry {
   necklace, brooch, pin, ring, earring
   };

__value enum Phone {
   busy, ring, disconnect
   };

void main() {
   Phone p = ring;   // C3275
   // try the following line instead
   // Phone p = Phone::ring;

   Console::Out->Write(ring);   // C3275
   // try the following line instead
   // Console::Out->Write(Phone::ring);
}


Compiler Error C3276

'keyword' : jump out of __finally block has undefined behavior during termination handling

This error is the same as the C4532 warning. However, when you are using Managed Extensions for C++, this condition cannot be disabled with the warning pragma.


Compiler Error C3277

'object' : an instance of an unmanaged class cannot be embedded within a managed class

The compiler does not allow you to instantiate an unmanaged class inside a managed class. It is possible, though, to have a pointer to an unmanaged class inside a managed class.

The following sample generates C3277:

#using <mscorlib.dll>
class X {
public:
   void mf();
};

__gc class Y {
private:
   X m_data;   // C3277
   // The following line resolves the error.
   // X* m_data;
};

void main() {
}


Compiler Error C3280

'class' : a member-function of a managed class cannot be compiled as an unmanaged function

Managed class member functions cannot be compiled as unmanaged functions.

The following sample generates C3280:

#using <mscorlib.dll>

__gc struct A {
   #pragma unmanaged   // remove this line to resolve
   void func() {      // C3280
   }
   #pragma managed
};

void main() {
}


Compiler Error C3303

'attribute': attribute can only be used on 'usage'

An attempt was made to use an attribute where it is not valid. For example, the following sample generates C3303:

[module(name="MyLib")];
[coclass, uuid("11111111-1111-1111-1111-111111111111")]   // C3303
__interface b {
};

void main() {
}


Compiler Error C3305

'attribute' : attribute usage is not supported

An attribute block was not properly formed. For example, an attribute block that should end with a semicolon is missing the semicolon.

The following sample generates C3305:

[module(name="xxx", lcid="0x0000")]
int main() {
return(0);
}


Compiler Error C3309

'macro_name': module name cannot be a macro

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:

#define NAME MyModule
[module(name="NAME")];   // C3309
// The following line resolves the error.
// [module(name="MyModule")];
[coclass]
class MyClass {
public:
   void MyFunc();
};

void main() {
}


Compiler Error C3313

'classname' : not a supported IDL type

You attempted to apply the export attribute to a class definition. For example:

[module(name=ExportModule)];

[export] class tagMyClass {
public:
   char m_JustData;
};


Compiler Error C3317

'attribute': is incompatible with attribute 'attribute'

Two incompatible attributes were encountered in an attribute block.

The following code sample shows two instances of this error, however, that this error is not limited to the use of custom and dual together, as demonstrated in the attribute block; the error may fire for other incompatible attributes.

#include <unknwn.h>
// a COM interface must be either custom or dual, but cannot be both.
[ com, uuid("6df06330-5fbd-11d2-97d3-0000f805d73b"), custom, dual ]
__interface A {
};


Compiler Error C3320

'udt': UDT cannot have same the name as the module 'name' property

An exported user-defined type (UDT), which could be a struct, class, enum, union or __value, cannot have the same name as the parameter passed to the module attribute’s name property.

The following sample generates C3320:

#include "unknwn.h"
[module(name="xx")];

[export] struct xx {   // C3320. Rename the struct or value passed to the module's name property.
   int i;
};

void main() {
}


Compiler Error C3322

'property': is not a valid property for attribute 'attribute'

A invalid or unrecognized property (or parameter) was passed to an attribute. Check the documentation for the attribute.

The following sample generates C3322:

// x is not a property of the idl_module attribute:
[idl_module(name="MyModule", x="My.dll", uuid="..."), helpstring("Not a rectangle, a square"), entry(1)]
double square([in] double x);

void main() {
}


Compiler Error C3333

'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 C3340

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

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

void main()
{
}


Compiler Error C3346

'attribute': cannot assign values to this attribute

A syntax error was found where an attempt was made to assign a value to an attribute.

The following sample generates C3346:

#include <unknwn.h>
[module(name="xx")];

[object, helpstringdll="xx.dll", uuid("00000000-0000-0000-0000-000000000001")]   // C3346, try helpstringdll("xx.dll")
__interface IMyI {
   HRESULT xx();
};

void main(){
}

See Also

Attributes by Usage


Compiler Error C3347

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

[module(name="xx")];

[idl_module(dllname=x)];   // C3347
// try the following line instead
// [idl_module(name=test, dllname=x)];

void main() {
}


Compiler Error C3350

'delegate' : a Delegate constructor expects two arguments

When you create an instance of a delegate, you must pass two arguments.

The following sample generates C3350:

#using <mscorlib.dll>
__delegate int SumDelegate(int, int);

public __gc class X {
public:
   int MySum(int i, int j) {
      return i + j;
   }
};

void main() {
   SumDelegate *pSD = new SumDelegate();   // C3350
   // try the following line instead
   // SumDelegate *pSD = new SumDelegate(17, &X::MySum);
}


Compiler Error C3351

'object' : if you pass a NULL object instance to a Delegate constructor you must also pass the address of a static member function

The compiler expected the address of a function declared static.

The following sample generates C3351:

#using <mscorlib.dll>

__delegate int D(int, int);

__gc class C {
public:
   int mf(int, int) {
   // declare the function as static
   // static int mf(int, int) {
      return 1;
   }
};

void main() {
   C *pC = new C;

   System::Delegate *pD = new D(0, &C::mf);   // C3351
}


Compiler Error C3352

'function' : the specified function does not match the Delegate type 'type'

The parameter lists for function and the delegate do not match.

The following sample generates C3352:

#using <mscorlib.dll>

__delegate int D(int, int);

__gc class C {
   public:
      int mf(int) {
         return 1;
      }

      /* use the following function definition to resolve the error
      int mf(int, int) {
         return 1;
      }
      */
};

void main() {
   C *pC = new C;

   System::Delegate *pD = new D(pC, &C::mf);   // C3352
}


Compiler Error C3354

'delegate' : the function used to create a multicast Delegate must have a 'void' return type

A multicast __delegate must return void.

The following sample generates C3354:

#using <mscorlib.dll>
__delegate(multicast) int D(int, int);   // C3354
// The following line resolves the error.
// __delegate(multicast) void D(int, int);

__gc class C {
public:
   void mf(int, int) {
   }
};

void main() {
C *pC = new C;
System::Delegate *pD = new D(pC, &C::mf);
}


Compiler Error C3358

'symbol': symbol not found

The required symbol was not found.

The following sample generates C3358:

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

void main() {
}


Compiler Error C3360

'string': cannot create name

The value that was passed to the uuid attribute was not valid.

The following sample generates C3360:

[ uuid("1") ]

// try this line instead
// [ uuid("12341234-1234-1234-1234-123412341234") ]

struct A {   // C3360
};

void main() {
}


Compiler Error C3363

'delegate' : cannot create a Delegate from member of unmanaged class

A method from an unmanaged class was used in the creation of a delegate. Methods used in the creation of a delegate must come from a managed class.

The following sample generates C3363:

#using <mscorlib.dll>
__delegate String* md(int x);

__nogc class td {
// try the following line
// __gc class td {
   public:
      String* method(int x) {
         return Int32::ToString(x);
      };
   };

void main() {
   td* x = new td();
   md* dx = new md(x, td::method);   // C3363
}


Compiler Error C3364

'delegate' : invalid second argument for Delegate constructor; needs to be an lvalue

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:

#using <mscorlib.dll>

__delegate int D(int, int);

__gc class C {
public:
   int mf(int, int) {
      return 1;
   }
};

void main() {
   C *pC = new C;
   System::Delegate *pD = new D(pC, pC->mf(1, 2));   // C3364
   // try the following line instead
   // System::Delegate *pD = new D(pC, &C::mf);
}


Compiler Error C3365

'property name' : a property of this name and type has already been declared

You tried to define a property twice in the same class or interface. For example:

class A {
property int i;
property int i;   // C3365
};


Compiler Error C3366

'variable' : static data members of managed classes must be defined within the class definition

You attempted to reference a static member of a NGWS class or interface outside the definition of that class or interface.

For example, the following example generates C3366:

#using <mscorlib.dll>

__gc class X {
   public:
   static int i;   // initialize i here to avoid C3366
};

int X::i = 5;   // C3366

int main() {
   return 0;
}


Compiler Error C3367

invalid argument for Delegate constructor

An argument passed to the delegate constructor was incorrect.

The following sample generates C3367:

#using <mscorlib.dll>

__delegate void D(int, int);

__gc class C {
   public:
      void mf(int, int) {
      }
};

void main() {
   C *pC = new C;
   int i;

   System::Delegate *pD = new D(i);   // C3367

   // try the line below to resolve the error
   // System::Delegate *pD = new D(pC, &C::mf);
}


Compiler Error C3368

'function declaration' : invalid calling convention for IDL

You can only use the __stdcall or __cdecl calling conventions in an IDL file.

For example, the following sample will generate C3368:

[idl_module(name="Name", dllname="Some.dll")];

[idl_module(name="Name")]
int __fastcall f1();


Compiler Error C3369

'module name': idl_module already defined

The idl_module usage where you define the DLL can only occur once in a program. For example, the following sample generates C3369.

 [idl_module(name="name1", dllname=x.dll)];
[idl_module(name="name1", dllname=x.dll)];

void main(){
}


Compiler Error C3370

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

For example, the following sample generates C3370:

 [module(name=MyLibrary)];
// uncomment the following line to resolve the error
// [idl_module(name="name1", dllname=x.dll)];
[idl_module(name="name1"), entry(100)]
int f1();

void main(){
}


Compiler Error C3371

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

[idl_module(name="Name", dllname="Some.dll")];
[idl_module(name="Name", helpstring="Some help")]   // C3371
int f1();
// try
// [idl_module(name="Name")]
// int f1();

void main(){
}


Compiler Error C3372

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:

#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) ]
class CMyClass {
};

void main() {
}


Compiler Error C3373

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:

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

[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f) ]
class CMyClass : public IMyIface {
};

void main() {
}


Compiler Error C3374

Illegal use of managed function with no arguments

You must use parentheses () with any call to a method in the NGWS Framework.

The following sample generates C3374:

#using <mscorlib.dll>
void main(){
   Exception *e = new Exception();
   Console::WriteLine(e->ToString);   // C3374
   // try the following line
   // Console::WriteLine(e->ToString());
}


Compiler Error C3375

Cannot explicitly inherit 'object' from Delegate

An NGWS Delegate is not eligible as a base class for a class that uses managed extensions for C++.

The following sample generates C3375:

#using <mscorlib.dll>
__gc class X : Delegate {
};


Compiler Error C3376

'type' : type is inaccessible

The type is not accessible. To resolve the error, make the type public. To generate C3376, create two source code files and compile them as described below:

// a.cpp
// compile with /com+ and /LD
// creates a DLL called a.dll
#using <mscorlib.dll>

private __gc class X {   // change 'private' to 'public' to resolve
};

public __gc class Y {
   public:
      Y() {
      }

      X *m_pX;
};

// b.cpp
// compile with /com+
// creates an EXE called b.exe
#using "a.dll"
#using <mscorlib.dll>

void main() {
   Y *pY = new Y;   // C3376
}


Compiler Error C3377

'method' : cannot import method - a parameter type or the return type is inacessible

The method could not be imported because one of the types is not accessible. To generate C3377, create two source code files and compile them as described below:

// a.cpp
// compile with /com+ and /LD
// creates a DLL called a.dll
#using <mscorlib.dll>

private __gc class X {   // change 'private' to 'public' to resolve
};

public __gc class Y {
   public:
      Y() {
      }

      void mf1(X *pX) {
      }
};

// b.cpp
// compile with /com+
// creates an EXE called b.exe
#using "a.dll"
#using <mscorlib.dll>

void main() {
Y *pY = new Y;   // C3377
}


Compiler Error C3378

'type' : cannot import field - the type is inacessible

The field cannot be imported because the type is not accessible. To resolve the error, make the type public. To generate C3378, create two source code files and compile them as described below:

// a.cpp
// compile with /com+ and /LD
// creates a DLL called a.dll
#using <mscorlib.dll>

private __gc class X {   // change 'private' to 'public' to resolve
};

public __gc class Y {
   public:
      Y() {
      }

      X *m_pX;
};

// b.cpp
// compile with /com+
// creates an EXE called b.exe
#using "a.dll"
#using <mscorlib.dll>

void main() {
   Y *pY = new Y;   // C3378
}


Compiler Error C3379

'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 via 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 /com+, the following keywords indicate that a class is managed:

  • __gc
  • __value
  • __serializable

The following sample generates C3379:

#using <mscorlib.dll>

public __gc class A {
public:
   static int i = 9;

   public __gc class BA {   // C3379. Remove public keyword.
   public:
      static int ii = 8;
   };
};

void main() {

   A *myA = new A;
   Console::WriteLine(myA->i);

   A::BA *myBA = new A::BA;
   Console::WriteLine(myBA->ii);
}


Compiler Error C3380

'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 via assembly metadata. public or private can only be applied to a class in a program compiled with /com+.

The following keywords, when used with /com+, indicate that a class is managed:

  • __gc
  • __value
  • __serializable

The following sample generates C3380:

#using <mscorlib.dll>
protected __gc class A {   // C3380. Remove protected keyword.
public:
   static int i = 9;
};

void main() {
   A *myA = new A;
   Console::WriteLine(myA->i);
}


Compiler Error C3381

'class' : an assembly access specifier can only be applied to a managed class, interface or a value-type

When applied to a managed type, such as class or struct, the public and private keywords indicate whether the class will be exposed via assembly metadata. public and private cannot be applied to unmanaged classes.

When used with /com+, the following keywords indicate that a class is managed:

  • __gc
  • __value
  • __serializable

The following sample generates C3381:

public class A {   // C3381. Remove public or make the class managed.
};
void main() {
}


Compiler Error C3382

'type' : assembly access specifier has changed: was 'specifier' is now 'specifier'

You cannot change a type's assembly-level access.

The following sample generates C3382:

#using <mscorlib.dll>

private __gc class X;

public __gc class X {   // C3382
};

void main() {
}


Compiler Error C3401

'structure': cannot resolve export

You attempted to use the export attribute to export an illegal structure. For example, the following code generates C3401:

[emitidl];
[module(name=xxx)];
typedef int IID;
[export] struct StructUnion {
   IID *riidPre;
   union Union {
      [iid_is(riidPre)]  IUnknown * pvObjectPre;
      [iid_is(riidPost)] IUnknown * pvObjectPost;
   };
   IID *riidPost;
};

int main()
{
return(0);
}


Compiler Error C3406

'attribute': empty attribute argument list is not allowed

Either when defining the custom attribute class or when applying the attribute, an empty argument list can never be passed to the attribute.

#using <mscorlib.dll>

using namespace System;

[attribute()]   // C3406
// try the following line instead
// [attribute(Method)]
public __gc class MyAttribute : public Attribute {
public:
   MyAttribute() : Attribute() {
   }
};

public __gc class Data {
public:

   [MyAttribute()]   // C3406
   // try the following line instead
   // [MyAttribute]
   void Exit() {
   };
};

void main() {
}


Compiler Error C3408

'attribute': attribute is not allowed on template definitions

Attributes cannot be applied to template definitions.

The following sample generates C3408:

[coclass]
template <class T>   // templated class definition
class a {
   public:
      a<T>();
};

void main() {
}


Compiler Error C3409

empty attribute block is not allowed

The square brackets were interpreted by the compiler as an attribute block, but no attributes were found.

The following sample generates C3409:

[] // C3409, specify the coclass attribute?
class a {
   };

void main(){
}


Compiler Error C3500

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

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 C3507

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:

[module(name="x")];
[
coclass,
progid("0123456789012345678901234567890123456789"),
uuid("00000000-0000-0000-0000-000000000001")
]
struct CMyStruct {
};
void main() {
}


Compiler Error C3603

'Symbol' : type 'Type' not yet supported in the NGWS runtime

You attempted to use a data type that is not yet supported by the NGWS runtime in a managed object.


Compiler Error C3604

'object': can only create an instance of a NGWS runtime managed class on the managed heap

You cannot declare objects to managed classes on the stack.

The following sample generates C3604:

#using <mscorlib.dll>

[coclass]
__gc class B {
public:
   int i;
   ~B() {
   }
};

void main() {
   B b;   // C3604

/* the following works
   B *b2 = new B;
   B *b3;
   b2 = b;
   b->i = 99;

   Console::Out->WriteLine(b2->i);
   Console::Out->WriteLine(b->i);
   b2->i = 66;
   Console::Out->WriteLine(b2->i);
   Console::Out->WriteLine(b->i);
*/
}


Compiler Error C3607

'calling convention' : calling convention unavailable from the NGWS runtime

When using sysimport on a function, the function cannot be declared with the __fastcall or thiscall calling convention.


Compiler Error C3608

cannot take sizeof a managed array

The sizeof operator gets the value of an object at compile time. The size of a managed array (or managed class) is dynamic and cannot be known at compile time.

For example, the following sample generates C3608:

#using <mscorlib.dll>
void main() {
   int i;
   __gc int arr[];
   arr = new __gc int[6];
   i = sizeof(arr);   // cannot use sizeof on managed array
   Console::Out->WriteLine(i);
}


Compiler Error C3609

'element': 'sealed' keyword can only be used on classes, structs and member functions

The sealed keyword is invalid unless used on a class, struct, or member function.

The following sample generates C3609:

void main() {
   __sealed int i;   // __sealed not allowed on a variable
}


Compiler Error C3610

'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 NGWS runtime classes, such as Object, you need to move the value type to the managed heap.

#using <mscorlib.dll>

__value class A {
};

void main() {
   A a;
   a.GetType(); // C3610

   /* to resolve the error use the lines below
   Object *ovar = dynamic_cast<Object*>(a);
   ovar->GetType();
   */
}


Compiler Error C3613

'symbol': symbol must be 'managed' in this context

You attempted to use a feature that is only permitted on managed objects.


Compiler Error C3614

'function' : sysimport cannot be used on a non-static member function of a managed class

Because sysimport implies a native function, and because the NGWS runtime controls the layout of a class, a native function cannot access members of an instance of a class. However, a static member function has no such restriction as it can only access static data members or other global data, not per-instance object data.

The following sample generates C3614:

#using <mscorlib.dll>

__gc class C {
   [sysimport(dll="Some.dll")] int f1();         // C3614
   // try this
   // [sysimport(dll="Some.dll")] static int f1();
};

void main() {
}


Compiler Error C3616

'number' : subscript not allowed in managed array declaration

A managed array was incorrectly declared. Subscript values are allowed on the right-hand side of the expression but not on the left.

The following sample generates C3616 and shows one way to resolve the error:

#using <mscorlib.dll>

void main() {
   __gc int a[2] = new __gc int [12];   // C3616

   __gc int b[] = new __gc int [12];   // ok
}


Compiler Error C3618

'function': a method marked sysimport cannot be defined

Methods marked with sysimport are defined in the specified .DLL.

The following code sample generates C3618:

#using <mscorlib.dll>
using namespace System;

[ sysimport(dll="user32.dll", name="MessageBox", charset="auto")  ]
void Func();

void Func() {   // C3618, remove this function definition to resolve
}

void main() {
}


Compiler Error C3619

a template cannot be declared within a managed class or interface

Class templates are not allowed in a managed class or interface.

The following sample generates C3619:

#using <mscorlib.dll>

__gc class X {
   template<typename T> class Y {   // C3619; remove template declaration
   };
};


Compiler Error C3622

'class' : class marked 'abstract' 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. For example:

__abstract class a {
};
void main() {
   a aa;   // C3622
}


Compiler Error C3623

'variable' : bit fields are not supported

The use of bit fields is not permitted on variables in a managed class.

The following sample generates C3623:

#using <mscorlib.dll>
__gc class CMyClass {
   public:
      int i : 1;   // C3623
};

void main() {
   CMyClass *pMyClass = new CMyClass();
   pMyClass->i = 3;
   Console::Out->WriteLine(pMyClass->i);
}


Compiler Error C3625

'declaration': 'abstract' keyword can only be used on classes and structs

The __abstract keyword can only be applied to a class or a struct.

The following sample generates C3625:

// to resolve this C3625, remove __abstract from the int declaration
// and declare the struct as follows
// __abstract struct A {
struct A {
   __abstract int j;   // C3625
};

void main() {
}


Compiler Error C3626

'declaration': '__event' keyword can only be used on COM interfaces, native member functions and data members that are pointers to NGWS runtime delegates

The __event keyword can only be applied to an interface or member function.

The following sample generates C3626:

struct A {
   __event int i;   // C3626
// try __event int i();
};

void main() {
}


Compiler Error C3627

Only a value type can be boxed

Only value classes can be boxed.

The following sample generates C3627:

#using <mscorlib.dll>

__value class vA {
};

__gc class A {
};

void main()
{
   A* a;
   __box(a);   // C3627

   // box a value type
   vA va;
   __box(va);
}


Compiler Error C3628

'base class' : managed classes only support public inheritance

An attempt was made to use a managed class as a private or protected base class. A managed class can only be used as a base class with public access.

The following sample generates C3628:

#using <mscorlib.dll>
__gc class B {
};

__gc class D : B {   // C3628, private is the default access level

// The following line resolves the error.
// __gc class D : public B {
};

void main() {
}


Compiler Error C3629

'class': a class that is declared as '__abstract' cannot be a value type nor can it be declared as '__sealed'

A class or struct marked with the __abstract keyword cannot also be marked with __sealed or __value.

The following sample generates C3629:

#using <mscorlib.dll>
using namespace System;

__abstract __value class AB {   // C3629, remove __value
};

__abstract __value struct AS {   // C3629, remove __value
};

__abstract __sealed class SC {   // C3629, remove __sealed
};

__abstract __sealed struct SS {   // C3629, remove __sealed
};

void main() {
}


Compiler Error C3700

'function' : you cannot define a method of a class that has come from an #import

You attempted to define a class method for a class that is available in your code via the #using directive statement.

The following sample generates C3700:

// creates a .dll
// compile with /com+ /LD /link /noentry
#using <mscorlib.dll>
__gc class A {
   public:
      void mf(){
      };
};

// compile with /com+ /c
#using <x1.dll>
void A::mf() {   // C3700
}

void main() {
}


Compiler Error C3701

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

[ event_source(native) ]
class CEventSrc {
public:
   // uncomment the following line to resolve this C3701
   // __event void fireEvent(int i);
};   // C3701

void main() {
}


Compiler Error C3702

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

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

void main() {
}


Compiler Error C3703

'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 resolve the error, give the event and the event handler the same storage class.

The following sample generates C3703:

#include <stdio.h>

[event_source(type=native)]
class CEventSrc {
public:
   __event static void MyEvent();
};

[event_receiver(type=native)]
class CEventHandler {
public:
   void MyHandler() {
   // try the following function declaration instead
   // static void MyHandler() {
      printf("MyHandler was called.\n");
   }

   void HookIt(CEventSrc* pSource) {
      __hook(CEventSrc::MyEvent, pSource, MyHandler);    // C3703
   }

   void UnhookIt(CEventSrc* pSource) {
      __unhook(CEventSrc::MyEvent, pSource, MyHandler);  // C3703
   }
};

void main() {
   CEventSrc src;
   CEventHandler hnd;

   hnd.HookIt(&src);
   __raise src.MyEvent();
   hnd.UnhookIt(&src);
}


Compiler Error C3704

'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 code sample below.

The following sample generates C3704:

[ event_source(native) ]
class CEventSrc {
public:
   __event void fireEvent(int i, ...);   // C3704
// try the following line instead:
//   __event void fireEvent(int i);
};

void main() {
}


Compiler Error C3705

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

#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

[module(dll, name=idid, uuid="12341234-1234-1234-1234-123412341234")];

// To fix the error, uncomment the IEvents interface definition:
///*
[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;   // C3705

   HRESULT fireEvents()
   {
      HRESULT hr = IEvents_event1(123);
      return hr;
   }
};

void main() {
}


Compiler Error C3706

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

The following sample generates C3706:

#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

[module(dll, name=idid, uuid="12341234-1234-1234-1234-123412341234")];

// uncomment [object]
//[object]
__interface IEvents : IUnknown {
   HRESULT event1(/*[in]*/ int i);   // uncomment [in]
};

[dual]
__interface IBase {
   HRESULT fireEvents();
};

[coclass, event_source(com)]
class CEventSrc : public IBase {
   public:
   __event __interface IEvents;   // C3706

   HRESULT fireEvents() {
      HRESULT hr = IEvents_event1(123);
      return hr;
   }
};

void main() {
}


Compiler Error C3707

'function' : dispinterface method must have a dispid

If you use a dispinterface method, you must assign it a dispid. To fix this error, assign a dispid to the 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:

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

void main() {
}


Compiler Error C3708

'interface': improper use of __event; must be a member of a compatible event source

The event cannot be used with the chosen event source. To resolve the error, be sure that the event and the source are compatible.

The following sample generates C3708:

#define _ATL_ATTRIBUTES 1
#include "atlbase.h"
#include "atlcom.h"

[module(name="MyLibrary", version="1.2", helpfile="MyHelpFile")];

[object]
__interface I {
   HRESULT func();
};

// To fix error, change 'native' to 'com' in the following line:
[event_source(native), coclass ]
struct A {
   __event __interface I;   // C3708
};

void main() {
}


Compiler Error C3709

'function': improper syntax for specifying event source in __hook/__unhook

When you specify an event source with __hook or __unhook, the source must be a valid method.

The following sample generates C3709:

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

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

void main() {
}


Compiler Error C3710

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

The following sample generates C3710:

#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("Executing handler1().\n");
   }
   void HookEvents(CEventSrc* pSrc) {
      __hook(CEventSrc::event1, pSrc, bogus);   // C3710
// try the following line instead
// __hook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
   void UnhookEvents(CEventSrc* pSrc) {
      __unhook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
};

void main() {
   CEventSrc eventSrc;
   CEventRec eventRec;
   eventRec.HookEvents(&eventSrc);
   eventSrc.event1();
   eventRec.UnhookEvents(&eventSrc);
}


Compiler Error C3711

'method': an 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:

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

void main() {
}


Compiler Error C3712

'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. For example, in the code below, change the return type of handler1 or event1 to the same type (such as void or another integral type) where indicated by comments.

The following sample generates C3712:

[event_source(native)]
class CEventSrc {
public:
   __event void event1();
};

[event_receiver(native)]
class CEventRec {
public:
   int handler1() {
   // Try the following instead
   // void handler1() {
      return 0;
   }

   void HookEvents(CEventSrc* pSrc) {
      __hook(CEventSrc::event1, pSrc, CEventRec::handler1);   // C3712
   }
   void UnhookEvents(CEventSrc* pSrc) {
      __unhook(CEventSrc::event1, pSrc, CEventRec::handler1); // C3712
   }
};

void main() {
}


Compiler Error C3713

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

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

void main() {
}


Compiler Error C3714

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

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

void main() {
}


Compiler Error C3715

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

The following sample generates C3715:

[event_source(native)]
class CEventSrc {
public:
   __event void event1();
};

[event_receiver(native)]
class CEventRec {
public:
   void handler1() {
   }

   void HookEvents(CEventSrc* pSrc) {
      CEventRec* pRec = this;
      __hook(CEventSrc::event1, pRec, CEventRec::handler1);   // C3715
      // try the following line instead
      // __hook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }

   void UnhookEvents(CEventSrc* pSrc) {
      __unhook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
};

void main() {
}


Compiler Error C3716

'method': improper syntax for 'method'

You called __hook or __unhook with an incorrect syntax. To fix this error, ensure that your __hook and __unhook calls specify pointers to valid classes.

The following sample generates C3716:

[event_source(native)]
class CEventSrc {
public:
   __event void event1();
};

[event_receiver(native)]
class CEventRec {
public:
   void handler1() {
   }

   void HookEvents(CEventSrc* pSrc) {
      CEventRec* pRec = this;
      int __hook  = 0;   // C3716
      // try the following line instead
      // __hook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }

   void UnhookEvents(CEventSrc* pSrc) {
      __unhook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
};

void main() {
}


Compiler Error C3717

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

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

void main() {
}


Compiler Error C3718

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.

The following sample generates C3718:

[event_source(native)]
struct A {
        __event void func();
};

[event_receiver(native)]
struct B {
   void func2();
   void HOOK(A* pa) {
   __hook(&A::func, pa, &B::func2);         // valid call
   }
};

void main() {
   A a;
   B b;
   __hook(&A::func, &a, &B::func2, &b);   // C3718, remove this line to resolve the error
   a.func();
}


Compiler Error C3719

'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 C3718:

#include <stdio.h>

__interface I {
   void f();
};

struct MyStruct* pB;

struct MyStruct2 {
   void f();
   MyStruct2() {
      __hook(&I::f, pB, &MyStruct2::f);   // C3719
   }
};

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

#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>

[module(name="xx")];
[object]
__interface I {
   HRESULT f();
};

[coclass, event_source(com)]
struct MyStruct {
   __event __interface I;
};

[event_receiver(com)]
struct MyStruct2 {
   void f() {
   }
   MyStruct2(I* pB) {
      __hook(&I::f, pB, &MyStruct2::f);
   }
};

void main() {
}


Compiler Error C3721

'function': a NGWS runtime event source must return 'void'

NGWS event sources cannot return values.

The following sample generates C3721:

#using <mscorlib.dll>

[event_source(com+)]
__gc class A {
public:
        __event int func();   // C3721, change 'int' to 'void' to resolve
};

void main() {
}


Compiler Error C3722

'event': a native event must be a member function

Native events must be member functions.

The following sample generates C3722:

#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;   // C3722

   // try the following line instead
   // __event func2();
};

void main() {
}


Compiler Error C3723

'function': could not resolve event

function could not resolve which event to call.

The following sample generates C3723:

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

void main() {
}


Compiler Error C3724

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.

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

void main() {
}


Compiler Error C3725

'attribute class': cannot resolve attribute overload

A constructor for an attribute class is not available for an attribute invocation.

The following sample generates C3725:

#using <mscorlib.dll>
using namespace System;

[attribute(All)]
__gc class MyAttr {
public:
   MyAttr() {
   }
   MyAttr(int) {
   }
};

[MyAttr(1, 1)]
// try the following line instead
// [MyAttr(1)]
class AtClass {
};

void main() {
}


Compiler Error C3726

'class': cannot resolve attribute usage 'usage'

The first parameter to the attribute attribute must specify where the attribute will be valid.

The following sample generates C3726:

#using <mscorlib.dll>
using namespace System;

[attribute("MyAt")]
// try the following line instead
// [attribute(All)]
__gc class MyAttr {
        public:
      MyAttr() {
      }
};   // C3726

void main() {
}


Compiler Error C3727

'event': a NGWS runtime event must be a data member that has pointer to delegate type

NGWS events must be a pointer to a delegate type.

The following sample generates C3727:

#using <mscorlib.dll>

__gc class PseudoDelegate {
};

// Use the following declaration to resolve the error.
// __delegate(multicast) void PseudoDelegate(int);

__gc class MyAttr {
        __event PseudoDelegate* MyE;
};   // C3727

void main() {
}


Compiler Error C3728

'function': is not an event

A function that was called like an event is not declared as an event. For more information, see C3723.


Compiler Error C3731

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:

#using <mscorlib.dll>
[event_source(native)]
struct A {
        __event void MyEvent();
};

[event_receiver(com+)]
// try the following line instead
// [event_receiver(native)]
struct B {
        void func();
        B(A a) {
                __hook(&A::MyEvent, &a, &B::func);   // C3731
        }
};

void main() {
}


Compiler Error C3733

'event': improper syntax for specifying a COM event; did you forget '__interface'?

The wrong syntax was used for a COM event. To resolve the 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"

[event_source(com)]      // change 'com' to 'native' to resolve
struct A {
__event void func();   // C3733
};

void main() {
}


Compiler Error C3734

'class': a managed class cannot be a coclass

The coclass attribute cannot be used with managed classes.

The following sample generates C3734:

#using <mscorlib.dll>

[module(name=x)];

[coclass]
__gc class CMyClass {   // remove the __gc keyword to resolve
};

void main() {
}


Compiler Error C3735

'attribute': NGWS runtime only attribute

The attribute is a NGWS attribute.

The following sample generates C3735:

// compile without /com+ to reproduce C3735
// #using <mscorlib.dll>   // uncomment this line and compile with /com+ to resolve

[attribute(All)]
struct A {         // C3735
};

void main() {
}


Compiler Error C3736

'event': must be a method or, in the case of NGWS runtime events, optionally a data member

Native and COM events must be methods. NGWS events can also be data members.

The following sample generates C3736:

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

void main() {
}


Compiler Error C3737

'delegate': a delegate may not have an explicit calling convention

You cannot specify the calling convention for a __delegate.

The following sample generates C3737:

#using <mscorlib.dll>
__delegate void __stdcall MyFunc();   // C3737

// The following line resolves the error.
// __delegate void MyFunc();

void main() {
}


Compiler Error C3738

'class': custom attribute class does not have any public constructors

A custom attribute class must have a public constructor.

The following sample generates C3738:

#using <mscorlib.dll>
using namespace System;

[attribute(All)]
__gc class A {
private:
// The following line resolves the error.
// public:
   A() {
   }
};   // C3738

void main() {
}


Compiler Error C3739

'class': syntax is only supported when layout_dependent=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:

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

void main() {
}


Compiler Error C3740

templates cannot source or receive events

A templated class or struct cannot contain events.

The following sample generates C3740:

template <typename T>   // Delete the template specification
struct E {
   __event void f();   // C3740
};

void main() {
}


Compiler Error C3741

'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

#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
[module(name="xx")];

[object]
__interface I {
HRESULT f();
};

[ event_receiver(com, layout_dependent=true)]
// class or struct must be declared with coclass
// [ event_receiver(com, layout_dependent=true), coclass]
struct R : I {   // C3741
        HRESULT f() { return 0; }
        R() {}
        R(I* a) {
                __hook(I, a);
        }
};


Compiler Error C3742

'type': could not convert to System::Type*

An attempt was made to use the typeof operator on an unmanaged type.

The following sample generates C3742:

#using <mscorlib.dll>
using namespace System;

__nogc struct MyStruct {
};

// try the following lines instead
// __gc struct MyStruct {
// };

[attribute(All)]
__gc struct AtClass {
   AtClass(System::Type*) {
   }

   AtClass(String*) {
   }

   AtClass(int) {
   }
};

[AtClass(typeof(MyStruct))]
struct B {   // C3742
};

void main() {
}


Compiler Error C3743

too many parameters when the 'layout_dependent' parameter of event_receiver = 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:

#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

unhook must have at least 3 arguments for NGWS runtime events

The __unhook function must take three parameters when used in a program that is compiled for the NGWS run time.

The following sample generates C3744:

#using <mscorlib.dll>
using namespace System;

__delegate(multicast) void delegate1();

[ event_source(com+) ]
public __gc class CPSource {
public:
   __event delegate1* event1;
};

[event_receiver(com+)]
public __gc class CReceiver {
public:
   void Handler1() {
   }

   void UnhookAll1(CPSource* pSrc, CReceiver* pRec) {
      pRec;
      __unhook(pSrc);   // C3744
      // The following line resolves the error.
      // __unhook(&CPSource::event1, pSrc, &CReceiver::Handler1);
   }
};

void main() {
}


Compiler Error C3745

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

struct E {
   __event void func();
   void func(int) {
   }

   void func2() {
   }

   void bar() {
      __raise func();
      __raise func(1);   // C3745
      __raise func2();   // C3745
   }
};

void main() {
   E e;
   __raise e.func();
   __raise e.func(1);   // C3745
   __raise e.func2();   // C3745
}


Compiler Error C3746

'attribute': only custom attributes may be used on assemblies or modules

An attribute block was badly formed. See Using Global Attributes in Managed Extensions for C++.

The following sample generates C3746:

#using <mscorlib.dll>
using namespace System;

[ assembly::module(name="xx") ];   // C3746
// try the following line instead
// [ module(name="xx") ];

void main() {
}


Compiler Error C3747

NGWS frameworks string literals are not allowed in attribute blocks

NGWS string literals are not permitted in attribute blocks.

The following sample generates C3747:

#using <mscorlib.dll>
using namespace System;

[ attribute(All) ]
public __gc struct ABC {
   ABC(String*) {
   }
};

[ ABC(S"test") ]   // C3747
// try the following line instead
// [ ABC("test") ]
public __gc struct AAA {
};

void main() {
}


Compiler Error C3800

'property' : a property cannot be both 'static' and 'virtual'

A property can be static or virtual, but not both.

The following sample generates C3800:

#using <mscorlib.dll>

__gc class X {
   __property static virtual int Size {   // C3800; static or virtual but not both
   };
};

void main() {
}


Compiler Error C3805

'token' : unexpected token, expected either '}' or an identifier

When defining a property, an invalid token was encountered. Remove the invalid token. The following code generates C3805:

#using <mscorlib.dll>
__gc class X {
   __property int Size {
      get {
      };
      void set {   // C3805; void is not valid here
      };
   };
};


Compiler Error C3806

'property' : either a 'get' method and/or a 'set' method must be associated with this property

The body of a property must have at least one get or set method.

The following sample generates C3806:

#using <mscorlib.dll>
__gc __interface I {
   __property virtual int Size {   // C3806; add code for get or set to the body
   };
};

void main() {
}


Compiler Error C3807

unexpected 'character': did you forget a ';'?

A semicolon is missing from the end of an accessor definition.

The following sample generates C3807:

#using <mscorlib.dll>
__gc class X {
    __property int Size {
   get {
   };
   set {
   }   // C3807; add semicolon
   };
};


Compiler Error C3809

'structure' : a managed class/struct cannot have any friend functions/classes/interfaces

Managed classes and structures do not allow friends. To resolve the error do not declare friends inside managed classes.

The following sample generates C3809:

#using <mscorlib.dll>

__gc class A {
};

__gc class B {
   public:
   friend __gc class A;   // C3809
};

void main(){
}


Compiler Error C3811

member access operator '.' illegal with managed pointers

The dot operator cannot be used with managed pointers. The member-selection operator must be used.

The following sample generates C3811:

#using <mscorlib.dll>

class A {
   public:
   void fa(){
   }
};

__gc class B {
   public:
   void fb(){
   }
};

void main() {
   A* a = new A;
   B* b = new B;

   (*a).fa();   // ok, standard C++
   (*b).fb();   // C3811, not allowed with managed pointers

   a->fa();   // ok, stanard C++
   b->fb();   // ok with managed pointers
}


Compiler Error C3812

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

The following sample generates C3812:

#using <mscorlib.dll>

__gc class X {
   static __property int Size; // C3812, remove static specifier

      void get_Size() {
      }
      void set_Size() {
      }
};

void main() {
}


Compiler Error C3813

a property declaration can only appear within a managed class/struct/interface definition

A property can only be declared within a class.

The following sample generates C3813:

void main() {
   __property int Size;   // C3813
}


Compiler Error C3814

'class member' : this member cannot co-exist with a property of the same name

A property and another class member have the same identifier. To resolve this error, change one of the identifiers.

The following sample generates C3814:

// C3814
class CMyClass
{
   public:
   char Size;   // C3814, cannot have the same identifier as property
      __property int Size
   {
         get
         {
         return __Size;
         };
         set
      {
            __Size = value;
         };
   };
   protected:
      int __Size;
};

void main() {
}


Compiler Error C3815

return type of method 'get accessor' must match type of the last parameter of 'set accessor'

When declaring properties, the return value of the Get Accessor method must match the last parameter in the declaration of the Set Accessor method.

The following sample generates C3815:

#using <mscorlib.dll>
__gc class X {
public:
   __property int get_N( int i ) {
      Console::WriteLine( L"int" );
      return m_val[i];
   }
   __property void set_N( int i, char val ) {   // C3815
   // The following line resolves the error.
   // __property void set_N( int i, int val ) {
      m_val[i] = val;
   }

private:
   int m_val[10];
};

void main() {
}


Compiler Error C3816

'declaration' : forward declarations and/or definitions do not have the same attribute 'attribute'

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:

#using <mscorlib.dll>

class C1;

// try the following line to resolve the error
// __gc class C1;

__gc class C1{  // C3816, forward declaration does not use __gc
};

void main() {
}


Compiler Error C3817

'declaration' : property can only be applied to a function

The property keyword can only be a applied to a function definition.

The following sample generates C3817:

#using <mscorlib.dll>

__gc class G {
      __property int x;   // C3817
   };

// the following class defines a property
__gc class X {
public:
   __property int get_N( int i ) {
      Console::WriteLine( L"int" );
      return m_val[i];
   }

   __property void set_N( int i, int val ) {
      m_val[i] = val;
   }

private:
   int m_val[10];
};

void main() {
}


Compiler Error C3820

'construct' : not accessible outside the assembly

A program attempted to use a type, that was imported via metadata, but that was not marked as public.


Compiler Error C3821

'function' : value types/managed classes cannot be used in functions which use '__asm' or '__setjmp'

Functions with inline assembly or setjmp cannot contain value types or managed classes. To resolve the error, remove the inline assembly and setjmp or remove the managed objects.

The following sample generates C3821:

#using <mscorlib.dll>

__gc  class A {
   public:
   int i;
};

void main() {
   // cannot use managed classes in this function
   A *a;

   __asm {
      nop
   }
} // C3821


Compiler Error C3822

'property' : name of the property method must start with 'get_' or 'set_'

Property method names must start with either get_ or set_.

The following sample generates C3822:

#using <mscorlib.dll>

__gc struct A {
   __property int get_Size() {
      return 0;
   }

   __property void SET_Size(int i) {   // C3822
   }

   /* use the property below to resolve the error
   __property void set_Size(int i) {
   }
   */
};

void main() {
}


Compiler Error C3823

'__pin' : storage class modifier can only be applied to a pointer

The __pin keyword can only be applied to pointers.

The following sample generates C3823:

#using <mscorlib.dll>

__pin struct A {   // C3823, cannot use __pin on a struct
};

struct B {
};

void main() {
   __pin B *a1;   // C3823
   // try ..
   // B __pin* a2;
}


Compiler Error C3824

'pointer' : only non-static non-interior local pointers may be declared as pinned

Local pointers declared with the __pin keyword cannot be declared static and cannot be interior pointers.

The following sample generates C3824:

#using <mscorlib.dll>

__gc struct A {
};

void func() {
   static A __pin* a;   // C3824, remove 'static' to resolve
}

void main() {
}


Compiler Error C3825

'class': a managed class can only support NGWS runtime events

Only NGWS events are supported in managed classes. To fix the error, change type parameter of event_source and event_receiver from native to com+. Or remove the __gc from the class declarations so that they are not managed/garbage-collected classes.

The following sample generates C3825 (the code must be compiled with the /com+ compiler switch):

#using <mscorlib.dll>
#include <stdio.h>

[event_source(native)]           // To fix, change 'native' to 'com+'
                                 // or, remove __gc from class
__gc class CEventSrc {
public:
   __event void event1();        // C3825
};

[event_receiver(native)]         // To fix, change 'native' to 'com+'
                                 // or, remove __gc from class
__gc class CEventRec {
public:
   void handler1() {
      printf("Executing handler1().\n");
   }
   void HookEvents(CEventSrc* pSrc) {
      __hook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
   void UnhookEvents(CEventSrc* pSrc) {
      __unhook(CEventSrc::event1, pSrc, CEventRec::handler1);
   }
};

void main() {
   CEventSrc* pEventSrc = new CEventSrc;
   CEventRec* pEventRec = new CEventRec;
   pEventRec->HookEvents(pEventSrc);
   pEventSrc->event1();
   pEventRec->UnhookEvents(pEventSrc);
}


Compiler Error C3826

'__pin' : declaring pinned formal parameters is illegal

A function parameter cannot be decorated with the __pin keyword.

The following sample generates C3826 twice:

#using <mscorlib.dll>

__gc class G {
};

typedef G __pin * GPinPtrType;

void func1(G __pin * x) {
}   // C3826

void func2(GPinPtrType x) {
}   // C3826

void main() {
}


Compiler Error C3828

'object type': placement arguments not allowed while creating instances of managed classes

When creating an object from a managed type, you cannot use the placement form of operator new.

The following sample generates C3828:

#using <mscorlib.dll>

__gc struct M {
};

char bytes[256];

void main() {
   M *m1 = new (&bytes) M();   // C3828
   // The following line resolves the error.
   // M *m1 = new M();
}


Compiler Warning (level 4) C4001

nonstandard extension 'single line comment' was used

Single-line comments are standard in C++ but nonstandard in C. A single-line comment in a C file generates an error under strict ANSI compatibility (/Za) or a warning under Microsoft extensions (/Ze). To disable this warning, use #pragma warning(disable:4001).

Example

int i;    // warning
int j;    /* no warning */


Compiler Warning (level 1) C4002

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. The following sample generates C4002:

#define test(a) (a)

void main() {
   int a = 1;
   int b = 2;
   a = test(a,b);   // C4002
   // try..
   a = test(a);
}


Compiler Warning (level 1) C4003

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:

#define test(a,b) (a+b)

void main() {
   int a = 1;
   int b = 2;
   a = test(b);   // C4003
   // try..
   a = test(a,b);
}


Compiler Warning (level 1) C4004

incorrect construction after 'defined'

The defined operator is incorrectly terminated. When the remainder of the line following defined is compiled, a warning or error appears.

Example

This code generates warning C4004 and a fatal error:

#if defined( ID1 ) || ( ID2 )

The compiler assumes that ID1 is the only operand for defined. The remainder of the line cannot be parsed.

The following code fixes the problem:

#if defined( ID1 ) || defined( ID2 )


Compiler Warning (level 1) C4005

'identifier' : macro redefinition

The macro identifier is defined twice. The compiler uses the second macro definition.

Possible cause

  • Defining a macro on the command line and in the code with a #define directive.
  • Macros imported from include files.

Possible solutions

  • Remove one of the definitions.
  • Use an #undef directive before the second definition.

The following sample generates C4005:

#include <iostream.h>

#define TEST "test1"
#define TEST "test2"   // C4005, delete or rename to resolve the warning

void main() {
   cout << TEST << endl;
}


Compiler Warning (level 1) C4006

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

 #undef   // C4006

// try..
// #undef TEST

void main() {
}


Compiler Warning (level 2) C4007

'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

'identifier' : 'attribute' attribute ignored

The compiler ignored the __fastcall, static, or inline attribute for a function (level 3 warning) or data (level 2 warning).

Possible causes

  • __fastcall attribute with data.
  • static or inline attribute with main function.


Compiler Warning (level 1) C4009

string too big; trailing characters truncated

A string exceeds the compiler limit of 2047 characters. The compiler truncates the string to 2047 characters.

Possible solution

  • Break the string into smaller strings.


Compiler Warning (level 1) C4010

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:

void main() {
   // the next line is also a comment because of the backslash
   int a = 3;
   a++;   // C2065, a is undefined
}


Compiler Warning (level 1) C4011

'identifier' : identifier was truncated to 'number' characters

A name is too long. The maximum length of a linkable external identifier is 247 characters after name decoration. The default maximum length of an undecorated name, or a user-entered fragment of a decorated name, is 32 characters.

Possible solution

  • Use /H to set a different maximum length.


Compiler Warning (level 1) C4012

float constant in a cross compilation

Floating-point constants are not stored the same on different computer architectures. This warning occurs the first time the cross compiler encounters a floating-point constant.


Compiler Warning (level 3) C4013

'function' undefined; assuming extern returning int

The compiler encountered a call to an undefined function.

Possible causes

  • Incorrect spelling of function name.
  • External functions not prototyped as extern.


Compiler Warning (level 1) C4014

concatenating mismatched wide strings

A wide string literal is concatenated with a standard string literal.

Possible cause

  • Wide string literal not prefixed with "L".

Example

char   hello[] = L"Hello, " "world"   // Warning
char   hello[] = L"Hello, " L"world"  // OK


Compiler Warning (level 1) C4015

'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) C4016

'function' : no function return type; using int as default

The function has not been declared or defined, so the return type is unknown. The compiler uses int as a default return type.

Possible solution

  • Add a prototype for the function.


Compiler Warning (level 3) C4018

'expression' : signed/unsigned mismatch

Comparing a signed and unsigned number required the compiler to convert the signed value to unsigned.

Possible solution

  • Cast one of the two types when testing signed and unsigned types for equality (= =) or inequality (!=).

The following sample generates C4018:

void main() {
   unsigned int uc = 0;
   int c = 0;
   // try..
   // unsigned int c = 0;

   if (uc == c)   // C4018
      uc = 0;
}


Compiler Warning (level 4) C4019

empty statement at global scope

A semicolon at global scope is not preceded by a statement.

Possible solution

  • Remove the extra semicolon.

Example

#define declint( varname ) int #varname;
declint( a );         //Warning, int a;;
declint( b )          //OK, int b;


Compiler Warning (level 1) C4020

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


Compiler Warning (level 1) C4021

'function' : too few actual parameters

The number of formal parameters in the function prototype or definition exceeds the number of actual parameters in a function call. Using a formal parameter that has no corresponding actual parameter produces unpredictable results.


Compiler Warning (level 1) C4022

'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

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

Solution

  • Prototype functions that are passed based pointers.


Compiler Warning (level 1) C4024

'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

'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

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

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

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.


Compiler Warning (level 1) C4029

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

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

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

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

void func();
void func(char);     // warning, char promotes to int


Compiler Warning (level 1) C4033

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

int test_1(int x) {

   if (x) {
      test_2();
      return;
   }
}


Compiler Warning (level 1) C4034

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

unnamed 'type' as actual parameter

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

Possible solution

  • Provide the appropriate type.


Compiler Warning (level 1) C4037

conflicting ambient class modifiers

A class, structure, or union has more than one ambient class modifier.


Compiler Warning (level 1) C4038

'modifier' : illegal ambient class modifier

This modifier cannot be used for classes with dllimport or dllexport attributes.


Compiler Warning (level 1) C4041

compiler limit : terminating browser output

Browser information exceeded the compiler limit.

Possible cause

  • Compiling with /FR (browser information including local variables).

Possible solutions

  • Compile with /Fr (browser information without local variables).
  • Disable browser output (compile without /FR or /Fr).


Compiler Warning (level 1) C4042

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

Possible cause

  • Specifying a storage class other than register in a parameter declaration.


Compiler Warning (level 1) C4043

function specifier used more than once

The compiler ignores the second occurrence.

Example

inline inline void  no_op( void ) { };


Compiler Warning (level 1) C4044

'macro_name': macros are not expanded for attribute names or properties

A macro cannot be expanded to represent the name of an attribute or a property of an attribute. This warning is commonly followed by C2337.

The following sample generates C4044:

#define NAME uuid
[module(name="MyModule")];
[coclass, NAME="00000000-0000-0000-0000-000000000001"]   // C4044
// try ...
// [coclass, uuid="00000000-0000-0000-0000-000000000001"]
class MyClass {
public:
   void MyFunc();
};

void main() {
}


Compiler Warning (level 1) C4045

'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

'identifier1' : 'operator' : different 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

void main() {
    char **p;// two levels of indirection
    char *q; // one level of indirection
    p = q;   // warning C4047
}


Compiler Warning (level 1) C4048

different declared array subscripts : 'identifier1' and 'identifier2'

An expression involves pointers to arrays of different size. The pointers are used without conversion.

Possible solution

  • Explicitly cast the arrays to the same or equivalent type.


Compiler Warning (level 1) C4049

compiler limit : terminating line number emission

The file contains more than 65,536 (64K) source lines. The compiler stops numbering at 65,536.


Compiler Warning (level 2) C4051

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.

Possible solution

  • Cast the data items to the appropriate type.


Compiler Warning (level 1) C4052

function declarations different; one contains variable arguments

One declaration of the function does not contain variable arguments. It is ignored.


Compiler Warning (level 1) C4053

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

'conversion' : from function pointer 'type1' to data pointer 'type2'

A function pointer is cast (possibly incorrectly) to a data pointer. This cast generates an error with the C compiler and the ANSI-compatibility (/Za) option.


Compiler Warning (level 1) C4055

'conversion' : from data pointer 'type1' to function pointer 'type2'

A data pointer is cast (possibly incorrectly) to a function pointer. This cast generates an error with the C compiler and the ANSI-compatibility (/Za) option


Compiler Warning (level 2) C4056

overflow in floating point constant arithmetic

Floating-point constant arithmetic generates a result that exceeds the maximum allowable value.

Example

double fp_val = 1.0e300 * 1.0e300;

In this example, the result exceeds the maximum value for a double-precision data item.

Possible cause

  • Compiler optimizations performed during constant arithmetic. You can safely ignore this warning if it goes away when you turn off optimization (/Od).


Compiler Warning (level 4) C4057

'operator' : 'identifier1' indirection to slightly different base types from 'identifier2'

Two pointer expressions refer to different base types. The expressions are used without conversion.

Possible cause

  • Mixing signed and unsigned types.
  • Mixing short and long types.


Compiler Warning (level 1) C4058

unions are now aligned on alignment requirement, not size

When you use /Zp4 or greater to pack structures on boundaries of 4-or-more bytes, structures in a header file may be aligned differently than structures in a library compiled with Microsoft C version 6 or earlier.

Possible solutions

  • Recompile the old library with Visual C++.
  • In the header files, make structures that contain unions the same size they were in Microsoft C version 6 by adding extra members following the unions.
  • You can turn this warning off using #pragma warning(4058 : off).


Compiler Warning (level 1) C4059

pascal string too big, length byte is length % 256

A string followed by \p (the pascal escape sequence) cannot exceed 255 characters. The string is truncated.


Compiler Warning (level 3) C4060

switch statement contains no 'case' or 'default' labels

Example

void func( int i )
{
   switch( i );   // warning
}


Compiler Warning (level 4) C4061

enumerate 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label

The enumerate has no associated handler in a switch statement.

This warning is off by default. To turn it on, use the warning pragma:

#pragma warning(default : 4061)

Example

enum E { a, b, c };
void func ( E e )
{
   switch(e)
   {
   case a:
   case b:
   default:
      break;
   }        // warning, enumerate 'c' not handled by a case label
}


Compiler Warning (level 3) C4062

enumerate '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. To turn it on, use the warning pragma:

#pragma warning(default : 4062)

Example

enum E { a, b, c };
void func ( E e )
{
   switch(e)
   {
   case a:
   case b:
      break;    // no default label
   }            // warning, enumerate 'c' not handled
}


Compiler Warning (level 3) C4063

case 'identifier' is not a valid value for switch of enum 'enumeration'

Example

enum E { a, b };
void func ( E e )
{
   switch(e)
   {
   case a:
   case b:
   case 7:      // invalid switch value
      break;    // no default label
   }
}


Compiler Warning (level 3) C4064

switch of incomplete enum 'enumeration'

A switch statement specifies a selector of an enumerated type that is not defined.

Example

enum E;
void func ( E e )
{
   switch(e)
   {
   case 7:
      break;  // warning, E not defined
   }
}


Compiler Warning (level 3) C4065

switch statement contains 'default' but no 'case' labels

The switch statement specifies a default case only. This is equivalent to a sequence of statements.

Example

void func(int i)
{
   switch(i)
   {
   default:
      func(8);
   }                // warning 4065
}


Compiler Warning (level 3) C4066

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

unexpected tokens following preprocessor directive - expected a newline

The compiler found, and ignored, extra characters following a preprocessor directive. This warning appears only under ANSI compatibility (/Za).

Example

#endif    NO_EXT_KEYS

Possible solutions

  • Compile with /Ze.
  • Use comment delimiters:
#endif    /* NO_EXT_KEYS */


Compiler Warning (level 1) C4068

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:

#pragma NotAValidPragmaName   // C4068, use valid name to resolve
void main() {
}


Compiler Warning (level 3) C4069

long double is the same precision as double

Some platforms, such as the R4000 processor, consider long double to have the same precision as double.


Compiler Warning (level 1) C4070

return of a 'void' expression

Returning a void expression generates a warning when compiling with the C language and Microsoft extensions (/Ze).


Compiler Warning (level 2) C4071

'function' : no function prototype given

The function was called before the compiler found a prototype. The compiler makes the call using the default rules for a function without a prototype.


Compiler Warning (level 1) C4072

'function' : no function prototype on 'convention' function

The function was called before the compiler found a prototype. The compiler makes the call using the default rules for a function without a prototype.


Compiler Warning (level 3) C4073

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:

#pragma init_seg(lib)   // C4073

// try this line to resolve the warning
// #pragma init_seg(user)

void main() {
}


Compiler Warning (level 1) C4074

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:

#pragma init_seg( compiler )   // C4074

// try this line to resolve the warning
// #pragma init_seg(user)

void main() {
}


Compiler Warning (level 1) C4075

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:

#pragma init_seg("mysegƒ\")   // C4075

// try..
// #pragma init_seg(user)

void main() {
}


Compiler Warning (level 1) C4076

'typemod' : may be used on integral types only

A type modifier, whether it is signed or unsigned, cannot be used with a noninteger type. It is ignored.

Example

unsigned double x; // warning


Compiler Warning (level 1) C4077

unknown check_stack option

The old form of the check_stack pragma is used with an unknown argument. The argument must be +, -, or empty.

The compiler ignores the pragma and leaves the stack checking unchanged.

Example

#pragma check_stack yes // warning
#pragma check_stack +    // Correct old form
#pragma check_stack (on) // Correct new form


Compiler Warning (level 1) C4078

case constant 'value' too big for the type of the switch expression

A case statement contains a value larger than the type in the switch expression. The compiler casts the type of the case constant to the type of the switch expression.

If two case constants have different values before casting but the same value afterward, a problem can occur.


Compiler Warning (level 1) C4079

unexpected token 'token'

An unexpected separator token occurs in a pragma argument list. The remainder of the pragma was ignored.

Example

#pragma comment( "Kilroy was here", ) // warning


Compiler Warning (level 1) C4080

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:

extern "C" void func(void);

#pragma alloc_text()   // C4080

// try this line to resolve the warning
// #pragma alloc_text("mysection", func)

void main() {
}

void func(void) {
}


Compiler Warning (level 1) C4081

expected 'token1'; found 'token2'

The compiler expected a different token in this context.

Example

#pragma optimize) "l", on ) // warming


Compiler Warning (level 1) C4082

expected an identifier; found 'token'

A pragma argument list is missing an identifier. The remainder of the pragma is ignored.


Compiler Warning (level 1) C4083

expected 'token'; found identifier 'identifier'

An identifier occurs in the wrong place in a #pragma statement.

Example

#pragma warning disable:4083   //warning
#pragma warning(disable:4083)   //correct

Check the syntax of the #pragma directives.


Compiler Warning (level 1) C4084

expected a pragma keyword; found 'token'

A directive is required after #pragma. The pragma is ignored.

Example

#pragma (on)   // warning


Compiler Warning (level 1) C4085

expected 'on' or 'off'

The pragma requires an on or off parameter. The pragma is ignored.

Example

#pragma optimize( "t", maybe )  // warning


Compiler Warning (level 1) C4086

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

#pragma pack( 3 )


Compiler Warning (level 1) C4087

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

Example

int f1( void );
f1( 10 );


Compiler Warning (level 1) C4088

'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

'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

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

Possible cause

  • A pointer to a const or volatile item is assigned to a pointer not declared as pointing to const or volatile.

Example

const  char *p = "abcde";
int    str( char *s );
str( p ); // warning


Compiler Warning (level 2) C4091

'extended-attribute' : ignored on left of 'type' when no variable is declared

A __declspec attribute at the beginning of a user-defined type declaration applies to the variable of that type. Warning C4091 indicates no variable is declared:

__declspec(dllimport) class X {}; // generates C4091

// correct: the __declspec attribute applies to varX
__declspec(dllimport) class X {} varX;

A __declspec attribute after the class or struct keyword applies to the user defined type (X in the following example):

class __declspec(dllimport) X {};


Compiler Warning (level 4) C4092

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 3) C4093

unescaped newline in character constant in inactive code

The constant expression of an #if, #elif, #ifdef, or #ifndef preprocessor directive evaluates to zero, making the code following it inactive. The inactive code contains a newline character in a set of single or double quotes. All text until the next double quote is considered to be within a character constant.


Compiler Warning (level 2) C4094

untagged 'token' declared no symbols

The compiler detected an empty declaration using an untagged structure, union, or class. The declaration is ignored.

Example

struct  { }; // warning

This condition generates an error under ANSI compatibility (/Za).


Compiler Warning (level 1) C4095

expected ')'; found 'token'

A pragma that takes one argument is given more than one argument. The compiler ignores the remainder of the line.

Example

#pragma inline_depth( 10, 18, 67 )  // warning


Compiler Warning (level 1) C4098

'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

'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 declares as a class is defined as a structure. The compiler uses the type given in the definition. The following sample generates C4099:

struct A;

class A {   // C4099, use different identifer or use same object type
};

void main() {
}


Compiler Warning (level 4) C4100

'identifier' : unreferenced formal parameter

The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored. The following sample generates C4100:

void func(int i) {   // C4100, delete the unreferenced parameter to
//resolve the warning
}

void main() {
    func(1);
}


Compiler Warning (level 3) C4101

'identifier' : unreferenced local variable

The local variable is never used. This warning will occur in the obvious situation:

void main() {
int i;   // C4101
}

However, this warning will also occur when calling a static member function through an instance of the class:

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

'label' : unreferenced label

The label is defined but never referenced. The compiler ignores the label. The following sample generates C4102:

void main() {
   int a;

   test:   // C4102, remove the unreferenced label to resolve

   a = 1;
}


Compiler Warning (level 1) C4103

'filename' : used #pragma pack to change alignment

An include file uses the pack pragma to change the default structure alignment.


Compiler Warning (level 1) C4104

'identifier' : near data in same_seg pragma; ignored

A same_seg pragma specifies a near variable. The same_seg pragma applies only to external far variables.


Compiler Warning (level 1) C4105

'identifier' : code modifiers only on function or pointer to function

The identifier is declared with a code modifier that applies only to a function or function pointer. The modifier is ignored.


Compiler Warning (level 1) C4106

pragma requires an integer between 1 and 127

The page and skip pragmas require an integer constant between 1 and 127. The compiler uses a default value of 1.

Example

#pragma skip( 0 )


Compiler Warning (level 1) C4107

pragma requires an integer between 15 and 255

The pagesize pragma requires an integer constant between 15 and 255. The compiler uses a default value of 63.

Example

#pragma pagesize( 10 )


Compiler Warning (level 1) C4108

pragma requires an integer between 79 and 132

The linesize pragma requires an integer constant between 79 and 132. The compiler uses a default value of 79.

Example

#pragma linesize( 42 )


Compiler Warning (level 1) C4109

unexpected identifier 'identifier'

The pragma containing the unexpected identifier is ignored.

Example

#pragma optimize( on, off )


Compiler Warning (level 1) C4110

unexpected token 'number'

The pragma containing an unexpected integer constant is ignored.

Example

#pragma title( 1984 )


Compiler Warning (level 1) C4111

unexpected token 'string'

The pragma containing an unexpected string is ignored.

Example

#pragma linesize( "92" )


Compiler Warning (levels 1 and 4) C4112

#line requires an integer between 1 and 32767

The #line directive specifies an integer outside the allowable range.

If the specified number is less than 1, the line counter is reset to 1. If the specified number is greater than 32767, 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:

#line 0   // C4112, value must be between 1 and 32767

void main() {
}


Compiler Warning (level 1) C4113

'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

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

Example

volatile volatile int i;   // warning


Compiler Warning (levels 1 and 3) C4115

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

Example

void func(struct S *);  /* warning */

You can avoid this warning by declaring or defining the structure outside the parentheses before the line where the warning occurred:

struct S;
void func(struct S *);

or:

struct S
{
   int mem;
};
void func(struct S *);


Compiler Warning (level 1) C4116

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

macro name 'name' is reserved; 'Command' ignored

Possible causes

  • Trying to define or undefine a predefined macro.
  • Trying to define or undefine the preprocessor operator defined.

The following sample generates C4117:

#define __FILE__ test         // C4117. __FILE__ is a predefined macro
#define ValidMacroName test   // ok

void main() {
}


Compiler Warning (levels 1 and 3) C4118

pragma not supported during fast compile

The fast compiler does not support the pragma. This is a level-3 warning with #pragma comment(), and a level-1 warning otherwise.

To avoid this warning when using the fast compiler, disable the pragma using #ifdef _FAST.


Compiler Warning (level 1) C4119

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

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

'symbol' : alignment of a member was sensitive to packing

A structure member is aligned on a memory offset whose value is not a multiple of the member’s size. For example, the following code snippet will produce this warning:

// compile with cl /W4 /c
#pragma pack(2)
struct foo { char a; int b; };

You could make one of the following changes to prevent this warning:

  • Change pack(2) to pack(4).
  • Reverse the order of the structure members such that the int precedes the char.

When data is not aligned on boundaries that are multiples of the data’s size performance can degrade and if you port your code to a RISC machine it will not compile.

You can specify the structure alignment with #pragma pack or /Zp.


Compiler Warning (level 1) C4122

'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

__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

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

char array1[] = "\\709";

If the digit 9 is intended as a character, correct the example as follows:

char array[] = "\\0709";  /* String containing "89" */


Compiler Warning (level 1) C4126

'option' : unknown memory-model command-line option

/A option uses a character or characters not recognized as a valid memory-model specifier. The option is ignored.


Compiler Warning (level 4) C4127

conditional expression is constant

The controlling expression of an if statement or while loop evaluates to a constant. The code in the body of the if statement or while loop always executes or never executes. The following sample generates C4127:

void main() {
   if (1 == 1) {   // C4127, constant expression
   }
}


Compiler Warning (level 4) C4128

storage-class specifier after type

A storage-class specifier (auto, extern, register, or static) follows a type specifier in a declaration. New-style code places the storage-class specifier first.


Compiler Warning (level 1) C4129

'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 following sample generates C4129:

void main() {
   char array1[] = "\/709";   // C4129

   char array2[] = "\n709";   // try this
}


Compiler Warning (level 4) C4130

'operator' : logical operation on address of string constant

Using the operator with the address of a string literal produces unexpected code.

Example

char *pc;
pc = "Hello";
if (pc == "Hello")
   { }

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

'function' : uses old-style declarator

The specified function declaration is not in prototype form.

Old-style function declarations should be converted to prototype form.

Old style

 int addrec( name, id )
 char *name;
 int id;
 { }

New style

 int addrec( char *name, int id )
 { }


Compiler Warning (level 4) C4132

'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

'type' : incompatible types - from 'type1' to 'type2'

Cause

  • Trying to subtract two pointers of different types.

To avoid this warning, providing an appropriate type cast.


Compiler Warning (level 4) C4134

conversion between pointers to members of same class

A pointer to one member of a class was converted to a pointer to another member of the class. This is necessary because void pointers to members are not allowed.


Compiler Warning (level 3) C4135

conversion between different integral types

Information was lost while converting between two integer types.

To avoid this warning, provide an appropriate type cast.

Example

void main(void)
{
   int intvar;
   long longvar;
   intvar = longvar;  // warning
// intvar = (int) longvar; // No warning for this line
}


Compiler Warning (level 3) C4136

conversion between different floating-point types

Information was lost or truncated during conversion.

Example

double doublevar;
float floatvar;
floatvar = doublevar;
floatvar = 1.0;  // Warning
                 // Unsuffixed floating-point constant has type double
floatvar = 1.0F; // Suffix prevents warning


Compiler Warning (level 1) C4137

'function' : no return value from floating-point function

The function has no return statement. A long double function returns its value on the floating-point stack or emulation stack. If the function does not return a value, a run-time floating-point stack underflow error can occur. Make sure all floating-point functions return a floating-point value.


Compiler Warning (level 1) C4138

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

int */*comment*/ptr;   // Ambiguous first delimiter causes warning

Possible cause

  • Trying to nest comments.

Possible solution

  • To comment out sections of code that contain comments, enclose the code in an #if/#endif block and set the controlling expression to zero:
    #if 0
int my_variable;   /* Declaration currently not needed */
#endif


Compiler Warning (level 1) C4141

'modifier' : used more than once

Example

inline inline void func ();   // warning


Compiler Warning (level 1) C4142

benign redefinition of type

A type is redefined in a manner that has no effect on the generated code.

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.


Compiler Warning (level 1) C4143

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

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

void main() {
   int i = 0;
   switch(!i) {   // C4144, remove the ! to resolve
      case 1:
         break;
      default:
         break;
   }
}


Compiler Warning (level 1) C4145

'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? The following sample generates C4145:

void 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

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 comparsion, 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 MIN_INT from Limits.h, which has the type signed int.

The following sample generates C4146:

#include <stdio.h>
void check(int i)
{
    if (i > -2147483648)   // C4146
      printf("%d is greater than the most negative int\n", i);
}

void main()
{
    check(-100);
    check(1);
}


Compiler Warning (level 2) C4150

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.

Example

class  IncClass;
void   NoDestruct( IncClass* pIncClass )
  {   delete pIncClass;   }


Compiler Warning (level 4) C4152

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

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

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

void func()
{
   int array[ 10 ];
   delete array;       // warning
}


Compiler Warning (level 1) C4155

deletion of an array expression without using the array form of 'delete'

The non-array form of delete cannot delete an array. This warning occurs only under ANSI-compatibility (/Za).

Example

T (*array)[ 10 ] = new T[ 5 ][ 10 ];
delete array;                         // warning


Compiler Warning (level 2) C4156

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

T (*array)[ 10 ] = new T[ 5 ][ 10 ];
delete array;     // warning, changed by compiler to "delete [] array;"


NGWS SDK Documentation

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Compiler Warning (level 1) C4157

pragma was ignored by C compiler

Only the C++ compiler recognizes init_seg().


Compiler Warning (level 1) C4158

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

#pragma pragma(pop,...) : has popped previously pushed identifier 'identifier'

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.

To avoid this warning, give an identifier in the pop instruction. For example:

#pragma pack(push, foo)
#pragma pack(pop) // C4159

// using the identifier resolves the warning
// #pragma pack(pop, foo)


Compiler Warning (level 1) C4160

#pragma pragma(pop,...) : did not find previously pushed identifier 'identifier'

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. For example:

#pragma pack(push)

#pragma pack(pop, id) // C4160
// use identifier when pushing to resolve the warning
// #pragma pack(push, id)

void main() {
}


Compiler Warning (level 3) C4161

#pragma pragma(pop...) : more pops than pushes

Because your source code contains one more pop than pushes, 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. The following example generates C4161:

#pragma pack(push, id)
#pragma pack(pop, id)
#pragma pack(pop, id)   // C4161, an extra pop

void main() {
}


Compiler Warning (level 1) C4162

'identifier' : no function with C linkage found

A function with C linkage is declared but cannot be found.


Compiler Warning (level 1) C4163

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

// compile with /W1
#include <math.h>

#pragma intrinsic(mysin)   // C4163

// use the following line to resolve the warning
// #pragma intrinsic(sin)

void main() {
}


Compiler Warning (level 1) C4164

'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

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

The following sample generates C4165

#include <windows.h>
#pragma warning(1:4165)

extern HRESULT hr;
void main() {
   if (hr) {
   // try either of the following ...
   // if (FAILED(hr)) {
   // if (hr != S_OK) {
   }
}


Compiler Warning (level 1) C4166

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


Compiler Warning (level 1) C4167

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

#include <malloc.h>
#pragma function(_alloca )   // warning: _alloca() is intrinsic only
void main(){}


Compiler Warning (level 1) C4168

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

unexpected end of file found

The file ends with a line-continuation character.

Example

#define BOTTESINI    \
if (1) {             \
}                    \


Compiler Warning (level 1) C4171

'identifier' : modifier functions require prototypes

A function with the __fastcall calling convention is not prototyped or has an old-style prototype.

Example

void __fastcall func1 ( i, j );      // old-style
void __fastcall func2 ( int i, int ) // new style


Compiler Warning (level 1) C4172

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. The following sample generates C4172:

int *func1() {
   int test = 1;
   return &test;      // C4172
}

/* use the following definition of func1 to resolve the warning
int *func1() {
   int test = 1;
   int* testptr = &test;
   return testptr;
}
*/

void main() {
}


Compiler Warning (level 1) C4173

enabling the option option will hinder the performance of incremental compilation

This warning is not used.


Compiler Warning (level 1) C4174

'name' : not available as a #pragma component

Example

#pragma component(info)  // warning; unknown
#pragma component(browser, off)  // turn off browse info


Compiler Warning (level 1) C4175

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

To generate browse information

  • From the command line, specify /FR.

    —or—

  1. From the Project menu, choose Settings.
  2. In the Project Settings dialog box, click the C/C++ tab and select the Generate Browse Info check box.


Compiler Warning (level 1) C4176

'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

#pragma component(browser, off, i)  // warning
#pragma component(browser, off, references, i) // ok


Compiler Warning (level 1) C4177

pragma pragma should be at global scope

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

// #pragma bss_seg("global")   // OK

void main() {
   #pragma bss_seg("local")   // C4177
}


Compiler Warning (level 1) C4178

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

void main()
{
    int i;  // maximum size of unsigned long int is 4294967295
    switch( i )
    {
        case 4294967295:   // OK
            break;
        case 4294967296:   // warning
            break;
    }
 }


Compiler Warning (level 1) C4179

'//*' : parsed as '/' and '/*': confusion with standard '//' comments

//* is an incorrect comment delimiter. Use // or /* instead.


Compiler Warning (level 1) C4180

qualifier applied to function type has no meaning

A qualifier, such as const, is applied to a function type defined by typedef.

Example

typedef int *FuncType(void);

//the const qualifier cannot be applied to the
//function type FuncType, generates warning:
const FuncType f;


Compiler Warning (level 1) C4181

qualifier applied to reference type ignored

A qualifier, such as const, is applied to a reference type defined by typedef.

Example

typedef int &RefInt;
int I;
const RefInt cri=i; //generates warning C4181


Compiler Warning (level 1) C4182

#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

'identifier' : member function definition looks like a ctor, but name does not match enclosing class

The inline definition of a member function in a class or a structure looks like a constructor, but the name of the member function does not match the class or structure name enclosing it. This member function is assumed to have a default return type of int.

Example

class MyClass1;
class MyClass2 {
   MyClass1() {...};
}

The member function MyClass1() is treated as int MyClass1(), not as the constructor for MyClass1.

Make sure the constructor of this class is not misspelled. Misspelled constructors can lead to run time errors that are hard to isolate. If this member function is not intended to be a constructor, you can avoid this warning by explicitly specifying the return type of the member function.


Compiler Warning (level 1) C4185

ignoring unknown #import attribute 'attribute'

The attribute is not a valid attribute of #import. It is ignored.

Example

#import "olepro32.dll" no_such_attribute  // warning


Compiler Warning (level 1) C4186

#import attribute 'attribute' requires count arguments; ignored

A #import attribute has the wrong number of arguments.

Example

#import "olepro32.dll" no_namespace("abc") rename("a","b","c")  // warning

The no_namespace attribute takes no arguments. The rename attribute takes only two arguments.


Compiler Warning (level 1) C4187

#import attributes 'attribute1' and 'attribute2' are incompatible; both ignored

A #import statement specifies no_implementation and implementation_only attributes. Both are ignored.


Compiler Warning (level 4) C4189

'identifier' : local variable is initialized but not referenced

A variable is declared and initialized but not used. The following sample generates C4189:

void main() {
   int a = 1;   // C4189, remove declaration to resolve
}


Compiler Warning (level 1) C4190

'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, union, or __value type) 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

struct X
{
   int i;
   X ();
   virtual ~X ();
};

extern "C" X func ();   // warning


Compiler Warning (level 3) C4191

'operator/operation' : unsafe conversion from 'type of expression' to 'type required'

Calling this function through the result pointer may cause your program to crash.

This warning is disabled by default. See #pragma warning for how to disable or enable warnings.


Compiler Warning (level 3) C4192

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 (levels 2 and 4) C4200

nonstandard extension used : zero-sized array in struct/union

A structure or union contains an array with zero size.

Level-2 warning when compiling a C++ file and a Level-4 warning when compiling a C file.

Example

#include <stdio.h>
struct A {
int a[0];
};
void main(void) {
}


Compiler Warning (level 4) C4201

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

struct S
{
   float y;
   struct
   {
      int a, b, c;  // warning
   };
} *p_s;


Compiler Warning (level 4) C4202

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

void func( a, b, ...)
int   a, b;  // warning
{}


Compiler Warning (level 4) C4203

nonstandard extension used : union with static member variable

Static union members are valid using Microsoft exstensions (/Ze). Such members are illegal in the ANSI standard (/Za). Conforming to the ANSI standard ensures more portable programs. The following sample generates C4203:

// compile with /Ze and /W4 to generate warning
union test {
   static int a;   // C4203, remove static to resolve
};

void main() {
}


Compiler Warning (level 1) C4204

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

int func1();
struct S1{ int i; };
S1 struct1 = { func1() };  // warning

Such initializations are illegal under ANSI compatibility (/Za).


Compiler Warning (level 1) C4205

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

void func1()
{
   static int func2();  // warning
};

Such initializations are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4206

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

nonstandard extension used : extended initializer form

With Microsoft extensions (/Ze), you can initialize an unsized array of char using a string within braces.

Example

char c[] = { 'a', 'b', "cdefg" };

Such initializations are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4208

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.

delete [18] MyArray;  // warning
delete [] MyArray;    // OK

Such values are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4209

nonstandard extension used : benign typedef redefinition

A type was redefined to be the same type as in the first definition.

Example

typedef long lPulseWidth;
typedef long lPulseWidth;  // warning

Such benign redefinitions are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4210

nonstandard extension used : function given file scope

With the default Microsoft extensions (/Ze), function declarations have file scope.

void func1()
{
    extern int func2( double );
}

void main( void )
{
    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

nonstandard extension used : redefined extern to static

With the default Microsoft extensions (/Ze), you can redefine an extern identifier as static.

Example

extern int i;
static int i;  // warning

Such redefinitions are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4212

nonstandard extension used : function declaration used ellipsis

The function prototype has a variable number of arguments. The function definition does not.

This is legal under the default Microsoft extensions (/Ze), but illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4213

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

void *a;
void f()
{
   int   i[3];
   a = &i;
   *(( int * )a )++ = 3;  // warning
}

Such casts are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4214

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

struct bitfields
{
   unsigned short j:4;  // warning
};

Such bitfields are illegal under ANSI compatibility (/Za).


Compiler Warning (level 1) C4215

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:

long float a;   // C4215

// use the line below to resolve the warning
// double a;

void main() {
}


Compiler Warning (level 1) C4216

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:

float long a;   // C4216

// use the line below to resolve the warning
// double a;

void main() {
}


Compiler Warning (level 1) C4218

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

i;  // warning

Such declarations are illegal under ANSI compatibility (/Za).


Compiler Warning (level 1) C4219

nonstandard extension used : trailing ',' used for variable argument list

An argument list ends with a comma. The compiler assumes that it is a variable argument list with the ellipsis accidentally left off.

Example

int func1( int first, );       // warning
int func2( int first, ... );   // OK


Compiler Warning (level 4) C4220

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

int ( *pFunc1) ( int a, ... );
int ( *pFunc2) ( int a, int b);
if ( pFunc1 != pFunc2 ) {};  // warning

Such pointers do not match under ANSI compatibility (/Za).


Compiler Warning (level 4) C4221

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

struct S
{
   int *i;
};
void func()
{
   int j;
   struct S s1 = { &j };  // warning
}

Such initializations are illegal under ANSI compatibility (/Za).


Compiler Warning (level 4) C4222

nonstandard extension used : 'identifier' : 'static' should not be used on member functions defined at file scope

A static member function is defined at file scope. Under ANSI compatibility (/Za), static member functions must be declared with external linkage.

Example

class C
{
   static void func();
};

static void C::func(){};    // warning


Compiler Warning (levels 1 and 4) C4223

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

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

typedef int I;
void func ( int I );  // warning


Compiler Warning (level 1) C4226

nonstandard extension used : 'keyword' is an obsolete keyword

The current version of Visual C++ does not use this keyword.

Possible cause

  • The __export keyword, which is obsolete in 32-bit versions of Windows. Use __declspec dllexport instead.

This warning is automatically promoted to an error. If you wish to modify this behavior, use #pragma warning. For example, to make C4226 into a level 2 warning issue,

#pragma warning(2:4226)

in your source code file.


Compiler Warning (level 1) C4227

anachronism used : qualifiers on reference are ignored

Using qualifiers like const or volatile with C++ references is an outdated practice.

Example

int j = 0;
int &const i = j; /* warning C4227 */


Compiler Warning (level 1) C4228

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 (/Za).

Example

int j, const i = 0;  /* warning C4228 */
int k;
int const m = 0;  /* ok */


Compiler Warning (level 1) C4229

anachronism used : modifiers on data are ignored

Using a Microsoft modifier such as __cdecl on a data declaration is an outdated practice.

Example

int __cdecl counter; / * cdecl ignored */


Compiler Warning (level 1) C4230

anachronism used : modifiers/qualifiers interspersed, qualifier ignored

Using a qualifier before a Microsoft modifier such as __cdecl is an outdated practice.

Example

int __cdecl const function1(); /* cost ignored */


Compiler Warning (level 3) C4231

nonstandard extension used : 'identifier' before template explicit instantiation

When Microsoft extensions are enabled (/Ze), an extern template can be instantiated, generating this warning. Under ANSI compatibility (/Za), such instantiations cause an error.

Example

template<class T, int i> class MyStack {};
extern template MyStack< int, 4>;


Compiler Warning (level 4) C4232

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.


Compiler Warning (level 4) C4233

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,

#pragma warning(2:4233)

in your source code file.


Compiler Warning (level 4) C4234

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

nonstandard extension used : 'keyword' keyword not supported in this product

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 4 warning issue,

#pragma warning(2:4235)

in your source code file.


Compiler Warning (level 4) C4236

nonstandard extension used : 'keyword' is an obsolete keyword, see documentation for __declspec(dllexport)

The _export keyword is obsolete. Use __declspec(dllexport) instead. The following sample generates C4236:

void _export abc() {   // C4236
}

/* use the lines below to resolve the warning
void __declspec(dllexport) abc() {
}
*/

void main() {
}


Compiler Warning (level 4) C4238

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

struct C
{
C();
};
C * pC = &C();   // yields C4238

This usage causes an error under ANSI compatibility (/Za).


Compiler Warning (level 4) C4239

nonstandard extension used : 'token' : conversion from 'type' to 'type'

This type conversion is not allowed by the C++ draft 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

struct C { C(); };
void func(void)
{
//Yields: warning C4239: nonstandard extension used :
//'initializing' : conversion from 'struct C' to
//'struct C&'
//A reference that is not to 'const' cannot be bound
//to a non-lvalue
   C & rC = C();
}


Compiler Warning (level 3) C4240

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

class X {
private:
   class N;
public:
   class N {
   };
};


Compiler Warning (level 3) C4241

'member' : member access is restricted

Code tries to access a private or protected member function or data.

If you need to access this member, change the object access level or make the member a friend of the accessing function.


Compiler Warning (level 4) C4242

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

The following sample generates C4242:

// compile with /W4
#pragma warning(4:4242)
int func() {
   return 0;
}

void main() {
   char a;
   a = func();   // C4242, return type and variable type do not match
}


Compiler Warning (level 1) C4243

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

Example

class B {};
class D : private B {};

D d;
B *q = (B*)&d;;      // warning


Compiler Warning (level 1) C4244

'variable' : conversion from 'type' to 'type', possible loss of data

You assigned a value of type __int64 to a variable of type unsigned int. A possible loss of data may have occurred.


Compiler Warning (levels 3 and 4) C4244

'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 type2 is int and type1 is smaller than int. Otherwise, it is a level 3.

The conversion may have a problem due to implicit conversions.

Example

short a, b, c;
a = b + c;    // warning

See Also

Usual Arithmetic Conversions


Compiler Warning (level 4) C4245

'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch

You tried to convert a signed const that has a negative value to an unsigned.

Example

const int i = -1;
unsigned int j = i; // warning C4245

const int k = 1;
unsigned int l = k; // okay

int m = -1;
unsigned int n = m; // okay


Compiler Warning (level 3) C4247

'member' not accessible because 'class1' uses 'access' to inherit from 'class2'

You tried to access a member of a class that was inherited from another class with the private or protected attribute. This is a warning instead of an error because the access violation occurred due to a type cast.


Compiler Warning (level 3) C4248

'class1' : cannot access 'access' 'member' declared in class 'class2'

The member cannot be accessed from class1 because class1 does not have access rights. The member was not accessed.

To avoid this warning, give class1 access to members of class2 by changing the class access specifier or using the friend specifier.


Compiler Warning (level 3) C4249

'class1' : no path to 'access' 'member' declared in virtual base 'class2'

A member of the virtual base class cannot be accessed from the derived class because the derived class does not have access rights. The member was not accessed.

To avoid this warning, give class1 access to members of class2 by changing the class access specifier or using the friend specifier.


Compiler Warning (level 2) C4250

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


Compiler Warning (level 1) C4251

'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'

A base class or structure must be declared with the __declspec(dllexport) keyword for a function in a derived class to be exported.


Compiler Warning (level 1) C4253

'identifier' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name

A pointer to a non-static member function of a class or structure must have the form of an & followed by the qualified identifier not enclosed in parentheses. This warning is only issued under /Za.

The following sample generates C4253:

#include <stdio.h>

struct A {
   void f() {
      printf("test");
   }
};

int main() {
   A a;
   A *as = new A;

   void (A::*p3)() =  A::f; // ok with -Ze, warning with -Za
   // the following line shows how to assign a pointer to a class member
   // from outside the class
   // void (A::*p3)() = &A::f;

   // calling member function from outside the class
   (as->*p3)();
   return 0;
}


Compiler Warning (level 3) C4255

'type' : redefinition; wchar_t and unsigned short are not always equivalent

wchar_t and unsigned short may not be the same size. The first definition is in effect. This warning is off by default. For example:

// compile with cl /c
#include <wchar.h>

#pragma warning(1: 4255)  // Warning is off by default.

typedef unsigned short WCHAR;
typedef wchar_t WCHAR;   // WCHAR may not be the same type as wchar_t as it is as an unsigned short

typedef wchar_t wchar;
typedef unsigned short wchar;      // warning

See Also

#pragma warning


Compiler Warning (level 1) C4256

'function' : constructor for class with virtual bases has '...'; calls may not be compatible with older versions of Visual C++

Possible incompatibility.

Based on the code sample below, if the definition of the constructor S2::S2( int i, ... ) was compiled with a version of Visual C++ prior to 7, but the code snippet here were compiled with current version, the call to the constructor for S3 would not work correctly, due to a special-case calling convention change. Note that if both were compiled with Visual C++ 6.0, the call would not work quite right either, unless no parameters were passed for the ellipsis.

To resolve 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.
// #pragma warning(disable : 4256)
struct S1 {};
struct S2: virtual public S1 {
   S2( int i, ... );      // C4256 issued here
};

void func1() {
   S2 S3( 2, 1, 2 );      // C4256 issued here as well.
}


Compiler Warning (level 1) C4257

'structure_name' : class has no data members; initialization ignored

You attempted to initialize a structure that contains no members.

// compile with cl /c
struct S { } ;
S anS = {0};


Compiler Warning (level 1) C4258

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

void main() {
int i;
   {
   for (int i =0; i < 1; i++)
      ;
   i = 20;   // i (in for loop) has gone out of scope
   }
}


Compiler Warning (level 1) C4259

'identifier' : pure virtual function was not defined

This warning is generated once for each undefined abstract function defined in a class specified in a C2259 error message. The following sample generates C4259:

class A {
   public:
      virtual void f() = 0;
      /* the following code resolves the warning
      virtual void f() {
      }
      */
};

void main() {
   A a;   // C4259
}


Compiler Warning (level 1) C4261

no override, 'class1::func1' has 'model1' calling convention whereas 'class2::func2' has 'model2' calling convention

The functions have different calling conventions.

Microsoft calling convention specifiers are used for disambiguation between overloaded functions.

The virtual mechanism will not be invoked for functions with differing calling conventions.

Example

struct X
{
   virtual void __near func();
};
struct Y : X
{
   void __far func();  // warning
};


Compiler Warning (level 1) C4263

'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. By default, this warning is off; you can enable it with the warning pragma.

The following sample generates C4263:

#pragma warning(1:4263)
#pragma warning(1:4264)
class B {
    public:
      virtual void func();
};

class D : public B {
      void func(int);   // C4263
};

void main(){}


Compiler Warning (level 1) C4264

'virtual_function' : no override available for virtual member function from base 'class'; function is hidden

The C4264 warning, which is off by default, is always generated after C4263.


Compiler Warning (level 4) C4268

'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

class X {
public:
   int m_data;
};

const X x1;   // Generates warning C4268

As this instance of the class is const, the value of m_data cannot be changed.


Compiler Warning (level 1) C4269

'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

class X {
public:
   int m_data;
};

void g() {
   const X x1;   //Generates the warning
};

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

nonstandard extension used: 'initializing': a non-const 'type1' must be initialized with an l-value, not a function returning 'type2'

A nonconst reference must be initialized with an l-value, making the reference a name for that l-value. A function call is an l-value only if the return type is a reference. Under Microsoft extensions to the C++ language, treat any function call as an l-value for the purpose of initializing references. If Microsoft extensions are disabled (/Za), an error occurs.

Example

struct X
{
   X(int);
   X(X&);
};
X f(X);
X b = f(X(2));   // warning

To avoid this warning

  • Make the reference a const reference. If the reference is const and the function return type is not compatible with the type of the reference, the compiler generates and initializes a temporary variable (which is inefficient), or
  • Use the following pragma:
    #pragma warning(disable:4270)


Compiler Warning (level 1) C4271

'identifier' : 'naked' functions cannot be 'inline'; inline expansion not performed

The function is declared with naked and inline attributes.

Example

inline __declspec( naked )  int func() {}   // warning


Compiler Warning (level 1) C4273

'function' : inconsistent DLL linkage. dllexport assumed

  • A member function is declared in a class with dllexport linkage, then imported or a member function is declared in a class with dllimport linkage, but it is not imported, static, or inline.

The function is linked as dllexport.

The following sample generates C4273:

char __declspec(dllimport) c;

char c;   // C4273, delete this line or the line above to resolve

void main (){
}


Compiler Warning (level 2) C4275

non – DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier'

An exported class was derived from a class that was not exported.


Compiler Warning (level 1) C4276

'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) C4280

'operator –>' was self recursive through type 'type'

Your code incorrectly allows operator–> to call itself.

Example

struct A {
   int z;
   A& operator ->();
};

void f(A y) {
   int i = y->z; // warning C4280
}


Compiler Warning (level 3) C4281

'operator –>' recursion occurred through type 'type'

Your code allows operator–> to call itself.

Example

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


Compiler Warning (level 3) C4282

then through type 'type'

This continuation of warning C4281 shows that operator–> calls itself through type.


Compiler Warning (level 3) C4283

and through type 'type'

This continuation of warning C4281 shows that operator–> calls itself through type.


Compiler Warning (level 2) C4285

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.

Example

class C
{
public:
    C operator->();   // warning
    C& operator->();  // warning
};


Compiler Warning (level 1) C4286

'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

#include <eh.h>
class C {};
class D : public  C {};
void main()
{
    try
    {
        throw "ooops!";
    }
    catch( C ) {}
    catch( D ) {}  // warning, D is derived from C
}


Compiler Warning (level 1) C4287

'operator' : unsigned/negative constant mismatch

An unsigned variable was used in an operation with a negative number.

C4287 is off by default. The following sample generates C4287:

#pragma warning(1 : 4287)
#include <stdio.h>
int main() {
   unsigned int u = 1;
   if (u < -1)   // C4287
      printf("u LT -1");
   else
      printf("u !LT -1");
   return 0;
}


Compiler Warning (level 1) C4288

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

The following sample generates C4288:

void main() {
   int i = 0;   // not used in this program
   for (int i = 0 ; ; ){}
   i++;   // C4288, using for-loop declaration of i
}

See also

The for Statement


Compiler Warning (level 4) C4289

nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope

When compiling with /Ze, 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.

By default, this warning is off.

#pragma warning(default:4289)
void main() {
   for (int i = 0 ; ; )
      ;
   i++;
}


Compiler Warning (level 3) C4290

C++ Exception Specification ignored

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.

You can avoid this warning by using the warning pragma:

#pragma warning( disable : 4290 )


Compiler Warning (level 1) C4291

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

#include <malloc.h>

class CList
{
public:
   CList(int) { throw "Fail!"; }
};

void* operator new(size_t size, char* pszFilename, int nLine)
{
   return malloc(size);
}

void 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);
   }
   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 3) C4292

terminating debug information emission for enum 'enum' with member 'member'

A record in a PDB file can be no larger than 64K. The size of an enum in your code, along with the use of /Zi, resulted in a PDB's record size greater than 64K. You can either reduce the size of the enum or break it into two enums.


Compiler Warning (level 3) C4293

new in default argument will not free memory if initialization throws an exception

Because an exception can happen while creating an instance of an object, the destructor must be accessible and unambiguous so that the object can be deleted correctly.

Possible solutions

  • Change the access of the delete operator.
  • Compile without exception handling (/GX–).

Example

// compiled with (/GX)
class B {
public:
    void *operator new(unsigned int);
};

class D : public B {
protected:
    void operator delete(void *);
};

class E : public D {
public:
    E();
    ~E();
};

class X {
public:
    X(class E);
};

void f()
{
    X x(E *e = new E); // warning C4293, delete not accessible (protected)
}


Compiler Warning (level 1) C4294

C++ Exception Specification missing

This warning helps you check to see if functions explicitly specify whether they throw exceptions. This warning is off by default.

The following sample generates C4294:

#pragma warning(1: 4294)               // turn on warning C4294
void main(){                           // throw not explicit
// instead, try …
// void main() throw(){                  // does not throw
// void main() throw(...){               // throw
// void __declspec(nothrow) main() {   // use throw() instead
}


Compiler Warning (level 1) C4296

'operator' : expression is always false

An unsigned variable was used in a comparison operation with zero.

C4296 is off by default. The following sample generates C4296:

#pragma warning(1 : 4296)
void main() {
   unsigned int u = 9;

   if (u < 0)   // C4296
      u++;
   if (u >= 0)  // C4296
      u++;
}


Compiler Warning (level 1) C4297

'function' : function assumed to not throw an exception (because of __declspec(nothrow), throw(), or it is extern "C")

A function contains a nothrow declaration and one or more throw statements. To resolve C4297, do not attempt to throw exceptions in functions that are declared with nothrow or to remove the nothrow specification.

The following sample generates C4297:

#pragma warning(1:4297)
void __declspec(nothrow) f1() {   // declared nothrow
// instead, try ...
// void f1() {
throw 1;   // C4297
}
void main() {
}


Compiler Warning (level 1) C4300

conversion of pointer to non-integral type

A pointer was cast to a noninteger type, such as float. The cast pointer address may be invalid.

Example

   int     i = 24;
   printf( "Address: %f\\n", ( float ) &i );


Compiler Warning (level 1) C4301

'function' of 'derivedclass': overriding virtual function only differs from 'baselcass::function' by const/volatile qualifier

The qualifiers in the parameter lists for the functions in the base and derived classes differ. The compiler implements the function declaration in the derived class. To resolve the warning, be sure the qualifiers match. The following sample generates C4301:

#include <stdio.h>

class Base
{
   public:
      virtual void Func(const int i) {
         printf("base\n");
      }
};

class Derived : public Base
{
   public:
      void Func(int i) {      // C4301
         printf("derived\n");
      }

      /* use the code below to resolve the warning
      void Func(const int i) {
         printf("derived\n");
      }
      */
};

void main() {
   Base B;
   Derived D;

   B.Func(0);
   D.Func(0);
}


Compiler Warning (level 1) C4303

C-style cast from 'type1' to 'type2' is deprecated

C-style type casting is not supported when using Managed Extensions for C++. To cast, use either dynamic_cast Operator or static_cast Operator. The following sample generates C4303:

#using <mscorlib.dll>

__gc struct A {
};
__gc struct B {
};

void main() {
   B *b = new B;

   // old 'c' style cast, warning C4303
   A *a = (A*)b;

   // use the line below to resolve the warning
   // A *a = dynamic_cast<A*>(b);
}


Compiler Warning (level 3) C4304

'type' : simple type cast conversion of no expression

An empty expression is cast to the specified type.

Example

void func()
{
   int ();   // warning
}


Compiler Warning (level 1) C4305

'identifier' : truncation from 'type1' to 'type2'

The identifier is converted to a smaller type, resulting in loss of information.

If you used the ATL Connection Point Wizard, see Knowledge Base article:

  • Q250847 : ATL Connection Point Wizard Generated Code for Event with VARIANT Argument Gives C4305 Warning


Compiler Warning (level 3) C4306

'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

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

Example

int i = 2000000000 + 2000000000; // warning

int j = (unsigned)2000000000 + 2000000000;  // OK


Compiler Warning (level 2) C4308

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

unsigned int i = 20000 + (-5);   // warning


Compiler Warning (level 2) C4309

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

Example

char c = 128;                  // warning
char x = (char) 128;           // warning


Compiler Warning (level 3) C4310

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:

void main() {
   long int a;
   a = (char) 128;   // C4310, use value 0-127 to resolve
}


Compiler Warning (level 1) C4311

'variable' : pointer truncation from 'type' to 'type'

A 64-bit pointer was truncated to a 32-bit int or 32-bit long.


Compiler Warning (level 1) C4312

'variable' : conversion from 'type' to 'type' of greater size

You attempted to assign a 32-bit value to a 64-bit integer. For example, casting a 32-bit int or 32-bit long to a 64-bit pointer.


Compiler Warning (level 1) C4313

'function' : 'format specifier' in format string conflicts with argument %d of type 'type'

There is a conflict between the format specified and the value that you are passing. For example, you passed a 32-bit pointer to %d format specifier, which can hold a 64-bit integer.


Compiler Warning (level 1) C4318

passing constant zero as the length to memset

You called the C run-time library’s memset function with a zero character length. For example, memset(p,size,0). Instead, specify memset(p,0,size).


Compiler Warning (level 1) C4319

'operator' : zero extending 'type' to 'type' of greater size

The result of the ~ operator is unsigned and then converted to a larger type.

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 leads to pointer truncations.

void* p;
unsigned long a;
typedef unsigned __int64 ULONG_PTR;

void main()
{
  p = (void*)((ULONG_PTR)p & ~(a - 1));
}


Compiler Warning (level 4) C4320

treating structure as an interface

The compiler regards a struct with an associated uuid (specified with declspec(uuid("..."))) and a single base class that is also an interface (except for a struct by the name of IUnknown, which does not inherit an interface) as an interface.

The following struct will be deduced as an interface by the compiler:

struct __declspec(uuid("{10338100-fc02-11d1-a4fe-444553540000}")) IExample : public IDispatch {
public:
   virtual HRESULT mf1() = 0;
   virtual HRESULT mf2() = 0;
};

It is equivalent to the following interface, written using the interface keyword and the uuid attribute:

[ uuid="10338100-fc02-11d1-a4fe-444553540000" ]
interface IExample : IDispatch {
   HRESULT mf1();
   HRESULT mf2();
};


Compiler Warning (level 4) C4324

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

struct __declspec(align(32)) A {
   char a;
};


Compiler Warning (level 1) C4325

attributes for standard section 'section' ignored

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

pragma section


Compiler Warning (level 4) C4326

return type of 'function' should be 'int' instead of 'type'

A function returned a type other than int. For example, using /Za, main did not return an int.

The following sample generates C4326:

// use /Za
void main() {
// try the following line
// int main() {
}


Compiler Warning (level 1) C4329

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

enum __declspec(align(256)) TestEnum {
   TESTVAL1,
   TESTVAL2,
   TESTVAL3
};
__declspec(align(256)) enum TestEnum1;


Compiler Warning (level 1) C4330

#pragma no_binary must appear before any declaration or directive in this file; ignored

This warning is issued if #pragma no_binary appears after any declaration or directive in the file. For instance:

// myheader.h - not suitable for binary header

#ifndef MYHEADER
#define MYHEADER

#pragma no_binary   // Yields warning 4330

// ....

#endif

This would be correctly written as:

// myheader.h - not suitable for binary header

#pragma no_binary   // Must be first

#ifndef MYHEADER
#define MYHEADER

// ....

#endif


Compiler Warning (level 1) C4340

'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 3) C4341

'value' : signed value is out of range for enum constant

An enumerated constant exceeds the limit for an int. The value of the illegal constant is undefined. Constants must resolve to integers between – 32,768 and +32,767 (signed) or 0 and +65,535 (unsigned).

Example

enum ELEMENTS
{
   Hydrogen = 1,
   Helium,
   Lithium,
   Beryllium,
   Impossibillium = 500000
} ;


Compiler Warning (level 1) C4353

nonstandard extension used: constant 0 as function expression. Use '__noop' function intrinsic instead

You cannot use the constant zero (0) as a function expression.

See __noop for more details.

The following sample generates C4353:

void MyPrintf(void){};
#define X 0
#if X
   #define DBPRINT MyPrint
#else
   #define DBPRINT 0
#endif
void main(){
DBPRINT();
}


Compiler Warning (level 1) C4354

'reference' : initialization of reference member requires a temporary variable

You tried to initialize a member that was a reference. The compiler creates a temporary stack variable to perform the initialization. Since the stack variable will be eliminated after the termination of the constructor, the pointer will be invalid.

This initialization causes an error under the default Microsoft extensions (/Ze).

To avoid this warning, initialize the member instead of its reference.


Compiler Warning (levels 1 and 4) C4355

'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 using the this pointer until all construction has completed.

This is a level-1 warning under Microsoft extensions (/Ze) and a level-4 warning otherwise.


Compiler Warning (level 1) C4360

the template parameter list for 'function' is incompatible with the template parameter list for its parent class 'class'

The compiler found non-type template parameters with different names. A class template definition may have been modified without updating the out-of-line member function definitions. The following sample generates C4360:

template <class T, T::aaa_t x> class C {
        public:
                void f();
        };
template <class T, T::bbb_t x> void C<T,x>::f() {   // C4360
}
// try ...
// template <class T, T::aaa_t x> void C<T,x>::f() {

void main() {
}


Compiler Warning (level 1) C4385

text the 'identifier' in base 'base'

This warning provides additional information about an ambiguous class hierarchy reported in error C2385. A member of a derived class is declared in more than one base class. The following sample generates C4385:

struct A {
   int x;
};

struct B {
   int x;
};

struct C : A, B {
};

struct D : C {
   C::x;   // C4385, delete one of the declarations for x to resolve
};

void main() {
}


Compiler Warning (level 1) C4386

'text' to the 'identifier1' in base 'identifier2'

An identifier on the current line cannot be distinguished from the identifier listed in the warning.

This warning provides additional information about an ambiguous class hierarchy reported in error C2386.


Compiler Warning (level 3) C4388

'function' : 'naked' ignored when targeting managed code

The naked __declspec modifier is ignored when /com+ is used.


Compiler Warning (level 3) C4390

';' : empty controlled statement found; is this the intent?

A semicolon is found after a control statement that contains no instructions.

If you get C4390 because of a macro, you should either use warning pragma to disable c4390 in the module where the macro is or use __pragma to specify the warning pragma inside the macro to disable and then reenable the warningC4390.

Example

if (condition);      // note extra semi-colon
      statement;      // intended to execute only if <cond> is true


Compiler Warning (level 1) C4401

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

typedef struct bitfield {
   signed bit : 1;
} mybitfield;

void 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

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

illegal PTR operator

A PTR operator is used inappropriately in inline assembler code.

The compiler ignored the PTR operator.


Compiler Warning (level 3) C4404

period on directive ignored

The optional period preceding the directive is ignored.


Compiler Warning (level 1) C4405

'identifier' : identifier is reserved word

A word reserved for inline assembly is used as a variable name. This may cause unpredictable results. To resolve the warning, avoid naming variables with words reserved for inline assembly. The following sample generates C4405:

void func1() {
   int mov = 0, i = 0;
   _asm {
      mov mov, 0;   // C4405
      // instead, try ..
      // mov i, 0;
   }
}

void main() {
}


Compiler Warning (level 1) C4406

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

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

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

'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 3) C4414

'function' : short jump to function converted to near

Short jumps generate a 1-byte instruction. The instruction includes a short offset that represents the distance between the jump and the function definition. The compiler must generate a special record for the jump, which requires the jmp instruction to be either NEAR or FAR, but not SHORT. The compiler made the conversion.

Example

main()
{
    _asm jmp SHORT main
}


Compiler Warning (level 1) C4420

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

The following sample program shows how C4420 warnings are generated and avoided,

// Test for direct use of global new/delete
void func1() {
   int * pi = new int[10];      // warning

   delete [] pi;            // warning
}

// Test for use on class; class has vec dtor helper
struct s1 {
   virtual ~s1() {};
};

void func2() {
   s1 *ps1 = new s1[10];      // warning

   delete [] ps1;
}                        // warning  with message extensions

// Add a placement vector new; should still get warning
void *operator new[]( size_t s, int op1, int op2 );
void *operator new( size_t s, int op1 );

void func3() {
   int * pi = new (1) int[10];   // warning

   delete [] pi;            // warning
}


Compiler Warning (level 1) C4440

calling convention redefinition from '__stdcall' to '__cdecl' ignored

An attempt to change the calling convention was ignonred.

The following sample generates C4440:

typedef void __stdcall F();
typedef F __cdecl *PFV;      // C4440

void main() {
}


Compiler Warning (level 1) C4501

'identifier' : use of '::' unnecessary here

The given identifier was local in scope, so the scope resolution operator (::) was not required.

The compiler ignored the optional scope resolution operator.


Compiler Warning (level 1) C4502

'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

'identifier' : decorated name length exceeded, name was truncated

The decorated name was longer than the compiler limit (247), and was truncated. To avoid this warning and the truncation, reduce the number of arguments or name length of identifiers used.


Compiler Warning (level 4) C4504

type still ambiguous after parsing 'number' tokens, assuming declaration

The compiler could not resolve the type after looking ahead in the code.

Simplify the code to make the statement clearer. This warning can often be eliminated by using an explicit type cast to an ambiguous expression.


Compiler Warning (level 4) C4505

'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

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

'function' : function should return a value; 'void' return type assumed

The function has no return type specified. The compiler assumes that the return type is void. To resolve the warning, explicitly declare the return type of functions. The following sample generates C4508:

func() {   // C4508
}

/* use the code below to resolve the warning
void func() {
}
*/

void main() {

}


Compiler Warning (level 3) C4509

nonstandard extension used: 'function' uses SEH and 'object' has destructor

You should not use structured exception handling in functions that use objects with destructors. If an exception occurs, the destructor cannot be called. Use C++ exception handling instead.


Compiler Warning (level 4) C4510

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

struct A {
   const int i;
   int &j;
   A& operator=( const A& );
   // uncomment the following line to resolve this C4510
   // A(int ii, int &jj) : i(ii), j(jj) {}
};   // C4510

void main() {
}


Compiler Warning (level 3) C4511

'class' : copy constructor could not be generated

The compiler cannot generate a copy constructor for the given class. No constructor was created.

This warning can be caused by having a copy constructor for the base class that is not accessible by the derived class. An inherited copy constructor from a base class with a different ambient memory model can also cause this warning.

This warning can be avoided by specifying a user-defined copy constructor for the class.


Compiler Warning (level 4) C4512

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

For example, the following code generates C4512:

#include <iostream.h>
class base    {
   const int a;
   public:
      base(int val = 0) : a(val) {}
      int get_a(void) { return a; }
      };

   void main()
   {
      base first;
      base second(5);

      cout << "First = " << first.get_a() << endl;
      cout << "Second = " << second.get_a() << endl;
      }

You can resolve the C4512 warning for this code in one of three ways:

  • Explicitly define an assignment operator for the class.
  • Remove const from the data item in the class.
  • Use the #pragma warning statement.


Compiler Warning (level 4) C4513

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

The following sample generates C4513:

// compile with /W4
class Base
{
   private:
      ~Base();
};
class Derived : public Base
{
   public:
      Derived();
};
void main()
{
}


Compiler Warning (level 4) C4514

'function' : unreferenced inline function has been removed

The optimizer removed an inline function that is not called. The following sample generates C4514:

class A {
   public:
      void func() {   // C4514, remove the function to resolve
      }
};

void main() {
}


Compiler Warning (level 4) C4515

'namespace' : namespace uses itself

A namespace is used recursively.

Example

namespace A {
   using namespace A; // warning C4515
}


Compiler Warning (level 4) C4516

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

Example

class A {
public:
   x(char);
};

class B : protected A {
public:
   A::x;  // access-declaration, warning C4516
};

Rewrite class B with the using keyword:

class B : protected A {
public:
   using A::x; // using-declaration, ok
};


Compiler Warning (level 4) C4517

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

Example.

class A {
public:
   x(char);
};

class B : protected A {
public:
   A::x;  // access-declaration, warning C4516
};

Rewrite class B with the using keyword:

class B : protected A {
public:
   using A::x; // using-declaration, ok
};


Compiler Warning (level 1) C4518

'specifier' : storage-class or type specifier(s) unexpected here; ignored

Example

__declspec(dllexport) extern "C" void foo();   // warning
   class C {
      int * virtual vfunc();         // warning
   };

extern "C" DLLEXPORT STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv); // warning

The macro should be written as:

STDAPI DLLEXPORT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv);


Compiler Warning (level 1) C4519

default template arguments are only allowed on a class template; ignored

Default template arguments are allowed only on a class template declaration or definition. Default template arguments may not be used in a function template, or in the definition of a member of a class template.

The following code shows how to use default template arguments and some common mistakes.

/*****
Default template arguments are allowed only on a class template declaration or definition. Default template arguments may not be used in a function template, or in the definition of a member of a class template.
*****/

#include <stdio.h>

// OK : default template argument is allowed on a class template
template<class T=int> class A {
public:
   static T f(T a, T b) { return a + b; };
};

class B {
public:
   // C4519 : default template argument is not allowed here
   template<class T=int> static T f(T a, T b) { return a + b; };
};

// C4519 : default template argument is not allowed here
template<class T=int> T f(T a, T b) { return a + b; };

int main() {
   double a = 3.5, b = 4.25;
   double d = 0.0;

   d = f(a, b);             // double f(double, double)
                            //   Double is deduced from the types of the
                            //   arguments to f(). Note that f's default
                            //   template argument is ignored.
   printf("%2.2lf\n", d);   // Prints the value 7.75

   d = A<>::f(a, b);        // int A<>::f(int, int)
                            //   Template argument defaults to int. Arguments
                            //   are coerced to ints, and an int is returned.
   printf("%2.2lf\n", d);   // Prints the value 7.00

   d = B::f(a, b);          //   Double is deduced from the types of the
                            //   arguments to B::f(). Note that B::f's default
                            //   template argument is ignored.
   printf("%2.2lf\n", d);   // Prints the value 7.75

   return 0;
}


Compiler Warning (level 3) C4520

'class' : multiple default constructors specified

The class has multiple default constructors. The first constructor is used.


Compiler Warning (level 3) C4521

'class' : multiple copy constructors specified

The class has multiple copy constructors of a single type. The first constructor is used.


Compiler Warning (level 3) C4522

'class' : multiple assignment operators specified

The class has multiple assignment operators of a single type. The first constructor is used.


Compiler Warning (level 3) C4523

'class' : multiple destructors specified

The class has multiple destructors. The first destructor is used.


Compiler Warning (level 1) C4526

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

// compile with cl /c
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 4) C4527

instances of type 'class' can never be destroyed - user-defined destructor required

The given derived class has no destructor and the compiler cannot generate one.

To avoid this warning, include a user-defined destructor for the class.

See C4513 for more information.


Compiler Warning (level 1) C4529

'member_name' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name

A pointer to a non-static member function of a class or structure must have the form of an & followed by the qualified identifier not enclosed in parentheses. This warning is only issued under /Ze. This warning is disabled by default.

The following sample generates C4529:

#include <stdio.h>
#pragma warning(1:4529)

struct A {
   void f(){
      printf("test");
   }
   void g();
};

void A::g() {
   void (A::*p3)() = A::f;   // C4529
   void (A::*p4)() = &A::f; // correct way
}

void main() {
   A a;
   A *ptr = new A;
   void (A::*p3)() = A::f;   // C4529
   void (A::*p4)() = &A::f; // correct way
   (ptr->*p4)();
}


Compiler Warning (level 1) C4530

C++ exception handler used, but unwind semantics are not enabled. Specify -GX

C++ exception handling was used but the Enable Exception Handling (/GX) option was not selected.

When the /GX 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.


Compiler Warning (level 1) C4532

'continue' : jump out of __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 block during abnormal termination.

If an exception occurs, and while the stack is being unwound during execution of the termination handlers (the __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.

void main()
{
   // 2 warnings
   int i;
   for (i = 0; i < 10; i++) {
       __try {
       } __finally {
          continue;
       }

       __try {
       } __finally {
          break;
       }
   }

   // 1 warning
out1:
   __try {
   } __finally {
      goto out1;
   }

   // 1 warning
   __try {
   } __finally {
      goto out2;
   }
out2:

   // no warnings
   __try {
   } __finally {
in1:
      goto in1;
   }

   // no warnings
   __try {
   } __finally {
      goto in2;
in2:
      ;
   }

}


Compiler Warning (level 1) C4533

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:

#include <stdio.h>
void main(void) {
   if (1)
      goto Label;

   int i = 100;

   Label:   // C4533
      printf("\n%d", i);   // prints an uninitialized value
}


Compiler Warning (level 1) C4540

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 D is derived from class B. The program uses dynamic_cast to cast from class D (the derived class) to class B, which will always fail because class B is private and thus inaccessible. Changing the access on B to public will fix the problem.

class B { virtual void g(); };
class D : private B {};

void a() {
   D   d;
   B*   bp;
   bp = dynamic_cast<B*>(&d); // error C4540
}


Compiler Warning (level 1) C4541

'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

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

expression evaluates to a function which is missing an argument list

A dereferenced pointer to a function is missing an argument list.

Example

bool f()
{
   return true;
}

typedef bool (*pf_t)();

int main()
{
   pf_t pf = f;
   if (*pf) {}   // Error
   return 0;

}


Compiler Warning (level 1) C4551

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.

Example

void function1(){

}

main()
{
   function1;
   return 0;
}


Compiler Warning (level 1) C4552

‘operator’ : operator has no effect; did you forget something?

If an expression statement has an operator with no side effect as the top of the expression, it's probably a mistake.

Example

int i, j;
   i + j;

You can suppress this warning by placing parentheses around the i + j:

(i + j)


Compiler Warning (level 1) C4553

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

Example

int i;
   i == func();   // intended i = func(); //warning


Compiler Warning (level 3) C4554

'operator' : possible operator precedence error; use parentheses to avoid ambiguity

Example

a = a << b + c;   // probably intended (a << b) + c,
                  // but will get a << (b + c)


Compiler Warning (level 1) C4555

expression has no effect; expected expression with side-effect

This warning, which is off by default, informs you when an expression has no effect.

For example:

// compile with cl /c
#pragma warning(default:4555)

void func1() {
1;      //C4555
}

void func2() {
int x;
x;      //C4555
}


Compiler Warning (level 1) C4556

value of intrinsic immediate argument 'value' is out of range 'range'

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.

The following sample generates C4556:

#include <xmmintrin.h>
void test() {
   __m64 m;
   _m_pextrw(m, 5);   // C4556
}


Compiler Warning (level 3) C4557

'__assume' contains effect 'effect'

The value passed to an __assume statement was modified. By default, this warning is off.

The following sample generates C4557:

// compile with /Wall
void main() {
   int i;
   __assume(i++);   // C4557
}


Compiler Warning (level 3) C4558

value of operand 'value' is out of range 'range'

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:

void asm_test() {
   __asm pinsrw   mm1, eax, 8;   // C4558
}

void main() {
}


Compiler Warning (level 1) C4559

'parameter': formal parameter with __declspec(align('#')) may not be aligned

A parameter had a __declspec(align(#)) modifier. The compiler will ignore the modifier.

The following sample generates C4559:

void func(int __declspec(align(32)) i);   // C4559

void main() {
}


Compiler Warning (level 1) C4560

'argument' : non-constant default arguments unavailable when importing NGWS runtime function

This warning results when you use a non-constant value as an argument to a NGWS function that is called when you #import its module. NGWS metadata can only represent constants as values for default arguments to functions. The default argument would still work as expected when #import is not used.

The following code will produce warning C4560 if you #import the module:

int i;
void f(int j = i){   //error; i is non-constant
}

Solution

Remove the default argument or find a constant to use as a default instead.


Compiler Warning (level 1) C4561

'__fastcall' incompatible with the '/com+' switch: converting to '__stdcall'

The __fastcall function-calling convention cannot be used with the /com+ compiler option. The compiler ignores the calls to __fastcall. To resolve the warning, either remove the calls to __fastcall or compile without /com+. The following sample generates C4561:

void __fastcall Func(void *p);   // C4561, remove __fastcall to resolve

void main() {
}


Compiler Warning (level 4) C4562

fully prototyped functions are required with the '/com+' switch: converting '()' to '(void)'

Function prototypes should be fully defined when compiling a C source code file using the /com+ compiler option. The compiler automatically converts empty parameter lists to void. The following sample generates C4562:

// compile with /com+ /W4 and /Tc
void main() {   // C4562, use (void) instead of () to resolve
}


Compiler Warning (level 1) C4563

'/Gr - __fastcall calling convention' switch incompatible with the '/com+' switch: changing to '/Gz - __stdcall calling convention'

The /com+ and /Gr compiler options cannot be used together. The compiler ignores the /Gr option. To resolve the warning eliminate one of the compiler options. The following sample generates C4563:

// compile with /com+ and /Gr
void main() {
}


Compiler Warning (level 1) C4584

'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,

class A {
};

class B : public A {
};

class C : public A, public B {
};

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 Warning (level 1) C4600

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

void main() {
   #pragma push_macro("")   // C4600; passing an empty string
}


Compiler Warning (level 1) C4601

#pragma push_macro : 'macro name' is not currently defined as a macro

It is not possible to pass an undefined macro name to push_macro. For example, the following sample generates C4601:

#define X 1

void main() {
   #pragma push_macro("x")   // C4601; x is undefined
}


Compiler Warning (level 1) C4602

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

void main() {
   #pragma pop_macro("x")   // C4602; x is not on the stack
}


Compiler Warning (level 3) C4608

'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

// compile with /W3
class X {
public:
   X(char c) : m_i( c + 1), m_c(c) {
   // try the following line instead
   // X(char c) : m_c(c) {
   } // C4608

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

main() {
}


Compiler Warning (level 4) C4610

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:

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

void main() {
}


Compiler Warning (level 4) C4611

interaction between '_setjmp' and C++ object destruction is non-portable

On some platforms, functions that include _setjmp may not support C++ object semantics of destruction when out of scope.

To avoid unexpected behavior, avoid using _setjmp in functions that have constructors and destructors.

This warning is only issued once; see pragma warning.


Compiler Warning (level 1) C4612

error in include filename

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 from (“filename”) or angle-bracket form (<filename>), but both must use the same form.

Example

#pragma include_alias("StandardIO", <stdio.h>) // warning


Compiler Warning (level 1) C4613

'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) C4614

'type' : vararg parameters with this type were promoted

The compiler performed standard promotion on the arguments to a varargs function, including char-to-int and float-to-double.

To avoid this promotion, use normal functions instead of varargs functions.


Compiler Warning (level 1) C4615

#pragma warning : unknown user warning type

An illegal warning specifier was used with pragma warning. To resolve the error, use a valid warning specifier. The following sample generates C4615:

#pragma warning(enable : 4401)   // C4615, 'enable' not valid specifier

// use the code below to resolve the error
// #pragma warning(default : 4401)

void main() {
}


Compiler Warning (level 1) C4616

#pragma warning : warning number 'number1' out of range, must be between 'number2' and 'number3'

The warning number specified in the warning pragma cannot be reassigned. Only warnings between number2 and number3 can be reassigned. The pragma was ignored. The following sample generates C4616:

#pragma warning( disable : 0 )   // C4616, use number between 1 and 999
// or 4001 and 4999

void main() {
}


Compiler Warning (level 1) C4617

#pragma warning : invalid warning number

An illegal warning number appears with the warning pragma.


Compiler Warning (level 1) C4618

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.

Example

#pragma code_seg("")    // warning
void main() {}


Compiler Warning (level 1) C4620

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:

class prepost
{
public:
   prepost operator++ ()
   {
 // inline prefix routine
   };
   prepost operator++ ( int )
   {
 // inline postfix routine
   };
}


Compiler Warning (level 1) C4621

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:

class prepost
{
public:
   prepost operator-- ()
   {
 // inline prefix routine
   };
   prepost operator-- ( int )
   {
 // inline postfix routine
   };
}


Compiler Warning (level 3) C4622

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 1) C4630

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

class A {
   void func();
};

extern void A::func() {   // C4630, remove 'extern' to resolve
}

void main() {
}


Compiler Warning (level 3) C4645

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:

void __declspec(noreturn) func() {
   return;   // C4645, delete this line to resolve
}

void main() {
}


Compiler Warning (level 3) C4646

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:

int __declspec(noreturn) bar() {   // C4546, make return type void
}

void main() {
}


Compiler Warning (level 1) C4650

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

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


Compiler Warning (level 1) C4652

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

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

'symbol' : variable type is new since the last build, or is defined differently elsewhere

You changed or added a new data type since the last successful build. Edit and Continue does not support changes to existing data types.

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.

This warning is followed by a Fatal Error C1092. For further information, see the Limitations of Edit and Continue.


Compiler Warning (level 1) C4656

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

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.

This warning will always be followed by Fatal Error C1092. For further information, see the Limitations of Edit and Continue.


Compiler Warning (level 1) C4657

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.

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.

This warning will always be followed by Fatal Error C1092. For further information, see the Limitations of Edit and Continue.


Compiler Warning (level 1) C4659

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

#pragma comment(linker, "...")


Compiler Warning (level 1) C4661

'identifier' : no suitable definition provided for explicit template instantiation request

A member of the template class is not defined.

Example

template<class T> class MyClass
{
public:
   void i();              // declaration but not definition
};
template MyClass< int >;  // warning


Compiler Warning (level 1) C4662

explicit instantiation; template-class 'identifier1' has no definition from which to specialize 'identifier2'

The specified template-class was declared, but not defined.

Example

template<class T, int i> class MyClass; // no definition
template MyClass< int, 1>;              // warning


Compiler Warning (level 4) C4663

C++ language change: to explicitly specialize class template 'identifier' use the following syntax:

To explicitly specialize a template class, use the new syntax.

Example

template<class T> class X {};
template<> class X<int> {}   //New syntax: explicitly specialize X
class X<char> {};      //old way - now illegal
Note If the compiler option /Za (Disable Language Extensions) is selected, then the compiler will generate error C2906.


Compiler Warning (level 4) C4665

C++ language change: assuming 'declaration' is an explicit specialization of a function template

The compiler assumes that the definition of a non-template function is an explicit specialization of the function template.

Example

template<class T> void f(T) {};
void f(int) {};   // assumes the user means
            // template<> void f(int);


Compiler Warning (level 1) C4666

'declaration' : function differs from 'declaration' only by calling convention

This warning occurs when the calling convention of an explicit specialization of a function template is different from that of the function template.

Example

template<class T> void __cdecl f(const T &) { }
template<> void __stdcall f(const int &) { } //warning


Compiler Warning (level 1) C4667

'function' : no function template defined that matches forced instantiation

You cannot instantiate a function template that has not been declared. For example, the following sample will cause C4667:

// compile with cl /c
template
void max(const int &, const int &);

To avoid this warning, first declare the function template:

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

'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. This warning is off by default. To define a symbol, you can use either the #define directive or /D compiler option.

The following sample generates C2668:

#include <stdio.h>
#pragma warning (default : 4668)   // turn warning on
void main() {
#if q   // q is not defined
   printf("defined");
#else
   printf("undefined");
#endif
}


Compiler Warning (level 4) C4669

'cast' : unsafe conversion: 'class' has managed members

The cast class contains managed extensions for C++. The compiler completes the cast by performing a bitwise copy of one pointer to the other, but provides no other checking. To resolve the warning, do not cast classes containing members with managed extensions.

The following sample generates C4669:

#using "mscorlib.dll"

__gc struct A {
   int i;
   Object   * pObj;   // remove the managed member to resolve the warning
};

__gc struct B {
   int j;
};

void main() {
   A *a = new A;

   B *b = reinterpret_cast<B*>(a);   // C4669
}


Compiler Warning (level 4) C4670

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

Example

class A {};
class B : A {} b;   // inherits A with private access by default

void main()
{
    try
    {
       throw b;
    }
    catch( B )      // warning
    {
    }
}


Compiler Warning (level 4) C4672

'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

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:

// compile with /GX

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 the previous line and uncomment the next line to resolve
      // Base D1;

      throw D1;   // C4670
   }

   catch(...) {
   }
}


Compiler Warning (level 4) C4680

'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 and shows one way to resolve it:

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

void main()
{
}


Compiler Warning (level 4) C4681

'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 and shows one way to resolve it:

// 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();
};
// uncomment out the source attribute to resolve this C4681
[ coclass, uuid(373a1a4d-469b-11d3-a6b0-00c04f79ae8f), default(IMyIface1)/*, source(IMyface1)*/]
class CMyClass
{
};

void main()
{
}


Compiler Warning (level 4) C4682

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

The following sample generates C4682:

#include <windows.h>
[module(name="MyModule")];

[ library_block, object, uuid("c54ad59d-d516-41dd-9acd-afda17565c2b") ]
__interface IMyIface : IUnknown {
   HRESULT f1(int i, int *pi);
   // try the following line
   // HRESULT f1([in] int i, [in] int *pi);
};

void main() {
}


Compiler Warning (level 4) C4699

Note: pre-compiled header usage information message

This warning provides informational messages about the status of precompiled headers.


Compiler Warning (level 1) C4700

local variable 'name' used without having been initialized

You used the local variable name without first assigning it a value, which could lead to unpredictable results.

This warning is issued only when either /Od or /Ox is specified.


Compiler Warning (level 4) C4701

local variable 'name' may be used without having been initialized

You may have used the local variable name without first assigning it a value, which could lead to unpredictable results.


Compiler Warning (level 4) C4702

unreachable code

An instruction will never be executed. To generate this warning, you must use the /Og compiler option. The following program will generate C4702 on the last instruction.

#include <stdio.h>
int main()
{
   return 1;
   printf("I won’t print.\n");      // Unreachable.
}


Compiler Warning (level 4) C4706

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 code will generate this warning:

if ( a  = b )
{
...
}

The warning will occur even if you double the parentheses around the test condition:

if ( ( a  =  b ) )
{
...
}

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:

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:

if ( ( a = b ) != 0 )
{
...
}


Compiler Warning (level 4) C4709

comma operator within array index expression

When a comma occurs in an array index expression, the compiler uses the value after the last comma. The following sample generates C4709:

#include <stdio.h>
void main() {
   int arr[2][2];
   arr[0][0] = 10;
   arr[0][1] = 11;

   // Prints 10, not 11
   printf("\n%d",arr[0][1,0]);   // C4709
}


Compiler Warning (level 4) C4710

'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. To enable a warning, use #pragma warning.


Compiler Warning (level 1) C4711

function 'function' selected for inline expansion

The compiler performed inlining on the given function, although it was not marked for inlining.

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.


Compiler Warning (level 4) C4714

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


Compiler Warning (level 1) C4715

'function' : not all control paths return a value

The specified function can potentially not return a value.

Example

int func1( int i )
{
   if( i )
   return 3;  // warning, nothing returned if i == 0
}

To prevent this warning, modify the code so that all paths assign a return value to the function:

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:

int glue()
{
   if(...)
     return 1;
   else if(...)
     return 0;
   else
     fatal();
}

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

'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. For example, to make C4716 into a level 4 warning issue,

#pragma warning(4:4716)

in your source code file.

The following sample generates C4716:

int test(void) {
   // uncomment the following line to resolve
   // return 0;
}

void main() {
}


Compiler Warning (level 1) C4717

'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 code demonstrates how this warning would be generated:

int func(int x)
{
   if (x > 1) {
      return func(x - 1); // recursive call
   }
   else {
      int y = func(0) + 1; // recursive call
      return y;
   }
}

void main(){
   func(1);
}


Compiler Warning (level 4) C4718

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

The following code generates C4718,

// compile with optimizations
int func(int x)
{
   if (x > 1)
      return func(x - 1); // recursive call
   else
      return x;
}

void func2(void)
{
   func(10);  // deleted; no side effects and return value used
}

void main() {
   func2();
}


Compiler Warning (level 2) C4720

'initializing' : do not initialize a non-const 'type1' with a non-lvalue 'type2' function return

A nonconst T& was initialized with the value of a function call which returns T. This is an error, because a function call is not an l-value (unless it returns a reference) and a nonconst T& must be initialized with a T l-value. However, when Microsoft extensions have been enabled (/Ze), Visual C++ renders this as a warning because the construction is harmless and because the construction occurs fairly frequently in existing code.

The warning can be eliminated by changing the reference being initialized to a const T&.

Example

struct X {};
X f();
X&r = f();  // warning


Compiler Warning (level 3) C4723

potential divide by 0

The second operand in a divide operation evaluated to zero at compile time, giving undefined results.

The compiler may have generated the zero operand, as in the following example:

int    i, j, k = 42;
i /= ( j && k );


Compiler Warning (level 3) C4724

potential mod by 0

The second operand in a remainder operation evaluated to zero at compile time, giving undefined results.


Compiler Warning (level 3) C4725

instruction may be inaccurate on some Pentiums

Your code contains an inline assembly instruction that may not produce accurate results on some Pentium microprocessors.


Compiler Warning (level 2) C4756

overflow in constant arithmetic

The compiler generated an exception while doing constant arithmetic during compilation.

Example

float fp_val = 1.0e100;

In this example, the floating-point constant 1.0e100 exceeds the maximum allowable value for a double-precision data item.


Compiler Warning (level 1) C4786

'identifier' : identifier was truncated to 'number' characters in the debug information

The identifier string exceeded the maximum allowable length and was truncated.

The debugger cannot debug code with symbols longer than 255 characters. In the debugger, you cannot view, evaluate, update, or watch the truncated symbols.

This limitation can be overcome by shortening identifier names. The example code below demonstrates this method.

A trace mechanism can also be used to solve this problem. A trace mechanism is like the printf statements in the code. It keeps track of what is going on in an application during the debugging process. The _ASSERT, _ASSERTE, _RPTn and _RPTFn macros provide concise and flexible ways to perform the trace. These macros are not defined when _DEBUG is not defined. See Using Macros for Verification and Reporting for more information.

The example below demonstrates a situation that would cause this compiler warning to occur, and the solution to this problem.

 //sample1.cpp
 //In this program we have a class of a very long name.
 //We instantiate an object of that class type. We will
 //get multiple C4786 warnings. The comments below
 //demonstrate the solution to this problem.

 #define a_really_long_class_name a_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really_really//_really_long_class_name

 //SOLUTION: Uncomment the lines below

 //#ifdef _DEBUG
 //#define a_really_long_class_name A_SHORT_CLASS_NAME
 //#endif

 class a_really_long_class_name
 {
 public:
   a_really_long_class_name() {};
   int m_data;
 };

 void main()
 {
    a_really_long_class_name test_obj;
    test_obj.m_data = 12;
 }

The following example demonstrates that templates with some long class names as their parameters can easily exceed the 255 character limit. Solutions to the problem are also provided.

 //sample2.cpp
 //SOLUTION1: uncomment the next 4 lines
 //#ifdef _DEBUG
 //#define VeryLongClassNameA A
 //#define VeryLongClassNameB B
 //#endif

 //SOLUTION2: An alternative solution:
 //uncomment the next 3 lines.
 //#ifdef _DEBUG
 //#define SomeRandomClass SRC
 //#endif

 template <class A1, class A2, class A3, class A4>
 class VeryLongClassNameA{};

 template <class B1, class B2, class B3>
 class VeryLongClassNameB{};

 template <class C1, class C2>
 class VeryLongClassNameC{};

 template <class D1>
 class VeryLongClassNameD{};

 class SomeRandomClass{};

 typedef VeryLongClassNameD<SomeRandomClass> ClassD ;
 typedef VeryLongClassNameC<SomeRandomClass, ClassD> ClassC;
 typedef VeryLongClassNameB<SomeRandomClass, ClassC, ClassD> ClassB;
 typedef VeryLongClassNameA<SomeRandomClass, ClassB, ClassC, ClassD> ClassA;

 void SomeRandomFunction(ClassA aobj){}

 void main()
 {
   ClassA AObj ;
   SomeRandomFunction(AObj) ;
 }


Compiler Warning (level 3) C4792

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

// compile with /com+ /W3
#using <mscorlib.dll>
[sysimport(dll="msvcrt")]
extern "C" int __cdecl puts(const char *);

void main() {
}
// uncomment the following line to disable C4792
// #pragma warning(disable : 4792)
#pragma unmanaged
void func(void) {
   puts("test");   // C4792
}


Compiler Warning (level 3) C4793

native code generated for function 'function': 'reason'

function was compiled to unmanaged, native code, even though the file was compiled /com+. The compiler will not be able to create an MSIL version of the function if the function includes setjmp, inline assembly, or a parameter list that includes a variable number of parameters.

The following sample generates C4793:

// compile with /com+ /W3
int asmfunc(void) {   // C4793, compiled as unmanaged, native code
   __asm {
      mov eax, 0
   }
}

void main(void) {
}


Compiler Warning (level 1) C4794

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$. For example:

#pragma data_seg(".someseg")
__declspec(thread) int i;

Instead, use something similar to this:

#pragma data_seg(".tls$9")
__declspec(thread) int i;

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.


Compiler Warning (level 1) C4799

function 'function' has no EMMS instruction

The function has at least one MMX instruction, but does not have an EMMS instruction. When a multimedia instruction is used, an EMMS instruction should also be used to clear the multimedia tag word at the end of the MMX code.

For related information, see the Intel’s MMX Instruction Set.


Compiler Warning (level 3) C4800

'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 will not disable the warning, which is by design.

The following sample generates C4800:

void main() {
   int i = 0;

   // try..
   // bool i = 0;

   bool j = i;   // C4800
   j++;
}


Compiler Warning (level 1) C4802

'function': out-of-class member template definitions are not supported

The template member function for a class should be defined inside the enclosing class. The compiler implements the function definition.

The following sample generates C4802:

// Compile with /GX
#include <iostream>
class MyClass {
public:
        template<class T>
   void MyFunc(T x);
/*
   // Uncomment the following definition and delete the out-of-class
   // definition to resolve this warning.
        void MyFunc(T x) {
      std::cout << x << std::endl;
   }
*/
};

template<class T>
void MyClass::MyFunc(T x) {   // C4802
   std::cout << x << std::endl;
}

void main() {
   MyClass a;
   a.MyFunc(909);
}


Compiler Warning (level 1) C4804

'operation' : unsafe use of type 'bool' in operation

This warning is for unary operations and is generated when you used a bool variable or value in an unexpected way, For example, it is generated if you use operators such as the negative unary operator (-) or the complement operator (~). The compiler evaluates the expression.

The following sample generates C4804:

void main() {
   bool i = true;
   if (-i) {      // C4804, remove the '-' to resolve
      i = false;
   }
}


Compiler Warning (level 1) C4805

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

void main() {
   int i = 1;
   bool b = true;

   if (i == b) {   // C4805, comparing bool and int variables
   }
}


Compiler Warning (level 1) C4806

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

void main() {
   bool b = true;
   // try..
   // int b = true;

   if (b == 3) {      // C4806
      b = false;
   }
}


Compiler Warning (level 1) C4807

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

The following sample generates C4807:

typedef struct bitfield {
   signed mybit : 1;
} mybitfield;

void main() {
   mybitfield bf;
   bool b = true;

   // try..
   // int b = true;

   bf.mybit = -1;
   if (b == bf.mybit) {   // C4807
      b = false;
   }
}


Compiler Warning (level 1) C4808

case 'value' is not a valid value for switch condition of type 'bool'

This warning occurs if a switch condition is of type bool and one of the case values is outside the range of bool (that is, true and false). Only true, false, 1, 0, and default are valid case values if the switch condition is of type bool.


Compiler Warning (level 1) C4809

switch statement has redundant 'default' label; all possible 'case' labels are given

This message is generated in places where you have both 'true' and 'false' cases in addition to a default label.


Compiler Warning (level 1) C4810

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:

#pragma pack(show)
#pragma pack(4)
#pragma pack(show)
void main(){}


Compiler Warning (level 1) C4811

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 3) C4833

__fastcall or __stdcall is mapped to __cdecl

For managed code, the compiler maps __stdcall and __fastcall to __cdecl.

The following sample generates C4833:

// compile with cl /EEi /c /W3
void __fastcall test(void) {}


Compiler Warning (level 1) C4900

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

'register' : too many formal parameters specified

You gave too many argumentRegisters with the MPW #pragma parameter preprocessor directive.


Compiler Warning (level 1) C4902

'register' : register already used once in this list

You used an argumentRegister more than once with the MPW #pragma parameter preprocessor directive.


Compiler Warning (level 1) C4903

'register' : is not a valid register in this context

You used an invalid register with the MPW #pragma parameter preprocessor directive.


Compiler Warning (level 1) C4904

'register' : function previously seen with a different register list

You already defined function elsewhere with the MPW #pragma parameter preprocessor directive and a different register list.


Compiler Warning (level 1) C4911

using the 'calling convention' calling convention specified in the interface 'interface' for method 'class::method'

The compiler checks for the mismatched calling convention and replaces the calling convention specified in the implementing class with the calling convention specified in the interface.

If an application is compiled with an ambient calling convention other than __stdcall and you do not explicitly state what the calling convention is in the implementation, you will also get this warning.

The following code causes this warning:

// compile : cl /c
#undef interface

__interface IMy {
int __cdecl MyFunc( void );
};

class x : public IMy {
int __stdcall MyFunc( void ){return 0;};
};


Compiler Warning (level 1) C4912

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

// compile with cl /c
[emitidl, module(name="xx")];

struct IUnknown {};
[custom, uuid("00000000-0000-0000-0000-000000000002")]
__interface IMy { };

[coclass, appobject, uuid("00000000-0000-0000-0000-000000000001")]
class CMy : public IMy
{
   [export, v1_enum] typedef enum myEnum { k3_1 = 1, k3_2 = 2 } myEnumv;
};


Compiler Warning (level 1) C4917

'declarator' : a GUID cannot only be associated with a class, interface or namespace

A user-defined structure other than class, interface, or namespace cannot have a GUID.

The following code sample generates C4917:

// compile with cl /c
__declspec(uuid("00000000-0000-0000-0000-000000000001")) struct S { } s;


Compiler Warning (level 4) C4918

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

// compile with cl /c
#pragma optimize("X", on)


Compiler Warning (level 1) C4922

'base-class function': function marked as 'sealed' -- will not be overridden by 'derived-class function'

The compiler detected an override function for a function that was marked with the __sealed keyword. This warning informs you that when the function is accessed via a pointer of the base class to the derived class, that the base class function will be called. If you call the derived-class function, you will access the derived class function.

For example:

#include <stdio.h>
class A {
   public:
      virtual __sealed int func1(void) {
         return 1;
      }
   };

class B : public A {
   public:
      int func1(void) {   // C4922
         return 2;
      }
   };

void main() {
   B b;
   printf("\n%d",b.func1());   // prints 2

   B *pBb = new B;
   printf("\n%d",pB->func1());   // prints 2

   A *pA = new B;
   printf("\n%d",pA->func1());   // prints 1
}


Compiler Warning (level 3) C4925

'function': non-virtual member function marked as 'final'; ignored the qualifier 'final'

The __sealed keyword was found on a non-virtual member function. The __sealed keyword is only allowed on virtual member functions within a class.

The following generates C4925:

// compile with /W3
#include <stdio.h>
class A {
   public:
      __sealed int func1();   // C4925, remove __sealed or add virtual
};

class B : public A {
   public:
      int func1(){return 10;}
};

void main() {
}


Compiler Warning (level 1) C4926

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

[module(name="MyLib")];

[coclass]
struct a {
};

[coclass]
struct a;   // C4926

void main() {
}


Compiler Warning (level 1) C4995

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

The following sample generates C4995:

#include <stdio.h>
// #pragma warning(disable : 4995)
void func1(void){printf("\nIn func1");}

void main() {
func1();
#pragma deprecated(func1)
func1();   // C4995
}


Compiler Warning (level 1) C4996

'function': symbol was declared as __declspec(deprecated)

The compiler encountered a function that was marked with deprecated. The function may no longer be supported in a future release. You can turn this warning off with the warning pragma (example below).

C4996 is generated for the line on which the function is declared and for the line on which the function is used.

The following sample generates C4996:

#include <stdio.h>
// #pragma warning(disable : 4996)
void func1(void){printf("\nIn func1");}
__declspec(deprecated) void func1(int){printf("\nIn func2");}

void main() {
func1();
func1(1);
}


Compiler Warning (level 1) C4999

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 consult Microsoft Technical Support.


Compiler Errors when Implementing a CObject-Derived Class

When you implement a class derived from CObject and your code is written so that the copy constructor or assignment operator for the class needs to be called, the compiler may report errors similar to the following:

error C2660: 'CSample::CSample' : function does not take 1 parameters

error C2582: 'CSample' : 'operator =' function is unavailable

You can reproduce the problem by compiling the example in the Sample Code section below.

Note The sample code shown in this article generates the following error messages:
error C2558: 'CSample::CSample' : no copy constructor available
error C2582: 'CSample' : 'operator =' function is unavailable

The reason for the compiler errors is that CObject declares a private copy constructor and assignment operator in the AFX.h file. Consequently, the compiler does not generate a default copy constructor and assignment operator for the CObject-derived class. Because the compiler does not find these functions declared in the class, it reports the errors.

To avoid the compiler errors, you need to implement a copy constructor and assignment operator for the CObject-derived class. This is illustrated in the sample code below. You can avoid the errors by uncommenting the lines indicated in the sample code.

Sample Code

/* Compile options needed: /c
*/

// replace with #define _CONSOLE when compiling for Windows NT
#define _DOS

#include <afx.h>

class CSample : public CObject
{
private:
    short m_nValue;
public:
// uncomment the lines below to avoid the compiler errors
//    CSample() {}
//    CSample( const CSample &s )  // copy ctor
//        { m_nValue = s.m_nValue; }
//    CSample& operator=( const CSample &s )  // assignment operator
//        { m_nValue = s.m_nValue; return *this; }
};

void main()
{
    CSample a;
    CSample b = a;
    a = b;
}


Managed Extensions for C++ Keywords

The following keywords and attribute implement Managed Extensions for C++.

Note All code examples must be compiled using the /com+ compiler option.
Keyword | Description
__abstract | Declares a class that cannot be instantiated directly.
__box | Creates a copy of a value class.
__delegate | Declares a reference to a unique method within an instance of a managed class.
__finally | Declares a finally block.
__gc | Declares a garbage-collected class.
__nogc | Declares a native C++ class that is not garbage-collected.
__pin | Prevents a managed object from being moved by the NGWS runtime.
__property | Declares a property member for a managed class.
__sealed | Prevents a method or class from being a base class.
__serializable | Allows a garbage-collected class to be serialized.
__transient | Prevents a data member from being serialized.
__try_cast | Throws an exception if the cast is illegal.
__value | A version of dynamic_cast that may throw an exception.

The following attribute supports various features of the NGWS runtime.

Attribute | Description
sysimport | Imports an unmanaged function into a managed application.

See Also

Contents of the C++ Language Reference | Managed Extensions for C++| Introduction to Managed Extensions for C++


__abstract

Declares a class that cannot be instantiated directly.

__abstract class-specifier
__abstract struct-specifier

Remarks

The __abstract keyword declares that the target class can only be used as a base class of another class. Applying __abstract to a class or structure does not imply that the result is a managed class or structure.

Differing from the C++ notion of an abstract base class, a class with the __abstract keyword can provide function definitions for all of its member functions.

Note The __abstract keyword is illegal when used with the __value or __sealed keyword and redundant with __interface keyword.

Example

In the following example, the Derived class is derived from an abstract base class (Base). Instantiation is then attempted on both but only Derived is successful.

#using <mscorlib.dll>
#using namespace System;

__abstract __gc class Base
{
   int BaseFunction() { return 0; }
};

class __gc Derived: public Base
{
};

void main()
{
   Base MyBase; //Error: cannot instantiate an abstract class
   Derived MyDerived;
}

See Also

Managed Extensions for C++ Keywords | __value | Delegates in Managed Extensions for C++ | C++ Keywords


__box

Creates a copy of a value class.

__box(value-class-name)

Remarks

The __box keyword is used to create a managed object (derived from System::Value) from an existing value class. When the __box keyword is applied to a value class:

  • a managed class is allocated on the NGWS heap
  • the current value of the target class is bit-wise copied into the managed class
  • the address of the new managed class is returned

This process is known as boxing. This enables any value class to be used in generic routines that work for any managed class because the managed class inherits from System::Value, which inherits from System::Object.

Note The newly created managed object is a copy of the value class. Therefore, modifications to the value of the managed object do not affect the contents of the value class.

For more information on boxing and box conversions, see Boxing Conversion and the Value Classes section of Managed Classes.

Example

#using <mscorlib.dll>
#using namespace System;

__value struct V
{
   int i;
};
void Positive(Object*);   //expects a managed class

void main()
{
   V v={10};   //allocate and initialize
   Object* o = __box(v);   //copy to the NGWS heap
   Positive( o );   //treat as a managed class
   o->i = 20;   //update the boxed version
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__delegate

Defines a reference type that can be used to encapsulate a method with a specific signature.

__delegate function-declarator
__delegate( multicast ) function-declarator

Remarks

A delegate is roughly equivalent to a C++ function pointer except for the following differences:

  • A delegate can only point to a method within a managed class.
  • A delegate that points to a nonstatic method must bind to a specific instance of the managed class.

Multicast delegates (a delegate that points to multiple methods) are also supported by a variant of the __delegate keyword: __delegate( multicast ).

When the compiler encounters the __delegate keyword, a definition of a managed class is generated. This managed class has the following characteristics:

  • It inherits from System::Delegate for a single-cast delegate or System::MulticastDelegate for a multicast delegate.
  • It has a constructor that takes two arguments: a pointer to a managed class or NULL, and a fully qualified method of the specified type.
  • It has a method called Invoke, whose signature matches the declared signature of the delegate.

For more information on delegates and their base implementations, see Delegates in Managed Extensions for C++ and Handling Events in NGWS Framework.

Example

In the following example, a managed class (MyCalendar) and a single-cast delegate are declared (GetDayOfWeek). The delegate is then bound to the different methods of MyCalendar, invoking each in turn:

#using <mscorlib.dll>
#using namespace System;

__delegate int GetDayOfWeek();
__gc class MyCalendar
{
public:
   MyCalendar() : m_nDayOfWeek(4) {}
   int MyGetDayOfWeek() { return m_nDayOfWeek; }
   static int MyStaticGetDayOfWeek() { return 6; }
private:
   int m_nDayOfWeek;
};

void main ()
{
   GetDayOfWeek * pGetDayOfWeek;  // declare delegate type
   int nDayOfWeek;

   // bind delegate to static method
   pGetDayOfWeek = new GetDayOfWeek(0, MyCalendar::MyStaticGetDayOfWeek);
   nDayOfWeek = pGetDayOfWeek->Invoke();
   Console::WriteLine(dynamic_cast<Object *>(nDayOfWeek)->ToString());

   // bind delegate to instance method
   MyCalendar * pcal = new MyCalendar();
   pGetDayOfWeek = new GetDayOfWeek(pcal, &MyCalendar::MyGetDayOfWeek);
   nDayOfWeek = pGetDayOfWeek->Invoke();
   Console::WriteLine(dynamic_cast<Object *>(nDayOfWeek)->ToString());
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__gc

Declares a garbage-collected object.

__gc class-specifier
__gc struct-specifier
__gc interface-specifier

Remarks

A garbage-collected class is a C++ language extension that simplifies NGWS programming by providing features such as interoperability and garbage collection.

Garbage collection is implemented by the NGWS runtime and is a high-performance, asynchronous, compacting algorithm that provides precise tracking of all pointers into the managed heap at runtime. As a result of this garbage collection algorithm, any operations that might hide addresses from the NGWS garbage collector or manipulate them in unsafe ways are disallowed.

Note The __gc keyword can also be applied to array and pointer types.

For more information on the rules for managed objects, see Managed Classes and Managed Arrays.

For more information on creating and using managed object types, see Writing Managed Programs.

Example

In the following example, a managed class (X) is declared with a public data member:

#using <mscorlib.dll>
#using namespace System;

__gc class X
{
public:
   int i;
   int ReturnInt() { return 5; }
};

void main()
{
   X* px;                    // declares a managed pointer of type X
   px = new X;               // creates a managed object of type X
   px->i = 4;                // modifies X::i through px
   int n = px->ReturnInt();  // calls X::ReturnInt through px
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__nogc

Explicitly declares a class, structure, or interface to be unmanaged.

__nogc class-specifier
__nogc struct-specifier
__nogc interface-specifier

Remarks

An unmanaged class is a C++ language extension that simplifies NGWS programming by providing features such as interoperability and garbage collection.

Note The __nogc keyword can also be applied to array and pointer types.

Example

In the following example, an unmanaged class is declared (X) and an object is instantiated and modified:

#using <mscorlib.dll>
#using namespace System;

__nogc class X
{
   public:
      int i;
};

void main()
{
   X* x;         // declares an unmanaged pointer of type X
   x = new X();  // creates a unmanaged object of type X
   x->i = 4;     // modifies the unmanaged object referred to
                 // by the unmanaged pointer x.
   delete x;
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords | __gc


__pin

Prevents a managed object from being moved by the NGWS runtime.

__pin identifier

Remarks

The __pin keyword prevents the NGWS runtime from moving a local variable during garbage collection. This is useful when passing the address of a managed variable to an unmanaged function because the address does not change unexpectedly during resolution of the external function call.

Example

In the following example, the object pointed to by pG is pinned until it passes out of scope:

#using <mscorlib.dll>
#using namespace System;

__gc class G
{
   public: int i;
};
void GenericFunc(G* pG)
{
   G __pin* ppG = pG;
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__property

Declares a property for the managed class.

__property function-declarator

Remarks

The __property keyword introduces the declaration of a property and can appear in a class, interface, or value type. A property can have a Get function (read only), a Set function (write only), or both (read-write).

For more information on properties in a managed object, see Properties of Managed Objects.

Example

In the following example, a property (Size) is added to the MyClass declaration. The property is then implicitly set and retrieved using the get_Size and set_Size functions:

#using <mscorlib.dll>
#using namespace System;

__gc class MyClass
{
   __property int get_Size() { ... };
   __property void set_Size(int i) { ... };
   // compiler generates a pseudo data member called Size

};

void main()
{
   MyClass* class1;
   Int32 curValue;

   class1->Size = 4;        // calls the set_Size function with value==4
   curValue= class1->Size;  // calls the get_Size function
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__sealed

Prevents a method or class from being a base class.

__sealed class-specifier
__sealed struct-specifier
__sealed function-declarator

The __sealed keyword specifies that a class method cannot be overridden or that a class cannot be a base class.

A __sealed virtual method cannot be overridden. A __sealed method cannot be pure.

If a nonvirtual member method is marked __sealed, the __sealed qualification is ignored.

When a class (or struct) is marked with __sealed, the class cannot be used as a base class. For example:

__sealed class A {
   // ...
   };
class B : public A {   // error
   // ...
};

On a virtual method in a class, __sealed indicates that no other implementation of this function in any derived classes is allowed.

Note The __sealed keyword is illegal when used with the __abstract keyword.

Example

extern "C" int printf(const char*, ...);

struct I {
   virtual void f() { printf("I::f()\n"); }
};

struct B1 : I {
   virtual void f() { printf("B1::f()\n"); }
};

struct B2 : I {
   // the following function cannot be overridden in the vtable
   __sealed virtual void f() { printf("B2::f()\n"); }
};

struct A : B1, B2 {
   virtual void f() { printf("A::f()\n"); }
};

void main() {
   A* pA = new A;
   B1* pB1 = new A;
   B2* pB2 = new A;

   pA->f();
   pB1->f();
   pB2->f();
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


__serializable

Specifies that the garbage-collected class can be serialized.

serializable class-specifier

Remarks

The__ serializable keyword specifies that the state of the specified garbage-collected class can be serialized. To prevent individual data members from serialization, use the __transient keyword.

Note The __serializable keyword can only be applied to garbage-collected classes.

Example

See the example for __transient.

See Also

Managed Extensions for C++ Keywords | C++ Keywords | Serialization


__transient

Specifies that the data member can not serialized.

transient member-declarator

Remarks

The__transient keyword specifies that the value of the variable is not serialized (or saved) along with other data stored in the class object.

Note The __transient keyword can only be applied to data members of a garbage-collected class.

Example

#using <mscorlib.dll>
#using namespace System;

__serializable __gc class MyClass
{
   int i;  //serializable
   __transient   int ti;  //not serializable
};

See Also

Managed Extensions for C++ Keywords | C++ Keywords | __serializable


__try_cast

Throws an exception when a cast is unsuccessful.

__try_cast < type-id > ( expression )

Remarks

The __try_cast keyword provides support for automatically throwing an exception (of type System::InvalidCastException) whenever the specified casting operation fails.

The __try_cast keyword can be used during the testing phase of your application, automatically alerting you to possible casting failures. After your application has completed testing, you can replace the __try_cast keyword with static_cast.

Example

#using <mscorlib.dll>
#using namespace System;

__gc struct Base
{
};
__gc struct Derived : Base
{
};
__gc struct MoreDerived : Derived
{
};
void main()
{
   Base*bp = new Derived;
   try
   {
       MoreDerived* mdp = __try_cast<MoreDerived*>(bp);
   }
   catch(System::InvalidCastException*)
   {
       Console::WriteLine("Could not cast 'bp' to MoreDerived*");
   }

See Also

Managed Extensions for C++ Keywords | __gc | dynamic_cast | Handling Exceptions Using Managed Extensions for C++ | C++ Keywords


__value

Declares a class to be a value class.

__value class-specifier
__value struct-specifier

Remarks

Value classes differ from managed classes in that value class variables directly contain their data, whereas managed variables point to their data, which is stored on the heap.

The following restrictions apply only to value classes:

  • The __value keyword can not be applied to an interface or union.
  • A value class can inherit from any number of interfaces and can not inherit from other classes or value classes.
  • A value class is sealed by definition. For more information, see __sealed.
  • It is legal to use a value class anywhere a managed class type is allowed.

A value class can be explicitly connected to a System::Object pointer. This is known as boxing. For more information, see Value Classes in Managed Extensions for C++.

Note The __value keyword is illegal when used with the __abstract keyword.

Example

In the following example, a value class is declared (V) and then two instances of the value class are manipulated:

#using <mscorlib.dll>
#using namespace System;

__value struct V { int m_i; };

void main()
{
   V v1, v2;
   v1.m_i = 5;
   v2 = v1;      // copies all fields of of v1 to v2
   v2.m_i = 6;   // does not affect v1.m_i
}

See Also

Managed Extensions for C++ Keywords | C++ Keywords


Pragma Directives

Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for instance, need to exercise precise control over the memory areas where data is placed or to control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating-system-specific features while retaining overall compatibility with the C and C++ languages. Pragmas are machine- or operating-system-specific by definition, and are usually different for every compiler.

Pragmas can be used in conditional statements, to provide new preprocessor functionality, or to provide implementation-defined information to the compiler. The C and C++ compilers recognize the following pragmas:

alloc_text | auto_inline | bss_seg | check_stack
code_seg | comment | component | conform 1
const_seg | data_seg | deprecated | function
hdrstop | include_alias | init_seg 1 | inline_depth
inline_recursion | intrinsic | managed | message
once | optimize | pack | pointers_to_members 1
pop_macro | push_macro | runtime_checks | section
setlocale | unmanaged | vtordisp 1 | warning

1. Supported only by the C++ compiler.

#pragma token-string

The token-string is a series of characters that gives a specific compiler instruction and arguments, if any. The number sign (#) must be the first non-white-space character on the line containing the pragma; white-space characters can separate the number sign and the word pragma. Following #pragma, write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.

If the compiler finds a pragma it does not recognize, it issues a warning, but compilation continues.

You can also use __pragma to specify pragma directives.

Some pragmas provide the same functionality as compiler options. When a pragma is encountered in the code, it overrides the behavior specified by the compiler option. For example, if you specified /Zp8, you can override this compiler setting for specific portions of the code with pack:

cl /Zp8 ...

<file> - packing is 8
// ...
#pragma pack(push, 1) - packing is now 1
// ...
#pragma pack(pop) - packing is 8
</file>

See Also

C/C++ Preprocessor Reference


alloc_text

#pragma alloc_text( "textsection", function1, ... )

Names the code section where the specified function definitions are to reside. The pragma must occur between a function declarator and the function definition for the named functions.

The alloc_text pragma does not handle C++ member functions or overloaded functions. It is applicable only to functions declared with C linkage — that is, functions declared with the extern "C" linkage specification. If you attempt to use this pragma on a function with C++ linkage, a compiler error is generated.

Since function addressing using __based is not supported, specifying section locations requires the use of the alloc_text pragma. The name specified by textsection should be enclosed in double quotation marks.

The alloc_text pragma must appear after the declarations of any of the specified functions and before the definitions of these functions.

Functions referenced in an alloc_text pragma should be defined in the same module as the pragma. If this is not done and an undefined function is later compiled into a different text section, the error may or may not be caught. Although the program will usually run correctly, the function will not be allocated in the intended sections.

Other limitations on alloc_text are as follows:

  • It cannot be used inside a function.
  • It must be used after the function has been declared, but before the function has been defined.

See Also

Pragma Directives


auto_inline

#pragma auto_inline( [{on | off}] )

Excludes any functions defined within the range where off is specified from being considered as candidates for automatic inline expansion. To use the auto_inline pragma, place it before and immediately after (not in) a function definition. The pragma takes effect at the first function definition after the pragma is seen. Pragma auto_inline does not apply to explicit inline functions.

See Also

Pragma Directives


bss_seg

#pragma bss_seg( [ [ { push | pop }, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )

Specifies the segment where uninitialized variables are stored in the .obj file. Obj files can be viewed with the dumpbin application. The default segment in the .obj file for uninitialized data is .bss. In some cases use of bss_seg can speed load times by grouping uninitialized data into one section.

bss_seg with no parameters resets the segment to .bss.

push (optional)
Puts a record on the internal compiler stack. A push can have an identifier and segment-name.
pop (optional)
Removes a record from the top of the internal compiler stack.
identifier (optional)
When used with push, assigns a name to the record on the internal compiler stack. When used with pop, pops records off the internal stack until identifier is removed; if identifier is not found on the internal stack, nothing is popped.

identifier enables multiple records to be popped with a single pop command.

"segment-name" (optional)
The name of a segment. When used with pop, the stack is popped and segment-name becomes the active segment name.
"segment-class" (optional)
Included for compatibility with C++ prior to version 2.0. It is ignored.

Example

int i;                     // stored in .bss
#pragma bss_seg(".my_data1")
int j;                     // stored in "my_data1"

#pragma bss_seg(push, stack1, ".my_data2")
int l;                     // stored in "my_data2"

#pragma bss_seg(pop, stack1)   // pop stack1 from stack
int m;                     // stored in "stack_data1"

void main() {
}

You can also specify sections for initialized data (data_seg), functions (code_seg), and const variables (const_seg).

Data allocated using the bss_seg pragma does not retain any information about its location.

See /SECTION for a list of names you should not use when creating a section.

See Also

Pragma Directives


check_stack

#pragma check_stack([ {on | off}] )
#pragma check_stack{+ | –}

Instructs the compiler to turn off stack probes if off (or –) is specified, or to turn on stack probes if on (or +) is specified. If no argument is given, stack probes are treated according to the default. This pragma takes effect at the first function defined after the pragma is seen. Stack probes are not a part of macros nor of functions that are generated inline.

If you don’t give an argument for the check_stack pragma, stack checking reverts to the behavior specified on the command line. For more information, see Compiler Reference. The interaction of the #pragma check_stack and the /Gs option is summarized in the following table.

Using the check_stack Pragma

Syntax Compiled with
/Gs option? 		Action
#pragma check_stack( ) or
#pragma check_stack 		Yes Turns off stack checking for functions that follow
#pragma check_stack( ) or
#pragma check_stack 		No Turns on stack checking for functions that follow
#pragma check_stack(on) or
#pragma check_stack + 		Yes or no Turns on stack checking for functions that follow
#pragma check_stack(off) or
#pragma check_stack – 		Yes or no Turns off stack checking for functions that follow

See Also

Pragma Directives


code_seg

#pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )

Specifies the segment where functions are stored in the .obj file. OBJ files can be viewed with the dumpbin application. The default segment in the .obj file for functions is .text.

code_seg with no parameters resets the segment to .text.

push (optional)
Puts a record on the internal compiler stack. A push can have an identifier and segment-name.
pop (optional)
Removes a record from the top of the internal compiler stack.
identifier (optional)
When used with push, assigns a name to the record on the internal compiler stack. When used with pop, pops records off the internal stack until identifier is removed; if identifier is not found on the internal stack, nothing is popped.

identifier enables multiple records to be popped with a single pop command.

"segment-name" (optional)
The name of a segment. When used with pop, the stack is popped and segment-name becomes the active segment name.
"segment-class" (optional)
Included for compatibility with C++ prior to version 2.0. It is ignored.

Example

void func1() {                  // stored in .text
}

#pragma code_seg(".my_data1")
void func2() {                  // stored in my_data1
}

#pragma code_seg(push, r1, ".my_data2")
void func3() {                  // stored in my_data2
}

#pragma code_seg(pop, r1)      // stored in my_data1
void func4() {
}

void main() {
}

See /SECTION for a list of names you should not use when creating a section.

You can also specify sections for initialized data (data_seg), uninitialized data (bss_seg), and const variables (const_seg).

See Also

Pragma Directives


comment

#pragma comment( "comment-type" [, commentstring] )

Places a comment record into an object file or executable file. The comment-type is one of five predefined identifiers, described below, that specify the type of comment record. The optional commentstring is a string literal that provides additional information for some comment types. Because commentstring is a string literal, it obeys all the rules for string literals with respect to escape characters, embedded quotation marks ("), and concatenation.

compiler
Places the name and version number of the compiler in the object file. This comment record is ignored by the linker. If you supply a commentstring parameter for this record type, the compiler generates a warning.
exestr
Places commentstring in the object file. At link time, this string is placed in the executable file. The string is not loaded into memory when the executable file is loaded; however, it can be found with a program that finds printable strings in files. One use for this comment-record type is to embed a version number or similar information in an executable file.
lib
Places a library-search record in the object file. This comment type must be accompanied by a commentstring parameter containing the name (and possibly the path) of the library that you want the linker to search. The library name follows the default library-search records in the object file; the linker searches for this library just as if you had named it on the command line provided that the library is not specified with /nodefaultlib. You can place multiple library-search records in the same source file; each record appears in the object file in the same order in which it is encountered in the source file.

If the order of the default library and an added library is important, compiling with the /Zl switch will prevent the default library name from being placed in the object module. A second comment pragma then can be used to insert the name of the default library after the added library. The libraries listed with these pragmas will appear in the object module in the same order they are found in the source code.

linker
Places a linker option in the object file. You can use this comment-type to specify a linker option instead of passing it to the command line or specifying it in the development environment. For example, you can specify the /include option to force the inclusion of a symbol:
#pragma comment(linker, "/include:__mySymbol")

Only the following linker options are available to be passed to the linker identifier:

  • /DEFAULTLIB
  • /EXPORT
  • /INCLUDE
  • /LARGEADDRESSAWARE
  • /MERGE
  • /SECTION
user
Places a general comment in the object file. The commentstring parameter contains the text of the comment. This comment record is ignored by the linker.

The following pragma causes the linker to search for the EMAPI.LIB library while linking. The linker searches first in the current working directory and then in the path specified in the LIB environment variable.

#pragma comment( lib, "emapi" )

The following pragma causes the compiler to place the name and version number of the compiler in the object file:

#pragma comment( compiler )
Note For comments that take a commentstring parameter, you can use a macro in any place where you would use a string literal, provided that the macro expands to a string literal. You can also concatenate any combination of string literals and macros that expand to string literals. For example, the following statement is acceptable:
#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )

See Also

Pragma Directives


component

#pragma component( browser, { on | off }[, references [, name ]] )
#pragma component( minrebuild, on | off )
#pragma component( mintypeinfo, on | off )

Controls the collecting of browse information or dependency information from within source files.

Browser

You can turn collecting on or off, and you can specify particular names to be ignored as information is collected.

Using on or off controls the collection of browse information from the pragma forward. For example:

#pragma component(browser, off)

stops the compiler from collecting browse information.

Note To turn on the collecting of browse information with this pragma, browse information must first be enabled from the Project Settings dialog box or the command line.

The references option can be used with or without the name argument. Using references without name turns on or off the collecting of references (other browse information continues to be collected, however). For example:

#pragma component(browser, off, references)

stops the compiler from collecting reference information.

Using references with name and off prevents references to name from appearing in the browse information window. Use this syntax to ignore names and types you are not interested in and to reduce the size of browse information files. For example:

#pragma component(browser, off, references, DWORD)

ignores references to DWORD from that point forward. You can turn collecting of references to DWORD back on by using on:

#pragma component(browser, on, references, DWORD)

This is the only way to resume collecting references to name; you must explicitly turn on any name that you have turned off.

To prevent the preprocessor from expanding name (such as expanding NULL to 0), put quotes around it:

#pragma component(browser, off, references, "NULL")

Minimal Rebuild

The Visual C++ minimal rebuild feature requires that the compiler create and store C++ class dependency information, which takes disk space. To save disk space, you can use #pragma component( minrebuild, off ) whenever you don't need to collect dependency information, for instance, in unchanging header files. Insert #pragma component(minrebuild, on) after unchanging classes to turn dependency collection back on.

Reduce Type Information

The mintypeinfo option reduces the debugging information for the region specified. The volume of this information is considerable, impacting .pdb and .obj files. You cannot debug classes and structures in the mintypeinfo region. Use of the mintypeinfo option can be helpful to avoid the following warning:

LINK : warning LNK4018: too many type indexes in PDB "filename", discarding subsequent type information

For more information, see the Enable Minimal Rebuild (/Gm) compiler option.

See Also

Pragma Directives


conform

C++ Specific

#pragma conform(name [, show ] [, on | off ] [ [, push | pop ] [, identifier  ] ] )

Specifies the run-time behavior of the /Zc:forScope compiler option.

name
Specifies the name of the compiler option to be modified. The only valid name is forScope. When used with no parameters, name is the same as #pragma conform(name, off).
show (optional)
Causes the current setting of name (true or false) to be displayed by means of a warning message during compilation. For example, #pragma conform(forScope, show).
on, off (optional)
Setting name to on enables the /Zc:forScope compiler option. The default value is off.
push (optional)
Pushes the current value of name onto the internal compiler stack. If you specify identifier, you can specify the on or off value for name to be pushed onto the stack. For example, #pragma conform(forScope, push, myname, on).
pop (optional)
Sets the value of name to the value at the top of the internal compiler stack and then pops the stack. If identifier is specified with pop, the stack will be popped back until it finds the record with identifer, which will also be popped; the current value for name in the next record on the stack becomes the new value for name. If you specify pop with an identifier that is not in a record on the stack, the pop is ignored.
identifier (optional)
Can be included with a push or pop command. If identifier is used, then an on or off specifier can also be used.

Example

#pragma conform(forScope, show)
#pragma conform(forScope, push, x, on)
#pragma conform(forScope, push, x1, off)
#pragma conform(forScope, push, x2, off)
#pragma conform(forScope, push, x3, off)
#pragma conform(forScope, show)
#pragma conform(forScope, pop, x1)
#pragma conform(forScope, show)

void main() {
}

END C++ Specific

See Also

Pragma Directives


const_seg

#pragma const_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )

Specifies the segment where const variables are stored in the .obj file. OBJ files can be viewed with the dumpbin application. The default segment in the .obj file for const variables is .rdata. Some const variables, such as scalars, are automatically inlined into the code stream. Inlined code will not appear in .rdata.

data_seg with no parameters resets the segment to .rdata.

push (optional)
Puts a record on the internal compiler stack. A push can have an identifier and segment-name.
pop (optional)
Removes a record from the top of the internal compiler stack.
identifier (optional)
When used with push, assigns a name to the record on the internal compiler stack. When used with pop, pops records off the internal stack until identifier is removed; if identifier is not found on the internal stack, nothing is popped.

Using identifier enables multiple records to be popped with a single pop command.

"segment-name" (optional)
The name of a segment. When used with pop, the stack is popped and segment-name becomes the active segment name.
"segment-class" (optional)
Included for compatibility with C++ prior to version 2.0. It is ignored.

Example

// compile with /GX
#include <iostream>

const int i = 7;               // inlined, not stored in .rdata
const char sz1[]= "test1";      // stored in .rdata

#pragma const_seg(".my_data1")
const char sz2[]= "test2";      // stored in .my_data1

#pragma const_seg(push, stack1, ".my_data2")
const char sz3[]= "test3";      // stored in .my_data2

#pragma const_seg(pop, stack1)   // pop stack1 from stack
const char sz4[]= "test4";      // stored in .my_data1

void main() {
   // const data must be referenced to be put in .obj
   std::cout << sz1 << std::endl;
   std::cout << sz2 << std::endl;
   std::cout << sz3 << std::endl;
   std::cout << sz4 << std::endl;
}

See /SECTION for a list of names you should not use when creating a section.

You can also specify sections for initialized data (data_seg), uninitialized data (bss_seg), and functions (code_seg).

See Also

Pragma Directives


data_seg

#pragma data_seg( [ [ { push | pop }, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )

Specifies the data segment where initialized variables are stored in the .obj file. OBJ files can be viewed with the dumpbin application. The default segment in the .obj file for initialized variables is .data. Variables initialized to zero are considered uninitialized and are stored in .bss.

data_seg with no parameters resets the segment to .data.

push (optional)
Puts a record on the internal compiler stack. A push can have an identifier and segment-name.
pop (optional)
Removes a record from the top of the internal compiler stack.
identifier (optional)
When used with push, assigns a name to the record on the internal compiler stack. When used with pop, pops records off the internal stack until identifier is removed; if identifier is not found on the internal stack, nothing is popped.

identifier enables multiple records to be popped with a single pop command.

"segment-name" (optional)
The name of a segment. When used with pop, the stack is popped and segment-name becomes the active segment name.
"segment-class" (optional)
Included for compatibility with C++ prior to version 2.0. It is ignored.

Example

int h = 1;                     // stored in .data
int i = 0;                     // stored in .bss
#pragma data_seg(".my_data1")
int j = 1;                     // stored in "my_data1"

#pragma data_seg(push, stack1, ".my_data2")
int l = 2;                     // stored in "my_data2"

#pragma data_seg(pop, stack1)   // pop stack1 off the stack
int m = 3;                     // stored in "stack_data1"

void main() {
}

Data allocated using data_seg does not retain any information about its location.

See /SECTION for a list of names you should not use when creating a section.

You can also specify sections for const variables (const_seg), uninitialized data (bss_seg), and functions (code_seg).

See Also

Pragma Directives


deprecated

#pragma deprecated( function1 [, function2, ...] )

The deprecated pragma lets you indicate that a function:

  • May no longer be supported in a future release.
  • Should no longer be used.

When the compiler encounters a deprecated function, it issues C4995.

You can deprecate macro names. Place the macro name in quotes or else macro expansion will occur.

The deprecated __declspec modifier allows you to specify deprecated status for particular forms of overloaded functions.

Example

#include <stdio.h>
void func1(void){printf("\nIn func1");}
void func2(void){printf("\nIn func2");}

void main() {
   func1();
   func2();
   #pragma deprecated(func1, func2)
   func1();   // C4995
   func2();   // C4995
}

See Also

Pragma Directives


function

#pragma function( function1 [, function2, ...] )

Specifies that calls to functions specified in the pragma’s argument list be generated. If you use the intrinsic pragma (or /Oi) to tell the compiler to generate intrinsic functions (intrinsic functions are generated as inline code, not as function calls), you can use the function pragma to explicitly force a function call. Once a function pragma is seen, it takes effect at the first function definition containing a specified intrinsic function. The effect continues to the end of the source file or to the appearance of an intrinsic pragma specifying the same intrinsic function. The function pragma can be used only outside of a function — at the global level.

For lists of the functions that have intrinsic forms, see #pragma intrinsic.

Example

/* compile : cl /W4 sample.c */
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// use intrinsic forms of memset and strlen
#pragma intrinsic(memset, strlen)

/*
 * Find first word break in string, and set remaining
 * chars in string to specified char value.
 */
char *set_str_after_word(char *string, char ch)
{
  int i;
  int len = strlen(string);  /* NOTE: uses intrinsic for strlen */

  for(i = 0; i < len; i++) {
    if (isspace(*(string + i)))
      break;
  }

  for(; i < len; i++)
    *(string + i) = ch;

  return string;
}

// do not use strlen intrinsic
#pragma function(strlen)

/*
 * Set all chars in string to specified char value.
 */
char *set_str(char *string, char ch)
{
  /* NOTE: uses intrinsic for memset, but calls strlen library function */
  return (char *) memset(string, ch, strlen(string));
}

int main(void)
{
  char *str = (char *) malloc(20 * sizeof(char));

  strcpy(str, "Now is the time");
  printf("str is '%s'\n", set_str_after_word(str, '*'));
  printf("str is '%s'\n", set_str(str, '!'));

  return 0;
}

See Also

Pragma Directives


hdrstop

#pragma hdrstop [( "filename" )]

The hdrstop pragma gives you additional control over precompilation file names and over the location at which the compilation state is saved.

The filename is the name of the precompiled header file to use or create (depending on whether /Yu or /Yc is specified). If filename does not contain a path specification, the precompiled header file is assumed to be in the same directory as the source file. Any filename is ignored when /YX, the automatic precompiled header option, is specified.

If a C or C++ file contains a hdrstop pragma when compiled with either /YX or /Yc, the compiler saves the state of the compilation up to the location of the pragma. The compiled state of any code that follows the pragma is not saved.

Use filename to name the precompiled header file in which the compiled state is saved. A space between hdrstop and filename is optional. The file name specified in the hdrstop pragma is a string and is therefore subject to the constraints of any C or C++ string. In particular, you must enclose it in quotation marks and use the escape character (backslash) to specify directory names. For example:

#pragma hdrstop( "c:\\projects\\include\\myinc.pch" )

The name of the precompiled header file is determined according to the following rules, in order of precedence:

  1. The argument to the /Fp compiler option
  2. The filename argument to #pragma hdrstop
  3. The base name of the source file with a .PCH extension

For the /Yc and /Yu options, if neither of the two compilation options nor the hdrstop pragma specifies a file name, the base name of the source file is used as the base name of the precompiled header file. This differs from the precompiled-header naming conventions of /YX; with /YX, the default name of the precompiled header is MSVC.pch.

You can also use preprocessing commands to perform macro replacement as follows:

#define INCLUDE_PATH "c:\\progra~`1\\devstsu~1\\vc\\include\\"
#define PCH_FNAME "PROG.PCH"
.
.
.
#pragma hdrstop( INCLUDE_PATH PCH_FNAME )

The following rules govern where the hdrstop pragma can be placed:

  • It must appear outside any data or function declaration or definition.
  • It must be specified in the source file, not within a header file.

Example

#include <windows.h>                 // Include several files
#include "myhdr.h"

__inline Disp( char *szToDisplay )   // Define an inline function
{
    ...                              // Some code to display string
}
#pragma hdrstop

In this example, the hdrstop pragma appears after two files have been included and an inline function has been defined. This might, at first, seem to be an odd placement for the pragma. Consider, however, that using the manual precompilation options, /Yc and /Yu, with the hdrstop pragma makes it possible for you to precompile entire source files — even inline code. The Microsoft compiler does not limit you to precompiling only data declarations.

See Also

Pragma Directives


include_alias

#pragma include_alias( "long_filename", "short_filename" )
#pragma include_alias( <long_filename>, <short_filename> )

Specifies that short_filename is to be used as an alias for long_filename. Some file systems allow longer header filenames than the 8.3 FAT file system limit. The compiler cannot simply truncate the longer names to 8.3, because the first eight characters of the longer header filenames may not be unique. Whenever the compiler encounters the long_filename string, it substitutes short_filename, and looks for the header file short_filename instead. This pragma must appear before the corresponding #include directives. For example:

// First eight characters of these two files not unique.
#pragma include_alias( "AppleSystemHeaderQuickdraw.h", "quickdra.h" )
#pragma include_alias( "AppleSystemHeaderFruit.h", "fruit.h" )

#pragma include_alias( "GraphicsMenu.h", "gramenu.h" )

#include "AppleSystemHeaderQuickdraw.h"
#include "AppleSystemHeaderFruit.h"
#include "GraphicsMenu.h"

The alias being searched for must match the specification exactly, in case as well as in spelling and in use of double quotation marks or angle brackets. The include_alias pragma performs simple string matching on the filenames; no other filename validation is performed. For example, given the following directives,

#pragma include_alias("mymath.h", "math.h")
#include "./mymath.h"
#include "sys/mymath.h"

no aliasing (substitution) is performed, since the header file strings do not match exactly. Also, header filenames used as arguments to the /Yu, /Yc, and /YX compiler options, or the hdrstop pragma, are not substituted. For example, if your source file contains the following directive,

#include <AppleSystemHeaderStop.h>

the corresponding compiler option should be

/YcAppleSystemHeaderStop.h

You can use the include_alias pragma to map any header filename to another. For example:

#pragma include_alias( "api.h", "c:\version1.0\api.h" )
#pragma include_alias( <stdio.h>, <newstdio.h> )
#include "api.h"
#include <stdio.h>

Do not mix filenames enclosed in double quotation marks with filenames enclosed in angle brackets. For example, given the above two #pragma include_alias directives, the compiler performs no substitution on the following #include directives:

#include <api.h>
#include "stdio.h"

Furthermore, the following directive generates an error:

#pragma include_alias(<header.h>, "header.h")  // Error

Note that the filename reported in error messages, or as the value of the predefined __FILE__ macro, is the name of the file after the substitution has been performed. For example, after the following directives,

#pragma include_alias( "VeryLongFileName.H", "myfile.h" )
#include "VeryLongFileName.H"

an error in VERYLONGFILENAME.H produces the following error message:

myfile.h(15) : error C2059 : syntax error

Also note that transitivity is not supported. Given the following directives,

#pragma include_alias( "one.h", "two.h" )
#pragma include_alias( "two.h", "three.h" )
#include "one.h"

the compiler searches for the file TWO.H rather than THREE.H.

See Also

Pragma Directives


init_seg

C++ Specific

#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )

Specifies a keyword or code section that affects the order in which startup code is executed. Because initialization of global static objects can involve executing code, you must specify a keyword that defines when the objects are to be constructed. It is particularly important to use the init_seg pragma in dynamic-link libraries (DLLs) or libraries requiring initialization.

The options to the init_seg pragma are:

compiler
Reserved for Microsoft C run-time library initialization. Objects in this group are constructed first.
lib
Available for third-party class-library vendors’ initializations. Objects in this group are constructed after those marked as compiler but before any others.
user
Available to any user. Objects in this group are constructed last.
section-name
Allows explicit specification of the initialization section. Objects in a user-specified section-name are not implicitly constructed; however, their addresses are placed in the section named by section-name.

The section name you give will contain pointers to helper functions that will construct the global objects declared in that module after the pragma.

For a list of names you should not use when creating a section, see /SECTION.

func-name
Specifies a function to be called in place of atexit when the program exits. This helper function also calls atexit with a pointer to the destructor for the global object. If you specify a function identifier in the pragma of the form,
int myexit (void (__cdecl *pf)(void))

then your function will be called instead of the C run-time library’s atexit. This allows you to build a list of the destructors that will need to be called when you are ready to destroy the objects.

If you need to defer initialization (for example, in a DLL) you may choose to specify the section name explicitly. You must then call the constructors for each static object.

There are no quotes around the identifier for the atexit replacement.

Your objects will still be placed in the sections defined by the other XXX_seg pragmas.

The objects that are declared in the module will not be automatically initialized by the C run-time. You will need to do that yourself.

Example

#include <stdio.h>
#pragma warning(disable : 4075)

typedef void (__cdecl *PF)(void);
int cxpf = 0; //number of destructors we need to call
PF pfx[200];  //ptrs to those dtors. Watch out for overflow!

int myexit (PF pf) {
   pfx[cxpf++] = pf;
   return 0;
}

struct A {
   A() { puts("A()"); }
   ~A() { puts("~A()"); }
};

// ctor & dtor called by CRT startup code
// because this is before the pragma init_seg
A aaaa;

// The order here is important.
// Section names must be 8 characters or less.
// The sections with the same name before the $
// are merged into one section. The order that
// they are merged is determined by sorting
// the characters after the $.
// InitSegStart and InitSegEnd are used to set
// boundaries so we can find the real functions
// that we need to call for initialization.

#pragma data_seg(".mine$a")
PF InitSegStart = (PF)1;
#pragma data_seg(".mine$z")
PF InitSegEnd = (PF)1;
#pragma data_seg()

// The comparison for 0 is important.
// For now, each section is 256 bytes. When they
// are merged, they are padded with zeros. You
// can't depend on the section being 256 bytes, but
// you can depend on it being padded with zeros.

void InitializeObjects () {
   PF *x = &InitSegStart;
   for (++x; x<&InitSegEnd; ++x) {
      if (*x) (*x)();
   }
}

void DestroyObjects () {
   while (cxpf>0) {
      --cxpf;
      (pfx[cxpf])();
   }
}

#pragma init_seg(".mine$m",myexit)

// I get to call the ctor & dtor from now on.
A bbbb;
A cccc;

int main () {
   InitializeObjects();

   // do some stuff here

   DestroyObjects();
   return 0;
}

END C++ Specific

See Also

Pragma Directives


inline_depth

#pragma inline_depth( [0... 255] )

Controls the number of times inline expansion can occur by controlling the number of times that a series of function calls can be expanded (from 0 to 255 times). This pragma controls the inlining of functions marked inline and __inline or inlined automatically under the /Ob2 option.

The inline_depth pragma controls the number of times a series of function calls can be expanded. For example, if the inline depth is four, and if A calls B and B then calls C, all three calls will be expanded inline. However, if the closest inline expansion is two, only A and B are expanded, and C remains as a function call.

To use this pragma, you must set the /Ob compiler option to 1 or 2. The depth set using this pragma takes effect at the first function call after the pragma. If you do not specify a value within the parentheses, inline_depth sets the inline depth back to its default value of 8.

The inline depth can be decreased during expansion but not increased. If the inline depth is six and during expansion the preprocessor encounters an inline_depth pragma with a value of eight, the depth remains six.

An inline depth of 0 inhibits inline expansion; an inline depth of 255 places no limit on inline expansion. If either pragma is used without specifying a value, the default value is used.

See Also

Pragma Directives | inline_recursion


inline_recursion

#pragma inline_recursion( [{on | off}] )

Controls the inline expansion of direct or mutually recursive function calls. Use this pragma to control functions marked as inline and __inline or functions that the compiler automatically expands under the /Ob2 option. Use of this pragma requires an /Ob compiler option setting of either 1 or 2. The default state for inline_recursion is off. This pragma takes effect at the first function call after the pragma is seen and does not affect the definition of the function.

The inline_recursion pragma controls how recursive functions are expanded. If inline_recursion is off, and if an inline function calls itself (either directly or indirectly), the function is expanded only once. If inline_recursion is on, the function is expanded multiple times until it reaches the value set by inline_depth, the default value of 8, or a capacity limit.

See Also

Pragma Directives


intrinsic

#pragma intrinsic( function1 [, function2, ...] )

Specifies that calls to functions specified in the pragma’s argument list are intrinsic. The compiler generates intrinsic functions as inline code, not as function calls. The library functions with intrinsic forms are listed below. Once an intrinsic pragma is seen, it takes effect at the first function definition containing a specified intrinsic function. The effect continues to the end of the source file or to the appearance of a function pragma specifying the same intrinsic function. The intrinsic pragma can be used only outside of a function definition — at the global level.

The following functions have intrinsic forms:

_disable | _outp | fabs | strcmp
_enable | _outpw | labs | strcpy
_inp | _rotl | memcmp | strlen
_inpw | _rotr | memcpy |
_lrotl | _strset | memset |
_lrotr | abs | strcat |

Programs that use intrinsic functions are faster because they do not have the overhead of function calls but may be larger due to the additional code generated.

Note The _alloca and setjmp functions are always generated inline; this behavior is not affected by the intrinsic pragma.

x86 Specific

The _disable and _enable parameters are kernel-mode instructions to disable/enable interrupts and could be useful in kernel-mode drivers.

Compile the following code from the command line with "cl -c -FAs sample.c" and look at sample.asm to see that they turn into x86 instructions CLI and STI:

#include <dos.h>   // definitions for _disable, _enable
#pragma intrinsic(_disable)
#pragma intrinsic(_enable)
void f1(void) {
   _disable();
   // do some work here that should not be interrupted
   _enable();
}
void main() {
}

End x86 Specific

The floating-point functions listed below do not have true intrinsic forms. Instead they have versions that pass arguments directly to the floating-point chip rather than pushing them onto the program stack:

acos | cosh | pow | tanh
asin | fmod | sinh |

The floating-point functions listed below have true intrinsic forms when you specify both the /Oi and /Og compiler options (or any option that includes /Og: /Ox, /O1, and /O2):

atan | exp | log10 | sqrt
atan2 | log | sin | tan
cos |  |  |

You can use the /Op or /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.

See # pragma function for information and an example on how to enable/disable intrinsics for a block of source text.

See Also

Pragma Directives


managed, unmanaged

#pragma managed
#pragma unmanaged

Using the /com+ compiler option provides module-level control for compiling functions either as managed or unmanaged. Using the managed and unmanaged pragmas enable function-level control for compiling functions managed or unmanaged.

An unmanaged function will be compiled for the native platform and execution of that portion of the program will be passed to the native platform by the runtime.

Functions are managed by default when /com+ is used. The compiler ignores the managed or unmanaged pragmas if /com+ is not used in the compilation.

Example

// compile with /com+
#using <mscorlib.dll>

#pragma unmanaged
static void func1(void) {
   __asm {
      nop
   }
}

// func2 is unmanaged
static void func2(void) {   // ok
   __asm {
      nop
   }
}

#pragma managed
// main is managed
void main() {
}

See Also

Pragma Directives


message

#pragma message( messagestring )

Sends a string literal to the standard output without terminating the compilation. A typical use of the message pragma is to display informational messages at compile time.

The following code fragment uses the message pragma to display a message during compilation:

#if _M_IX86 == 500
#pragma message( "Pentium processor build" )
#endif

The messagestring parameter can be a macro that expands to a string literal, and you can concatenate such macros with string literals in any combination. For example, the following statements display the name of the file being compiled and the date and time when the file was last modified:

#pragma message( "Compiling " __FILE__ )
#pragma message( "Last modified on " __TIMESTAMP__ )

See Also

Pragma Directives


once

#pragma once

Specifies that the file, in which the pragma resides, will be included (opened) only once by the compiler in a build. A common use for this pragma is the following:

//header.h
#pragma once
// Your C or C++ code would follow:

See Also

Pragma Directives


optimize

#pragma optimize( "[optimization-list]", {on | off} )
Feature Only in Professional and Enterprise Edition Code optimization is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.

Specifies optimizations to be performed on a function-by-function basis. The optimize pragma must appear outside a function and takes effect at the first function defined after the pragma is seen. The on and off arguments turn options specified in the optimization-list on or off.

The optimization-list can be zero or more of the parameters shown in the following table.

Parameters of the optimize Pragma

Parameter(s) | Type of optimization
a | Assume no aliasing.
g | Enable global optimizations.
p | Improve floating-point consistency.
s or t | Specify short or fast sequences of machine code.
w | Assume that aliasing can occur across function calls (achieves the same effect as /Ow).
y | Generate frame pointers on the program stack.

These are the same letters used with the /O compiler options. For example:

#pragma optimize( "atp", on )

Using the optimize pragma with the empty string ("") is a special form of the directive:

  • When you use the off parameter, it turns the optimizations, listed in the table above, off.
  • When you use the on parameter, it resets the optimizations to those that you specified with the /O compiler option.
#pragma optimize( "", off )
.
.
.
#pragma optimize( "", on )

See Also

Pragma Directives


pack

#pragma pack( [ show ] | [ push | pop ] [, identifier ] , n  )

Specifies packing alignment for structure, union, and class members. pack gives control at the data-declaration level. This differs from compiler option /Zp, which only provides module-level control. pack takes effect at the first struct, union, or class declaration after the pragma is seen; pack has no effect on definitions. Calling pack with no arguments sets n to its default value. This is equivalent to compiler option /Zp8.

show (optional)
Displays the current byte value for packing alignment. The value is displayed by means of a warning message.
push (optional)
Puts a specified packing alignment value, n, on the internal compiler stack, and sets the current packing alignment value to n. If n is not specified, the current packing alignment value is pushed.
pop (optional)
Removes the record from the top of the internal compiler stack. If n is not specified with pop, then the packing value associated with the resulting record on the top of the stack is the new packing alignment value. If n is specified, for example, #pragma pack(pop, 16), n becomes the new packing alignment value. If you pop with identifier, for example, #pragma pack(pop, r1), then all records on the stack are popped until the record with identifier is found, and that record is popped and the packing value associated with the resulting record on the top of is the stack the new packing alignment value. If you pop with an identifier that is not found in any record on the stack, then the pop is ignored.
identifier (optional)
When used with push, assigns a name to the record on the internal compiler stack. When used with pop, pops records off the internal stack until identifier is removed; if identifier is not found on the internal stack, nothing is popped.
n (optional)
Specifies the value, in bytes, to be used for packing. Can be used with push or pop for setting a particular stack value, or alone for setting the current value used by the compiler. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16.

Example

#pragma pack()               // n defaults to 8; equivalent to /Zp8
#pragma pack(show)         // C4810
#pragma pack(4)            // n=4
#pragma pack(show)         // C4810
#pragma pack(push, r1, 16)   // n=16, pushed to stack
#pragma pack(show)         // C4810
#pragma pack(pop, r1, 2)   // n=2 , stack popped
#pragma pack(show)         // C4810

void main() {
}

See Also

Pragma Directives


pointers_to_members

C++ Specific

#pragma pointers_to_members( pointer-declaration, [most-general-representation] )

Specifies whether a pointer to a class member can be declared before its associated class definition and is used to control the pointer size and the code required to interpret the pointer. You can place a pointers_to_members pragma in your source file as an alternative to using the /vmx compiler options or the inheritance keywords.

The pointer-declaration argument specifies whether you have declared a pointer to a member before or after the associated function definition. The pointer-declaration argument is one of the following two symbols:

Argument | Comments
full_generality | Generates safe, sometimes nonoptimal code. You use full_generality if any pointer to a member is declared before the associated class definition. This argument always uses the pointer representation specified by the most-general-representation argument. Equivalent to /vmg.
best_case | Generates safe, optimal code using best-case representation for all pointers to members. Requires defining the class before declaring a pointer to a member of the class. The default is best_case.

The most-general-representation argument specifies the smallest pointer representation that the compiler can safely use to reference any pointer to a member of a class in a translation unit. The argument can be one of the following:

Argument | Comments
single_inheritance | The most general representation is single-inheritance, pointer to a member function. Causes an error if the inheritance model of a class definition for which a pointer to a member is declared is ever either multiple or virtual.
multiple_inheritance | The most general representation is multiple-inheritance, pointer to a member function. Causes an error if the inheritance model of a class definition for which a pointer to a member is declared is virtual.
virtual_inheritance | The most general representation is virtual-inheritance, pointer to a member function. Never causes an error. This is the default argument when #pragma pointers_to_members(full_generality) is used.

Example

//   Specify single-inheritance only
#pragma pointers_to_members( full_generality, single_inheritance )

END C++ Specific

See Also

Pragma Directives


pop_macro

#pragma pop_macro("macro_name")

Sets the value of the macro_name macro to the value on the top of the stack. You must first issue a push_macro for macro_name before you can do a pop_macro.

Example

#include <stdio.h>
#define X 1
#define Y 2

void main() {
   printf("\n%d",X);
   #pragma push_macro("X")
   printf("\n%d",X);
   #define X 2
   printf("\n%d",X);
   #pragma pop_macro("X")
   printf("\n%d",X);
}

See Also

Pragma Directives


push_macro

#pragma push_macro("macro_name")

Saves the value of the macro_name macro on the top of the stack. You can retrieve the value for macro_name with pop_macro.

See pop_macro for a sample.

See Also

Pragma Directives


runtime_checks

#pragma runtime_checks( "[runtime_checks]", {restore | off} )

Disables or restores the /RTC settings. You cannot enable a run-time check that was not enabled with a compiler option. For example, if you do not specify /RTCs, specifying #pragma runtime_checks( "s", restore) will not enable stack (frame).verification.

The runtime_checks pragma must appear outside a function and takes effect at the first function defined after the pragma is seen. The restore and off arguments turn options specified in the runtime_checks on or off.

The runtime_checks can be zero or more of the parameters shown in the following table.

Parameters of the runtime_checks Pragma

Parameter(s) | Type of run-time check
s | Enables stack (frame) verification.
c | Reports when a value is assigned to a smaller data type that results in a data loss.
u | Reports when a variable is used before it is defined.

These are the same letters used with the /RTC compiler option. For example:

#pragma runtime_checks( "sc", restore )

Using the runtime_checks pragma with the empty string ("") is a special form of the directive:

  • When you use the off parameter, it turns the run-time error checks, listed in the table above, off.
  • When you use the restore parameter, it resets the run-time error checks to those that you specified with the /RTC compiler option.
#pragma runtime_checks( "", off )
.
.
.
#pragma runtime_checks( "", restore )

See Also

Pragma Directives | RTC sample


section

#pragma section( "section-name" [, attributes] )

Creates a section in an .obj file. Once a section is defined, it remains valid for the remainder of the compilation. However, you must use __declspec(allocate) or nothing will be placed in the section.

section-name is a required parameter that will be the name of the section. The name must not conflict with any standard section names. See /SECTION for a list of names you should not use when creating a section.

attributes is an optional parameter consisting of one or more comma-separated attributes that you want to assign to the section. Possible attributes are:

read
Allows read operations on data.
write
Allows write operations on data.
execute
Allows code to be executed.
shared
Shares the section among all processes that load the image.
nopage
Marks the section as not pageable; useful for Win32 device drivers.
nocache
Marks the section as not cacheable; useful for Win32 device drivers.
discard
Marks the section as discardable; useful for Win32 device drivers.
remove
Marks the section as not memory-resident; virtual device drivers (VxD) only.

If you do not specify attributes, the section will have read and write attributes.

Example

In the following example, the first instruction identifies the section and its attributes. The integer j is not put into mysec because it was not declared with __declspec(allocate); j goes into the data section. The integer i does go into mysec as a result of its __declspec(allocate) storage-class attribute.

#pragma section("mysec",read,write)
int j = 0;
__declspec(allocate("mysec")) int i;
int i = 1;

See Also

Pragma Directives


setlocale

#pragma setlocale( "[locale-string]" )

Defines the locale (Country/Region and language) to be used when translating wide-character constants and string literals. Since the algorithm for converting multibyte characters to wide characters may vary by locale or the compilation may take place in a different locale from where an executable file will be run, this pragma provides a way to specify the target locale at compile time. This guarantees that the wide-character strings will be stored in the correct format.

The default locale-string is "".

The "C" locale maps each character in the string to its value as a wchar_t (unsigned short). Other values that are valid for setlocale are those entries that are found in the Language Strings list. For example, you could issue:

#pragma setlocale("dutch")

The ability to issue a language string depends on the code page and language ID support on your computer.

See Also

Pragma Directives


vtordisp

C++ Specific

#pragma vtordisp({on | off} )

Enables the addition of the hidden vtordisp construction/destruction displacement member. The vtordisp pragma is applicable only to code that uses virtual bases. If a derived class overrides a virtual function that it inherits from a virtual base class, and if a constructor or destructor for the derived class calls that function using a pointer to the virtual base class, the compiler may introduce additional hidden “vtordisp” fields into classes with virtual bases.

The vtordisp pragma affects the layout of classes that follow it. The /vd0 and /vd1 options specify the same behavior for complete modules. Specifying off suppresses the hidden vtordisp members. Specifying on, the default, enables them where they are necessary. Turn off vtordisp only if there is no possibility that the class’s constructors and destructors call virtual functions on the object pointed to by the this pointer.\

#pragma vtordisp( off )
class GetReal : virtual public { ... };
#pragma vtordisp( on )

END C++ Specific

See Also

Pragma Directives


warning

#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...] )
#pragma warning( push[ ,n ] )
#pragma warning( pop )

Allows selective modification of the behavior of compiler warning messages.

The warning-specifier can be one of the following.

Warning-specifier | Meaning
once | Display the specified message(s) only once.
default | Reset warning behavior to its default value.
1, 2, 3, 4 | Apply the given warning level to the specified warning message(s). This also has the effect of turning a specified warning on that is off by default.
disable | Do not issue the specified warning message(s).
error | Report the specified warnings as errors.

The warning-number-list can contain any warning numbers. Multiple options can be specified in the same pragma directive as follows:

#pragma warning( disable : 4507 34; once : 4385; error : 164 )

This is functionally equivalent to:

#pragma warning( disable : 4507 34 )  // Disable warning messages
                                      //  4507 and 4034.
#pragma warning( once : 4385 )        // Issue warning 4385
                                      //  only once.
#pragma warning( error : 164 )        // Report warning 4164
                                      //  as an error.

Note that the compiler will add 4000 to any warning number that is between 0 and 999.

For warning numbers greater than 4699, those associated with code generation, the warning pragma has effect only when placed outside function definitions. The pragma is ignored if it specifies a number greater than 4699 and is used inside a function. The following example shows the correct placement of warning pragmas to disable, and then restore, the generation of a code-generation warning message:

int a;
#pragma warning( disable : 4705 )
void func()
{
    a;
}
#pragma warning( default : 4705 )

Note that within a function body, the last setting of the warning pragma will be in effect for the entire function.

The warning pragma also supports the following syntax:

#pragma warning( push [ ,n ] )

#pragma warning( pop )

Where n represents a warning level (1 through 4).

The pragma warning( push ) stores the current warning state for all warnings. The pragma warning( push, n) stores the current state for all warnings and sets the global warning level to n.

The pragma warning( pop ) pops the last warning state pushed onto the stack. Any changes made to the warning state between push and pop are undone. Consider this example:

#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
// Some code
#pragma warning( pop )

At the end of this code, pop restores the state of all warnings (including 4705, 4706, and 4707) to what it was at the beginning of the code.

When you write header files, you can use push and pop to ensure that changes to warning states made by the user do not prevent your headers from compiling properly. Use push at the beginning of the header and pop at the end. Suppose, for example, you have a header that does not compile cleanly at warning level 4. The following code changes the warning level to 3, then restores the original warning level at the end of the header:

#pragma warning( push, 3 )
// Declarations/ definitions
#pragma warning( pop )

See /FI and /w for compiler options that help you suppress warnings.

See Also

Pragma Directives


The Preprocessor

The preprocessor is a text processor that manipulates the text of a source file as part of the first phase of translation. The preprocessor does not parse the source text, but it does break it up into tokens for the purpose of locating macro calls. Although the compiler ordinarily invokes the preprocessor in its first pass, the preprocessor can also be invoked separately to process text without compiling.

The reference material on the preprocessor includes the following sections:

  • Preprocessor directives
  • Preprocessor operators
  • Predefined macros
  • Pragmas

Microsoft Specific

You can obtain a listing of your source code after preprocessing by using the /E or /EP compiler option. Both options invoke the preprocessor and output the resulting text to the standard output device, which, in most cases, is the console. The difference between the two options is that /E includes #line directives and /EP strips these directives out.

END Microsoft Specific

Special Terminology

In the preprocessor documentation, the term “argument” refers to the entity that is passed to a function. In some cases, it is modified by “actual” or “formal,” which mean the argument expression specified in the function call and the argument declaration specified in the function definition, respectively.

The term “variable” refers to a simple C-type data object. The term “object” refers to both C++ objects and variables; it is an inclusive term.

See Also

C/C++ Preprocessor Reference | Phases of Translation


Phases of Translation

C and C++ programs consist of one or more source files, each of which contains some of the text of the program. A source file, together with its include files (files that are included using the #include preprocessor directive) but not including sections of code removed by conditional-compilation directives such as #if, is called a “translation unit.”

Source files can be translated at different times — in fact, it is common to translate only out-of-date files. The translated translation units can be kept either in separate object files or in object-code libraries. These separate translation units are then linked to form an executable program or a dynamic-link library (DLL).

Translation units can communicate using:

  • Calls to functions that have external linkage.
  • Calls to class member functions that have external linkage.
  • Direct modification of objects that have external linkage.
  • Direct modification of files.
  • Interprocess communication (for Microsoft Windows®-based applications only).

The following list describes the phases in which the compiler translates files:

Character mapping
Characters in the source file are mapped to the internal source representation. Trigraph sequences are converted to single-character internal representation in this phase.
Line splicing
All lines ending in a backslash (\) and immediately followed by a newline character are joined with the next line in the source file, forming logical lines from the physical lines. Unless it is empty, a source file must end in a newline character that is not preceded by a backslash.
Tokenization
The source file is broken into preprocessing tokens and white-space characters. Comments in the source file are replaced with one space character each. Newline characters are retained.
Preprocessing
Preprocessing directives are executed and macros are expanded into the source file. The #include statement invokes translation starting with the preceding three translation steps on any included text.
Character-set mapping
All source-character-set members and escape sequences are converted to their equivalents in the execution-character set. For Microsoft C and C++, both the source and the execution character sets are ASCII.
String concatenation
All adjacent string and wide-string literals are concatenated. For example, "String " "concatenation" becomes "String concatenation".
Translation
All tokens are analyzed syntactically and semantically; these tokens are converted into object code.
Linkage
All external references are resolved to create an executable program or a dynamic-link library.

The compiler issues warnings or errors during phases of translation in which it encounters syntax errors.

The linker resolves all external references and creates an executable program or DLL by combining one or more separately processed translation units along with standard libraries.

See Also

The Preprocessor


Preprocessor Directives

Preprocessor directives, such as #define and #ifdef, are typically used to make source programs easy to change and easy to compile in different execution environments. Directives in the source file tell the preprocessor to perform specific actions. For example, the preprocessor can replace tokens in the text, insert the contents of other files into the source file, or suppress compilation of part of the file by removing sections of text. Preprocessor lines are recognized and carried out before macro expansion. Therefore, if a macro expands into something that looks like a preprocessor command, that command is not recognized by the preprocessor.

Preprocessor statements use the same character set as source file statements, with the exception that escape sequences are not supported. The character set used in preprocessor statements is the same as the execution character set. The preprocessor also recognizes negative character values.

The preprocessor recognizes the following directives:

#define | #error | #import | #undef
#elif | #if | #include | #using
#else | #ifdef | #line |
#endif | #ifndef | #pragma |

The number sign (#) must be the first nonwhite-space character on the line containing the directive; white-space characters can appear between the number sign and the first letter of the directive. Some directives include arguments or values. Any text that follows a directive (except an argument or value that is part of the directive) must be preceded by the single-line comment delimiter (//) or enclosed in comment delimiters (/* */). Lines containing preprocessor directives can be continued by immediately preceding the end-of-line marker with a backslash (\).

Preprocessor directives can appear anywhere in a source file, but they apply only to the remainder of the source file.

See Also

Preprocessor Operators | Predefined Macros | C/C++ Preprocessor Reference


The #define Directive

You can use the #define directive to give a meaningful name to a constant in your program. The two forms of the syntax are:

#define identifier token-stringopt
#define identifier[( identifieropt,  ... , identifieropt )] token-stringopt

The #define directive substitutes token-string for all subsequent occurrences of an identifier in the source file. The identifier is replaced only when it forms a token. (See C++ Tokens in the C++ Language Reference.) For instance, identifier is not replaced if it appears in a comment, within a string, or as part of a longer identifier.

A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested using the #if defined and #ifdef directives.

The token-string argument consists of a series of tokens, such as keywords, constants, or complete statements. One or more white-space characters must separate token-string from identifier. This white space is not considered part of the substituted text, nor is any white space following the last token of the text.

Formal parameter names appear in token-string to mark the places where actual values are substituted. Each parameter name can appear more than once in token-string, and the names can appear in any order. The number of arguments in the call must match the number of parameters in the macro definition. Liberal use of parentheses ensures that complicated actual arguments are interpreted correctly.

The second syntax form allows the creation of function-like macros. This form accepts an optional list of parameters that must appear in parentheses. References to the identifier after the original definition replace each occurrence of identifier( identifieropt, ..., identifieropt ) with a version of the token-string argument that has actual arguments substituted for formal parameters.

The formal parameters in the list are separated by commas. Each name in the list must be unique, and the list must be enclosed in parentheses. No spaces can separate identifier and the opening parenthesis. Use line concatenation — place a backslash (\) immediately before the newline character — for long directives on multiple source lines. The scope of a formal parameter name extends to the new line that ends token-string.

When a macro has been defined in the second syntax form, subsequent textual instances followed by an argument list constitute a macro call. The actual arguments following an instance of identifier in the source file are matched to the corresponding formal parameters in the macro definition. Each formal parameter in token-string that is not preceded by a stringizing (#), charizing (#@), or token-pasting (##) operator, or not followed by a ## operator, is replaced by the corresponding actual argument. Any macros in the actual argument are expanded before the directive replaces the formal parameter. (The operators are described in Preprocessor Operators.)

The following examples of macros with arguments illustrate the second form of the #define syntax:

// Macro to define cursor lines
#define CURSOR(top, bottom) ((top) << 8) | bottom))

// Macro to get a random integer with a specified range
#define getrandom(min, max) \
    ((rand()%(int)(((max) + 1)-(min)))+ (min))

Arguments with side effects sometimes cause macros to produce unexpected results. A given formal parameter may appear more than once in token-string. If that formal parameter is replaced by an expression with side effects, the expression, with its side effects, may be evaluated more than once. (See the examples under Token-Pasting Operator (##).)

The #undef directive causes an identifier’s preprocessor definition to be forgotten. See The #undef Directive for more information.

If the name of the macro being defined occurs in token-string (even as a result of another macro expansion), it is not expanded.

A second #define for a macro with the same name generates an error unless the second token sequence is identical to the first.

Microsoft Specific

Microsoft C/C++ allows the redefinition of a macro, but generates a warning, provided the new definition is lexically identical to a previous definition. ANSI C considers macro redefinition an error. For example, these macros are equivalent for C/C++ but generate warnings:

#define test( f1, f2 ) ( f1 * f2 )
#define test( a1, a2 ) ( a1 * a2 )

END Microsoft Specific

This example illustrates the #define directive:

#define WIDTH       80
#define LENGTH      ( WIDTH + 10 )

The first statement defines the identifier WIDTH as the integer constant 80 and defines LENGTH in terms of WIDTH and the integer constant 10. Each occurrence of LENGTH is replaced by (WIDTH + 10). In turn, each occurrence of WIDTH + 10 is replaced by the expression (80 + 10). The parentheses around WIDTH + 10 are important because they control the interpretation in statements such as the following:

var = LENGTH * 20;

After the preprocessing stage the statement becomes:

var = ( 80 + 10 ) * 20;

which evaluates to 1800. Without parentheses, the result is:

var = 80 + 10 * 20;

which evaluates to 280.

Microsoft Specific

Defining macros and constants with the /D compiler option has the same effect as using a #define preprocessing directive at the beginning of your file. Up to 30 macros can be defined with the /D option.

END Microsoft Specific

See Also

Preprocessor Directives


The #error Directive

Error directives produce compiler-time error messages.

#error token-string

The error messages include the argument token-string and are subject to macro expansion. These directives are most useful for detecting programmer inconsistencies and violation of constraints during preprocessing. The following example demonstrates error processing during preprocessing:

#if !defined(__cplusplus)
#error C++ compiler required.
#endif

When #error directives are encountered, compilation terminates.

See Also

Preprocessor Directives


The #if, #elif, #else, and #endif Directives

The #if directive, with the #elif, #else, and #endif directives, controls compilation of portions of a source file. If the expression you write (after the #if) has a nonzero value, the line group immediately following the #if directive is retained in the translation unit.

Grammar

conditional :
if-part elif-partsopt else-partopt endif-line
if-part :
if-line text
if-line :
#if constant-expression
#ifdef identifier
#ifndef identifier
elif-parts :
elif-line text
elif-parts elif-line text
elif-line :
#elif constant-expression
else-part :
else-line text
else-line :
#else
endif-line :
#endif

Each #if directive in a source file must be matched by a closing #endif directive. Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. The #else directive, if present, must be the last directive before #endif.

The #if, #elif, #else, and #endif directives can nest in the text portions of other #if directives. Each nested #else, #elif, or #endif directive belongs to the closest preceding #if directive.

All conditional-compilation directives, such as #if and #ifdef, must be matched with closing #endif directives prior to the end of file; otherwise, an error message is generated. When conditional-compilation directives are contained in include files, they must satisfy the same conditions: There must be no unmatched conditional-compilation directives at the end of the include file.

Macro replacement is performed within the part of the command line that follows an #elif command, so a macro call can be used in the constant-expression.

The preprocessor selects one of the given occurrences of text for further processing. A block specified in text can be any sequence of text. It can occupy more than one line. Usually text is program text that has meaning to the compiler or the preprocessor.

The preprocessor processes the selected text and passes it to the compiler. If text contains preprocessor directives, the preprocessor carries out those directives. Only text blocks selected by the preprocessor are compiled.

The preprocessor selects a single text item by evaluating the constant expression following each #if or #elif directive until it finds a true (nonzero) constant expression. It selects all text (including other preprocessor directives beginning with #) up to its associated #elif, #else, or #endif.

If all occurrences of constant-expression are false, or if no #elif directives appear, the preprocessor selects the text block after the #else clause. If the #else clause is omitted and all instances of constant-expression in the #if block are false, no text block is selected.

The constant-expression is an integer constant expression with these additional restrictions:

  • Expressions must have integral type and can include only integer constants, character constants, and the defined operator.
  • The expression cannot use sizeof or a type-cast operator.
  • The target environment may not be able to represent all ranges of integers.
  • The translation represents type int the same as type long, and unsigned int the same as unsigned long.
  • The translator can translate character constants to a set of code values different from the set for the target environment. To determine the properties of the target environment, check values of macros from LIMITS.H in an application built for the target environment.
  • The expression must not perform any environmental inquiries and must remain insulated from implementation details on the target computer.

The preprocessor operator defined can be used in special constant expressions, as shown by the following syntax:

Syntax

defined( identifier )
defined identifier

This constant expression is considered true (nonzero) if the identifier is currently defined; otherwise, the condition is false (0). An identifier defined as empty text is considered defined. The defined directive can be used in an #if and an #elif directive, but nowhere else.

In the following example, the #if and #endif directives control compilation of one of three function calls:

#if defined(CREDIT)
    credit();
#elif defined(DEBIT)
    debit();
#else
    printerror();
#endif

The function call to credit is compiled if the identifier CREDIT is defined. If the identifier DEBIT is defined, the function call to debit is compiled. If neither identifier is defined, the call to printerror is compiled. Note that CREDIT and credit are distinct identifiers in C and C++ because their cases are different.

The conditional compilation statements in the following example assume a previously defined symbolic constant named DLEVEL.

#if DLEVEL > 5
    #define SIGNAL  1
    #if STACKUSE == 1
        #define STACK   200
    #else
        #define STACK   100
    #endif
#else
    #define SIGNAL  0
    #if STACKUSE == 1
        #define STACK   100
    #else
        #define STACK   50
    #endif
#endif
#if DLEVEL == 0
    #define STACK 0
#elif DLEVEL == 1
    #define STACK 100
#elif DLEVEL > 5
    display( debugptr );
#else
    #define STACK 200
#endif

The first #if block shows two sets of nested #if, #else, and #endif directives. The first set of directives is processed only if DLEVEL > 5 is true. Otherwise, the statements after #else are processed.

The #elif and #else directives in the second example are used to make one of four choices, based on the value of DLEVEL. The constant STACK is set to 0, 100, or 200, depending on the definition of DLEVEL. If DLEVEL is greater than 5, then the statement

#elif DLEVEL > 5
display(debugptr);

is compiled and STACK is not defined.

A common use for conditional compilation is to prevent multiple inclusions of the same header file. In C++, where classes are often defined in header files, constructs like the following can be used to prevent multiple definitions:

// EXAMPLE.H - Example header file

#if !defined( EXAMPLE_H )
#define EXAMPLE_H

class Example
{
...
};

#endif // !defined( EXAMPLE_H )

The preceding code checks to see if the symbolic constant EXAMPLE_H is defined. If so, the file has already been included and need not be reprocessed. If not, the constant EXAMPLE_H is defined to mark EXAMPLE.H as already processed.

Microsoft Specific

Conditional compilation expressions are treated as signed long values, and these expressions are evaluated using the same rules as expressions in C++. For example, this expression:

#if 0xFFFFFFFFL > 1UL

is true.

END Microsoft Specific

See Also

Preprocessor Directives


The #ifdef and #ifndef Directives

The #ifdef and #ifndef directives perform the same task as the #if directive when it is used with defined( identifier ).

Syntax

#ifdef identifier
#ifndef identifier

is equivalent to

#if defined identifier
#if !defined identifier

You can use the #ifdef and #ifndef directives anywhere #if can be used. The #ifdef identifier statement is equivalent to #if 1 when identifier has been defined, and it is equivalent to #if 0 when identifier has not been defined or has been undefined with the #undef directive. These directives check only for the presence or absence of identifiers defined with #define, not for identifiers declared in the C or C++ source code.

These directives are provided only for compatibility with previous versions of the language. The defined( identifier ) constant expression used with the #if directive is preferred.

The #ifndef directive checks for the opposite of the condition checked by #ifdef. If the identifier has not been defined (or its definition has been removed with #undef), the condition is true (nonzero). Otherwise, the condition is false (0).

Microsoft Specific

The identifier can be passed from the command line using the /D option. Up to 30 macros can be specified with /D.

This is useful for checking whether a definition exists, because a definition can be passed from the command line. For example:

// PROG.CPP
#ifndef test    // These three statements go in your source code.
#define final
#endif

CL /Dtest prog.cpp // This is the command for compilation.

END Microsoft Specific

See Also

Preprocessor Directives


The #import Directive

C++ Specific

The #import directive is used to incorporate information from a type library. The content of the type library is converted into C++ classes, mostly describing the COM interfaces.

#import  "filename" [attributes]
#import  <filename> [attributes]
attributes
One or more #import Attributes. Separate attributes with either a space or comma. For example:
   #import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only

or

   #import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only
filename
Allows you to specify which type library you want to import. filename can be one of the following:
  • A type library (.TLB or .ODL). file:, which indicates type library, can precede each filename.
  • The progid of a control in the type library. Note that progid: can precede each progid. For example:
    #import "progid:my.prog.id.1.5"

    For more on progids, see Specifying the Localization ID and Version Number.

  • The library ID of the type library. Note that libid: can precede each library ID. For example:
    #import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")

    If you do not specify version or lcid, the rules that are applied to progid: are also applied to libid:.

  • An executable (.EXE) file.
  • A library (.DLL) file containing a type library resource (such as .OCX).
  • A compound document holding a type library.
  • Any other file format that can be understood by the LoadTypeLib API.

See Knowledge Base article Q242527 for more information about #import.

Search Order for filename

filename is optionally preceded by a directory specification. The file name must name an existing file. The difference between the two syntax forms is the order in which the preprocessor searches for the type library files when the path is incompletely specified.

Syntax Form | Action
Quoted form | Instructs the preprocessor to look for type library files first in the directory of the file that contains the #import statement, and then in the directories of whatever files that include (#include) that file. The preprocessor then searches along the paths shown below.
Angle-bracket form | Instructs the preprocessor to search for type library files along the paths shown below.

The preprocessor will search in the following directories for the named file:

  1. The PATH environment variable path list
  2. The LIB environment variable path list
  3. The path specified by the /I (additional include directories) compiler option

Specifying the Localization ID and Version Number

When you specify a progid, you can also specify the localization ID and version number of the progid. For example:

#import "progid:my.prog.id" lcid("0") version("4.0)

If you do not specify a localization ID, a progid is chosen according to the following rules:

  • If there is only one localization ID, that one is used.
  • If there is more than one localization ID, the first one with version number 0, 9, or 409 is used.
  • If there is more than one localization ID and none of them are 0, 9, or 409, the last one is used.
  • If you do not specify a version number, the most recent version is used.

Header Files Created by Import

#import creates two header files that reconstruct the type library contents in C++ source code. The primary header file is similar to that produced by the Microsoft Interface Definition Language (MIDL) compiler, but with additional compiler-generated code and data. The primary header file has the same base name as the type library, plus a .TLH extension. The secondary header file has the same base name as the type library, with a .TLI extension. It contains the implementations for compiler-generated member functions, and is included (#include) in the primary header file.

Both header files are placed in the output directory specified by the /Fo (name object file) option. They are then read and compiled by the compiler as if the primary header file was named by a #include directive.

The following compiler optimizations come with the #import directive:

  • The header file, when created, is given the same timestamp as the type library.
  • When #import is processed, the compiler first checks if the header exists and is up to date. If yes, then it does not need to be re-created.

The #import directive also participates in minimal rebuild and can be placed in a precompiled header file. See Creating Precompiled Header Files for more information.

The Primary Type Library Header File

The primary type library header file consists of seven sections:

  1. Heading boilerplate: Consists of comments, #include statement for COMDEF.H (which defines some standard macros used in the header), and other miscellaneous setup information.
  2. Forward references and typedefs: Consists of structure declarations such as struct IMyInterface and typedefs.
  3. Smart pointer declarations: The template class _com_ptr_t is a smart-pointer implementation that encapsulates interface pointers and eliminates the need to call AddRef, Release, QueryInterface functions. In addition, it hides the CoCreateInstance call in creating a new COM object. This section uses macro statement _COM_SMARTPTR_TYPEDEF to establish typedefs of COM interfaces to be template specializations of the _com_ptr_t template class. For example, for interface IMyInterface, the .TLH file will contain:
    _COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));

    which the compiler will expand to:

    typedef _com_ptr_t<_com_IIID<IMyInterface, __uuidof(IMyInterface)> > IMyInterfacePtr;

    Type IMyInterfacePtr can then be used in place of the raw interface pointer IMyInterface*. Consequently, there is no need to call the various IUnknown member functions.

  4. Typeinfo declarations: Primarily consists of class definitions and other items exposing the individual typeinfo items returned by ITypeLib:GetTypeInfo. In this section, each typeinfo from the type library is reflected in the header in a form dependent on the TYPEKIND information.
  5. Optional old-style GUID definition: Contains initializations of the named GUID constants. These are names of the form CLSID_CoClass and IID_Interface, similar to those generated by the MIDL compiler.
  6. #include statement for the secondary type library header.
  7. Footer boilerplate: Currently includes #pragma pack(pop).

All sections, except the heading boilerplate and footer boilerplate section, are enclosed in a namespace with its name specified by the library statement in the original IDL file. You can use the names from the type library header either by an explicit qualification with the namespace name or by including the following statement:

using namespace MyLib;

immediately after the #import statement in the source code.

The namespace can be suppressed by using the no_namespace attribute of the #import directive. However, suppressing the namespace may lead to name collisions. The namespace can also be renamed by the rename_namespace attribute.

The compiler provides the full path to any type library dependency required by the type library it is currently processing. The path is written, in the form of comments, into the type library header (.TLH) that the compiler generates for each processed type library.

If a type library includes references to types defined in other type libraries, then the .TLH file will include comments of the following sort:

//
// Cross-referenced type libraries:
//
//  #import "c:\path\typelib0.tlb"
//

The actual filename in the #import comment is the full path of the cross-referenced type library, as stored in the registry. If you encounter errors that are due to missing type definitions, check the comments at the head of the .TLH to see which dependent type libraries may need to be imported first. Likely errors are syntax errors (for example, C2143, C2146, C2321), C2501 (missing decl-specifiers), or C2433 ('inline' not permitted on data declaration) while compiling the .TLI file.

You must determine which of the dependency comments are not otherwise provided for by system headers and then provide an #import directive at some point before the #import directive of the dependent type library in order to resolve the errors.

#import Attributes

#import can optionally include one or more attributes. These attributes tell the compiler to modify the contents of the type-library headers. A backslash (\) symbol can be used to include additional lines in a single #import statement. For example:

#import "test.lib" no_namespace \
   rename("OldName", "NewName")

The #import attributes are listed below:

exclude | no_namespace
high_method_prefix | no_smartpointers
high_property_prefixes | raw_dispinterfaces
implementation_only | raw_interfaces_only
include(…) | raw_method_prefix
inject_statement | raw_native_types
named_guids | raw_property_prefixes
no_auto_exclude | rename
no_dual_interfaces | rename_namespace
no_implementation |

exclude attribute

exclude("Name1"[, "Name2",...])
Name1
First item to be excluded
Name2
Second item to be excluded (if necessary)

Type libraries may include definitions of items defined in system headers or other type libraries. This attribute can be used to exclude these items from the type library header files being generated. This attribute can take any number of arguments, each being a top-level type library item to be excluded.

high_method_prefix attribute

high_method_prefix("Prefix")
Prefix
Prefix to be used

By default, high-level error-handling properties and methods are exposed by member functions named without a prefix. The names are from the type library. The high_method_prefix attribute is used to specify a prefix to be used in naming these high-level properties and methods.

high_property_prefixes attribute

high_property_prefixes("GetPrefix","PutPrefix","PutRefPrefix")
GetPrefix
Prefix to be used for the propget methods
PutPrefix
Prefix to be used for the propput methods
PutRefPrefix
Prefix to be used for the propputref methods

By default, high-level error-handling propget, propput, and propputref methods are exposed by member functions named with prefixes Get, Put, and PutRef respectively. The high_property_prefixes attribute is used to specify alternate prefixes for all three property methods.

implementation_only attribute

The implementation_only attribute suppresses the generation of the .TLH header file (the primary header file). This file contains all the declarations used to expose the type-library contents. The .TLI header file, with the implementations of the wrapper member functions, will be generated and included in the compilation.

When this attribute is specified, the content of the .TLI header is in the same namespace as the one normally used in the .TLH header. In addition, the member functions are not declared as inline.

The implementation_only attribute is intended for use in conjunction with the no_implementation attribute as a way of keeping the implementations out of the precompiled header (PCH) file. An #import statement with the no_implementation attribute is placed in the source region used to create the PCH. The resulting PCH is used by a number of source files. An #import statement with the implementation_only attribute is then used outside the PCH region. You are required to use this statement only once in one of the source files. This will generate all the required wrapper member functions without additional recompilation for each source file.

Note The implementation_only attribute in one #import statement must be use in conjunction with another #import statement, of the same type library, with the no_implementation attribute. Otherwise, compiler errors will be generated. This is because wrapper class definitions generated by the #import statement with the no_implementation attribute are required to compile the implementations generated by the implementation_only attribute.

include(...) attribute

include(Name1[, Name2, ...])
Name1
First item to be forcibly included
Name2
Second item to be forcibly included (if necessary)

Type libraries may include definitions of items defined in system headers or other type libraries. #import attempts to avoid multiple definition errors by automatically excluding such items. If items have been excluded, as indicated by warning C4192, and they should not have been, this attribute can be used to disable the automatic exclusion. This attribute can take any number of arguments, each being the name of the type-library item to be included.

inject_statement attribute

inject_statement("source_text")
source_text
Source text to be inserted into the type library header file

The inject_statement attribute inserts its argument as source text into the type-library header. The text is placed at the beginning of the namespace declaration that wraps the type-library contents in the header file.

named_guids attribute

The named_guids attribute tells the compiler to define and initialize GUID variables in old style, of the form LIBID_MyLib, CLSID_MyCoClass, IID_MyInterface, and DIID_MyDispInterface.

no_auto_exclude attribute

Type libraries may include definitions of items defined in system headers or other type libraries. #import attempts to avoid multiple definition errors by automatically excluding such items. When this is done, warning C4192 will be issued for each item to be excluded. You can disable this automatic exclusion by using this attribute.

no_dual_interfaces attribute

The no_dual_interfaces attribute changes the way the compiler generates wrapper functions for dual interface methods. Normally, the wrapper will call the method through the virtual function table for the interface. With no_dual_interfaces, the wrapper instead calls IDispatch::Invoke to invoke the method.

no_implementation attribute

The no_implementation attribute suppresses the generation of the .TLI header, which contains the implementations of the wrapper member functions. If this attribute is specified, the .TLH header, with the declarations to expose type-library items, will be generated without an #include statement to include the .TLI header file.

This attribute is used in conjunction with implementation_only.

no_namespace attribute

The type-library contents in the #import header file are normally defined in a namespace. The namespace name is specified in the library statement of the original IDL file. If the no_namespace attribute is specified, this namespace is not generated by the compiler.

If you want to use a different namespace name, use the rename_namespace attribute instead.

no_smartpointers attribute

By default, when you use #import, you get a smart pointer declaration for all interfaces in the type library. These smart pointers are of type _com_ptr_t. The no_smartpointers attribute suppresses the creation of these smart pointers.

raw_dispinterfaces attribute

The raw_dispinterfaces attribute tells the compiler to generate low-level wrapper functions for dispinterface methods and properties that call IDispatch::Invoke and return the HRESULT error code.

If this attribute is not specified, only high-level wrappers are generated, which throw C++ exceptions in case of failure.

raw_interfaces_only attribute

The raw_interfaces_only attribute suppresses the generation of error-handling wrapper functions and __declspec(property) declarations that use those wrapper functions.

The raw_interfaces_only attribute also causes the default prefix used in naming the non-property functions to be removed. Normally, the prefix is raw_. If this attribute is specified, the function names are directly from the type library.

This attribute allows you to expose only the low-level contents of the type library.

raw_method_prefix attribute

raw_method_prefix("Prefix")
Prefix
The prefix to be used

Low-level properties and methods are exposed by member functions named with a default prefix of raw_ to avoid name collisions with the high-level error-handling member functions. The raw_method_prefix attribute is used to specify a different prefix.

Note The effects of the raw_method_prefix attribute will not be changed by the presence of the raw_interfaces_only attribute. The raw_method_prefix always takes precedence over raw_interfaces_only in specifying a prefix. If both attributes are used in the same #import statement, then the prefix specified by the raw_method_prefix attribute is used.

raw_native_types attribute

By default, the high-level error-handling methods use the COM support classes _bstr_t and _variant_t in place of the BSTR and VARIANT data types and raw COM interface pointers. These classes encapsulate the details of allocating and deallocating memory storage for these data types, and greatly simplify type casting and conversion operations. The raw_native_types attribute is used to disable the use of these COM support classes in the high-level wrapper functions, and force the use of low-level data types instead.

raw_property_prefixes attribute

raw_property_prefixes("GetPrefix","PutPrefix","PutRefPrefix")
GetPrefix
Prefix to be used for the propget methods
PutPrefix
Prefix to be used for the propput methods
PutRefPrefix
Prefix to be used for the propputref methods

By default, low-level propget, propput, and propputref methods are exposed by member functions named with prefixes of get_, put_, and putref_ respectively. These prefixes are compatible with the names used in the header files generated by MIDL. The raw_property_prefixes attribute is used to specify alternate prefixes for all three property methods.

rename attribute

rename("OldName","NewName")
OldName
Old name in the type library
NewName
Name to be used instead of the old name

The rename attribute is used to work around name collision problems. If this attribute is specified, the compiler replaces all occurrences of OldName in a type library with the user-supplied NewName in the resulting header files.

This attribute can be used when a name in the type library coincides with a macro definition in the system header files. If this situation is not resolved, then various syntax errors will be generated, such as C2059 and C2061.

Note The replacement is for a name used in the type library, not for a name used in the resulting header file.

Here is an example: Suppose a property named MyParent exists in a type library, and a macro GetMyParent is defined in a header file and used before #import. Since GetMyParent is the default name of a wrapper function for the error-handling get property, a name collision will occur. To work around the problem, use the following attribute in the #import statement:

rename("MyParent","MyParentX")

which renames the name MyParent in the type library. An attempt to rename the GetMyParent wrapper name will fail:

rename("GetMyParent","GetMyParentX")

This is because the name GetMyParent only occurs in the resulting type library header file.

rename_namespace attribute

rename_namespace("NewName")
NewName
The new name of the namespace

The rename_namespace attribute is used to rename the namespace that contains the contents of the type library. It takes a single argument, NewName, which specifies the new name for the namespace.

To remove the namespace, use the no_namespace attribute instead.

END C++ Specific

See Also

Preprocessor Directives


The #include Directive

The #include directive tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears. You can organize constant and macro definitions into include files and then use #include directives to add these definitions to any source file. Include files are also useful for incorporating declarations of external variables and complex data types. You only need to define and name the types once in an include file created for that purpose.

#include  "path-spec"
#include  <path-spec>

The path-spec is a filename optionally preceded by a directory specification. The filename must name an existing file. The syntax of the path-spec depends on the operating system on which the program is compiled.

Both syntax forms cause replacement of that directive by the entire contents of the specified include file. The difference between the two forms is the order in which the preprocessor searches for header files when the path is incompletely specified.

Syntax Form | Action
Quoted form | This form instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of any files that include (#include) that file. The preprocessor then searches along the path specified by the /I compiler option, then along paths specified by the INCLUDE environment variable.
Angle-bracket form | This form instructs the preprocessor to search for include files first along the path specified by the /I compiler option, then, when compiling from the command line, along the path specified by the INCLUDE environment variable.

The preprocessor stops searching as soon as it finds a file with the given name. If you specify a complete, unambiguous path specification for the include file between two sets of double quotation marks (" "), the preprocessor searches only that path specification and ignores the standard directories.

If the filename enclosed in double quotation marks is an incomplete path specification, the preprocessor first searches the “parent” file’s directory. A parent file is the file containing the #include directive. For example, if you include a file named file2 within a file named file1, file1 is the parent file.

Include files can be “nested”; that is, an #include directive can appear in a file named by another #include directive. For example, file2, above, could include file3. In this case, file1 would still be the parent of file2 but would be the “grandparent” of file3.

When include files are nested and when compiling from the command line, directory searching begins with the directories of the parent file and then proceeds through the directories of any grandparent files. Thus, searching begins relative to the directory containing the source currently being processed. If the file is not found, the search moves to directories specified by the /I compiler option. Finally, the directories specified by the INCLUDE environment variable are searched.

From within the development environment, the INCLUDE environment variable is ignored. To set the directories searched for include files, use the following steps (This information also applies to the LIB environment variable.):

  1. Select Options from the Tools menu.
  2. Select the Directories tab in the Options dialog box.
  3. Select the appropriate platform (for example, Win32) in the Platform drop-down list box. The directories to be searched will be specific to this platform.
  4. Select Include files in the Show directories for drop-down list box.
  5. Enter the full paths of the directories to be searched in the Directories editable list box, one directory per line. The directories will be searched in the order listed.
  6. Press OK to confirm the selections.

The following example shows file inclusion using angle brackets:

#include <stdio.h>

This example adds the contents of the file named STDIO.H to the source program. The angle brackets cause the preprocessor to search the directories specified by the INCLUDE environment variable for STDIO.H, after searching directories specified by the /I compiler option.

The following example shows file inclusion using the quoted form:

#include "defs.h"

This example adds the contents of the file specified by DEFS.H to the source program. The double quotation marks mean that the preprocessor searches the directory containing the parent source file first.

Nesting of include files can continue up to 10 levels. Once the nested #include is processed, the preprocessor continues to insert the enclosing include file into the original source file.

Microsoft Specific

To locate includable source files, the preprocessor first searches the directories specified by the /I compiler option. If the /I option is not present or fails, the preprocessor uses the INCLUDE environment variable to find any include files within angle brackets. The INCLUDE environment variable and /I compiler option can contain multiple paths separated by semicolons (;). If more than one directory appears as part of the /I option or within the INCLUDE environment variable, the preprocessor searches them in the order in which they appear.

For example, the command

CL /ID:\MSVC\INCLUDE MYPROG.C

causes the preprocessor to search the directory D:\MSVC\INCLUDE for include files such as STDIO.H. The commands

SET INCLUDE=D:\MSVC\INCLUDE
CL MYPROG.C

have the same effect. If both sets of searches fail, a fatal compiler error is generated.

If the filename is fully specified for an include file with a path that includes a colon (for example, F:\MSVC\SPECIAL\INCL\TEST.H), the preprocessor follows the path.

For include files specified as #include "path-spec", directory searching begins with the directory of the parent file and then proceeds through the directories of any grandparent files. Thus, searching begins relative to the directory containing the source file containing the #include directive being processed. If there is no grandparent file and the file has not been found, the search continues as if the filename were enclosed in angle brackets.

END Microsoft Specific

See Also

Preprocessor Directives


The #line Directive

The #line directive tells the preprocessor to change the compiler’s internally stored line number and filename to a given line number and filename. The compiler uses the line number and filename to refer to errors that it finds during compilation. The line number usually refers to the current input line, and the filename refers to the current input file. The line number is incremented after each line is processed.

#line digit-sequence "filename"opt

The digit-sequence value can be any integer constant. Macro replacement can be performed on the preprocessing tokens, but the result must evaluate to the correct syntax. The filename can be any combination of characters and must be enclosed in double quotation marks (" "). If filename is omitted, the previous filename remains unchanged.

You can alter the source line number and filename by writing a #line directive. The translator uses the line number and filename to determine the values of the predefined macros __FILE__ and __LINE__. You can use these macros to insert self-descriptive error messages into the program text. For more information on these predefined macros, see Predefined Macros.

The __FILE__ macro expands to a string whose contents are the filename, surrounded by double quotation marks (" ").

If you change the line number and filename, the compiler ignores the previous values and continues processing with the new values. The #line directive is typically used by program generators to cause error messages to refer to the original source file instead of to the generated program.

The following examples illustrate #line and the __LINE__ and __FILE__ macros.

In this statement, the internally stored line number is set to 151 and the filename is changed to copy.c.

#line 151 "copy.c"

In this example, the macro ASSERT uses the predefined macros __LINE__ and __FILE__ to print an error message about the source file if a given “assertion” is not true.

#define ASSERT(cond)

if( !(cond) )\
{printf( "assertion error line %d, file(%s)\n", \
__LINE__, __FILE__ );}

See Also

Preprocessor Directives


The Null Directive

The null preprocessor directive is a single number sign (#) alone on a line. It has no effect.

#

See Also

Preprocessor Directives


The #undef Directive

As its name implies, the #undef directive removes (undefines) a name previously created with #define.

#undef identifier

The #undef directive removes the current definition of identifier. Consequently, subsequent occurrences of identifier are ignored by the preprocessor. To remove a macro definition using #undef, give only the macro identifier ; do not give a parameter list.

You can also apply the #undef directive to an identifier that has no previous definition. This ensures that the identifier is undefined. Macro replacement is not performed within #undef statements.

The #undef directive is typically paired with a #define directive to create a region in a source program in which an identifier has a special meaning. For example, a specific function of the source program can use manifest constants to define environment-specific values that do not affect the rest of the program. The #undef directive also works with the #if directive to control conditional compilation of the source program. See The #if, #elif, #else, and #endif Directives for more information.

In the following example, the #undef directive removes definitions of a symbolic constant and a macro. Note that only the identifier of the macro is given.

#define WIDTH           80
#define ADD( X, Y )     (X) + (Y)
.
.
.
#undef WIDTH
#undef ADD

Microsoft Specific

Macros can be undefined from the command line using the /U option, followed by the macro names to be undefined. The effect of issuing this command is equivalent to a sequence of #undef macro-name statements at the beginning of the file.

END Microsoft Specific

See Also

Preprocessor Directives


The #using Directive

Imports metadata into a program that will use the Managed Extensions for C++.

#using file

where:

file
A .dll or .exe that was built as a managed program.

Remarks

file can be an MSIL file that you import for its managed data and managed constructs. If a .dll contains an assembly manifest, then all the .dlls referenced in the manifest are imported and the assembly you are building will list file in the metadata as an assembly reference.

If file does not contain an assembly, then you will also need to pass the file name to the /ASSEMBLYMODULE linker option.

Note that when importing metadata built from source that used __declspec(thread), that the thread semantics are not persisted in metadata. For example, a variable declared with __declspec(thread), compiled in a program that is build for the NGWS runtime, and then imported via #using, will no longer have __declspec(thread) semantics on the variable.

If file has metadata only and not an assembly manifest, the following guidelines discuss how to access the metadata:

  • If the metadata only contains one class, the class and the file name must be the same.
  • One of the classes must have the same name as the file name. Before you can use any of the other classes, you must first allocate memory for the class that has the same name as file.
  • If one or more classes in the metadata are in a namespace, the namespace must have the same name as file. You can access classes in the metadata in one of two ways:
    • Qualify access to each class with the namespace name.
    • Use using namespace file to load all classes in the namespace.

Example

#using <mscorlib.dll>

See Also

Preprocessor Directives


Preprocessor Operators

Four preprocessor-specific operators are used in the context of the #define directive (see the following list for a summary of each). The stringizing, charizing, and token-pasting operators are discussed in the next three sections. For information on the defined operator, see The #if, #elif, #else, and #endif Directives.

Operator | Action
Stringizing operator (#) | Causes the corresponding actual argument to be enclosed in double quotation marks
Charizing operator (#@) | Causes the corresponding argument to be enclosed in single quotation marks and to be treated as a character (Microsoft Specific)
Token-pasting operator (##) | Allows tokens used as actual arguments to be concatenated to form other tokens
defined operator | Simplifies the writing of compound expressions in certain macro directives

See Also

Preprocessor Directives | Predefined Macros | C/C++ Preprocessor Reference


Stringizing Operator (#)

The number-sign or “stringizing” operator (#) converts macro parameters (after expansion) to string constants. It is used only with macros that take arguments. If it precedes a formal parameter in the macro definition, the actual argument passed by the macro invocation is enclosed in quotation marks and treated as a string literal. The string literal then replaces each occurrence of a combination of the stringizing operator and formal parameter within the macro definition.

White space preceding the first token of the actual argument and following the last token of the actual argument is ignored. Any white space between the tokens in the actual argument is reduced to a single white space in the resulting string literal. Thus, if a comment occurs between two tokens in the actual argument, it is reduced to a single white space. The resulting string literal is automatically concatenated with any adjacent string literals from which it is separated only by white space.

Further, if a character contained in the argument usually requires an escape sequence when used in a string literal (for example, the quotation mark (") or backslash (\) character), the necessary escape backslash is automatically inserted before the character. The following example shows a macro definition that includes the stringizing operator and a main function that invokes the macro:

#define stringer( x ) printf( #x "\n" )

void main()
{
    stringer( In quotes in the printf function call\n );
    stringer( "In quotes when printed to the screen"\n );
    stringer( "This: \"  prints an escaped double quote" );
}

Such invocations would be expanded during preprocessing, producing the following code:

void main()
{
   printf( "In quotes in the printf function call\n" "\n" );
   printf( "\"In quotes when printed to the screen\"\n" "\n" );
   printf( "\"This: \\\" prints an escaped double quote\"" "\n" );
}

When the program is run, screen output for each line is as follows:

In quotes in the printf function call

"In quotes when printed to the screen"

"This: \" prints an escaped double quotation mark"

Microsoft Specific

The Microsoft C (versions 6.0 and earlier) extension to the ANSI C standard that previously expanded macro formal arguments appearing inside string literals and character constants is no longer supported. Code that relied on this extension should be rewritten using the stringizing (#) operator.

END Microsoft Specific

See Also

Preprocessor Operators


Charizing Operator (#@)

Microsoft Specific

The charizing operator can be used only with arguments of macros. If #@ precedes a formal parameter in the definition of the macro, the actual argument is enclosed in single quotation marks and treated as a character when the macro is expanded. For example:

#define makechar(x)  #@x

causes the statement

a = makechar(b);

to be expanded to

a = 'b';

The single-quotation character cannot be used with the charizing operator.

END Microsoft Specific

See Also

Preprocessor Operators


Token-Pasting Operator (##)

The double-number-sign or “token-pasting” operator (##), which is sometimes called the “merging” operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token and therefore cannot be the first or last token in the macro definition.

If a formal parameter in a macro definition is preceded or followed by the token-pasting operator, the formal parameter is immediately replaced by the unexpanded actual argument. Macro expansion is not performed on the argument prior to replacement.

Then, each occurrence of the token-pasting operator in token-string is removed, and the tokens preceding and following it are concatenated. The resulting token must be a valid token. If it is, the token is scanned for possible replacement if it represents a macro name. The identifier represents the name by which the concatenated tokens will be known in the program before replacement. Each token represents a token defined elsewhere, either within the program or on the compiler command line. White space preceding or following the operator is optional.

This example illustrates use of both the stringizing and token-pasting operators in specifying program output:

#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;

If a macro is called with a numeric argument like

paster( 9 );

the macro yields

printf( "token" "9" " = %d", token9 );

which becomes

printf( "token9 = %d", token9 );

See Also

Preprocessor Operators


Macros

Preprocessing expands macros in all lines that are not preprocessor directives (lines that do not have a # as the first non-white-space character) and in parts of some directives that are not skipped as part of a conditional compilation. “Conditional compilation” directives allow you to suppress compilation of parts of a source file by testing a constant expression or identifier to determine which text blocks are passed on to the compiler and which text blocks are removed from the source file during preprocessing.

The #define directive is typically used to associate meaningful identifiers with constants, keywords, and commonly used statements or expressions. Identifiers that represent constants are sometimes called “symbolic constants” or “manifest constants.” Identifiers that represent statements or expressions are called “macros.” In this preprocessor documentation, only the term “macro” is used.

When the name of the macro is recognized in the program source text or in the arguments of certain other preprocessor commands, it is treated as a call to that macro. The macro name is replaced by a copy of the macro body. If the macro accepts arguments, the actual arguments following the macro name are substituted for formal parameters in the macro body. The process of replacing a macro call with the processed copy of the body is called “expansion” of the macro call.

In practical terms, there are two types of macros. “Object-like” macros take no arguments, whereas “function-like” macros can be defined to accept arguments so that they look and act like function calls. Because macros do not generate actual function calls, you can sometimes make programs run faster by replacing function calls with macros. (In C++, inline functions are often a preferred method.) However, macros can create problems if you do not define and use them with care. You may have to use parentheses in macro definitions with arguments to preserve the proper precedence in an expression. Also, macros may not correctly handle expressions with side effects. See the getrandom example in The #define Directive for more information.

Once you have defined a macro, you cannot redefine it to a different value without first removing the original definition. However, you can redefine the macro with exactly the same definition. Thus, the same definition can appear more than once in a program.

The #undef directive removes the definition of a macro. Once you have removed the definition, you can redefine the macro to a different value. The #define Directive and The #undef Directive discuss the #define and #undef directives, respectively.

See Also

Predefined Macros | Macros and C++ | C/C++ Preprocessor Reference


Macros and C++

C++ offers new capabilities, some of which supplant those offered by the ANSI C preprocessor. These new capabilities enhance the type safety and predictability of the language:

  • In C++, objects declared as const can be used in constant expressions. This allows programs to declare constants that have type and value information, and enumerations that can be viewed symbolically with the debugger. Using the preprocessor #define directive to define constants is not as precise. No storage is allocated for a const object unless an expression that takes its address is found in the program.
  • The C++ inline function capability supplants function-type macros. The advantages of using inline functions over macros are:
    • Type safety. Inline functions are subject to the same type checking as normal functions. Macros are not type safe.
    • Correct handling of arguments that have side effects. Inline functions evaluate the expressions supplied as arguments prior to entering the function body. Therefore, there is no chance that an expression with side effects will be unsafe.

For more information on inline functions, see inline, __inline, __forceinline.

For backward compatibility, all preprocessor facilities that existed in ANSI C and in earlier C++ specifications are preserved for Microsoft C++.

See Also

Predefined Macros | Macros


Predefined Macros

The compiler recognizes seven predefined ANSI C macros, and the Microsoft C++ implementation provides several more. These macros take no arguments and cannot be redefined. Their value, except for __LINE__ and __FILE__, must be constant throughout compilation. Some of the predefined macros listed below are defined with multiple values. Their values can be set by selecting the corresponding menu option in the Visual C++ development environmen, or by using a command-line switch. See the following tables for more information.

ANSI-Compliant Predefined Macros

Macro | Description
__COUNTER__ Expands to an integer, starting with 0 and incrementing by one every time it is used in a compiland. __COUNTER__ remembers its state when using precompiled headers. If the last __COUNTER__ value was 4 after building a PCH, it will start with 5 on each PCH use.

__COUNTER__ lets you generate unique variable names. You can use token pasting with a prefix to make a unique name. For example,

#include <stdio.h>
#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)

int FUNC(my_unique_prefix);
int FUNC(my_unique_prefix);

void main() {
   my_unique_prefix0 = 0;
   printf("\n%d",my_unique_prefix0);
   my_unique_prefix0++;
   printf("\n%d",my_unique_prefix0);
}
__DATE__ | The compilation date of the current source file. The date is a string literal of the form Mmm dd yyyy. The month name Mmm is the same as for dates generated by the library function asctime declared in TIME.H.
__FILE__ The name of the current source file. __FILE__ expands to a string surrounded by double quotation marks.

You can create your own wide string version of __FILE__ as follows:

   #define WIDEN2(x)   L ## x
   #define WIDEN(x)   WIDEN2(x)
   #define __WFILE__   WIDEN(__FILE__)
   wchar_t *pwsz = __WFILE__;
__FUNCDNAME__ | Valid only within a function and returns the decorated name of the enclosing function (as a string). __FUNCDNAME__ is not expanded if you use /EP or /P compiler options.
__FUNCTION__ | Valid only within a function and returns the undecorated name of the enclosing function (as a string). __FUNCTION__ is not expanded if you use /EP or /P compiler options.
__LINE__ | The line number in the current source file. The line number is a decimal integer constant. It can be altered with a #line directive.
__STDC__ | Indicates full conformance with the ANSI C standard. Defined as the integer constant 1 only if the /Za compiler option is given and you are not compiling C++ code; otherwise is undefined.
__TIME__ | The most recent compilation time of the current source file. The time is a string literal of the form hh:mm:ss.
__TIMESTAMP__ | The date and time of the last modification of the current source file, expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy, where Ddd is the abbreviated day of the week and Date is an integer from 1 to 31.

Microsoft-Specific Predefined Macros

Macro | Description
_CHAR_UNSIGNED | Default char type is unsigned. Defined when /J is specified.
__cplusplus | Defined for C++ programs only.
_CPPRTTI | Defined for code compiled with /GR (Enable Run-Time Type Information).
_CPPUNWIND | Defined for code compiled with /GX (Enable Exception Handling).
_DLL | Defined when /MD or /MDd (Multithread DLL) is specified.
_M_ALPHA | Defined for DEC ALPHA platforms. It is defined as 1 by the ALPHA compiler, and it is not defined if another compiler is used.
_M_IX86 | Defined for x86 processors. See Values for _M_IX86 for more details.
_M_MPPC | Defined for Power Macintosh platforms (no longer supported).
_M_MRX000 | Defined for MIPS platforms (no longer supported).
_M_PPC | Defined for PowerPC platforms (no longer supported).
_MFC_VER | Defines the MFC version. Defined as 0x0600 for Microsoft Foundation Class Library 6.0 or later. Always defined.
_MSC_EXTENSIONS | This macro is defined when compiling with the /Ze compiler option (the default). Its value, when defined, is 1.
_MSC_FULL_VER Defines the full version number for the compiler (cl.exe). _MSC_FULL_VER allows you to put conditional statements in your code that are based on which version of the compiler is being used.

Version number is in the format MajorMinorBuild.

major
The major version of the compiler.
minor
The minor (or point release) version of the compiler.
build
The Microsoft-specific number of the build.

If you type cl /? at the command line, you will see the full version for the compiler you are using.

For example, in Visual C++ 6.0, the version number is 12.00.8168.
_MSC_VER Defines the major and minor versions of the compiler. For example, 1200 for Microsoft Visual C++ 6.0. 1200 represents version 12 and no point release. This represents the fact that there have been a total of 12 releases of the compiler.

If you type cl /? at the command line, you will see the full version for the compiler you are using.
_MT | Defined when /MD or /MDd (Multithreaded DLL) or /MT or /MTd (Multithreaded) is specified.
_WIN32 | Defined for applications for Win32®. Always defined.

As shown in following table, the compiler generates a value for the preprocessor identifiers that reflect the processor option specified.

Values for _M_IX86

Option in Development Environment | Command-Line Option | Resulting Value
Blend | /GB | _M_IX86 = 500 (Default. Future compilers will emit a different value to reflect the dominant processor.)
Pentium | /G5 | _M_IX86 = 500
Pentium Pro, Pentium II, and Pentium III | /G6 | _M_IX86 = 600
80386 | /G3 | _M_IX86 = 300
80486 | /G4 | _M_IX86 = 400

See Also

Macros | Preprocessor Operators | Preprocessor Directives


Topic Not Found

No matching topic was found. The link may be out of date, incorrectly authored, or the topic may not be available in this release.

You may be able to find the topic by using the index or search tab instead.


Copyright

NGWS SDK Documentation

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document, including URL and other Internet Web site references, is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. Unless otherwise noted, the example companies, organizations, products, people and events depicted herein are fictitious and no association with any real company, organization, product, person or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Unpublished work. © 1999 - 2000 Microsoft Corporation. All rights reserved.

Microsoft, MS-DOS, Windows, Windows NT, Active Directory, ActiveX, Authenticode, FrontPage, IntelliSense, JScript , Outlook, Visual Basic, Visual Basic Scripting Edition (VBScript), Visual C++, Visual Studio, and Win32 are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.