Accessing object with temporary lifetime

Операции чтения или записи объекта являются неопределенным поведением

Описание

Этот дефект возникает при попытке чтения или записи объекта с временным временем жизни, который возвращается вызовом функции. В структуре или объединении, возвращенном функцией и содержащем массив, представители массива являются временными объектами. Срок жизни временных объектов заканчивается:

  • Когда полное выражение или полный декларатор, содержащий вызов, заканчивается, как определено в C11 Standard.

  • После следующей точки последовательности, как определено в C90 и C99 стандартах. Точка последовательности является точкой выполнения программы, где все предыдущие вычисления завершены, и последующая оценка еще не началась.

Для кода С++ объект Accessing с временным временем жизни поднимает дефект только тогда, когда вы записываете в объект с временным временем жизни.

Если временный объект жизни возвращается по адресу, дефект не возникает.

Риск

Изменение объектов с временным временем жизни является неопределенным поведением и может вызвать ненормальное завершение программы и проблемы переносимости.

Зафиксировать

Присвойте объект, возвращенный из вызова функции, локальной переменной. Содержимое объекта временного срока службы копируется в переменную. Теперь вы можете изменять его безопасно.

Примеры

расширить все

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

/* func_temp() returns a struct value containing
* an array with a temporary lifetime.
*/
int func(void) {
 
/*Writing to temporary lifetime object is
 undefined behavior
 */
    return ++(func_temp().a[0]); 
}

void main(void) {
    (void)func();
}

В этом примере func_temp() возвращает по значению структуру с представителем массива a. У этот представитель есть временное время жизни. Его увеличение является неопределенным поведением.

Коррекция - Присвоение возвращенного значения локальной переменной перед записью

Одной из возможных коррекций является назначение возврата вызова func_temp() в локальную переменную. Содержимое временного объекта a копируется в переменную, которую можно безопасно увеличить.

 #include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

int func(void) {

/* Assign object returned by function call to 
 *local variable
 */
    struct S_Array s = func_temp(); 

/* Local variable can safely be
 *incremented
 */
    ++(s.a[0]);                                           
    return s.a[0];
}

void main(void) {
    (void)func();
}

Информация о результатах

Группа: Программирование
Язык: C | C++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : TEMP_OBJECT_ACCESS
Влияние: Низкое
ИДЕНТИФИКАТОР CWE: 825
Введенный в R2018a