< Old To New C++ .Net 3 | Main | .Net Framework Class Library 1 >



Managed Extensions for C++ to

New C++ .NET Syntax Migration 4



The code snippets used in this module if any, are the mix of Visual C++ .Net 2003 and 2005. If the old code used on VC++ 2005, compile with the /clr:OldSyntax option. The following are the topics in this part.

  1. Fixing Errors

  2. Metadata Merge

  3. Loader Lock Deadlock

  4. Data Exports

  5. Type Visibility

  6. Floating Point and Alignment Issues

  7. COM Initialization

  8. Performance Issues

  9. Program Crashes on Shutdown

  10. Using New C++ Features

  11. New C++ Language Features

  12. CLR Data Type Keywords

  13. Override Specifiers

  14. Keywords for Generics

  15. Miscellaneous New Keywords

  16. Non-Keyword Language Constructs

  17. New C++ Operators

  18. More CLR Constructs


Fixing Errors


Compiling with /clr may result in compiler, linker or runtime errors. The following section discusses the most common problems.


Metadata Merge


Differing versions of data types can cause the linker to fail because the metadata generated for the two types doesn't match. (This is usually caused when members of a type are conditionally defined, but the conditions are not the same for all CPP files that use the type.) In this case the linker fails, reporting only the symbol name and the name of the second OBJ file where the type was defined. It is often useful to rotate the order that OBJ files are sent to the linker to discover the location of the other version of the data type.


Loader Lock Deadlock


In Visual C++ .NET and Visual C++ 2003, initialization under /clr was susceptible to non-deterministic deadlock. This issue is known as "loader lock deadlock". In Visual C++ 2005, this deadlock is easier to avoid, it is detected and reported at runtime, and is no longer non-deterministic. Encountering the loader lock problem is still possible, but now it's much easier to avoid and fix.


Data Exports


Exporting DLL data is error-prone, and not recommended. This is because the data section of a DLL is not guaranteed to be initialized until some managed portion of the DLL has been executed. Reference metadata with the #using directive.


Type Visibility


Native types are now private by default. In Visual C++ .NET 2002 and Visual C++ 2003, native types were public by default. This can result in a native type not being visible outside the DLL. Resolve this error by adding public to these types. See Type and Member Visibility for more information.


Floating Point and Alignment Issues


The __controlfp is not supported on the common language runtime. The CLR will also not respect align (C++).


COM Initialization


The Common Language Runtime initializes COM automatically when a module is initialized (when COM is initialized automatically it’s done so as MTA). As a result, explicitly initializing COM yields return codes indicating that COM is already initialized. Attempting to explicitly initialize COM with one threading model when the CLR has already initialized COM to another threading model can cause your application to fail. COM initialization and associated error code should either allow for the case where COM is already initialized, or calls to CoInitialize and CoUninitialize can generally simply be removed. The common language runtime starts COM as MTA by default; use /CLRTHREADATTRIBUTE to modify this.


Performance Issues


You may see decreased performance when native C++ methods generated to MSIL are called indirectly (virtual function calls or using function pointers). When moving from native to MSIL, you will notice an increase in the size of your working set. This is because the common language runtime provides many features to ensure that programs run correctly. If your /clr application is not running correctly, you may want to enable C4793 (off by default).


Program Crashes on Shutdown


In some cases, the CLR can shutdown before your managed code is finished running. Using std::set_terminate and SIGTERM can cause this.





Using New C++ Features


After your application compiles, links, and runs, you can begin using .NET features in any module compiled with /clr. If you used Managed Extensions for C++, you can convert your code to use the new syntax.


New C++ Language Features


In Visual C++ 2005 Visual C++ includes new syntax for writing applications to target the common language runtime. This topic presents an overview of the new syntax. This syntax replaces the previous syntax, known as Managed Extensions for C++. Managed Extensions for C++ syntax is still available, but as a deprecated feature under /clr:oldSyntax compiler option. The new syntax is in effect by default when you use /clr.


CLR Data Type Keywords


The following table lists new keywords that have been added to the C++ language. Note that some keywords consist of two words separated by white space. These aggregate keywords are considered keywords despite the fact that used separately, they have different meanings. The word ref, for example, used without class is not a keyword and can be used as a regular identifier. Likewise, by itself class denotes a native class. But, used together, ref class defines a common language runtime (CLR) reference type.



Old keyword

Context sensitive


ref class

ref struct

__gc class

__gc struct


Defines a CLR reference class

value class

value struct

__value class

__value struct


Defines a CLR value class

interface class

interface struct

__interface class

__interface struct


Defines a CLR interface

enum class

enum struct




Defines a CLR enumeration




Defines a CLR property




Defines a CLR delegate




Defines a CLR event


Table 2


Override Specifiers


The following keywords can be used to qualify override behavior for derivation. The new keyword is not new to C++ but is listed here because of the additional context in which it can be used. Some specifiers are also valid for native programming.



Old Keyword

Context Sensitive





Indicates functions or classes are abstract.




Indicates that a function is not an override of a base class version.




Indicates that a method must be an override of a base-class version.




Prevents classes from being used as base classes.


Table 3


Keywords for Generics


The following keywords have been added to support generic types.



Context sensitive




Defines a generic type



Specifies the constraints of a generic typedef


Table 4





Miscellaneous New Keywords


The following keywords have been added to the C++ language.



Context sensitive




Indicates default exception handling behavior.

for each


Enumerate elements of a collection.



Allocates types on the garbage-collected heap.



Indicates a member can only be initialized at declaration or in a static constructor.



Creates a literal variable.



Indicates that a handle or pointer does not point at an object.


Table 5


Non-Keyword Language Constructs


The following are language constructs that, while not official keywords, are fundamental to .NET programming. These constructs are implemented as templates. Most are defined in the cli Namespace.





Type for representing CLR arrays.


Points to data inside reference types.


Points to CLR reference types to temporarily suppress the garbage collection system.


Determines and executes the optimal casting method for CLR types.


Retrieves a System.Type object describing the given type or object.


Table 6


New C++ Operators


Two new operators have been added to C++ to support garbage-collected programming.





Indicates a handle to an object located on the garbage-collected heap (instead of stack).


Indicates a tracking reference.


Table 7


More CLR Constructs


In addition to keywords and language constructs, the following reference includes the following CLR programming constructs for advanced topics. Well, you have to find it in your MSDN documentations.








Enables the use of C++ keywords as identifiers.

.NET Framework equivalents to C++ Native Types

Lists the CLR types used in place of C++ integral types.

appdomain __declspec modifier

__declspec modifier that mandates static and global variables exist per appdomain.

C-Style casts with /clr

Describes how C-style casts are interpreted.

__clrcall calling convention

Indicates the CLR-compliant calling convention.


Predefined Macros.

Custom attributes (C++)

Describes how to define your own CLR attributes.

Exception Handling under /clr

Provides an overview of exception handling.

Explicit overrides

Demonstrates how member functions can override arbitrary members.

Friend Assemblies

Discusses how a client assembly can access all types in an assembly component.

Implicit boxing

Demonstrates the conditions where values types are boxed.

Compiler support for Type Traits

Discusses how to detect characteristics of types at compile time.

managed, unmanaged pragmas

Demonstrates how managed and unmanaged functions can co-exist in the same module.

process __declspec modifier

__declspec modifier that mandates static and global variables exist per process.

Reflection in C++

Demonstrates the CLR version of run-time type information.

System::String handling in Visual C++

Discusses compiler conversion of string literals to String.

Type forwarding

Allows you to move a type in a shipping assembly to another assembly, such that, client code does not have to be recompiled.

User-defined attributes

Demonstrates use-defined attributes.

The #using Directive

Imports external assemblies.

XML documentation (C++)

Explains XML-based code documentation using /doc (Process Documentation Comments) (C/C++).


Table 8



Part 1 | Part 2 | Part 3 | Part 4



< Old To New C++ .Net 3 | Main | .Net Framework Class Library 1 >