RADE |
C++ Source Checker |
mkCheckSource Forbidden ConstructionsTesting source code in the CAA V5 environment |
Technical Article |
AbstractThis article describes the checks identified by UACS, STRTOK, UADC, PCOM, DOKM, PUCE, IDGP, VISI. |
Migrations lead to existence of deprecated constructions (call to a method, use of class or interface ...). Furthermore, some C++ constructions are prohibited with Object Modeler (identifier, call to delete on some kinds of pointers). CSC checks the uses of C++ entities, methods, constructions or identifiers which are declared as forbidden.
[Top]
UACS:
Some identifiers or keywords are forbidden when programming with CAA architecture. When CSC sees one of these keywords, an error is reported.
STRTOK:
This check is a particular case of the previous one as its aim is to prevent the usage of strtok function. strtok is a standard C library function whose use is not safe. Indeed, the function is not thread-safe and not re-entrant and can induce unpredictable run-time errors. That is why it may be safe to use a substitute.
UADC:
The Lifecycle of the instances of some classes (like dialog objects) must not be managed by the user, but by the infrastructure itself. These objects are automatically and recursively deleted by the infrastructure when useless. The user must not delete these instances himself.
For example, to delete a dialog object in a dialog window while the dialog window remains active, you can use the RequestDelayedDestruction ; the delete operation is then delayed. See Deleting Dialog Objects in [1].
CSC looks, for each pointer of these types, if the pointer is deleted. In that case, an error is reported, and a message specifies the correct method to use.
PCOM:
Some methods are defined for a class (by inheritance for example) but must not be called on the class instances. When an object calls a method prohibited for its class (or for a parent class), an error is reported.
DOKM:
Overloading certain C++ keywords via a macro definition is not recommended, as it can transgress the encapsulation principle. An error is reported for each macro definition with a prohibited name.
PUCE:
Some C++ entities (classes, interfaces) have deprecated, or prohibited, uses. When one of these entities is used in a not allowed way, an error is reported.
IDGP:
To prevent dead-lock on multi-processor machines, the graphic primitives aggregated within a composite graphic primitive should not be destroyed during the destruction of the composite. Then, the check controls that no call to Destroy on a graphic primitive is done in the destructor of a CATGraphicPrimitive derived class.
VISI:
To prevent access to SpecsModeler internals, uses of some identifiers and the corresponding strings report an error.
[Top]
UACS stands for UnAuthorized Construction.
An error of type UACS is reported when:
"assert" is forbidden in CAA.
The following code will report an error:
... assert( iCKEFactory != NULL_var ); ... |
To correct the error, use the CAA error management [2].
[Top]
An error of type STRTOK is reported when:
The following code will report an error:
... char* input = ...; char* token = strtok( input, "\t"); ... |
To correct the error, use other standard library calls or system services.
[Top]
UADC stands for UnAuthorized Delete Class.
An error of type UADC is reported when:
If the user deletes the pointer himself, the application will try to delete the pointer again, implying a Freeing Freed Memory error.
One can specify in ReplaceDeleteMethods section of setting files which method should be used instead of delete.
The CATDialog object pointers must not be deleted by the user, but by the application itself. Method RequestDelayedDestruction() should be used instead of delete. The class CATDialogAgent inherits from class CATDialog:
Let's imagine a class CATTestImportCmd containing a data member _dialogAgentDlgOK of type CATDialogAgent:
... class CATTestImportCmd : public CATStateCommand { ... CATDialogAgent* _dialogAgentDlgOK; ... }; ... |
The following code will report an error:
... CATTestImportCmd::~CATTestImportCmd { if( _dialogAgentDlgOK!=NULL ) { delete _dialogAgentDlgOK; _dialogAgentDlgOK= NULL; } ... } ... |
To correct the error, replace the delete as follow:
... CATTestImportCmd::~CATTestImportCmd { if( _dialogAgentDlgOK!=NULL ) { _dialogAgentDlgOK->RequestDelayedDestruction(); _dialogAgentDlgOK= NULL; } ... } ... |
[Top]
PCOM stands for Prohibited Call Of Method.
Call of some methods are prohibited for the instances of specific classes. Only explicit calls are checked. The method signature is not taken into account for this check. The list of prohibited calls is provided in the setting files, see ProhibitedCalls section.
An error of type PCOM is reported when:
Instances of class CATRep and of all the inherited classes must not call the Release method, therefore the following code will report an error:
CATRep* rep = new CATRep(); ... rep->Release(); ... |
To correct the code, replace the call to Release() by a call to Destroy() method:
CATRep* rep = new CATRep(); ... rep->Destroy(); ... |
[Top]
DOKM stands for Dangerous Overloading of C++ Keyword via MacroDefinition.
Overloading certain C++ keywords via a macro definition leads to transgress the encapsulation principle. For example, defining a macro called "class" to expand in "struct" would give access to all class members with default private access.
An error of type PCOM is reported when:
The following code will report an error:
#define class struct |
[Top]
PUCE stands for Prohibited Use of C++ Entity.
For a class, a prohibited use can be one of the following:
For an interface, the possible prohibited uses are the same as above, except the creation of an instance by new, which means nothing for an interface. On the other hand, an additional interface use is the possibility to adhere to the interface using TIE_xxx or TIEchain_xxx macros.
The list of the prohibited / deprecated uses for each class concerned is provided in the ClassDetection section of the setting files. The list of the prohibited / deprecated uses for each interface concerned is provided in the InterfaceDetection section of the setting files.
An error of type PUCE is reported when:
To correct the error, see the C++ API documentation in CAA V5 Encyclopedia.
Let's assume that deriving class CATDlgFile is a deprecated use. The following code will report a PUCE error:
class CATFrmFile : public CATDlgFile{ ... } |
Let's assume that use of a CATDlgFile as method or function argument type is a deprecated use. The following code will report a PUCE error:
class CATScriptEditor : public CATDlgDialog { ... HRESULT SetFilterStrings(CATDlgFile * iDlgFile); } |
Let's assume that defining CATDlgFile data members is a deprecated use of CATDlgFile. The following code will report a PUCE error:
class CATMCVBBox : public CATFrmDialog { CATDlgFile * _fileDialog; ... } |
Let's assume that casting into CATDlgFile is a deprecated use of CATDlgFile. The following code will report a PUCE error:
CATDlgFile *dlgFile = (CATDlgFile *)iSendingCommand; |
Let's assume that the inclusion of the header of class CATDocument is a deprecated use of CATDocument. The following code will report a PUCE error:
#include "CATDlgFile.h" ... |
Let's assume that creating a CATDlgFile instance with the operator new is a deprecated use. The following code will report a PUCE error:
CATDlgFile * dlgFile = new CATDlgFile(this, "OpenDlgFile", CATDlgWndModal); |
Let's assume that adhesion to CATIPersistent interface is a deprecated use of CATIPersistent. The following code, implementation of class CATImplementPersistent, will report a PUCE error:
CATImplementClass( CATImplementPersistent, Implementation, CATBaseUnknown, CATNull ); #include "CATIPersistent.h" TIE_CATIPersistent(CATImplementPersistent); .... |
[Top]
IDGP stands for Invalid Destructor of a Graphic Primitive.
To prevent dead-lock on multi-processor machines, the graphic primitives aggregated within a composite graphic primitive should not be destroyed during the destruction of the composite.
Then, an error of type IDGP is reported when:
Let's assume that CATMyShapeGP class derives (indirectly) from CATGraphicPrimitive class and that its data member _pGroundGP points to an instance of CAT3DPlanarFaceGPclass. Finally, let's assume that CAT3DPlanarFaceGP is also a sub-class of CATGraphicPrimitive class.
class CATMyShapeGP : public CATMyGeneralShapeGP { public: ~CATMyShape(); ... private: CAT3DPlanarFaceGP* _pGroundGP; } |
The following implementation of CATMyShapeGP::~CATMyShapeGP will report a IDGP error:
CATMyShapeGP::~CATMyShapeGP(){ if (_pGroundGP){ CATGraphicPrimitive::Destroy(_pGroundGP); _pGroundGP = NULL; } } |
To correct the code, destruction of the face should not occur during the destruction of the main graphic primitive.
[Top]
VISI stands for Virtual Instances : SpecsModeler Impacts.
To prevent access to SpecsModeler internals, any use of
CATSpecRoot, CATSpecNamed, CATSpecObject, CATSpecValRoot, CATSpecValArray, CATSpecLiteral identifiers
CATListPtr<type> and CATListVal<type> identifiers, where <type> belongs to the previous list
strings corresponding to these identifiers ("CATSpecRoot", "CATListPtrCATSpecObject"...)
is prohibited.
An error of type VISI is reported when:
The following code will report 2 VISI errors:
CATListPtrCATSpecRoot lpSR_AllVisuPrd; CATProdListAllInstances(lpSR_AllVisuPrd, (CATSpecObject*)(iProd->GetImpl())); |
[Top]
For a more complete description of Setting Files, see [3].
This section is located in: SettingsSet > OptionLists > Various_OptionLists
This section contains a list of Word. Each Word describes an unauthorized identifier.
Example:
Word assert
This means that the C++ keyword "assert" is not authorized.
[Top]
This section is located in: SettingsSet > OptionLists > Various_OptionLists
This section contains a list of ClassName. Each ClassName describes a class one can not delete directly.
Be careful:
Example:
ClassName CATCommand
This means that no pointer of type CATCommand can be deleted directly. It also means that no pointer of an inheriting type can be deleted directly.
[Top]
This section is located in: SettingsSet > OptionLists > Various_OptionLists
This section contains a list of Call.
Be careful:
Example:
ClassName CATBaseUnknown MethodOrFunctionSign Release() ClassName CATRep MethodOrFunctionSign Destroy()
This means that a pointer of type CATBaseUnknown must be deleted by a call to Release and a pointer of type CATRep, although it inherits from CATBaseUnknown, by a call to Destroy. A pointer of type CATNotification, which inherits from CATBaseUnknown but not from CATRep, must be deleted by a call to Release ; a pointer of type CAT2DLineRep, which inherits from CATRep, must be deleted by a call to Destroy.
[Top]
This section is located in: SettingsSet > OptionLists > Various_OptionLists
This section contains a list of Call. Each Call describes a prohibited call:
Be careful:
Example 1:
ClassName CATRep MethodOrFunctionSign Release
means that CATRep instances, and instances of classes inheriting from CATRep, must not call Release method.
[Top]
This section is located in: SettingsSet > OptionLists > EntityDetection_OptionLists
This section contains a list of ClassDetection. Each ClassDetection is composed of
The possible values of use attribute are: "Derivation", "MethodOrFunctionArgument", "DataMemberOrLocalVar", "CastInto", "IncludeOfHeader" and "New".
Example 1:
ClassName : CATDlgFile ClassUseSet : Derivation prohibited MethodOrFunctionArgument prohibited DataMemberOrLocalVar prohibited CastInto prohibited IncludeOfHeader prohibited New prohibited Replacement : nothing specified
means that class CATDlgFile cannot be inherited or used as formal argument,
data member or local variable type. Casting into CATDlgFile is also prohibited,
as well as the inclusion of the CATDlgFile.h file and the call to new
CATDlgFile(...)
to create new CATDlgFile instances.
Be careful:
<ClassName>
is prohibited, all derived types (CATLISTP(<ClassName>,
<ClassName>*, <ClassName>&
...) are also prohibited.[Top]
This section is located in: SettingsSet > OptionLists > EntityDetection_OptionLists
This section is quite similar to the previous one. The only difference is in the possible values of use attribute, which are: "Derivation", "MethodOrFunctionArgument", "DataMemberOrLocalVar", "CastInto", "IncludeOfHeader" and "TIE".
Example 1:
ClassName : CATIFactoryOfContainers ClassUseSet : Derivation prohibited MethodOrFunctionArgument prohibited DataMemberOrLocalVar prohibited CastInto prohibited IncludeOfHeader prohibited TIE prohibited Replacement : CATCreateApplicativeContainer (in CATAppliContServices)
means that interface CATIFactoryOfContainers cannot be inherited or implemented directly, or used as formal argument, data member or local variable type. Casting into CATIFactoryOfContainers is prohibited, like the inclusion of the CATIFactoryOfContainers.h file
Be careful:
<InterfaceName>
is prohibited, all derived
types (CATLISTP(<InterfaceName>), <InterfaceName>*,
...) are
also prohibited.[Top]
UACS prevents from using unauthorized identifiers.
UADC prevents from using memory that has been de-allocated. These
errors can, in some cases, be fatal.
PCOM prevents prohibited calls of methods.
PUCE prevents deprecated or prohibited uses of classes or interfaces.
[Top]
[1] | Creating Dialog Objects |
[2] | Managing Errors |
[3] | Setting Files |
[Top] |
Version: 1 [May 2001] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.