Issues in treating OMG IDL basic data types as native C++ types

Issues in treating OMG IDL basic data types as native C++ types

[[wiki: Traps and Pitfalls in VisiBroker Application Development | Back]]

 

Let's say we have the following IDL definition to retrieve a customer account number based on his or her personal identity credential value, which both values are of numerical nature:

// IDL definition
module Bank {
  interface Account {
    boolean get_account_number (in long identity, out long account_number);
  };
};

Using the IDL to C++ compiler, it would generate the following function declaration for the skeleton code, for the purpose of illustration brevity, the rest of the generated details are ignored and the minimal are presented here,

class POA_Bank {
...
  // idl interface: Bank::Account
  class  Account : public Bank::Account_ops, public virtual PortableServer_ServantBase {
    ...
    virtual ::CORBA::Boolean get_account_number(::CORBA::Long _identity,
                                                ::CORBA::Long_out _account_number) = 0;
	...
  };
...
};

The following illustrative implementation is typical to a developer who is new to the CORBA world with the problem solving approach based on the purely C/C++ paradigm,

class MyBankAccount : public POA_Bank::Account {
...
    virtual ::CORBA::Boolean get_account_number(::CORBA::Long _identity,
                                                ::CORBA::Long_out _account_number)
	{
	  return Get_account_number(_identity, (long *)&_account_number);
	}
...
};


bool Get_account_number (long id, long *acct_num)
{
  long temp = retrieve_account_number(id);
  if (temp > 0) {
    // Potential crash may arise here depending on the 
// platform representation size. *acct_num = temp; return true; } return false; }

Are you able to know the answers immediately in your mind on what could have caused the serious issue pointed out in the function Get_account_number()?

At the first look, even for those who are experienced CORBA C++ developers, the answer would not be necessarily obvious. Therefore, a little explanation could aid the novice to further the journey.

The code in Get_account_number() works perfectly fine in the 32-bit platform runtime environment. However, when the same code runs in the 64-bit platform runtime environment, it may or may not crash depending on the representation size of the C++ long integer data type.

If the representation size of the long integer is 64 bits on a 64-bit machine, it would definitely crash. Why, you may be asking? According to the OMG IDL long integer type size requirement shown in the "The Common Object Request Broker: Architecture and Specification", "OMG IDL Syntax and Semantics" clause, "Basic Types" sub clause, it belongs to the 32 bits size range. You could also read further for the other OMG IDL basic types size requirements in the specification.

In the "C++ Language Mapping", "Mapping for Basic Data Types" section, the OMG IDL long is mapped as a C++ CORBA::Long typedef CORBA definition to increase portability across different representations on different platforms. Therefore, on a 64-bit machine where a native C++ long integer size is 64 bits, the definition of the CORBA::Long would still represented as a 32-bit integer. In VisiBroker, it would typedef int as Long within the CORBA namespace.

Therefore, by mistaking the CORBA::Long as the native C++ long integer type, the semantic error made in the coding of the C++ function Get_account_number() becomes very subtle. The fact that it runs under the 32-bit machine but failed under the 64-bit runtime environment when the same code is rebuilt make it obscure to debug.

 

Now, we know that since the _account_number is a 32-bit integer size for CORBA::Long, and by assigning a native 64-bit integer variable acct_num values to it would definitely caused a crash due to boundary overwrite during the runtime.

So, the solution is by changing the function Get_account_number() declaration according to the CORBA definitions in the following would greatly enhanced the portability across different machine representations,

bool Get_account_number (::CORBA::Long id, ::CORBA::Long_out acct_num)
{
  ::CORBA::Long temp = retrieve_account_number(id);
  if (temp > 0) {
    acct_num = temp;
    return true;
  }
  return false;
}

The modified version also allows you to do away with the pointer casting approach in C and instead using the C++ by reference feature as the CORBA::Long_out is a typedef to the CORBA::Long& type defined in the "C++ Language Mapping" specification.

 

For further information, please also refer to the Common Object Request Broker Architecture at http://www.omg.org/spec/CORBA/, and the C++ Language Mapping at http://www.omg.org/spec/CPP/.

 

[[wiki: Traps and Pitfalls in VisiBroker Application Development | Back]]

Labels (1)

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
2 of 2
Last update:
‎2020-03-13 21:05
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.