Main Content

AUTOSAR C++14 Rule A27-0-4

C-style strings shall not be used

Since R2021a

Description

Rule Definition

C-style strings shall not be used.

Rationale

The underlying character array that stores a C-style string has many disadvantages such as:

  • You must explicitly handle memory allocation and deallocation if you perform operations on the string that require non-trivial memory manipulations.

  • It is not always clear whether a char* points to a single character or to a C-style string.

  • You might accidentally convert an array to a raw pointer when you pass it by value or by pointer to a function, which results in a loss of information about the array size (array decay). For example, in this code snippet, func prints the size of the pointer to the first character of cString (8) , while the actual size of cString is 6.

    void func(char *c){ //function takes array by value
      cout << sizeof(c);
    }
    
    void main(){
      char cString[]{ "pizza" }; //Size is 6 (5 characters + null terminator)
      func(cString); // Size is 8 (size of char*)
    }

Instead, use the std::string class to store a sequence of characters. The class handles allocations and deallocations, and instantiates an object that you can safely pass to functions. The class also has built-in functionalities to manipulate the string such as iterators.

Polyspace Implementation

Polyspace® flags the use of:

  • Pointers to char (char*) and arrays of char (char someArray[]).

  • Pointers to and arrays of char with a type qualifier such as volatile or const. For example char const*.

  • Pointers to and arrays of type wchar_t, char16_t, and char32_t.

If you have a function declaration and its definition in your source code, Polyspace places the violation on the function definition. For example:

const char* greeter(void);
//....
const char* greeter(void){ //Non-compliant
  return "Hello"; 
}

Polyspace does not flag the use of:

  • Pointers to or arrays of signed or unsigned char. For example, signed_c and unsigned_arr are not flagged in this code snippet:

    signed char* signed_c;
    unsigned char unsigned_arr[2048];

  • Literal strings. For example, the return value of greeter() is not flagged in this code snippet, but the use of const char* in the first line is flagged:

    const char* greeter(void){ //Non-compliant
      return "Hello"; // Compliant
    }

  • The parameters of main().

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include<iostream>
#include <string>
#include<cstring>

char* sub_c_str(   //Non-compliant
    const char* str1, const int delim)  //Non-compliant
{
    size_t index {strlen(str1)};
    if (strchr(str1, delim)) {
        index = (size_t)(strchr(str1, delim) - str1);
    }
    char* p = (char*) malloc(index + 1); //Non-compliant
    //memory leak if p is not freed by caller
    strncpy(p, str1, index);
    return p;

}

std::string sub_str(std::string const str2, const char delim)
{
    return str2.substr(0, str2.find(delim));
}

int main()
{
    const char str1[] { "rootFolder/subFolder"}; // Non-compliant
    std::cout << sub_c_str(str1, '/') << std::endl;

    std::string const str2 { "rootFolder/subFolder" };
    std::cout << sub_str(str2, '/') << std::endl;
    return 0;
}

In this example, function sub_c_str returns a substring of C-style string parameter str1 up to but not including the first instance of delim. The return type and first parameter of sub_c_str are both non-compliant pointers to char. Pointer p, which stores the substring, is also non-compliant. Note that if you do not free the memory allocated to p before the end of the program, this results in a memory leak.

Function sub_str takes advantage of the std::string class to perform the same operation as sub_c_str. The class handles memory allocation and deallocation. The class also has built-in functionalities (find and subst) to perform the string manipulation.

Check Information

Group: Input/output library
Category: Required, Automated

Version History

Introduced in R2021a