[Home]CppCodingStandards/CppProgrammingPractices

TheSourcery | CppCodingStandards | RecentChanges | Preferences | Index | RSS

Difference (from prior minor revision) (no other diffs)

Changed: 1,259c1,261

Programming Practices ==


Avoid Global Functions, Data and Classes ===

One way to avoid global functions and classes.

Example:


// Instead of declaring:
void Emc2_myFunc1();
void Emc2_myFunc2();
class Emc2MyClass { /* ... */ };

// Encapsulate the functions using an abstract class:
class Emc2 {
public:
static void MyFunc1();
static void MyFunc2();
class MyClass { /* ... */ };
private:
virtual Dummy() = 0; // Make the class abstract
};

// Now, functions and classes are accessed by the scope-operator:
Emc2::MyFunc1();
Emc2::MyFunc2();
Emc2::MyClass my_object;

Placement of Declarations



Local variables can be declared at the start of the function, at the start of a conditional block, or at the point of first use. However, declaring within a conditional block or at the point of first use may yield a performance advantage, since memory allocation, constructors, or class loading will not be performed at all if those statements are not reached.

Switch Statements




Specify a break statement after every case block, including the last one unless multiple labels are used for one selection of code. Always define the default case.

Return Statements




Where practical, there will be only one return from a function or method as the last statement. Otherwise, the number of returns will be minimized. Highlight returns with comments and/or blank lines to keep them from being lost in other code.

Other Flow Control Statements




* Never use goto.
* The choice of loop construct (for, while or do-while) should depend on the specific use of the loop.
* Always use unsigned for variables which cannot reasonably have negative values.
* Always use inclusive lower limits and exclusive upper limits in conditionals.
* Avoid the use of continue.
* Use break to exit a loop if this avoids the use of flags.

Expressions




Always use parenthesis to clarify the order of evaluation when three or more operators are used.

Casts




Avoid the use of casts except where unavoidable, since this can introduce run-time bugs by defeating compiler type-checking. Working with third-party libraries often requires the use of casts. When you need to cast, document the reasons. Do not write code which depends on functions that use implicit type conversions. Never convert pointers to objects of a derived class to pointers to objects of a virtual base class. Never convert a const to a non-const.

Literals




Constants are to be defined using const or enum; never using #define. Avoid the use of numeric values in code; use symbolic values instead.

Example:


const double PI = 3.141259; // right
const char APP_NAME = "ACME Spreadsheet 1.0"; // right

area = 3.141259 * radius * radius; // not recommended
cout << "ACME Spreadsheet 1.0" << endl; // not recommended

Explicit Initialization




In general, explicitly initialize all variables before use. Always initialize all pointers either to zero or to an object. Set pointers to zero after delete.

Constructs to Avoid




* Inlines are preferred over #define macros
* The use of typedef is discouraged when actual types such as class, struct, or enum would be a better choice.
* Avoid side-effects! They make the code harder to read and the compiler is smarter than you are.

Example:


if ( p_record = get_record()) // This saves you nothing at all

int i = 0
while( i < 10 ) {
cout << i++ << endl; // Use a for loop or put i++ on another line
}

Macros




If macros must be used, they should be enclosed in parentheses to eliminate ambiguity on expansion.

Example:


#define MAX( x, y ) ( (x) > (y) ) ? (x) : (y) )

Debug Compile-time Switch




Code used only during development for debugging or performance monitoring should be conditionally compiled using #ifdef compile-time switches. The symbols used are DEBUG and STATS, respectively. DEBUG statements announcing entry into a function or member function should provide the entire function name including the class.

Example:


#ifdef DEBUG
cout << "ClassName::MemberName: about to do something" << endl;
#endif

Memory Management




Always use new and delete instead of malloc/calloc/realloc and free. Allocate memory with new only when necessary for variable to remain after leaving the current scope. Always use the delete[] operator to deallocate arrays. After deletion, set the pointer to zero, to safeguard possible future calls to delete.

Required Member Functions




* Default Constructor
* Virtual Destructor
* Copy Constructor
* Assignment Operator

Class Constructors




All constructors should initialize all member variables to a known state. This implies that all classes should have a default constructor (i.e., <nop>MyClass? ();) defined. Providing a deep copy constructor is strongly recommended. If the programmer wishes to not fully implement a copy constructor, then a stub copy constructor should be written and placed in the private section so no one will accidentally call it. A class which uses "new" to allocate instances managed by the class, must define a copy constructor. Do not do any real work in an object's constructor. Inside a constructor initialize variables only and perform only actions that can't fail.

Class Destructors




All classes which allocate resources which are not automatically freed should have a destructor which explicitly frees the resources. Since any class may someday be used as a base class, destructors should be declared virtual, even if empty.

Argument Passing




If the argument is small and will not be modified, use the default pass by value. If the argument is large and will not be modified, pass by const reference. If the argument will be modified, pass by reference.

Example:


void A::function( int not_changed ); // default: pass by value

void B::function( const C& r_big_object ) // pass by const reference

void C::function( int& r_result ); // pass by reference

Default Arguments




Where possible, use default arguments instead of function overloading to reduce code duplication and complexity.

Overriding Virtual Functions




When overriding virtual functions in a new subclass, explicitly declare the functions virtual. Although not normally required by the compiler, this aids maintainability by making clear that the function is virtual without having to refer to the base class header file.

Function Reentrancy




Functions should not keep static variables that prevent a function from being reentrant. Functions can declare variables static. Problems happen when the function is called one or more times at the same time. This can happen when multiple threads are used or from a signal handler. Using the static buffer caused results to overlap and become corrupted.

Const Member Functions




A member function that does not affect the state of an object (its instance variables) is to be declared const. If the behavior of an object is dependent on data outside the object, this data is not to be modified by const member functions.

Example:


func(...) const {
code here
}


This allows these functions to be called for objects which were either declared as const or passed as const arguments.

It is recommended that all member function parameters be declared const, if at all possible.

Example:


MyFunc(const int i) {
some code
}

Member Function Return Types




A public member function must never return a non-const reference or pointer to member data. A public member function must never return a non-const reference or pointer to data outside an object, unless the object shares the data with other objects. By allowing a user direct access to the private member data of an object, this data may be changed in ways not intended.

Referencing Non-C++ Functions




Use the extern "C" mechanism to allow access to non-C++ (not just C) functions. This mechanism disables C++ name mangling, which allows the linker to resolve the function references.

Example:


extern "C" {
void a_function(); // single non-C++ function prototype
}

extern "C" {
#include "functions.h" // library of non-C++ functions
}

NULL Pointer




Use the number zero (0) instead of the NULL macro for initialization, assignment, and comparison of pointers. The use of NULL is not portable. Cast when appropriate (e.g., (char*)0).

Enumerated Types




Use enumerated types instead of numeric codes. Enumerations improve robustness by allowing the compiler to perform type-checking, and are more readable and maintainable.

Terminating Stream Output




Use the iostream manipulator endl to terminate an output line, instead of the newline character \n or \n\r. In addition to being more readable, the endl manipulator flushes the output buffer and automatically performs platform dependent linefeed/carriage return translation.

Object Instantiation




Where possible, move object declarations and instantiations out of loops, using assignment to change the state of the object at each iteration. This minimizes overhead due to memory allocation from the heap.

Encapsulation




Instance attributes of a class never be declared public. Open access to internal variables exposes structure and does not allow methods to assume values are valid. Putting variables in the private section is preferable over the protected section, for more complete encapsulation. Use get and set methods in either protected or public if needed.

Miscellaneous




To determine to complexity of a routine roughly, hand calculate the Decision Point number. Decision points are calculated using the following formula:

* Start with 1 for straight path through routine
* Add 1 for each keyword (if, while, do, repeat, for, and, or)
* Add 1 for each case in a case statement, plus 1 for default

A routine with a Decision Point number greater than a 10 score may be too complicated and may need to be refactored.

Portability Concerns




* Avoid the direct use of pre-defined data types in declarations.
* Do not assume that an int and a long have the same size.
* Do not assume that an int is 32 bits long (it may be 64 bits long).
* Do not assume that a char is signed or unsigned.
* Always set char to unsigned if 8-bit ASCII is used.
* Be careful not to make type conversions from a `shorter' type to a `longer' one.
* Do not assume that pointers and integers have the same size.
* Use explicit type conversions for arithmetic using signed and unsigned values.
* Do not assume that you know how an instance of a data type is represented in memory.
* Do not assume that longs, floats, doubles or long doubles may begin at arbitrary addresses.
* Do not depend on underflow or overflow functioning in any special way.
* Do not assume that the operands in an expression are evaluated in a definite order.
* Do not assume that you know how the invocation mechanism for a function is implemented.
* Do not assume that an object is initialized in any special order in constructors.
* Do not assume that static objects are initialized in any special order.
* Do not write code which is dependent on the lifetime of a temporary object.
* Avoid using shift operations instead of arithmetic operations.
* Avoid pointer arithmetic.

Error Checking




Check every system call for an error return, unless you know you wish to ignore errors. Include the system error text and error numbers, if available, for every system error message.

Programming Practices ==


Avoid Global Functions, Data and Classes ===

One way to avoid global functions and classes.

Example:


// Instead of declaring:
void Emc2_myFunc1();
void Emc2_myFunc2();
class Emc2MyClass { /* ... */ };

// Encapsulate the functions using an abstract class:
class Emc2 {
public:
static void MyFunc1();
static void MyFunc2();
class MyClass { /* ... */ };
private:
virtual Dummy() = 0; // Make the class abstract
};

// Now, functions and classes are accessed by the scope-operator:
Emc2::MyFunc1();
Emc2::MyFunc2();
Emc2::MyClass my_object;

Placement of Declarations



Local variables can be declared at the start of the function, at the start of a conditional block, or at the point of first use. However, declaring within a conditional block or at the point of first use may yield a performance advantage, since memory allocation, constructors, or class loading will not be performed at all if those statements are not reached.

Switch Statements




Specify a break statement after every case block, including the last one unless multiple labels are used for one selection of code. Always define the default case.

Return Statements




Where practical, there will be only one return from a function or method as the last statement. Otherwise, the number of returns will be minimized. Highlight returns with comments and/or blank lines to keep them from being lost in other code.

Other Flow Control Statements




* Never use goto.
* The choice of loop construct (for, while or do-while) should depend on the specific use of the loop.
* Always use unsigned for variables which cannot reasonably have negative values.
* Always use inclusive lower limits and exclusive upper limits in conditionals.
* Avoid the use of continue.
* Use break to exit a loop if this avoids the use of flags.

Expressions




Always use parenthesis to clarify the order of evaluation when three or more operators are used.

Casts




Avoid the use of casts except where unavoidable, since this can introduce run-time bugs by defeating compiler type-checking. Working with third-party libraries often requires the use of casts. When you need to cast, document the reasons. Do not write code which depends on functions that use implicit type conversions. Never convert pointers to objects of a derived class to pointers to objects of a virtual base class. Never convert a const to a non-const.

Literals




Constants are to be defined using const or enum; never using #define. Avoid the use of numeric values in code; use symbolic values instead.

Example:


const double PI = 3.141259; // right
const char APP_NAME = "ACME Spreadsheet 1.0"; // right

area = 3.141259 * radius * radius; // not recommended
cout << "ACME Spreadsheet 1.0" << endl; // not recommended

Explicit Initialization




In general, explicitly initialize all variables before use. Always initialize all pointers either to zero or to an object. Set pointers to zero after delete.

Constructs to Avoid




* Inlines are preferred over #define macros
* The use of typedef is discouraged when actual types such as class, struct, or enum would be a better choice.
* Avoid side-effects! They make the code harder to read and the compiler is smarter than you are.

Example:


if ( p_record = get_record()) // This saves you nothing at all

int i = 0
while( i < 10 ) {
cout << i++ << endl; // Use a for loop or put i++ on another line
}

Macros




If macros must be used, they should be enclosed in parentheses to eliminate ambiguity on expansion.

Example:


#define MAX( x, y ) ( (x) > (y) ) ? (x) : (y) )

Debug Compile-time Switch




Code used only during development for debugging or performance monitoring should be conditionally compiled using #ifdef compile-time switches. The symbols used are DEBUG and STATS, respectively. DEBUG statements announcing entry into a function or member function should provide the entire function name including the class.

Example:


#ifdef DEBUG
cout << "ClassName::MemberName: about to do something" << endl;
#endif

Memory Management




Always use new and delete instead of malloc/calloc/realloc and free. Allocate memory with new only when necessary for variable to remain after leaving the current scope. Always use the delete[] operator to deallocate arrays. After deletion, set the pointer to zero, to safeguard possible future calls to delete.

Required Member Functions




* Default Constructor
* Virtual Destructor
* Copy Constructor
* Assignment Operator

Class Constructors




All constructors should initialize all member variables to a known state. This implies that all classes should have a default constructor (i.e., <nop>MyClass? ();) defined. Providing a deep copy constructor is strongly recommended. If the programmer wishes to not fully implement a copy constructor, then a stub copy constructor should be written and placed in the private section so no one will accidentally call it. A class which uses "new" to allocate instances managed by the class, must define a copy constructor. Do not do any real work in an object's constructor. Inside a constructor initialize variables only and perform only actions that can't fail.

Class Destructors




All classes which allocate resources which are not automatically freed should have a destructor which explicitly frees the resources. Since any class may someday be used as a base class, destructors should be declared virtual, even if empty.

Argument Passing




If the argument is small and will not be modified, use the default pass by value. If the argument is large and will not be modified, pass by const reference. If the argument will be modified, pass by reference.


Example:


void A::function( int not_changed ); // default: pass by value

void B::function( const C& r_big_object ) // pass by const reference

void C::function( int& r_result ); // pass by reference

Default Arguments




Where possible, use default arguments instead of function overloading to reduce code duplication and complexity.

Overriding Virtual Functions




When overriding virtual functions in a new subclass, explicitly declare the functions virtual. Although not normally required by the compiler, this aids maintainability by making clear that the function is virtual without having to refer to the base class header file.

Function Reentrancy




Functions should not keep static variables that prevent a function from being reentrant. Functions can declare variables static. Problems happen when the function is called one or more times at the same time. This can happen when multiple threads are used or from a signal handler. Using the static buffer caused results to overlap and become corrupted.

Const Member Functions




A member function that does not affect the state of an object (its instance variables) is to be declared const. If the behavior of an object is dependent on data outside the object, this data is not to be modified by const member functions.

Example:


func(...) const {
code here
}


This allows these functions to be called for objects which were either declared as const or passed as const arguments.

It is recommended that all member function parameters be declared const, if at all possible.

Example:


MyFunc(const int i) {
some code
}

Member Function Return Types




A public member function must never return a non-const reference or pointer to member data. A public member function must never return a non-const reference or pointer to data outside an object, unless the object shares the data with other objects. By allowing a user direct access to the private member data of an object, this data may be changed in ways not intended.

Referencing Non-C++ Functions




Use the extern "C" mechanism to allow access to non-C++ (not just C) functions. This mechanism disables C++ name mangling, which allows the linker to resolve the function references.

Example:


extern "C" {
void a_function(); // single non-C++ function prototype
}

extern "C" {
#include "functions.h" // library of non-C++ functions
}

NULL Pointer




Use the number zero (0) instead of the NULL macro for initialization, assignment, and comparison of pointers. The use of NULL is not portable. Cast when appropriate (e.g., (char*)0).

Enumerated Types




Use enumerated types instead of numeric codes. Enumerations improve robustness by allowing the compiler to perform type-checking, and are more readable and maintainable.

Terminating Stream Output




Use the iostream manipulator endl to terminate an output line, instead of the newline character \n or \n\r. In addition to being more readable, the endl manipulator flushes the output buffer and automatically performs platform dependent linefeed/carriage return translation.

Object Instantiation




Where possible, move object declarations and instantiations out of loops, using assignment to change the state of the object at each iteration. This minimizes overhead due to memory allocation from the heap.

Encapsulation




Instance attributes of a class never be declared public. Open access to internal variables exposes structure and does not allow methods to assume values are valid. Putting variables in the private section is preferable over the protected section, for more complete encapsulation. Use get and set methods in either protected or public if needed.

Miscellaneous




To determine to complexity of a routine roughly, hand calculate the Decision Point number. Decision points are calculated using the following formula:

* Start with 1 for straight path through routine
* Add 1 for each keyword (if, while, do, repeat, for, and, or)
* Add 1 for each case in a case statement, plus 1 for default

A routine with a Decision Point number greater than a 10 score may be too complicated and may need to be refactored.

Portability Concerns




* Avoid the direct use of pre-defined data types in declarations.
* Do not assume that an int and a long have the same size.
* Do not assume that an int is 32 bits long (it may be 64 bits long).
* Do not assume that a char is signed or unsigned.
* Always set char to unsigned if 8-bit ASCII is used.
* Be careful not to make type conversions from a `shorter' type to a `longer' one.
* Do not assume that pointers and integers have the same size.
* Use explicit type conversions for arithmetic using signed and unsigned values.
* Do not assume that you know how an instance of a data type is represented in memory.
* Do not assume that longs, floats, doubles or long doubles may begin at arbitrary addresses.
* Do not depend on underflow or overflow functioning in any special way.
* Do not assume that the operands in an expression are evaluated in a definite order.
* Do not assume that you know how the invocation mechanism for a function is implemented.
* Do not assume that an object is initialized in any special order in constructors.
* Do not assume that static objects are initialized in any special order.
* Do not write code which is dependent on the lifetime of a temporary object.
* Avoid using shift operations instead of arithmetic operations.
* Avoid pointer arithmetic.

Error Checking




Check every system call for an error return, unless you know you wish to ignore errors. Include the system error text and error numbers, if available, for every system error message.



Programming Practices

Avoid Global Functions, Data and Classes

One way to avoid global functions and classes.

Example:

  // Instead of declaring:
  void Emc2_myFunc1();
  void Emc2_myFunc2();
  class Emc2MyClass { /* ... */ };

  // Encapsulate the functions using an abstract class:
  class Emc2 {
  public:
    static void MyFunc1();
    static void MyFunc2();
    class MyClass { /* ... */ };
    private:
      virtual Dummy() = 0;   // Make the class abstract
   };

   // Now, functions and classes are accessed by the scope-operator:
   Emc2::MyFunc1();
   Emc2::MyFunc2();
   Emc2::MyClass  my_object;

Placement of Declarations

Local variables can be declared at the start of the function, at the start of a conditional block, or at the point of first use. However, declaring within a conditional block or at the point of first use may yield a performance advantage, since memory allocation, constructors, or class loading will not be performed at all if those statements are not reached.

Switch Statements

Specify a break statement after every case block, including the last one unless multiple labels are used for one selection of code. Always define the default case.

Return Statements

Where practical, there will be only one return from a function or method as the last statement. Otherwise, the number of returns will be minimized. Highlight returns with comments and/or blank lines to keep them from being lost in other code.

Other Flow Control Statements

Expressions

Always use parenthesis to clarify the order of evaluation when three or more operators are used.

Casts

Avoid the use of casts except where unavoidable, since this can introduce run-time bugs by defeating compiler type-checking. Working with third-party libraries often requires the use of casts. When you need to cast, document the reasons. Do not write code which depends on functions that use implicit type conversions. Never convert pointers to objects of a derived class to pointers to objects of a virtual base class. Never convert a const to a non-const.

Literals

Constants are to be defined using const or enum; never using #define. Avoid the use of numeric values in code; use symbolic values instead.

Example:

  const double PI = 3.141259;                     // right
  const char APP_NAME = "ACME Spreadsheet 1.0";   // right

  area = 3.141259 * radius * radius;              // not recommended 
  cout << "ACME Spreadsheet 1.0" << endl;         // not recommended

Explicit Initialization

In general, explicitly initialize all variables before use. Always initialize all pointers either to zero or to an object. Set pointers to zero after delete.

Constructs to Avoid

Example:

  if ( p_record = get_record())   //  This saves you nothing at all

  int i = 0
  while( i < 10 ) {
    cout << i++ << endl; // Use a for loop or put i++ on another line
  }

Macros

If macros must be used, they should be enclosed in parentheses to eliminate ambiguity on expansion.

Example:

  #define MAX( x, y )   ( (x) > (y) ) ? (x) : (y) )

Debug Compile-time Switch

Code used only during development for debugging or performance monitoring should be conditionally compiled using #ifdef compile-time switches. The symbols used are DEBUG and STATS, respectively. DEBUG statements announcing entry into a function or member function should provide the entire function name including the class.

Example:

  #ifdef DEBUG
    cout << "ClassName::MemberName: about to do something" << endl;
  #endif

Memory Management

Always use new and delete instead of malloc/calloc/realloc and free. Allocate memory with new only when necessary for variable to remain after leaving the current scope. Always use the delete[] operator to deallocate arrays. After deletion, set the pointer to zero, to safeguard possible future calls to delete.

Required Member Functions

Class Constructors

All constructors should initialize all member variables to a known state. This implies that all classes should have a default constructor (i.e., <nop>MyClass? ();) defined. Providing a deep copy constructor is strongly recommended. If the programmer wishes to not fully implement a copy constructor, then a stub copy constructor should be written and placed in the private section so no one will accidentally call it. A class which uses "new" to allocate instances managed by the class, must define a copy constructor. Do not do any real work in an object's constructor. Inside a constructor initialize variables only and perform only actions that can't fail.

Class Destructors

All classes which allocate resources which are not automatically freed should have a destructor which explicitly frees the resources. Since any class may someday be used as a base class, destructors should be declared virtual, even if empty.

Argument Passing

If the argument is small and will not be modified, use the default pass by value. If the argument is large and will not be modified, pass by const reference. If the argument will be modified, pass by reference.

Example:

  void A::function( int not_changed );      // default: pass by value

  void B::function( const C& r_big_object ) // pass by const reference

  void C::function( int& r_result );        // pass by reference

Default Arguments

Where possible, use default arguments instead of function overloading to reduce code duplication and complexity.

Overriding Virtual Functions

When overriding virtual functions in a new subclass, explicitly declare the functions virtual. Although not normally required by the compiler, this aids maintainability by making clear that the function is virtual without having to refer to the base class header file.

Function Reentrancy

Functions should not keep static variables that prevent a function from being reentrant. Functions can declare variables static. Problems happen when the function is called one or more times at the same time. This can happen when multiple threads are used or from a signal handler. Using the static buffer caused results to overlap and become corrupted.

Const Member Functions

A member function that does not affect the state of an object (its instance variables) is to be declared const. If the behavior of an object is dependent on data outside the object, this data is not to be modified by const member functions.

Example:

  func(...) const {
    code here
  }

This allows these functions to be called for objects which were either declared as const or passed as const arguments.

It is recommended that all member function parameters be declared const, if at all possible.

Example:

  MyFunc(const int i) {
    some code
  }

Member Function Return Types

A public member function must never return a non-const reference or pointer to member data. A public member function must never return a non-const reference or pointer to data outside an object, unless the object shares the data with other objects. By allowing a user direct access to the private member data of an object, this data may be changed in ways not intended.

Referencing Non-C++ Functions

Use the extern "C" mechanism to allow access to non-C++ (not just C) functions. This mechanism disables C++ name mangling, which allows the linker to resolve the function references.

Example:

  extern "C" {
    void a_function();       // single non-C++ function prototype 
  }

  extern "C" {
  #include "functions.h"     // library of non-C++ functions 
  }

NULL Pointer

Use the number zero (0) instead of the NULL macro for initialization, assignment, and comparison of pointers. The use of NULL is not portable. Cast when appropriate (e.g., (char*)0).

Enumerated Types

Use enumerated types instead of numeric codes. Enumerations improve robustness by allowing the compiler to perform type-checking, and are more readable and maintainable.

Terminating Stream Output

Use the iostream manipulator endl to terminate an output line, instead of the newline character \n or \n\r. In addition to being more readable, the endl manipulator flushes the output buffer and automatically performs platform dependent linefeed/carriage return translation.

Object Instantiation

Where possible, move object declarations and instantiations out of loops, using assignment to change the state of the object at each iteration. This minimizes overhead due to memory allocation from the heap.

Encapsulation

Instance attributes of a class never be declared public. Open access to internal variables exposes structure and does not allow methods to assume values are valid. Putting variables in the private section is preferable over the protected section, for more complete encapsulation. Use get and set methods in either protected or public if needed.

Miscellaneous

To determine to complexity of a routine roughly, hand calculate the Decision Point number. Decision points are calculated using the following formula:

A routine with a Decision Point number greater than a 10 score may be too complicated and may need to be refactored.

Portability Concerns

Error Checking

Check every system call for an error return, unless you know you wish to ignore errors. Include the system error text and error numbers, if available, for every system error message.


TheSourcery | CppCodingStandards | RecentChanges | Preferences | Index | RSS
Edit text of this page | View other revisions
Last edited September 15, 2005 8:59 pm by JonLambert (diff)
Search:
All material on this Wiki is the property of the contributing authors.
©2004-2006 by the contributing authors.
Ideas, requests, problems regarding this site? Send feedback.