Non-standard C++ syntax is regularly encountered when porting C++ code. Non-conforming code may be allowed by less-strictly conforming compilers, but is less portable. The best approach is to correct the code so that it conforms to the ISO standard. If you cannot correct the code, then the RVCT compilers have some options to allow some non-conformities:
Examples of some common non-conformities are given below, together with the corresponding compiler switch to allow it to compile with RVCT, and the corrected code.
--friend_injection
This allows the following (old style) code:
Example of non-conforming use:
//-- nonconform1.c --
struct X {
friend int f(); // this used to declare f in the surrounding
// scope but not anymore
};
int g() {
return f(); // without --friend_injection
// Error: #20: identifier "f" is undefined
}
Example of conforming use:
//-- conform1.c --
int f(); // added declaration
struct X {
friend int f();
};
int g() {
return f(); // now OK
}
--no_parse_templates
Without --no_parse_templates, templates are analyzed when they are defined.
Example of non-conforming use:
//-- nonconform2.c --
#include <stddef.h> // for size_t
/* gives an error because S is undefined, unless compiled
with --no_parse_templates
*/
template <class T> size_t f(T t) { return sizeof(S) * t; }
struct S { int s[10]; };
size_t g() { return f(2); }
Example of conforming use:
//-- conform2.c --
#include <stddef.h> // for size_t
struct S { int s[10]; };
template <class T> size_t f(T t) { return sizeof(S) * t; }
size_t g() { return f(2); }
--no_dep_name
This option is a subset of '--no_parse_templates'. When conforming to the C++ standard, names that are not "type-dependant" are looked up at the point the template is defined - and not in any type-dependant base classes.
Example of non-conforming use:
//-- nonconform3.h --
/* gives an error because g is undefined, unless compiled
with --no_dep_name
*/
template<class T> struct X;
template<class T> struct Y : X<T> { static int f(T t) { return g(0) * t; } };
//-- nonconform3-1.c --
#include "nonconform3.h"
template<class T> struct X { };
int g(int i) { return i; }
int h1() {return Y<int>::f(2);} // f(2) calls g(int) -> returns 0
//-- nonconform3-2.c --
#include "nonconform3.h"
template<class T> struct X { };
int g(short i) { return 1/i; }
int h2() {return Y<int>::f(2);} // f(2) calls g(short) -> divides by 0!
The reason the C++ standard disallows this is that having the meaning of g change in this way complicates writing robust templates. More discussion of this can be found in Stroustrup, "The C++ Programming Language, Third Edition" in section C.13.8.
Example of conforming use:
//-- conform3.h --
/* The use of 'g' in the template function Y<>::f(T t) gets bound to g(void*)
and later (overloaded) versions will not be considered
*/
int g(void *) { return 3; }
template<class T> struct X;
template<class T> struct Y : X<T> { static int f(T t) { return g(0) * t; } };
//-- conform3-1.c --
#include "conform3.h"
int g(int i) { return i; } // this g is not used by f
template<class T> struct X { int g(int) { return 10; } }; /* this g is not used
by Y<>::f */
int h1() {return Y<int>::f(2);} // f(2) -> returns 6
//-- conform3-2.c --
#include "conform3.h"
int g(short i) { return 1/i; } // this g is not used by f
template<class T> struct X { int g(int) { return 100; } }; /* this g is not used
by Y<>::f */
int h2() {return Y<int>::f(2);} // f(2) -> returns 6
Example of non-conforming use:
//-- nonconform3-3.c --
template<class T> struct ATemplate : public T {
void Callfoo() {
foo(); // not type-dependant, so will result in error
// or use --no_dep_name
}
};
Example of conforming use:
//-- conform3-3.c --
template<class T> struct ATemplate : public T {
void Callfoo() {
this->foo(); // make it (explicitly) type-dependant, now it is OK
}
};
--using_std
The C++ standard has defined that most of the C++ Language library is defined in the namespace 'std '. This means that references to objects and functions in that namespace need to use a correctly qualified name. Note this includes the C-library headers when they are included in the new form, for example: <cstddef>.
Example of non-conforming use:
//-- nonconform4.c --
#include <cstddef> // new C++ form, though "stddef.h" is also allowed
int f(size_t t); // without --using_std, this will give an error
// #20: identifier "size_t" is undefined
#include <vector> // there is no "vector.h"
int g(vector<int> vi); // without --using_std, this will give an error
There are four conforming ways to fix this:
a. Use all names from the libraries correctly qualified. Disadvantage is that it can be a lot of work
//-- conform4-1.c --
#include <cstddef>
int f(std::size_t t);
#include <vector>
int g(std::vector<int> vi);
b. Import the names that are needed into the current namespace.
//-- conform4-2.c --
#include <cstddef>
using std::size_t; // import the name size_t into the global namespace
int f(size_t t);
#include <vector>
using std::vector; // import the name vector into the global namespace
int g(vector<int> vi);
c. Import all names from the namespace 'std' into the current namespace.
Disadvantage is that the library names might clash with the user names in the current namespace.
//-- conform4-3.c --
#include <cstddef>
using namespace std;
int f(size_t t);
#include <vector>
// repeating using namespace std; is not needed
int g(vector<int> vi);
This is effectively what the option '--using_std' does.
d. In case of the C-Library headers, use the old '.h' form of the include headers
//-- conform4-4.c --
#include <stddef.h> // both size_t and std::size_t are available
int f(size_t t);
int f(std::size_t t);
// there is no "vector.h"
--diag_suppress nnn, --diag_warning nnn
Any error number that is postfixed with a '-D' can be configured to be either a warning or suppressed.
Example of non-conforming use:
struct X {
private:
int i;
};
struct Y : X {
int g() { return i; } // i member of struct X
// gives the error #265-D: member "X::i" is inaccessible
};
one could compile this example by using
--diag_warning 265
which turns the error into a warning. In general it is better to change the code, but there might be some reason why the code can not easily be modified.