A considerable number of developers are currently working with older compilers, which may not support C ++ 98. Therefore, when your code is ported to these older compilers, you may encounter some strange problems (including compilation errors and runtime errors ). The following considerations help you bypass these issues.
It is emphasized that the several terms mentioned later are to avoid the new syntax of C ++ to ensure portability. If you are using a new compiler, you can ignore these terms.
★Be careful about the scope of the for loop variable (new standards are not supported)
In the C ++ 98 standard, the scope of for loop variables is limited to the loop body. Some old compilers (such as Visual C ++ 6) believe that the scope of for loop variables is exclusive. Therefore, the following code may cause porting problems.
{
for(int i=0; i<XX; i++)
{
// ...
}
for(int i=0; i<XXX; i++)
{
// ...
}
}
We recommend that you change it to different cyclic variables as follows:
{
for(int i=0; i<XX; i++)
{
// ...
}
for(int j=0; j<XXX; j++)
{
// ...
}
}
★Do not use global class objects. Use a single key instead (Standard undefined)
The constructor of a global class object is executed before the main () function. If a module contains several global class objects at the same time, the calling sequence of the constructor is uncertain. The single key is initialized during the first call, which can avoid this problem. In addition, although the single key solves the construction problem, the analysis structure still has potential risks. For details, see "How does a C ++ object die? Process ".
★Keep inline functions as simple as possible
Do not use local static variables within the inline function, or use variable parameters in the inline function. These problems may cause transplantation.
★Do not rely on the order in which function parameters are evaluated (Standard undefined)
The criteria do not explicitly specify the order in which function parameters are evaluated. Therefore, the following code behaviors are uncertain.
Void Foo (int A, int B );
Int n = 1;
Foo (++ N, ++ N );
★Use the template with caution (new standards are not supported)
SomeVintageThe compiler does not support partial or full features.
★In Template inheritance, be careful when referencing base class members (new standards are not supported)
Take the following example:
Template <typename T>
Class tbase
{
Protected:
Typedef STD: vector <t> container;
Container m_container;
};
Template <typename T>
Class tderived: Public tbase <t>
{
Typedef tbase <t> baseclass;
Public:
Void func ()
{
Typename baseclass: Container Foo; // portable
Container Foo; // cannot be transplanted
This-> m_container.clear (); // portable
M_container.clear (); // cannot be transplanted
}
};
★Use rtti with caution (new standard and undefined standard are not supported)
Let us first declare that the rtti mentioned here mainly refers to the typeid operator and the type_info type.
First, some older compilers may not support the typeid operator and type_info type, which may cause portability problems. This is one reason to use rtti with caution. (If you are using a new compiler, you don't need to consider this)
Secondly, the standard constraints on the type_info type are relatively simple. This leads to a large difference in the implementation of type_info by different compilers. If you really want to use the type_info type, we recommend that you only use its operator = and operator! = These two member functions.
Therefore, if you do need to determine the type at runtime and do not want to encounter the above problems, you can consider adding the type information to your class system for implementation. For example, both MFC and wxWidgets do this.
★Use Nested classes with caution (new standards not supported)
If the internal class accesses non-public members of the external class, the internal class should be declared as the friend of the external class.
The following code has the porting problem.
class COuter
{
private:
char* m_name;
public:
class CInner
{
void Print(COuter* outer)
{
cout << outer->m_name;
}
};
};
The following code should be changed:
Class couter
{
PRIVATE:
Char * m_name;
Public:
Class cinner; // pre-declaration
Friend class cinner;
Class cinner
{
Void print (couter * outer)
{
Cout <outer-> m_name;
}
};
};
★Do not define functions with similar parameter types (Standard undefined)
Void Foo (short N );
Void Foo (long N );
Foo (0); // may cause a binary Error
★Do not rely on the length of the standard type (the standard is not defined)
The length of some standard types (such as int and wchar_t) will change with the specific platform.
★Use enumeration instead of static member constants of the class (new standards are not supported)
SomeVintageThe compiler does not support static member constants of the class and can be replaced by enumeration.
Class cfoo
{
Static const int min = 0; // cannot be transplanted
Enum {max = 64}; // portable
};
Today I have said a lot of things that are trivial and may be omitted. In the future, if you find any supplementary information, please advise me in the comments in this post. Due to the limited space, I leave the exception-related content to the next topic.
Http://program-think.blogspot.com/2009/01/cxx-cross-platform-develop-2-language.html