Main Content

Inefficient use of sprintf

The function sprintf, snprintf, or swprintf copies strings instead of the more efficient strcpy, strncopy, or wcsncpy

Since R2021b

Description

This checker is triggered when you use sprintf, snprintf, or swprintf to copy strings.

Risk

The functions sprintf, snprintf, or swprintf are complex function with a variable argument list. Before executing these functions, the compiler parses the argument list to determine the argument types, which adds overhead to the code. Handling the different input formats that these functions support makes the function difficult to optimize. For instance, even if you want to copy only strings by using sprintf, the function must still support copying integers. Using these functions for copying strings make your code inefficient.

Fix

To fix this defect, refactor your code and use dedicated functions such as strcpy, strcat, strncopy, wcsncpy or their variants to copy strings.

Performance improvements might vary based on the compiler, library implementation, and environment that you are using.

Examples

expand all

#include <string.h>
#include <stdio.h>
#include <stddef.h>

void foo(char* p1, const char* p2, const char* p3, size_t N){
	//...
	sprintf(p1, "%s", p2); //Defect
	sprintf(p1, "%s", "String");//Defect
	sprintf(p1, "NoFormatting"); //Defect
	sprintf(p1, ""); //Defect
	sprintf(p1, "%s%s", p2, p3);//Defect
	snprintf(p1, N, "%s", p2); //Defect
	snprintf(p1, N, p2);//Defect
}

void foo_w(wchar_t* w1, const wchar_t* w2, size_t N){
	swprintf(w1, N, L"%s", w2); //Defect
	swprintf(w1, N, w2);  //Defect 
}


void bar(char* p1, const char* p2, const char* p3){
	sprintf(p1, "%d", 5);//No Defect
	sprintf(p1, "%s%d", "String", 123);//No Defect
	int n = sprintf(p1, "%s", p2);//No Defect
}

In this example, the C strings p2 and p3 are copied into p1 by calling sprintf and snprintf. Polyspace® flags these inefficient copying. In the function, foo_w, the wide string w2 is copied into w1 by calling swprintf. Polyspace flags the inefficient copying. In the function bar, sprintf is called for formatting strings. When you use sprintf for formatting strings or use the return value of the function, Polyspace does not flag the call as inefficient.

Correction

To fix this defect, use dedicated string copying functions such as strcpy, strncopy, or wcsncpy.

#include <string.h>
#include <stdio.h>
#include <stddef.h>

void foo(char* p1, const char* p2, const char* p3, size_t N){
	//...
	strcpy(p1, p2); //Compliant
	strcpy(p1, "String");//Compliant
	strcpy(p1, "NoFormatting"); //Compliant
	*p1 = '\0';//Compliant
	strcpy(p1, p2); //Compliant
	strcat(p1, p3);//Compliant
	strncpy(p1, p2, N);//Compliant
	
}

void foo_w(wchar_t* w1, const wchar_t* w2, size_t N){
	wcsncpy(w1, w2, N);//Compliant 
}

Result Information

Group: Performance
Language:C | C++
Default: Off
Command-Line Syntax: INEFFICIENT_SPRINTF
Impact: Medium

Version History

Introduced in R2021b