Page tree
Skip to end of metadata
Go to start of metadata

On this page:

Target audience:

CAST Administrators

Summary: this page provides detailed information about CAST's support for the C / C++ technology.

Detailed technology support

Language/Version

Supported

Comments

C (C99 normalization)

(tick)

Project discoverers for the CAST Delivery Manager Tool are available for:

  • Visual C++ 2003
  • Visual C++ 2005
  • Visual C++ 2008
  • Visual C++ 2010
  • Visual C++ 2012

No project discoverers (for the CAST Delivery Manager Tool) are available for other supported C versions (i.e. Visual C++ 6 and non-Microsoft versions) as such, Analysis Units must be defined manually.

  • Oracle Pro*C and IBM DB2 SQC extensions (EXEC SQL commands embedded in C code) are supported.
C++ (2003 normalization and 2011 normalization (partially))(tick)

Project discoverers for the CAST Delivery Manager Tool are available for:

  • Visual C++ 2003
  • Visual C++ 2005
  • Visual C++ 2008
  • Visual C++ 2010
  • Visual C++ 2012

No project discoverers (for the CAST Delivery Manager Tool) are available for other supported C++ versions (i.e. Visual C++ 6 and non-Microsoft versions) as such, Analysis Units must be defined manually.

C++ 11 normalization is partially supported. Support currently includes:

  • Lambda expressions
  • "auto" and "decltype" keywords
  • Trailing return types for functions ( auto foo (int x, int y) -> returnType; )
  • "override" and "final" keywords
  • Scoped enums
  • RValue Reference

  • Other miscellaneous  features (nullptr, static_assert, noexcept, …)

Oracle Pro*C++ and IBM DB2 SQC++ extensions (EXEC SQL commands embedded in C++ code) are supported.

Required third-party software

To successfully deliver and analyze C / C++ code, the following third-party software is required:

Install on workstation running the DMT (for extraction)
Install on workstation running CMS (for analysis)

Nothing required

Note that no project discoverer exists for Visual Studio 6.0, however, source code can still be packaged.

Software required

If you intend to use the CAST - VC++ XXX - Mandatory Part Environment Profile (usage is recommended), then you MUST install:

  • All include files of third party libraries that are used.
  • The appropriate IDE depending on source code to be analyzed:
    • Visual Studio 6.0
    • Visual Studio .NET 2003
    • Visual Studio 2005
    • Visual Studio 2008
    • Visual Studio 2010
    • Visual Studio 2012
Note that if you do not install the appropriate IDE for your source code, then the analysis will fail.
Note that the above information does not apply to other source code (C/C++ compiler from vendors other than Microsoft).

C / C++ objects and links

The following section lists the objects and links between objects that the Business analyzer is capable of detecting and storing in the CAST Analysis Service:

Objects

Class

Folder for Classes, Unions and Structures
Dependencies Folder
Globals Folder
File Scope Folder

Constructor

Destructor

Enum

Enum Item

File

Function

Global Variable

Macro

Member

Method

Project

Struct

Class Template

Class Template Specialization

Constructor Template

Constructor Template Specialization

Function Template

Function Template Specialization

Method Template

Method Template Specialization

Subset

Template Parameter

Typedef

Union

CLR Event (Managed C++)

CLR EventAddon (Managed C++)

CLR EventRaise (Managed C++)

CLR EventRemoveOn (Managed C++)

CLR Property (Managed C++)

CLR PropertyGetter (Managed C++)

CLR PropertySetter (Managed C++)

Link TypeWhen is this type of link used?
ACCESSREAD

Specifies that an object reads a value of another object. For example if a function reads a global variable:

int g_nVar1;
void f()
{
int nVar1 = g_nVar1;
}

C++ Analyzer will generate this Access (Read) link:

WRITE

Specifies that an object modifies another one. For example if a function modifies a global variable:

int g_nVar1;
void f()
{
g_nVar1 = 1;
}

C++ Analyzer will generate this Access (Write) link:

EXEC

Specifies that an object executes another object (method or function). For example if a function calls another function:

void g()
{
f();
}

C++ Analyzer will generate this Access (Exec) link:

Please note that, as a convention, an EXEC link is also used when the definition or declaration of an object invokes a macro. The links is created from the object to the macro.
MEMBER

Specifies that an object accesses a member of another object. For example if a function "g()" accesses a global var "g_pVar" and to one of its members:

struct { int m_n1; }* g_Var;
void g()
{
g_pVar->m_n1 = 1;
}

C++ Analyzer will generate this Access (Member) link:

ARRAY

Specifies that an object accesses another using square brackets ([ ]). For example if a function "g()" accesses a character's array at its first position:

char g_lpBuffer[256];
void g()
{
g_lpBuffer[0] = '\0';
}

C++ Analyzer will generate this Access(Array) link (with the write property also):

BELONG

Represents a parent link between two objects. If "Sample.h" contains the following statement:

class C1
{
public: int foo() {}
};

C++ Analyzer will generate these Belong links:

  • An object always has a "logical" Belong link to its parent (function, class, global variable folder etc.). Furthermore, when the object is defined at the main file level (global variable or function, non-nested class, class method defined at file level), it has a second "physical" link to this implementation file.
  • An object never has more than two parents.
CONTAINDECLARE
This link type occurs between a file and a Global object when there is also a declaration (forward declaration or external declaration) in addition to the definition itself. For example, between a file and a:
  • Class
  • Structure
  • Enum
  • Union
  • Function or method
  • Variable or class member

This link can be seen in the example below (Zc):

DEFINE
This link type occurs when a method is defined outside the file containing the class definition. The link is created from the file containing the method definition to the class. For example, using the code below:

glob.h

extern int theGlobalVariable;
class theClass
{
void method();
};

glob.cpp

/* header comment */
#include "glob.h"
int theGlobalVariable = 3;
void theClass::method()
{ if(2+2==4);
}

C++ Analyzer will generate the following link (Zf):

FRIEND
Specifies that a class or a function is a friend of a class.

For example if the class "C2" is declared as friend of a new "C3" class:

{
//...
friend class C2;
};

C++ Analyzer will generate this Friend link:

INCLUDE

Represents an inclusion link between two files. If the "Sample.cpp" file contains the following statement:

#include "Sample.h"

C++ Analyzer will generate this Include link:

INHERIT-

Represents an inheritance between two classes or structures. If we define a new class "C2" inheriting from C1 as in following statement:

class C2 : public C1
{ int foo() {}
};

C++ Analyzer will generate following Inherit link:

OVERRIDE
Specifies that a method redefines another method from an inherited class. For example using the previous sample, "C2::foo()" redefines "C1::foo()". So C++ Analyzer will generate this link:

RELY ON

Specifies that an object uses an existing type. If we define a new variable of type "C1" in "Sample.cpp":

C1* g_pVar1;

C++ Analyzer will generate following Rely On link :

USE

Represents a link between a C/C++ object and a database object. For example, if we define a function "f_ExecSql" containing a ProC statement referencing the "Authors" table :

void f_ExecSql()
{
EXEC SQL EXECUTE select * from authors where au_id = 0;
}

C++ Analyzer will generate this Use link:

The following ESQL tags are also supported (non exhaustive list):

  • EXEC SQL ... INSERT
  • EXEC SQL ... UPDATE
  • EXEC SQL ... DELETE
  • EXEC SQL ... SELECT
  • EXEC SQL ... CALL
  • EXEC SQL ... DECLARE ... CURSOR FOR
  • EXEC SQL ... EXECUTE ... END-EXEC

In ESQL tags, links to the following objects will be found (non exhaustive list):

  • Tables
  • Views
  • Synonyms
  • Stored Procedures and Functions
  • Package Procedures and Functions (Oracle)

Technology support notes

This section provides more detail about the support for C and C++ and the way in which CAST handles the technologies:

Type modifiers inside Pro*C Embedded SQL

The following type modifiers for numeric constants are not supported when used inside Pro*C embedded SQL:

  • F or f (for "float")
  • 0x (to indicate a hexadecimal value)

As an example, the following statement will cause a syntax error because the use of 'F' in 727.98F:

EXEC SQL UPDATE MY_TABLE SET COL1_FLOAT = 727.98F

The syntax error occurs only when an Oracle schema is selected in the Object Manager of the C++ Analyzer job.

Precompiler directives inside Pro*C Embedded SQL

Precompiler directives (such as #define, #include, #if...) are not expanded when used inside Pro*C Embedded SQL. As a consequence, a syntax error can occur when a file is included (using #include) or when conditional statements exist (inside #if ... #else) and the resulting code is syntactically incorrect without expansion.

Embedded SQL syntax "static exec sql include"

The Embedded SQL syntax "static exec sql include xxx" is not supported. However, the syntax "exec sql include xxx" is supported.

Additional notes

The following section lists technical and functional aspects with regard to analysis of C/C++ source code:

Dynamic Link Manager

Viewing Source Code

A C++ link may possibly have several different associated pieces of code (in various files). When a server object is referenced in several files for a same Caller, CAST's Dynamic Link Manager will only display references found in one file.

For example:

file f1.h :
....
void f(const CString& s = CString(" T1" ) );
...
file f2.cpp
...
void f( const CString& s )
{
//...
LPSTR c = "T1";
//...
}
...

In this example, T1 is a server object and function f references T1. The references are spread among two files, f1.h and f2.cpp.
Although there is more than one file that contains references to T1, Dynamic Link Manager will only display one file (either f1.h or f2.cpp) and highlight all references in it. Thus all references in the other file will not be displayed. In this example, if the file displayed by Dynamic Link Manager is f2.cpp, there will be only one reference highlighted although there is another reference in f1.h. Therefore it can be difficult to decide, if links to T1 are valid or should be ignored.

To workaround this problem, you can use CAST's Code Viewer in Enlighten. It displays all bookmarks. This allows evaluating dynamic links based on complete information.

Macros

Dynamic links will be created to macros based on the source code that is defined in a macro. However, when examining these dynamic links in the Dynamic Link Manager, the link will appear to originate in the macro and call any corresponding object based only on the strings that are defined in the macro. This is a functional limitation of the analyzer. In order to check the validity of these links, the corresponding file where the macro is defined will need to be opened manually.

Virtual functions

The analyzer is not always able to know which function is called. If there is an ambiguity and several potentials target, all possible relations are created. In this case this will have an impact on quality rules that are based on relationships like fan-out etc.

The following example will illustrate the limitation:

class CMother
{
    public:
    virtual void TheFunction() { MessageBox( NULL,
                                             "CMother..",
                                             "CMother..",
                                             MB_OK); }
};

class CDaugther : public CMother
{
    public:
    void TheFunction() { MessageBox( NULL,
                                     "CDaugther..",
                                     "CDaugther..",
                                     MB_OK); }
};

void CTestDlg::OnOK()
{
    CDaugther cDaugther;
    CMother * pcMother=&cDaugther;
    pcMother->TheFunction();
}

When you run this program, CDaugther::TheFunction is called, but the analyzer will create a link to CMother::TheFunction.

Resolution of overloaded functions and operators

CONST methods

The analyzer does not take the const modifier of a method declaration into account, when resolving a call to an overloaded method. Example:

class K
{
int meth (int);
int meth (int) const;
};

void f(const K &var)
{
var.meth(0); /* Resolution fails.
                Analyzer does not choose the
                "const" version of "meth()". */
}

Automatic conversions

The analyzer does not take automatic conversions into account, when resolving a call to an overloaded method. Example:

class String
{public:
String (char);
operator const char*();
};

int f (const char*); int f(char);
int g (const String&); int g(int);

int main()
{
String s;
f(s);   /* Resolution fails.
           The analyzer does not consider
           the automatic conversion of s
           to const char* and therefore
           does not create a link to
           f(const char*). */

g('x'); /* Resolution fails.
           The analyzer does not consider
           the automatic conversion of 'x'
           to String and therefore does
           not create a link to g(String); */
}

Links to overloaded operators

Operators are correctly analyzed with all their properties and the links to the objects they call. However links toward those operators are not retrieved, except calls to

  • operator ->
  • operator *
  • operator []
  • operator ()

Implicit calls to constructor/destructor

Implicit calls to mother class constructor/destructor from derived classes are not created.

C preprocessor

  • The _Pragma operator is not supported in this version (the #pragma directive is).
  • Character literals inside a "#if" directive are not properly evaluated in this version
    : e.g.
#if ( 'Z' - 'A' ) == ( 'z' - 'a' )
true
#else
false
#endif

outputs (erroneously) "false"

"Friend" links from classes, functions or methods to classes no longer have bookmarks.

Sharing of properties and positions between analyses

Please note that if some sub-objects of files (functions, macros...) are shared between two analyses, their properties (position(s), comments, code line numbers, constness and the like) are also shared.
These properties usually do not depend on the analysis that identified them; but, if they do depend, they keep the value that has been set by the most recently executed analysis.

Example:
The following analyses and files are given:

Analysis 1

/* file foo.cpp */
#define INCLUDED_FROM_FOO
#include "foo.h"
...
/* end foo.cpp */

Analysis 2

/* file bar.cpp */
#define INCLUDED_FROM_BAR
#include "foo.h"
...
/* end bar.cpp */

/* File foo.h */
// foo.h // line 1
#ifdef INCLUDED_FROM_FOO // 2
#define mymacro // 3
std::string mainFileName() {return "foo.cpp";} //4
#elif defined INCLUDED_FROM_BAR
std::string mainFileName() {return "bar.cpp";} //6
#endif
// end foo.h

If Analysis 1 is executed, the macro mymacro is created, with a location at line 3 of foo.h, and the function mainFileName() is located at line 4. If, after that, Analysis2 is executed, the function mainFileName() is now located at line 6, and line 4 no longer appears as a position. The macro mymacro behaves a little more unexpected: it is not created during the second analysis, but it is not deleted, since it still belongs to the first analysis. As a result, the macro no longer has a position in the Analysis Service, even though it still appears in the Object Browser in Enlighten.

Templates

Parsing of Template Instantiations has the following limits:

  • Resolving function calls does not take into account function template explicit specializations
  • Partial specializations are ignored during instantiation
  • Template argument deduction fails in complex cases
  • The effective type of template arguments is not used yet by the analyzer when using members of these template arguments.

Hereafter, two examples are given to illustrate the last limitation (effective type not used):

Example 1

std::string::c_str() (where std::string is a specialization of std::basic_string<char>)

is not recognized as returning a char*.

Example 2

class Object
{
int size1() { return 0; }
};

template <class T> class myClass
{
int size2(T obj) { return obj.size1(); }
};

int main()
{
Object x;
myClass y;
y( x) ;
}

The following objects are created:

  1. C++ Class Objectwith following child:
    • C++ Method size1
  2. C++ Class Template myClasswith following children:
    • C/C++ Template Parameter T
    • C++ Method size2
    • C++ Class Specialization (Generated) *myClass<Object>

Due to the limitation (effective type not used), no link is created from myClass<Object> to size1. The reason is that generated instances are never parsed again with their effective arguments. Here, we should parse again MyClass, with T==Object, and resolve T.size1() as Object.size1().

Data Definition Language (DDL)

The following Data Definition Language (DDL) statements inside an Embedded SQL block in a C/C++ file are not supported by the C++ Analyzer:

  • Create Function
  • Create Procedure
  • Create Package
  • Create Package Body

When analyzing a Pro*C or other Embedded SQL file containing this type of DDL statement, the C++ Analyzer will emit several "Unresolved type/name/symbol ..." warnings. The analysis succeeds but no objects nor links are created for the DDL statements. You can safely ignore these "unresolved ..." warnings as well as all errors resulting from them. Please note that the other DDL statements (Create Table, Create Index and the like) ARE supported.

Object Definition Language (ODL) Files

Object Definition Language (ODL) files are not analyzed and are not stored in the KB.

COM objects and C/C++ objects

With regard relationships between COM objects and C/C++ objects, CAST creates links between COM Libraries and C/C++ files but not between lower level objects.

  • No labels