-
Type:
Code Smell Detection
-
Status: Active
-
Resolution: Unresolved
-
Labels:
-
Message:Replace this call to the non-reentrant "{0}" with a call to "{0}_r"
-
List of parameters:
-
Default Severity:Blocker
-
Impact:High
-
Likelihood:High
-
Default Quality Profiles:Sonar way
-
Legacy Key:NonReentrantFunction
-
Covered Languages:C, C++, Objective-C
-
Remediation Function:Constant/Issue
-
Constant Cost:30min
-
CPPCheck:nonreentrantFunctions.*
A function is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.
It is especially important that multi-threaded applications do not call the same non-reentrant function from different threads.
This rule will trigger an issue each time a function in the configurable list is invoked.
Noncompliant Code Example
Given a function that includes localtime:
#include <stdio.h> #include <time.h> void print_date_and_time(struct tm *time_ptr) { printf( "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n", time_ptr->tm_year + 1900, time_ptr->tm_mon, time_ptr->tm_mday, time_ptr->tm_hour, time_ptr->tm_min, time_ptr->tm_sec); } void print_unix_epoch_date_and_time() { time_t unix_epoch_time = (time_t)0; struct tm *local_time_ptr = localtime(&unix_epoch_time); // Noncompliant, call to the non-reentrant localtime() function print_date_and_time(local_time_ptr); } int main(int argc, char* argv[]) { time_t current_time; struct tm *local_time_ptr; time(¤t_time); local_time_ptr = localtime(¤t_time); // Noncompliant, call to the non-reentrant localtime() function // As expected, this will print: Current date and time: 1970/00/01 01:00:00 print_unix_epoch_date_and_time(); // This will actually also print Current date and time: 1970/00/01 01:00:00 // Indeed, localtime() is non-reentrant, and always returns the same pointer print_date_and_time(local_time_ptr); return 0; }
Compliant Solution
#include <stdio.h> #include <time.h> void print_date_and_time(struct tm *time_ptr) { printf( "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n", time_ptr->tm_year + 1900, time_ptr->tm_mon, time_ptr->tm_mday, time_ptr->tm_hour, time_ptr->tm_min, time_ptr->tm_sec); } void print_unix_epoch_date_and_time() { time_t unix_epoch_time = (time_t)0; struct tm local_time; localtime_r(&unix_epoch_time, &local_time); // Compliant print_date_and_time(&local_time); } int main(int argc, char* argv[]) { time_t current_time; struct tm local_time; time(¤t_time); localtime_r(¤t_time, &local_time); // Compliant // As expected, this will print: Current date and time: 1970/00/01 01:00:00 print_unix_epoch_date_and_time(); // As expected, this will print the current date and time print_date_and_time(&local_time); return 0; }
1.
|
C-Family | RSPEC-4379 |
|
Active | Unassigned |