A:
The following items, specified in the C++ International Standard, are
not supported in Version 6.3 but will be supported in a future
version. Details about each item are provided in the indicated sections
of the C++ International Standard document and The C++ Programming Language, 3rd Edition, by
Bjarne Stroustrup.
- The export keyword for templates
(Standard §14, paragraph 6; Stroustrup §9.2.3)
- <cname> version of headers
(Standard §17.4.1.2; Stroustrup §16.1.2)
Q:
Does the compiler support precompiled headers?
A:
The compiler supports precompiled headers (PCH) on
Compaq Tru64 UNIX with Compaq C++ Version 6.0 or higher.
Support for precompiled headers on OpenVMS Alpha is not yet implemented.
Q:
Why does check < int > (d) produce the error message
'Type not followed by "(" in an expression' ?
A:
Explicit specification of function template arguments is not supported in
the Version 5.n compiler. It is only partially supported in
our latest Version 6.n compiler; that is, the explicit call syntax
works but is not useful because you must use the template argument
somewhere in the function declaration. The compiler cannot support
this feature without a change in the name mangling mechanism, which
would break backward link compatibility (link compatiblity between
object files built with Version 6.n and Version 5.n
compilers).
S:
The problem is corrected in Version 6.2.
Q:
Why can't I compile /template_define=all for the Standard Library?
A:
Because this option instantiates all templates, even those that are not used,
it is not guaranteed to work with the Standard Library.
For example, rb_tree (the underlying implementation of map and set) supports
a bidirectional iterator class. Thus, operator+,
operator-, operator<,
and operator> are not defined in the iterator for that class.
When you instantiate the tree with cxx/template_define=all,
the compiler tries to instantiate recursively everything that is typedef'ed,
even if not used.
Inside rb_tree there is a typedef for
std::reverse_iterator<iterator>, which then instantiates the global
class reverse_iterator with the
rb_tree iterator as the template argument
"RandomAccessIterator" (a misnomer in this case).
This condition causes undefined symbols for these operators, because
the symbols are used within the definition of the operator member functions inside
reverse_iterator.
As a result, the compiler attempts to instantiate them, even though
they do not exist.
Q:
Why does the compiler generate an undefined identifier error for a variable I've
declared on a for loop?
A:
The C++ International Standard has changed the scope rule for variable declared on
a for loop. According to the standard, the scope ends at the end of the
scope of the for loop. Compiling -std arm will give you the old ARM scoping
rules. See Handling Scope Issues in
Using Compaq C++ for OpenVMS Alpha.
Q:
Why does the compiler generate undefined symbols for functions taking pointer to
functions?
A:
The linkage of the function that is pointed to is now part of the
function type.
From Standard §7.5; Stroustrup §9.2.5:
In a linkage specification, the specified language linkage
applies to the function types of all function declarators,
function names, and variable names introduced by the declaration.
For example:
extern "C" void f1(void (*pf)(int));
// the name f1 and its function type have C linkage;
// pf is a pointer to a C function
|
In the following example, the argument errFunc has C linkage in the
declaration but has C++ linkage in the definition in func.cpp.
As a result, the declaration and definition do not match.
// func.h
extern "C"
{
void Test_OK(char *msg);
typedef void (*fp)(char*);
void Test_Not_OK(fp);
}
// func.cpp
#include <func.h>
void Test_Not_OK(fp errFunc)
{
errFunc("Test not OK");
}
|
S:
Create a typedef with either C or C++ linkage and use it as
the argument type.
Q:
How do I link C++ with another language?
A:
See Using Compaq C++ with Other Languages.
One caveat for linking with Fortran is that in many cases Fortran add
a trailing underscore to its external name. The extern C
declaration must include this underscore when you define an
external Fortran name. See -assume nounderscore in the Fortran f77
and f90 reference pages.
Q:
Why does the compiler generate undefined symbol WHAT__K9BAD_ALLOCXV?
A:
The library object file bv_inst.obj, which
was created incorrectly, contains an undefined symbol bad_alloc::what().
If you #include <vector>,
some inline functions in the bitvector class
(at the bottom of the vector header file) cause the linker to
require references from bv_inst.obj.
The unresolved error occurs when the linker includes that object file.
Though disconcerting, the linker error is harmless.
S:
This problem has been fixed in Version 6.0 of the Standard Library.
W:
In most cases, you can ignore the linker message.
It is a problem only if a shareable image is being created (because
any application linking against it also receives the warning).
Q:
Why must classes reside in headers for automatic template
instantiation?
Q:
Why does the compiler generate undefined template symbols?
A:
This was a limitation in the Version 5.n compilers that has been fixed in
the Version 6.n compilers. For more information about Version 5 template limitations,
see the discussion of templates in your Version 5.n
Using DEC C++ guide.
S:
Upgrade to Version 6.0 or higher.
Q:
Why does the compiler generate duplicate symbol errors when I use automatic
instantiation?
A:
This was a limitation in the Version 5.n compilers that has been fixed in
the Version 6.n compilers. For more information about Version 5 template limitations,
see the discussion of templates in your Version 5.n
Using DEC C++ guide.
Note also that you cannot do automatic template instantiation if you defined templates and
non-templates in the same module. This restriction applies because each time
the compiler needs the template implementation, it includes the module
that defines it. If that module contains non-template elements, these also are
defined, and duplicate symbols can be generated.
Consider the following example:
mynode> cxx -o tt m.cxx m2.cxx t.cxx
m.cxx:
m2.cxx:
t.cxx:
ld (prelink):
m2.o compressed: worker_function(void): multiply defined
t.o compressed: worker_function(void): multiply defined
ld (prelink):
m2.o compressed: worker_function(void): multiply defined
t.o compressed: worker_function(void): multiply defined
ld:
m2.o compressed: worker_function(void): multiply defined
t.o compressed: worker_function(void): multiply defined
mynode> nm m.o | grep worker
worker_function(void) | 0000000000000080 | T | 0000000000000008
mynode> nm m2.o | grep worker
worker_function(void) | 0000000000000064 | T | 0000000000000008
mynode> nm t.o | grep worker
worker_function(void) | 0000000000000000 | T | 0000000000000008
mynode> cat t.h
#ifndef T_H
#define T_H
template void f(const T);
#endif
mynode> cat t.cxx
#include "t.h"
void worker_function() { }
template void f(const T) { worker_function(); }
mynode> cat m.cxx
#include "t.h"
extern void m2();
void main()
{
f(1);
m2();
}
mynode> cat m2.cxx
#include "t.h"
void m2()
{
f("hello");
}
For information about where to place function definitions depending on whether
they are templatized, see
How to Organize Your C++ Code in
Using Compaq C++ for OpenVMS Alpha