## 10.1.5. Semantics

Up: C++ Next: C++ Datatypes Previous: Class Member Functions for MPI

The semantics of the member functions constituting the C++ language binding for MPI are specified by the MPI function description itself. Here, we specify the semantics for those portions of the C++ language interface that are not part of the language binding. In this subsection, functions are prototyped using the type `MPI::<CLASS>` rather than listing each function for every MPI class; the word `<CLASS>` can be replaced with any valid MPI class name (e.g., `Group`), except as noted.

Construction / Destruction The default constructor and destructor are prototyped as follows:

`MPI::<CLASS>()
` `MPI::<CLASS>()
`

In terms of construction and destruction, opaque MPI user level objects behave like handles. Default constructors for all MPI objects except MPI::Status create corresponding MPI::*_NULL handles. That is, when an MPI object is instantiated, comparing it with its corresponding MPI::*_NULL object will return `true`. The default constructors do not create new MPI opaque objects. Some classes have a member function `Create()` for this purpose.

Example In the following code fragment, the test will return `true` and the message will be sent to `cout`.

    void foo()
    {
      MPI::Intracomm bar;

      if (bar == MPI::COMM_NULL)
        cout << "bar is MPI::COMM_NULL" << endl;
    }

The destructor for each MPI user level object does not invoke the corresponding MPI_*_FREE function (if it exists).

Rationale.

MPI_*_FREE functions are not automatically invoked for the following reasons:

1. Automatic destruction contradicts the shallow-copy semantics of the MPI classes.

2. The model put forth in MPI makes memory allocation and deallocation the responsibility of the user, not the implementation.

3. Calling MPI_*_FREE upon destruction could have unintended side effects, including triggering collective operations (this also affects the copy, assignment, and construction semantics). In the following example, we would want neither `foo_comm` nor `bar_comm` to automatically invoke MPI_*_FREE upon exit from the function.

    void example_function()
    {
      MPI::Intracomm foo_comm(MPI::COMM_WORLD), bar_comm;
      bar_comm = MPI::COMM_WORLD.Dup();
      // rest of function
    }

( End of rationale.)

Copy / Assignment The copy constructor and assignment operator are prototyped as follows:

`MPI::<CLASS>(const MPI::<CLASS>& data)
` `MPI::<CLASS>& MPI::<CLASS>::operator=(const MPI::<CLASS>& data)
`

In terms of copying and assignment, opaque MPI user level objects behave like handles. Copy constructors perform handle-based (shallow) copies. `MPI::Status` objects are exceptions to this rule. These objects perform deep copies for assignment and copy construction.

Advice to implementors.

Each MPI user level object is likely to contain, by value or by reference, implementation-dependent state information. The assignment and copying of MPI object handles may simply copy this value (or reference). ( End of advice to implementors.)
Example Example using assignment operator. In this example, `MPI::Intracomm::Dup()` is not called for `foo_comm`. The object `foo_comm` is simply an alias for `MPI::COMM_WORLD`. But `bar_comm` is created with a call to `MPI::Intracomm::Dup()` and is therefore a different communicator than `foo_comm` (and thus different from `MPI::COMM_WORLD`). `baz_comm` becomes an alias for `bar_comm`. If one of `bar_comm` or `baz_comm` is freed with MPI_COMM_FREE it will be set to MPI::COMM_NULL. The state of the other handle will be undefined --- it will be invalid, but not necessarily set to MPI::COMM_NULL.

      MPI::Intracomm foo_comm, bar_comm, baz_comm;

      foo_comm = MPI::COMM_WORLD;
      bar_comm = MPI::COMM_WORLD.Dup();
      baz_comm = bar_comm;

Comparison

The comparison operators are prototyped as follows:

`bool MPI::<CLASS>::operator==(const MPI::<CLASS>& data) const
` `bool MPI::<CLASS>::operator!=(const MPI::<CLASS>& data) const
`

The member function `operator==()` returns `true` only when the handles reference the same internal MPI object, `false` otherwise. `operator!=()` returns the boolean complement of `operator==()`. However, since the `Status` class is not a handle to an underlying MPI object, it does not make sense to compare `Status` instances. Therefore, the `operator==()` and `operator!=()` functions are not defined on the `Status` class.

Constants Constants are singleton objects and are declared `const`. Note that not all globally defined MPI objects are constant. For example, `MPI::COMM_WORLD` and `MPI::COMM_SELF` are not `const`.

Up: C++ Next: C++ Datatypes Previous: Class Member Functions for MPI

Return to MPI-2 Standard Index
Return to MPI 1.1 Standard Index
Return to MPI Forum Home Page

MPI-2.0 of July 18, 1997
HTML Generated on September 10, 2001