|
|
The following extensions are accepted in cfront transition mode via the -Xo option. Using them is discouraged unless they occur in existing code that would be difficult to change.
int *p; const int *&r = p; // No temporary used
struct A {
virtual void f() {}
A() {}
~A() {}
};
struct B : public A {
B() {}
~B() {f();} // Should call A::f according to ARM 12.7
};
struct C : public B {
void f() {}
} c;
In cfront transition mode, B::~B calls C::f.
struct A {
void f(int);
static void f(int);
typedef void A::T3(int); // nonstd typedef decl
typedef void T2(int); // std typedef
};
typedef void A::T(int); // nonstd typedef decl
T* pmf = &A::f; // nonstd ptr-to-member decl
A::T2* pf = A::sf; // std ptr to static mem decl
A::T3* pmf2 = &A::f; // nonstd ptr-to-member decl
where T is construed to name a routine type for a nonstatic member function of class A that takes an int argument and returns void; the use of such types is restricted to nonstandard pointer-to-member declarations. The declarations of T and pmf in combination are equivalent to a single standard pointer-to-member declaration:
void (A::* pmf)(int) = &A::f;
A nonstandard pointer-to-member declaration that appears outside of a class declaration, such as the declaration of T, is normally invalid and would cause an error to be issued. However, for declarations that appear within a class declaration, such as A::T3, this feature changes the meaning of a valid declaration. cfront version 2.1 accepts declarations, such as T, even when A is an incomplete type; so this case is also excepted.
class B { protected: int i; };
class D : public B { void mf()};
void D::mf() {
int B::* pmi1 = &B::i; // error, OK in cfront mode
int D::* pmi2 = &D::i; // OK
}
Note that protected member access checking for other operations (i.e., everything except taking a pointer-to-member address) is done in the normal manner.
class A {
~A();
};
class B : public A {
~B();
};
B::~B(){} // Error except in cfront mode
f(1, 2, );
class A { A(); };
double d;
A x(int(d));
A (x2);
By default int(d) is interpreted as a parameter declaration (with redundant parentheses), and so x is a function; but in cfront transition mode int(d) is an argument and x is a variable. The declaration A(x2); is also misinterpreted by cfront. It should be interpreted as the declaration of an object named x2, but in cfront mode is interpreted as a function style cast of x2 to the type A.
Similarly, the declaration
int xyz(int() );declares a function named xyz, that takes a parameter of type "function taking no arguments and returning an int." In cfront mode this is interpreted as a declaration of an object that is initialized with the value int() (which evaluates to zero).
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.
struct A {
friend B;
};
typedef class A T; class T *pa; // No error in cfront mode
short short int i; // No warning in cfront mode
struct A {int f();};
main () {
int (*p)();
p = (int (*)())A::f; // Okay, with warning
}
typedef struct { int i, j; } S;
struct S x; // No error in cfront mode
class A {
void f(int) const;
static void f(int); //No error in cfront mode
int f(int i) {
for (int j = 0; j < i; ++j) {/* ...*/ }
return j; //No error in cfront mode
}
typedef void (*PF) (); extern "C" typedef void (*PCF) (); void f(PF); void f(PCF);PF and PCF are considered identical and void f(PCF) is treated as a compatible redeclaration of f. (By contrast, in standard C++ PF and PCF are different and incompatible types -- PF is a pointer to an extern "C++" function whereas PCF is a pointer to an extern "C" function -- and the two declarations of f create an overload set.)
Note that implicit type conversion will always be done between a pointer to an extern "C" function and a pointer to an extern "C++" function.
struct A { virtual void f(); int i; };
const A a;
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-ISO mode B::operator=(A&) is
not
a copy
assignment
operator and B::operator=(const B&)
is
implicitly
declared.