Coding Guidelines-C
Coding Guidelines-C
I IA AS
Referenced Document
Document Attributes
Document No. A5E00785463A
File RTIL_Development_Guideline_C++_V111.doc
Status released
1
Document version 02
Type of source English (only)
Reference Key (RPH) RPH PLM-Realize
Reference to PCMB ./.
Referenced Standards ./.
Scope of validity I IA AS
Adapted for country global
Affiliated companies Sector/Division Companies: [_] Category 1 [_] Category 2 [_] Category 3
[_] Regional Companies (employees in the applicable organizations)
./.
Valid from 01.10.2012
2
Review (frequently) Implicit with corresponding regulation or process.
Responsible IOWA SW Architecture Team (SWAT)
Superseded regulation ./.
Corresponding regulation ./.
or process description
1
If released, all previous versions of this document are no longer be valid. They will be replaced by this version.
2
Review performed implicit with corresponding regulation or process, no re-release required if no need for change.
Copyright © 2012 Siemens Aktiengesellschaft – For internal use only – All rights reserved
Die Kopie oder Verteilung oder Kommunikation des Inhaltes dieses Dokumentes ist nicht gestattet ohne schriftliche Erlaubnis der Siemens AG.
Copying or distribution or communication of the content of this document is not allowed unless with express written permission from Siemens.
Vorlage/Template A5E00785494A DS12
I IA AS Copyright (C) Siemens AG 2012 All Rights Reserved.
Inhalt / Contents
1 Motivation ............................................................................................................4
2 Scope of the guidelines .....................................................................................5
3 Purpose................................................................................................................6
4 Checking the Rules ............................................................................................7
5 Not compliant code ............................................................................................8
6 C/C++ Rules.........................................................................................................9
6.1 Design and implementation .............................................................................................9
6.2 Module headers and footers..........................................................................................10
6.2.1 Code for file headers ................................................................................................10
6.2.2 Code headers for functions and member functions ..................................................11
6.2.3 Code for footers ........................................................................................................11
6.3 Inclusion of header files.................................................................................................12
6.3.1 Prevent multiple including of header files .................................................................12
6.3.2 C header files with C++ compiler ..............................................................................12
6.3.3 Inclusion of OS specific headers files .......................................................................13
6.3.4 Inclusion of headers files with “<>” brackets.............................................................13
6.3.5 Namespaces in header files .....................................................................................13
6.4 Storage of header files ..................................................................................................14
6.5 Definition of constants ...................................................................................................14
6.6 Explicit type conversion .................................................................................................15
6.7 Casting on const and type casting ................................................................................16
6.8 Global variables, instances and functions .....................................................................17
6.9 Comments in code ........................................................................................................17
6.10 Naming conventions ......................................................................................................18
6.10.1 Filenames .................................................................................................................18
6.10.2 Naming conventions for code elements....................................................................18
6.11 Designing classes .........................................................................................................21
6.11.1 Class header files .....................................................................................................21
6.11.2 Virtual methods, destructors, constructors and overrides.........................................21
6.11.3 Friending classes......................................................................................................23
6.11.4 Overloading operators ..............................................................................................23
6.11.5 Private properties or members .................................................................................24
6.11.6 RTTI..........................................................................................................................24
6.11.7 Public members ........................................................................................................25
6.11.8 Initializing member variables of a class ....................................................................25
6.11.9 Init functions..............................................................................................................27
6.11.10 Freeing memory in destructors .................................................................................27
6.11.11 Copy and assignment operators...............................................................................28
6.12 Structure of decision code .............................................................................................29
6.13 Wrapping long statements.............................................................................................29
6.14 Complex boolean expressions and operator precendence ...........................................30
6.15 Switch commands .........................................................................................................31
6.15.1 Case without break statements ................................................................................31
6.15.2 Switch commands based on enums .........................................................................32
6.16 Functions.......................................................................................................................33
6.16.1 Function parameters.................................................................................................33
Version Status Valid from Page
003 released 01.10.2012 2 of 2
Copyright © 2011 Siemens Aktiengesellschaft – For internal use only – All rights reserved
I IA AS Copyright (C) Siemens AG 2012 All Rights Reserved.
1 Motivation
With the increasing possibilities of new technologies, growing security concerns and
the desire to use results further from completed projects the requirements on a new
project increase.
Aiming to develop components using results from older projects it should be possible to
realize new requests on higher standard.
Exactly the last-named point causes problems if there exist only incomplete results and
the software developers are not available after the project end any more.
For this reason, a methodical and structured procedure of the software development is
mandatorily required to be able to access acquired know-how over project phases and
out of projects.
The most important qualities of software should be:
• correctness
• reliability acceptance of user errors
• usability intuitive use of SW
• maintainability modification of SW
• portability usage of different OS-platforms
• efficiency fast execution of SW
• testability verification of correctness
• readability good structure of code
• comprehensability code functionality is easy to understand
• security resilience against malicious users and attacks
The compliance with the development guidelines is demanded by all involved persons.
Besides the existence of the specifications, also the understanding of the rules and
why they apply, practical experiences, and checking the conformance to the
development guidelines lead to high-quality software.
In this guideline the rules are marked this way:
Security Style common rule old/new code
These checkboxes indicate, whether the rule concerns about security and/or style
and/or is a common rule for old/new code.
If there is an affected rule from CERT, then this rule is mentioned in brackets (e. g.
(API09-C).
The term “should not“ has the same meaning as “must not” or “is not allowed to” and is
a more legal and polite expression.
Document
PCPRT guideline RTIL_DevelopmentGuidline_V0.10.doc Version 0.10 by
Hector Colado (used as template for this document)
PVSS guideline ri_ProgrammierrichtlinienC++.doc Version 6.1F by Günther
Zoffmann
WinCE PA_RT_CppProgrammierung (Version 0.9)
PC-based SIEMENS I IA AS Programming guideline for C/C++ (Version
1.0), 2009
C++ Optimizing software in C++ by Agner Fog, July 2007
CERT software Memory management
engineering
Igor Zevaka http://www.somethingorothersoft.com/2010/02/02/double-
dispatch-rtti-vs-pure-vtable/
PLM Guidance Explorer Online
Programming Conventions for C++ and Visual Basic
SCGL GL_SecureProgrammingGuideline_CPP
GL_SecureProgrammingGuideline_C
All rules in this coding guideline apply to the new modules that are developed in IOWA
platform, WinCC IL RT Comfort and WinCC IL RT Professional. New modules, are
modules that are newly developed in IOWA and WinCC IL RT (means modules which
are newly developed from scratch). This includes also modules which have its origin in
PCPRT such as VDS, VCS, RH, and Logging. Also modules which are in development
(or are allready developed) for new IOWA features (e.g. RDF modules, System
Configuration Server) need to be compliant to all rules.
Nevertheless, these coding guidelines also include rules that apply for existing WinCC
OA (PVSS legacy) modules independent if a new or existing module is targeted. These
rules are marked with “common rule old/new code”.
See example:
Beyond the rules that are marked with “common rule old/new code” existing modules
keep the same rules in which they have been made so far. Means that for extending or
changing these existing modules (e.g. new classes, changed methods, change of data
types, etc.) the PVSS coding guidelines apply, with the exception that rules marked
with “common rule old/new code” overrule the PVSS rules.
3 Purpose
These programming guidelines describe the rules and best practices to be used by all
developers in the project Runtime Innovation Line Platform and the IL RT Products
(Comfort and Professional).
The problems regarding existing code and different coding guidelines are taken into
consideration. If existing code conflicts with one of the coding rules, the existing code
remains unchanged..
6 C/C++ Rules
Rule //----------------------------------------------------
------------------------
// Copyright (C) Siemens AG <current year YYYY>. All
Rights Reserved. Confidential.
//----------------------------------------------------
------------------------
// Descr.: <Brief description of the code>
//----------------------------------------------------
------------------------
Example //----------------------------------------------------
------------------------
// Copyright (C) Siemens AG 2011. All Rights
Reserved. Confidential.
//----------------------------------------------------
------------------------
// Descr.: Class definition of Data Access Optimizer
//----------------------------------------------------
------------------------
Rule //----------------------------------------------------
------------------------
// Copyright (C) Siemens AG <current Year YYYY> All
Rights Reserved. Confidential.
//----------------------------------------------------
------------------------
Code file footers do not have to be included necessarily as they
collide with automatic refactoring tools like Visual Assist.
Example //----------------------------------------------------
------------------------
// Copyright (C) Siemens AG 2011 All Rights Reserved.
Confidential.
//----------------------------------------------------
------------------------
Rule Each header file has to start with "#ifndef <Headerflag> #define
<Headerflag> … #endif
If you expect a naming conflict, include the namespace like
_NAMESPACE_FILENAME in the flag’s name.
Example #ifndef _PERFMGR_H_
#define _PERFMGR_H_
#endif // _PERFMGR_H_
Annotation Name should be defined by class name or file name.
#ifdef __cplusplus
}
#endif
Rule Header files, which are used by different systems (e. g. interface headers)
have to be stored in a global header directory.
Saving a header in a local subdirectory is allowed, when the
modules/subsystems using this header are part of a larger
module/subsystem.
The storage of header files has to be defined by CM together with
developer.
Correct:
int Value = 3;
char* pCh;
...
pCh = reinterpret_cast<char*>(Value);
Please keep in mind, that this example is only for illustration. If you want
to convert int to char, you should use other methods, e. g. like Strings.
6.10.1 Filenames
Rule Filenames can have more than eight characters. In the filename no
blanks and no special characters except “_” are allowed. Choose
descriptive filenames. Upper and lower case is allowed.
Annotation See CPP020.
Rule Header files containing only the definition of an interface have a filename
starting with “I”.
Rule Do not create names that differ only in case type (wrong example: class
WorkTest; class WorkTEST;).
Use PascalCasing, when there is no explicit naming convention (e.g.
structs).
Do not use special characters like umlauts or characters with
special meanings.
All identifiers must be named in English and should be descriptive.
Rule Interface elements always start with "I" and PascalCasing (e. g.
IDisposablePattern)
Rule CAPITALCASING (e.g. #ifdef WINCE) For grouping and separating “_” is
allowed, also at the beginning of the name.
Rule Only one class definition per header file is allowed. Inner class definitions
are allowed.
Rule For each class with virtual methods there must be an explicit destructor,
which is virtual, too.
Annotation This rule is only valid as long as calling delete is possible from outside –
usually as long as the destructor is public (e.g. for COM-objects lifetime
management is handled via AddRef/Release, so basic COM-Interfaces
like IUnknown don’t have virtual destructors).
There are some use cases, where it is not intended, that a class can be
derived and there a virtual destructor is producing unnecessary
performance costs. If you want, that your class should never be derived,
make the destructor non-virtual. But comment it in the header code of
your class.
Rule Each overridden virtual method remains virtual in the derived class and
must be declared as virtual.
Example class CBasicMessage
{
public:
virtual int DispatchMsg (const int DispID) {
m_MessageDispatcher = DispID; return DispID; }
private:
int m_MessageDispatcher;
int m_MessageController;
};
Wrong example:
class CControllerMessage: public CBasicMessage
{
public:
int DispatchMsg (const int DispID) {
m_MessageController = DispID; return 0; }
private:
int m_MessageDispatcher;
int m_MessageController;
};
Correct example:
Rule Provide public Get() and Set() property accessors for private properties or
members instead of making them public. The accessors name can start
with “Get” or “Set” prefix.
Example class CTestA
{
private:
int m_ID;
...
...
public:
int ClassID()const; // this is a get()-
function
void ClassID(int SetID); // this is a set()-
function
...
...
};
void TestFunc()
{
aCTest CTest;
int ClassIDTest;
const int ClIDDefault = 10;
...
...
aCTest.ClassID(ClIDDefault);
...
...
ClassIDTest = MyClass.ClassID();
}
6.11.6 RTTI
class DiversityHolder {
Obj* pObj;
int number;
bool read;
public:
DiversityHolder ()
{
number = 42;
read = true;
pObj = NULL;
}
HRESULT Init ()
{
pObj = new Obj();
}
~DiversityHolder ()
{
delete pObj;
}
};
//make assignment
...
return this;
}
Annotation Implement a copy and an assign operator, when you are using pointers or
handles on OS resources as class members. Implement the copy/assign
constructor, so that a full copy will be implemented, i. e. the copy/assign
operators of the base classes will be called, too. When implementing the
assign operator keep in mind that the applied memory has to be freed
again before. This is not needed, when the assignment operates on itself.
Rule
if ( .... )
{
if ( ... )
{
....
}
....
}
else if ( ... )
{
....
}
else
{
....
}
Rule Use blanks instead of tabs to align your code logically, when wrapping
long statements over several lines. As a best practice limit each line to
120 characters (including whitespaces).
Annotation If this rule is violated the developer has to think about the structure of the
code. This rule is not meant to be too restrictive.
Rule Switch commands based on enum types as selector must have an assert
mechanism in the default branch.
Risk Format string attack, denial of service, information leakage, leakage of
confidential data, arbitrary code execution, abnormal program termination,
bypassing authorization mechanisms.
Annotation The issue here is, that you get a compiler warning, if an enum type is
expanded and it is not handled in the switch command in a case
statement. No default branch should be implemented, but the compiler
warning C4061 shall be turned on to indicated unhandled enum cases.
Example DpMsg *DpMsg::Allocate(MsgType DpMsgType)
{
case DP_MSG_CONNECT:
return new DpMsg();
break;
// same handling for two cases
case DP_MSG_DISCONNECT:
case DP_MSG_DISCONNECT_ALL:
disconnected = true;
break;
// additional handling for one case with
// similarities
case DP_MSG_ALERT_CONNECT:
retVisible = false;
case DP_MSG_ALERT_CONN_RET_VISIBLE:
return new DpMsgConnection(DpMsgType);
break;
case DP_MSG_ALERT_DISCONN:
return new DpMsgConnection(DpMsgType);
break;
...
// The following types are only for
completeness:
case PVSS_MSG :
case NO_MSG :
...
case DP_MSG :
case DP_MSG_CONNECTION :
case DP_MSG_VALUECHANGE :
case DP_MSG_ALERT :
return 0;
break;
}
}
Annotation Missing break statements should be PCLint like commented. See PCLint
documentation Message #825.
6.16 Functions
6.16.1 Function parameters
Rule The function code shall start with a parameter check, if the function is a
public API function.
Risk Format string attack, denial of service, information leakage, leakage of
confidential data, arbitrary code execution, abnormal program termination,
bypassing authorization mechanisms
Example Result OnStatus(GAPStatusContext EnumContext, Result
ErrorCode)
{
if( 0 != EnumContext && S_OK != ErrorCode )
{
StopVCS();
}
Rule Code must be able to be built without errors or warnings. Use the highest
warning level.
If not the highest warning level is used, then this has to be
documented and approved by SWAT and PL/TPL.
Risk Some potential risky code can be in disguise, when the build produces
many warnings. Since the software must be kept always “ready for build”,
it must compile without errors.
Annotation Disabling warnings is only allowed on a global level via a global warning
header (which has to be approved by SWAT and PL).
Disabling warnings is allowed for 3rd party headers (in this case warnings
should be disabled and reenabled again e.g. pre-/post warning headers)
or 3rd party files (there it is allowed to set the warning level to 0). Also this
has to be approved by SWAT and PL..
6.19 “Goto”
CPP055 Goto statements (MSC35-CPP)
Security Style common rule old/new code
6.20.2 “this”
Insecure examples
char name[20];
unsigned age;
};
unsigned get_age(struct record *my_record)
{
return my_record->age;
}
Secure Examples:
Remark: Since str is allocated by malloc(), the test against NULL (not 0) is
fine here. Non-allocated pointers have to be initialized by “0”.
Rule Test possible overflows before doing mathematical operations, that might
exceed the range.
Risk Format string attack, denial of service, information leakage, leakage of
confidential data, arbitrary code execution, abnormal program termination,
bypassing authorization mechanisms
6.21.3 Algorithms
Rule The use of common algorithms and patterns is preferred. Self made
algorithms should be avoided, when there are already known algorithms
and patterns available.
Annotation Resolving already solved problems creates unnecessary costs and can
be a source of errors.
Using algorithms it is recommended to check the runtime behaviour and
to document it in brief. This elucates any rework of the runtime behaviour.
Using commonly known algorithms you have to think about a thin
economical embedding into the system, i. e. using functions from already
existing classes, avoiding unnecessary copy operations etc.
Always consider runtime conditions in algorithms, in particular loop
conditions and memory usage.
6.21.4 Recursion
Rule Use recursion only, where it is needed, since it can lead to high memory
consumption and can be error prone.
Annotation A while/for loop is usually even more error prone, so recursions are
generally preferable to loops in most languages – but C/C++…:
C/C++ does not specify tail recursion optimization as a core feature. E.g.
MSVC does no tail recursion optimization on optimization levels < 2, so
using tail recursion instead of while can lead to a stack overflow in e.g.
debug builds…
Rule Direct numerical values are not allowed in the code, only symbolic values
(use “const”) must be used. However setting pointers to “0” is allowed.
Example Wrong:
if (255 == BackgroundColor)
Correct:
...
return;
Rule Consider using smartpointers when using dynamic fields, since freeing
memory or resources is less error prone.
Example Wrong example:
class MyClass
{
protected:
Obj *pObj;
// the rest of the definition follows
MyClass~()
{
delete pObj;
}
// public methods working on pObj
};
void function()
{
MyClass ATestClass;
// Some processing involving pObj;
...
}
// when ATestClass goes out of scope, delete is
// called in the destructor
Correct example:
class MyClass
{
protected:
auto_ptr<Obj> pObj;
// public methods working on pObj
};
void function()
{
MyClass ATestClass;
// Some processing involving pObj
...
// delete in destructor not required anymore
}
With the smartpointer implementation, the pointer gets deleted when
leaving scope.
Correct:
size_t Size;
return 0;
}
Correct:
int copy_file(FILE *pSrc, FILE *pDst, size_t Bufsize)
{
if (0 == Bufsize)
{
// Handle Error
}
char *pBuf = (char *)malloc(Bufsize);
if (!pBuf)
{
return -1;
}
6.27 Exceptions
CPP074 No exceptions in general ( ERR33-C, ERR07-CPP, ERR33-CPP,
ERR30-CPP)
Security Style common rule old/new code
Rule Own code should not throw exceptions, exception handling has to be
used for code that throws exceptions though (e.g. STL). Internally, these
exceptions then have to be mapped to ErrorCodes.
Exception handling has to be implemented where exceptions can be
thrown. On interface-level ErrorCodes shall be used.
RT projects have to handle errors without exceptions, other projects may
decide differently for their own scope.
Exceptions have to be discussed with SWAT/PL, if they are really
necessary.
If an exception handling has to be implemented, it has to be documented
in the comments of the code why this exception is used (motivation) and
who has authorized it (e.g. PL, SWAT or architect).
Risk Denial of service, information leakage, abnormal program termination
Annotation Exceptions can reduce performance.
SIMPLE_TESTCASE_BEGIN
{
Result result;
OptimizerImplTest.OnInitialize();
}
SIMPLE_TESTCASE_END(result);
Correct:
// OptimizerImplTest will be removed automatically
SIMPLE_TESTCASE_BEGIN
{
tkt::COptimizerImpl OptimizerImplTest;
Result result;
OptimizerImplTest.OnInitialize();
}
SIMPLE_TESTCASE_END(result);
Correct1:
bool IsStartup = (Start < 0) ||(End < 0) || (End <
Start);
if (IsStartup ||
( (PosStart == 0) && (PosEnd == 0) )
)
{
...
}
Correct2:
bool IsStartup (const int Start, const int End)
{
if (( Start < 0 ) ||
( End < 0) ||
( End < Start)
)
{
return true;
}
else
{
return false;
}
}
6.30 Inlining
CPP077 Inlining in header files
Security Style common rule old/new code
Rule The Code of inline methods must be placed in the class header file.
Prefer inline functions to macros as far as possible.
Annotation The usage of inline functions creates some problems:
The Code of inline methods must be placed in the class header file. So
code gets larger for all developers, who are using this class.
The inline declaration of virtual functions is not sensible, since it will be
ignored by the compiler. Because many methods have to be declared as
virtual, the usage of inline methods is very small.
Get/Set member methods should be inlined as well.
Inline functions, which exceed the limits of the linesize, should be
declared outside the class definition in the same header file.
Example class CAlertTime : public CTime
{
public:
...
/**
* Checks whether the compared instances are equal.
* Time and count are compared.
*/
int operator==(const CAlertTime &rVal) const;
...
}; // end of class definition CAlertTime
Rule Use everything from the standard library with its std:: namespace prefix
Annotation Do not pull the whole standard library into the global namespace.
Rule Guarantee that storage for character arrays has sufficient space for
character data and the null terminator. Otherwise this will result in
memory leaks and crashes and is a high risk for attacks.
Prefer string classes, that take care of allocation issues.
In conclusion do not copy data from an unbounded source to a fixed-
length array and do not make assumptions about the size of an
environment variable.
The function gets() delivers character arrays of unknown length at
compile time. Prevent its usage or use it wisely.
Risk Format string attack, denial of service, information leakage, leakage of
confidential data, arbitrary code execution, abnormal program termination,
bypassing authorization mechanisms
Example Wrong example:
Correct:
int main(int argc, char *argv[]) {
/* ... */
char *pProgName = new char[strlen(argv[0])+1];
strcpy(pProgName, argv[0]);
/* ... */
}
or:
strncpy() does not write any null terminator into the target string unless
it is contained in copied input characters. In the following example, this
may result in parts of the memory being printed out until a null byte is
found:
char buffer[20];
strncpy(buffer, arg, sizeof(buffer));
printf("Input: %s", buffer);
}
Correct:
Here a null byte is added to the end of the byte string to ensure that it can
be handled correctly by standard C functions.
CPP086 Always define format string parameters and ensure that they
do not contain user input (FIO00-C, FIO30-C)
Security Style common rule old/new code
Rule Always define format string parameters and ensure that they do not
contain user input.
Risk Format string attack, denial of service, information leakage, leakage of
confidential data, arbitrary code execution, abnormal program termination,
bypassing authorization mechanisms
Annotation Format strings that are not explicit or contain user input can be abused to
read or write to arbitrary memory locations. Providing a specially crafted
format string, this can be exploited by an attacker to read sensitive
information, to make the application crash, or to run arbitrary code on the
system with the permissions of the vulnerable process. For example, the
attacker can write an integer value to a specified address using the %n
conversion specifier.
The following rules must be satisfied when using commands which
interpret format strings:
• Always supply a format string parameter if using functions that
support format strings e.g. printf(), fprintf(), sprintf(), snprintf(),
vfprintf(), vprintf(), vsprintf(), vsnprintf(), syslog(), scanf(), fscanf(),
sscanf().
• Ensure that format strings do not contain user input, e.g. by using
string literals as format strings in the functions listed above.
• Make sure that the conversion specifiers in the format string are
correct and match the arguments provided.
Note that sources of user input include configuration files which, for
example, might contain format strings for software localization.
The conversion specifier %n is disabled in the current MS libraries and
leads to a runtime error. The security-enhanced _s alternatives
printf_s() and scanf_s() validate the format string and exit with a
runtime error if the string contains unknown conversion specifiers. These
functions do not prevent vulnerabilities caused by format strings
containing user input or format strings whose conversion specifiers do not
match the arguments provided.
Current versions of the GNU C compiler perform format string checks at
compile time and issue warnings if the conversion specifiers do not match
the arguments. These checks, however, are restricted to those cases
where the format string parameter is a string literal. If the format string is
provided as a string variable, no checks are performed.
Example Wrong example:
Correct:
void my_function(char *input)
{
printf("%s", input);
}
class Example {
public:
Example() : myString("hello") {}
~Example() {}
std::string& getString()
{
return myString;
}
private:
std::string myString;
};
Correct:
std::string getString()
{
return myString;
}
CPP090 Use at() when accessing characters in strings and c_str() for
conversion to null-terminated C-strings (STR33-CPP, STR39-
CPP)
Security Style common rule old/new code
Rule Use at() when accessing characters in strings and c_str() for
conversion to null-terminated C-strings. Do not access invalid output of
c_str() or data() and check the range of the access.
Risk Denial of service, buffer overflow, arbitrary code execution, abnormal
program termination
Annotation std::string is the standard C++ class for strings. As this class
provides boundary checking for string operations, its usage is generally
preferable over operations on C-strings based on char arrays. However,
there is one exception: if the operator[] is used to read or write
individual characters, no boundary check is performed for the provided
character position. As a result, a buffer overflow may occur.
In C++ programs, it is often necessary to convert a std::string object
into a pointer to an array of char. The std::string class offers two
methods for this purpose: data() and c_str(). data() returns a
char* pointer to the internal character array. Since this method does not
ensure that the last character is followed by a null character, the returned
pointer does not necessarily refer to a null-terminated C-string. Hence, if
the pointer is used as a pointer to a C-string (e.g. passed to C string
handling functions), buffer overflows may occur.
Remember to use always the namespace std:: to access any element
of the standard namespace.
The method at() behaves like the operator[], except that at()
performs a range check, throwing an exception of type out_of_range in
case that the given character position is not an actual position in the
string. Hence, at()must be used instead the operator[] unless there
are good reasons why a boundary check is not required. Make sure that a
proper exception handling is in place.
If a std::string object needs to be converted into a null-terminated C-
string, use the method c_str(), not data(). c_str() returns a
constant pointer to a character array which is null-terminated. Note that
the returned pointer is no longer valid after invoking any non-constant
method of the original string object.
In this example, both insecure functions are used. If the input read by cin
has zero length, input[1] accesses an out-of-bounds array element
and possibly causes a program termination. Thereafter, strlen() is
applied to the non null-terminated character array returned by data(),
which results in an undefined program behaviour:
string input;
cin >> input;
cout << "2nd item: " << input[1] << endl;
int i = atoi(input.data());
Correct:
string input;
cin >> input;
try
{
Version Status Valid from Page
003 released 01.10.2012 65 of 65
Copyright © 2011 Siemens Aktiengesellschaft – For internal use only – All rights reserved
I IA AS Copyright (C) Siemens AG 2012 All Rights Reserved.
CPP086 Always define format string parameters and ensure that they
do not contain user input (FIO00-C, FIO30-C)
Security Style common rule old/new code
CPP090 Use at() when accessing characters in strings and c_str() for
conversion to null-terminated C-strings (STR33-CPP, STR39-
CPP)
Security Style common rule old/new code
8 Appendix
8.2 Authors
Name Role Department Location Tel. Comment
mrboess Development RTIL ETM- 62681
Eisenstadt
8.3 Release
Name Role Release Department Location Tel. Comment
Date
8.4 Glossary
PascalCasing casing format
OS Operating System
RTTI Runtime Type Information
RTIL Runtime Innovation Line
SWAT Software architecture team
HMI Human-machine interface
PL Project manager (Projektleiter)
TPL Subproject manager (Teilprojektleiter)
CM Configuration management
RAII Resource Acquisition Is Initialization – a method to put functions,
which have to grab system resources, into class concepts.