>
>
>
V1069. Do not concatenate string litera…


V1069. Do not concatenate string literals with different prefixes.

The analyzer found a code fragment where two concatenated strings have different encoding prefixes.

Take a look at this example:

// Until C99/C++11
L"Hello, this is my special "
 "string literal with interesting behavior";

Prior to the C11/C++11 standards, C and C++ provided only two kinds of string literals:

  • a "narrow" string literal - " s-char-sequence "
  • a "wide" string literal - L" s-char-sequence "

In languages prior to C99 or C++11, concatenating string literals with different prefixes leads to undefined behavior. This triggers the analyzer to issue a first-level warning. Below is the correct code:

// Until C99/C++11
L"Hello, this is my special "
L"string literal with defined behavior";

Starting with C99 and C++11 this behavior is defined. If one of string literals has a prefix, and the second one does not, the resulting string literal has the first string's prefix. In this case the analyzer issues no warnings:

// Since C99/C++11
L"Hello, this is my special "
 "string literal with "
 "defined behavior";

C11/C++11 and newer language versions provide three more prefixed string literals:

  • UTF-8 string literal - u8" s-char-sequence "
  • 16-bit wide string literal - u" s-char-sequence "
  • 32-bit wide string literal - U" s-char-sequence "

Concatenating UTF-8 and any "wide" string literal leads to a compile-time error. In this case the analyzer does not issue a warning.

L"Hello, this is my special "
u8"string literal that won't compile"; // compile-time error

Any other combinations of prefixed string literals lead to undefined behavior. In these cases, the analyzer issues second-level warnings:

// Until C11/C++11
L"Hello, this is my special "
u"string literal with implementation-defined behavior";

L"Hello, this is my special "
U"string literal with implementation-defined behavior";

u"Hello, this is my special "
U"string literal with implementation-defined behavior";

When one "narrow" string literal is concatenated with two or more prefixed string literals, the analyzer issues third-level warnings:

template <typename T>
void foo(T &&val) { .... }
....
void bar()
{
  foo("This" L"is" "strange");
  foo(L"This" "is" L"strange");
}

Though in modern standards this behavior is defined, such code cultivates errors and we recommend refactoring.