COBOL and .NET Data Types

Article description 

.NET  has created a new, level playing field for a multitude of programming languages to interact on a scale never before seen. In order to accomplish this feat though several new features had to designed and implemented such as a Common Language Runtime (CLR), and the Microsoft Intermediate Language (MSIL).  The runtime also enforces code robustness by implementing a strict type- and code-verification infrastructure called the common type system (CTS). The CTS ensures that all managed code is self-describing. The various Microsoft and third-party language compilers generate managed code that conforms to the CTS. This means that managed code can consume other managed types and instances, while strictly enforcing type fidelity and type safety.
But COBOL has been around long before the development of the CTS. How can existing COBOL developers and their code base interact with the new CTS? During the development phase of NetCOBOL for .NET Fujitsu Software paid attention to this issue and was able to identify how existing COBOL data types would "marshal" or integrate with the new .NET data types. In most cases the CTS type and the COBOL representation are obvious.

Take for example an integer data type. In COBOL integers are specified as PIC 9 and then have a length designator to quantify the extent of the information they will contain, such as PIC 9(10). In the .NET environment there are two basic integer types, INT16 and INT32. Both represent an integer but of different lengths. An INT16 is a 16-bit signed integer while an INT32 is a 32-bit signed integer. The COBOL representation of these integer types is PIC S9(04) COMP-5 and PIC S9(09) COMP-5, respectively.

One of the more common issues is "What does a PIC X convert to in .NET?"  The obvious answer would be a String data type. This is in fact true, the .NET compiler inserts automatic conversion (called coercions) between the COBOL variables and the CLR strings. What the developer has to be aware of though is when you define a STRING in .NET the length of the string by default is 8192 bytes. You may only require a string to be 10 characters long but when you use a String definition you need to be aware you are getting much more than you bargain for. While this may not be an issue in most cases, when you move that string definition back into an existing COBOL data type of PIC X(10) and there is data beyond the 10th character, it will be lost due to truncation. The developer needs to be aware of issues such as this when intermixing the data types. Users also have to be aware that the COBOL runtime is performing ANSI to Unicode conversions.

The table below gives the NetCOBOL for .NET data type that corresponds to the .NET data types. It also states whether the usage type is VALUE or REFERENCE and gives a brief description of the data type. You can locate the table in the Visual Studio .NET documentation after you have installed the Fujitsu NetCOBOL for .NET compiler. Search the Fujitsu NetCOBOL documentation for "COBOL Representations". It may be a good idea to locate and print this table and keep it handy as a reference.

For additional information, see the table in the topic "Introduction to the .NET Framework Class Library" in the Visual Studio .NET documentation for a mapping of the .NET types to other languages such as Visual Basic and C# - a lot of the .NET Framework documentation uses the Visual Basic and C# data type names when describing an item's type.

Category  .NET Type COBOL Equivalent    USAGE Type Description
Integer  Byte USAGE BINARY-CHAR UNSIGNED VALUE 8-bit unsigned integer (*2)
(non-CLS compliant type)
VALUE 8-bit signed integer (*2)
Int16 PIC S9(4) USAGE COMP-5 VALUE 16-bit signed integer
Int32 PIC S9(9) USAGE COMP-5 VALUE 32-bit signed integer
Int64 PIC S9(18) USAGE COMP-5 VALUE 64-bit signed integer
(non-CLS compliant type)
VALUE 16-bit unsigned integer (*2)
(non-CLS compliant type)
VALUE 32-bit unsigned integer (*2)
(non-CLS compliant type)
VALUE 64-bit unsigned integer (*2)
Floating-point Single USAGE COMP-1 VALUE Single-precision floating-point value
Double USAGE COMP-2 VALUE Double-precision floating-point value
VALUE Dedicated boolean type (True or False) (*2)
Other Char PIC N VALUE Unicode 2-byte character
VALUE Monetary value (*2)
(non-CLS compliant type)
VALUE struct IntPtr (*2)
(non-CLS compliant type)
VALUE struct UIntPtr (*2)
VALUE Date and time value (*2)
Enum You cannot define an enum in COBOL.However, you can reference enums by including the enum in the REPOSITORY paragraph, and use the syntax:
element-name OF enum-name
VALUE Enumerated integer data type
struct You cannot define a struct in COBOL.However, you can reference struct as an OBJECT REFERENCE. VALUE Group data type
Class Objects Object OBJECT REFERENCE
REFERENCE Reference to an object (*2)
REFERENCE Unicode (2-byte) b-string (*2)

*1 The NetCOBOL for .NET compiler defines implicit conversions from alphanumeric and national data types to CLR strings. For alphanumeric data, an additional conversion between UTF-8 and UCS-2 is performed.

*2 As indicated in the third column, the NetCOBOL for .NET compiler treats these items as objects, not as COBOL data.


Interacting with the .NET data types from your original COBOL data types may seem a bit frustrating at first. The best method I found to determine how all this fits together is to create a Console solution. Have fields that will be accepted from the console defined in Working Storage using the COBOL data types. Next, define equivalent variables in Working Storage using .NET data definitions. Move the variables from the COBOL data types to the .NET defined variables. Experiment with different PIC configurations to see how each interacts with the .NET data types. The attached project provides a template for you to experiment with.

Happy Coding!