### Symbol Versioning in ACE

To provide a means for ACE-based application developers to avoid symbol conflicts when multiple versions of ACE are linked to an application ACE supports versioned namespaces. When enabled (disabled by default), ACE's versioned namespace support causes all ACE symbols (classes, free functions, etc) to be placed within a C++ namespace of the form "`namespace ACE_5_5_1`". For example, the `ACE_Reactor` would end up being placed in the versioned namespace like so:

> `

>             namespace ACE_5_5_1
>             {
>               class ACE_Reactor
>               {
>                 ...
>               };
>             }
>             using namespace ACE_5_5_1;

> `

Notice that a `using` clause exposes the ACE types embedded in the versioned namespace back to the global namespace. This maximizes source code compatibility. ACE itself does this through the use of two macros:

- `ACE_BEGIN_VERSIONED_NAMESPACE_DECL`
  - Expands to "`namespace ACE_VERSIONED_NAMESPACE NAME {`", where `ACE_VERSIONED_NAMESPACE_NAME` by defaults to namespace name of the form `ACE_major_minor_beta`. Users may override the default by defining the `ACE_VERSIONED_NAMESPACE_NAME` preprocessor symbol in their `ace/config.h` header file.
- `ACE_END_VERSIONED_NAMESPACE_DECL`
  - Expands to "`} using namespace ACE_VERSIONED_NAMESPACE_NAME;`", where `ACE_VERSIONED_NAMESPACE_NAME` is described above.

## Things ACE-based Application Developers Should Know

Every effort has been made to make the versioned namespace support in ACE as transparent as possible, including transparent versioned symbol support in the ACE_Service_Configurator when the ACE_Service_Configurator macros, such as e.g., `ACE_FACTORY_DECLARE`, are used appropriately. No changes to service configurator directives are necessary. For example, the `ACE_Service_Configurator` will transparently mangle the factory function name in a service configurator directive on-the-fly, meaning it will only load a "versioned" factory function name. This allows multiple service object factory functions, for example, to coexist in the same process space.

There is, however, at least one caveat with respect to source code compatibility: any forward declarations of ACE symbols must also be placed within the versioned namespace. For example, if you have a forward declaration for `ACE_Reactor` in your application code, you will need to place it within the configured ACE versioned namespace as follows:

> `

>             ACE_BEGIN_VERSIONED_NAMESPACE_DECL
>             class ACE_Reactor;
>             ACE_END_VERSIONED_NAMESPACE_DECL

> `

This must only be done once, as these macros hide the versioned namespace name details from the application. Alternatively, you could place the forward declaration in a namespace that is an alias of the ACE versioned namespace, e.g.:

> `

>             namespace Foo = ACE_VERSIONED_NAMESPACE_NAME;

> ` namespace Foo { class ACE_Reactor; } using namespace Foo;

Versioned namespace support in ACE may be enabled by adding `versioned_namespace=1` to your MPC `default.features` file.

## Things ACE Developers Should Know

ACE developers should place all ACE symbols that are potentially exposed to the user, including forward declarations in a versioned namespace using the `ACE_BEGIN_VERSIONED_NAMESSPACE_DECL` and `ACE_END_VERSIONED_NAMESPACE_DECL` macros. Free functions that are declared to have a C calling convention (i.e., `extern "C"`) should have their names mangled using the `ACE_PREPROC_CONCATENATE` preprocessor. For example:

> `

>             void ACE_func (void) { ... }
>             ...
>             ACE_func(); // Call ACE_func()

> `

becomes:

> `

>             #if (defined (ACE_HAS_VERSIONED_NAMESPACE) \
>                  && ACE_HAS_VERSIONED_NAMESPACE == 1) \
>               && !(defined (_MSC_VER) && _MSC_VER <= 1200)
>             // MSVC++ 6's preprocessor can't handle macro expansions
>             // required by the versioned namespace support.  *sigh*

>             # define ACE_FOO_FUNC_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_foo_func)

>             #else

>             # define ACE_FOO_FUNC_NAME ACE_foo_func

>             #endif  /* ACE_HAS_VERSIONED_NAMESPACE == 1 */

>             ...
>             void ACE_FOO_FUNC_NAME (void) { ... }

>             ACE_FOO_FUNC_NAME();  // Call mangled ACE_foo_func().

> `

The `ACE_PREPROC_CONCATENATE` is used rather than a straight `##` preprocessor concatenation since in the latter case preprocessor symbols like `ACE_VERSIONED_NAMESPACE_NAME` will not be expanded if they are concatenated. `ACE_PREPROC_CONCATENATE` forces the preprocessor to expand them during the argument prescan by calling a macro that itself calls another that performs the actual concatenation.

### General Guidelines

- Versioned namespace macro/support must be added to all new files added to ACE.
- Do not place include directives between `ACE_BEGIN_VERSIONED_NAMESPACE_DECL` and `ACE_END_VERSIONED_NAMESPACE_DECL` macros. Doing so will cause nested namespace to be created, which is not the desired affect.
- Be aware of preprocessor conditional blocks when placing the versioned namespace macros. For example, if you open versioned namespace within a given preprocessor condition block, you'll most likely want to close it in the same block.
- If necessary, reopen and close the versioned namespace multiple times in the same file by using the macros multiple times to address the concerns described in the above two items.
- The `$ACE_ROOT/bin/fuzz.pl` script has a sanity checking test for versioned namespaces that may be of use when debugging nested namespace issues, and for detecting `BEGIN`/`END` mismatches.

Versioned namespace support in ACE may be enabled by adding `versioned_namespace=1` to your MPC `default.features` file. Additional information about versioned namespaces is available from the Riverace website.

Last modified: