Большой аргумент передачи значением

Большой аргумент передается значением между функциями

Описание

Большой аргумент передачи значением происходит, когда большой входной параметр или возвращаемое значение передаются между функциями его значением.

Риск

Копия значением создает копию аргумента в теле функции. Если аргумент является большим, его копия израсходовала существенную часть стекового пространства, доступного функции. Копия может также значительно увеличить время выполнения.

Специальные замечания для возвращаемых значений: В коде С, когда функция возвращается значением, возвращаемое значение копируется в вызывающую сторону. Поэтому этот дефект появляется на функциях, которые имеют большие возвращаемые значения. В Коде С++, если функциональное возвращаемое значение имеет тип класса при определенных обстоятельствах, стандарт позволяет компиляторам стараться не копировать возвращаемое значение (C++ 98: Разделите 12.8, Пункт 15; C++ 11: Разделите 12.8, Пункт 31). Большинство компиляторов не выполняет копию в таких случаях. Это поведение называется оптимизацией возвращаемого значения. В таких случаях Polyspace® Bug Finder™ не производит этот дефект, если большой объект возвращен значением.

Фиксация

Для переменных, больше, чем 64 байта, передайте значение указателем или ссылкой. Для структурированных переменных можно также осуществить рефакторинг тип переменной так, чтобы только некоторые участники были скопированы.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.

Примеры

развернуть все

typedef struct s_userid {
    char name[2];
    int idnumber[100];
} userid;

char username(userid first) {
    return first.name[0];
}

Большая структура, userid, передается функциональному username. Поскольку userid больше, чем 64 байта, эта функция производит большой дефект передачи значением.

Исправление — передает ссылкой

Одно возможное исправление должно передать аргумент ссылкой вместо значением. В этом исправленном примере указатель на структуру userid передается вместо фактической структуры.

typedef struct s_userid {
    char name[2];
    int idnumber[100];
} userid;

char username(userid *first) {
    return (*first).name[0];
}
#include <stdlib.h>

#define initialSize 4
#define idSize 100

typedef struct {
    char initials[initialSize];
    int id[idSize];
} userId;

userId* getAddress(void);
assignValues(char*, int*);

userId username(void) {
    userId * newId = getAddress();
    assignValues((*newId).initials, (*newId).id);
    return *newId;
}

В этом примере функциональный username возвращает большую структуру *newId значением. Когда вызовы функции username, значение в *newId копируется в вызывающую сторону.

Исправление — передает ссылкой

Одно возможное исправление должно возвратить большую структуру ссылкой. В этом исправленном примере указатель, чтобы структурировать newId возвращен в функциональный username.

#include <stdlib.h>

#define initialSize 4
#define idSize 100

typedef struct {
    char initials[initialSize];
    int id[idSize];
} userId;

userId* getAddress(void);
assignValues(char*, int*);

userId * username(void) {
    userId * newId = getAddress();
    assignValues((*newId).initials, (*newId).id);
    return newId;
}

Проверяйте информацию

Группа: Хорошая практика
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: PASS_BY_VALUE
Влияние: низко

Введенный в R2013b