Skip to content. Skip to navigation

ICTP Portal

Sections
You are here: Home Manuals on-line PGI Compiler pgiws_ug PGI Workstation User's Guide - C C++ Dialect Supported
Personal tools
Document Actions

PGI Workstation User's Guide - C C++ Dialect Supported

<< << " border=0> next Title Contents Index Home Help

C C++ Dialect Supported


The PGCC C++ compiler accepts the C++ language as defined by The Annotated C++ Reference Manual (ARM) by Ellis and Stroustrup, Addison-Wesley, 1990, including templates, exceptions, and support for the anachronisms described in section 18 of the ARM. This is the same language defined by the language reference for ATT's cfront version 3.0.1, with the addition of exceptions. PGCC C++ optionally accepts a number of features erroneously accepted by cfront version 2.1. Using the -b option, PGCC C++ accepts these features, which may never have been legal C++ but have found their way into some user's code.

Command-line options provide full support of many C++ variants, including strict standard conformance. PGCC C++ provides command line options that enable the user to specify whether anachronisms and/or cfront 2.1 compatibility features should be accepted. Refer to Section C.4 for details on features that are not part of the ARM but are part of the ANSI C++ working draft X3J16/WG21.

C.1 Anachronisms Accepted

The following anachronisms are accepted when anachronisms are enabled (when the +p option is not used):

  • overload is allowed in function declarations. It is accepted and ignored.

  • Definitions are not required for static data members that can be initialized using default initialization. This anachronism does not apply to static data members of template classes; they must always be defined.

  • The number of elements in an array may be specified in an array delete operation. The value is ignored.

  • A single operator++() and operator--() function can be used to overload both prefix and postfix operations.

  • The base class name may be omitted in a base class initializer if there is only one immediate base class.

  • Assignment to this in constructors and destructors is allowed. This is allowed only if anachronisms are enabled and the assignment to this configuration parameter is enabled.

  • A bound function pointer (a pointer to a member function for a given object) can be cast to a pointer to a function.

  • A nested class name may be used as a non-nested class name provided no other class of that name has been declared. This anachronism is not applied to template classes.

  • A reference to a non-const type may be initialized from a value of a different type. A temporary is created, it is initialized from the (converted) initial value, and the reference is set to the temporary.

  • A reference to a non-const class type may be initialized from an rvalue of the class type or a derived class thereof. No (additional) temporary is used.

  • A function with old-style parameter declarations is allowed and may participate in function overloading as though it were prototyped. Default argument promotion is not applied to parameter types of such functions when the check for compatibility is done, so that the following declares the overloading of two functions named f:

      int f(int); 
int f(x) char x; return x;
  • It will be noted that in C this code is legal but has a different meaning: a tentative
    declaration of f is followed by its definition.
  • When --nonconst_ref_anachronism is enabled, a reference to a nonconst class can be bound to a class rvalue of the same type or a derived type thereof.
      struct A {
A(int);
A operator=(A&);
A operator+(const A&);
}; main () {
A b(1);
b = A(1) + A(2); // Allowed as anachronism
}

C.2 New Language Features Accepted

The following features not in the ARM but in the X3J16/WG21 Working paper are accepted:

  • The dependent statement of an if, while, do-while, or for is considered to be a scope, and the restriction on having such a dependent statement be a declaration is removed.

  • The expression tested in an if, while, do-while, or for, as the first operand of a ''?'' operator, or as an operand of the "&&", "::", or "!" operators may have a pointer-to-member type or a class type that can be converted to a pointer-to-member type in addition to the scalar cases permitted by the ARM.

  • Qualified names are allowed in elaborated type specifiers.

  • Use of a global-scope qualifier in member references of the form x.::A::B
    and p->::A::B.

  • The precedence of the third operand of the ´´?'' operator is changed.

  • If control reaches the end of the main() routine, and main() has an integral return type, it is treated as if a return 0; statement were executed.

  • Pointers to arrays with unknown bounds as parameter types are diagnosed as errors.

  • A functional-notation cast of the form A() can be used even if A is a class without a (nontrivial) constructor. The temporary created gets the same default initialization to zero as a static object of the class type.

  • A cast can be used to select one out of a set of overloaded functions when taking the address of a function.

  • Template friend declarations and definitions are permitted in class definitions and class template definitions.

  • Type template parameters are permitted to have default arguments.

  • Function templates may have nontype template parameters.

  • A reference to const volatile cannot be bound to an rvalue.

  • Qualification conversions, such as conversion from T** to T const * const * are allowed.

  • Digraphs are recognized.

  • Operator keywords (e.g., and, bitand, etc.) are recognized.

  • Static data member declarations can be used to declare member constants.

  • wchar_t is recognized as a keyword and a distinct type.

  • bool is recognized.

  • RTTI (runtime type identification), including dynamic_cast and the typeid operator, are implemented.

  • Declarations in tested conditions (in if, switch, for, and while statements) are supported.

  • Array new and delete are implemented.

  • New-style casts (static_cast, reinterpret_cast, and const_cast) are implemented.

  • Definition of a nested class outside its enclosing class is allowed.

  • mutable is accepted on nonstatic data member declarations.

  • Namespaces are implemented, including using declarations and directives. Access declarations are broadened to match the corresponding using declarations.

  • Explicit instantiation of templates is implemented.

  • typename keyword is implemented.

  • explicit is accepted to declare Non-converting constructors .

  • The scope of a variable declared in a for-init-statement of a loop is the scope of the loop, not the surrounding scope.

  • Member templates are implemented.

  • The new specialization syntax (using "template<>") is implemented.

  • Cv-qualifiers are retained on rvalues (in particular, on function return values).
  • The distinction between trivial and nontrivial constructors has been implemented, as has the distinction between PODs and non-PODs with trivial constructors.
  • The linkage specification is treated as part of the function type (affecting function overloading and implicit conversions).
  • extern inline functions are supported, and the default linkage for inline functions is external.
  • a typedef name may be used in an explicit destructor call.
  • Placement delete is implemented.
  • An array allocated via a placement new can be deallocated via delete.
  • Covariant return types on overriding virtual functions are supported.
  • enum types are considered to be non-integral types.
  • Partial specialization of class templates is implemented.
  • Partial ordering of function templates is implemented.
  • Function declarations that match a function template are regarded as independent functions, not as "guiding declarations" that are instances of the template.
  • It is possible to overload operators using functions that take enum types and no class types.
  • Explicit specification of function template arguments is supported.
  • Unnamed template parameters are supported.
  • The new lookup rules for member references of the form x.A::PB and p->A::B are supported.
  • The notation :: template (and ->template, etc.) is supported.

C.3 The following language features are not accepted

The following features not in the ARM but in the X3J16/WG21 Working Paper are accepted:

  • enum types cannot contain values larger than can be contained in an int.

  • reinterpret_cast does not allow casting a pointer to a member of one class to a pointer to a member of another class if the classes are unrelated.
  • Two-phase name binding in templates, as described in [temp.res] and [temp.dep] of the Working Paper, is not implemented.

  • In a reference of the form f()->g(), with g a static member function, f() is not evaluated. This is as required by the ARM. The WP, however, requires that f() be evaluated.

  • Class name injection is not implemented.

  • Putting a try/catch around the initializers and body of a constructor is not implemented.

  • Template parameters are not implemented.

  • Koenig lookup of function names on all calls is not implemented.
  • Finding friend functions of the argument class types on name lookup on the function name in calls is not implemented.
  • String literals do not have const type.
  • Universal character set escapes (e.g., \uabcd) are not implemented.

C.4 Extensions Accepted in Normal C++ Mode

The following extensions are accepted in all modes (except when strict ANSI violations are diagnosed as errors, see the -A option): *

  • A friend declaration for a class may omit the class keyword:
      class A {
friend B; // Should be "friend class B"
};*

  • Constants of scalar type may be defined within classes:
      class A {
const int size = 10;
int a[size];
};*

  • In the declaration of a class member, a qualified name may be used:
      struct A{
int A::f(); // Should be int f();
}
  • The preprocessing symbol c_plusplus is defined in addition to the standard __cplusplus.

  • An assignment operator declared in a derived class with a parameter type matching one of its base classes is treated as a "default'' assignment operator --- that is, such a declaration blocks the implicit generation of a copy assignment operator. (This is cfront behavior that is known to be relied upon in at least one widely used library.) Here's an example:
      struct A { } ;
struct B : public A {
B& operator=(A&);
};
  • By default, as well as in cfront-compatibility mode, there will be no implicit declaration of B::operator=(const B&), whereas in strict-ANSI mode B::operator=(A&) is not a copy assignment operator and B::operator=(const B&) is implicitly declared.
  • Implicit type conversion between a pointer to an extern "C" function and a pointer to an extern "C++" function is permitted. Here's an example:
    extern "C" void f(); // f's type has extern "C" linkage
    void (*pf) () // pf points to an extern "C++" function
    = &f; // error unless implicit conv is allowed
    This extension is allowed in environments where C and C++ functions share the same calling conventions (though it is pointless unless DEFAULT_C_AND_CPP_FUNTION_TYPES_ARE_DISTINCT is TRUE). When DEFAULT_IMPL_CONV_BETWEEN_C_AND_CPP_FUNCTION_PTRS_ALLOWED is set, it is enabled by default; it can also be enabled in cfront-compatibility mode or with command-line option -implicit_extern_c_type_conversion. It is disabled in strict-ANSI mode.

C.5 cfront 2.1 Compatibility Mode

The following extensions are accepted in cfront 2.1 compatibility mode in addition to the extensions listed in the 2.1/3.0 section following (i.e., these are things that were corrected in the 3.0 release of cfront):

  • The dependent statement of an if, while, do-while, or for is not considered to define a scope. The dependent statement may not be a declaration. Any objects constructed within the dependent statement are destroyed at exit from the dependent statement.

  • Implicit conversion from integral types to enumeration types is allowed.

  • A non-const member function may be called for a const object. A warning is issued.

  • A const void * value may be implicitly converted to a void * value, e.g., when passed as an argument.

  • When, in determining the level of argument match for overloading, a reference parameter is initialized from an argument that requires a non-class standard conversion, the conversion counts as a user-defined conversion. (This is an outright bug, which unfortunately happens to be exploited in the NIH class libraries.)

  • When a builtin operator is considered alongside overloaded operators in overload resolution, the match of an operand of a builtin type against the builtin type required by the builtin operator is considered a standard conversion in all cases (e.g., even when the type is exactly right without conversion).

  • A reference to a non-const type may be initialized from a value that is a const-qualified version of the same type, but only if the value is the result of selecting a member from a const class object or a pointer to such an object.

  • A cast to an array type is allowed; it is treated like a cast to a pointer to the array element type. A warning is issued.

  • When an array is selected from a class, the type qualifiers on the class object (if any) are not preserved in the selected array. (In the normal mode, any type qualifiers on the object are preserved in the element type of the resultant array.)

  • An identifier in a function is allowed to have the same name as a parameter of the function. A warning is issued.
  • An expression of type void may be supplied on the return statement in a function with a void return type. A warning is issued.

  • cfront has a bug that causes a global identifier to be found when a member of a class or one of its base classes should actually be found. This bug is not emulated in cfront compatibility mode.

  • A parameter of type "const void *'' is allowed on operator delete; it is treated as equivalent to "void *".

  • A period (".") may be used for qualification where "::" should be used. Only "::'' may be used as a global qualifier. Except for the global qualifier, the two kinds of qualifier operators may not be mixed in a given name (i.e., you may say A::B::C or A.B.C but not A::B.C or A.B::C). A period may not be used in a vacuous destructor reference nor in a qualifier that follows a template reference such as A<T>::B.

  • cfront 2.1 does not correctly look up names in friend functions that are inside class definitions. In this example function f should refer to the functions and variables (e.g., f1 and a1) from the class declaration. Instead, the global definitions are used.

               int a1;
int e1;
void f1();
class A {
int a1;
void f1();
friend void f()
{
int i1 = a1; // cfront uses global a1
f1(); // cfront uses global f1
}
};
  • Only the innermost class scope is (incorrectly) skipped by cfront as illustrated in the following example.
int a1;
int b1;
struct A {
static int a1;
class B {
static int b1;
friend void f()
{
int i1 = a1; // cfront uses A::a1
int j1 = b1; // cfront uses global b1
}
};
};
  • operator= may be declared as a nonmember function. (This is flagged as an anachronism by cfront 2.1)

  • A type qualifier is allowed (but ignored) on the declaration of a constructor or destructor. For example:
class A {
A() const; // No error in cfront 2.1 mode
};

C.6 cfront 2.1/3.0 Compatibility Mode

The following extensions are accepted in both cfront 2.1 and cfront 3.0 compatibility mode (i.e., these are features or problems that exist in both cfront 2.1 and 3.0):

  • Type qualifiers on the this parameter may to be dropped in contexts such as this example:

    struct A {
    void f() const;
    };
    void (A::*fp)() = &A::f;

    This is actually a safe operation. A pointer to a const function may be put into a pointer to
    non-const, because a call using the pointer is permitted to modify the object and the function pointed to will actually not modify the object. The opposite assignment would not be safe.
  • Conversion operators specifying conversion to void are allowed.

  • A nonstandard friend declaration may introduce a new type. A friend declaration that omits the elaborated type specifier is allowed in default mode, but in cfront mode the declaration is also allowed to introduce a new type name.

      		struct A {
friend B;
};
  • The third operator of the ? operator is a conditional expression instead of an assignment expression as it is in the current X3J16/WG21 Working Paper.

  • A reference to a pointer type may be initialized from a pointer value without use of a temporary even when the reference pointer type has additional type qualifiers above those present in the pointer value. For example,

 			int *p;
const int *&r = p; // No temporary used
  • A reference may be initialized with a null.


<< << " border=0> next Title Contents Index Home Help

Powered by Plone This site conforms to the following standards: