Передача и возврат структур по значению или по указателю - есть ли рекомендации по умолчанию?

Итак, я искал практические рекомендации по двум темам:

  • Когда возвращать структуру по значению, а когда возвращать ее по указателю (в случае, когда вызываемая функция создала структуру). Например:
MyThing make_my_thing() { MyThing m; /* ... */ ; return m; }
// Vs.
MyThing* make_my_thing() { MyThing* m = malloc(sizeof(MyThing)); /* ... */ ; return m; }
  • Когда передавать структуру по значению, а когда - по указателю
// Assume do_something() doesn't need to mutate m
void do_something(MyThing m) { /* ... */ }  
// Vs.
void do_something(MyThing* m) { /* ... */ }

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

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

Я прочитал много вопросов и ответов на этом сайте и разработал следующие рекомендации:

  • По умолчанию используется возврат структуры по значению. В противном случае нам пришлось бы malloc это сделать и возиться с управлением его жизненным циклом.
  • По умолчанию используется передача структуры по указателю - не нужно беспокоиться об управлении жизненным циклом больше, чем мы уже делаем, и нет ненужного копирования данных.

Широко ли приняты эти рекомендации среди программистов на C? Если нет, какие соглашения будут более общепринятыми?


person Aviv Cohn    schedule 24.04.2019    source источник
comment
Передача struct любого размера по значению - это большой мертвый груз.   -  person Weather Vane    schedule 25.04.2019
comment
@WeatherVane Не согласен. Передача struct, который маленький, может быть, даже меньше указателя, не является мертвым грузом.   -  person chux - Reinstate Monica    schedule 25.04.2019
comment
@chux конечно. Мое выделение должно было быть любого размера, а не любого размера.   -  person Weather Vane    schedule 25.04.2019


Ответы (1)


Передача и возврат структур по значению или по указателям.

1) Маленький размер. Когда struct маленький - я бы сказал, ‹= в два раза больше размера указателя, мало что можно потерять с точки зрения размера, когда передается struct по значению, а не по указателю на struct. Достигнута простота передачи объекта по значению.

2) Большой размер. Когда struct большой, безусловно, передача pointer to astruct более эффективна.

3) Числовой объект. Когда struct имеет выделение фиксированного размера и представляет собой число, передача по значению, кажется, работает лучше.

4) Скрытие. Непрозрачные точки на struct - хороший способ скрыть внутренности struct и продвигать объектно-ориентированный код.

В других случаях я бы сказал код для ясности, что обычно означает использование указателя на struct как на идиоматику C.


Для общего использования я нахожу перенастройку указателя на struct с малым значением - кроме одного важного случая: формирование набора функций, в которых функция (и) init возвращает выделенный указатель на struct.

person chux - Reinstate Monica    schedule 25.04.2019
comment
Спасибо за ответ. Итак, насколько я понимаю, о чем вы говорите, мы должны передавать struct по значению, когда они маленькие или представляют собой какое-то скалярное числовое значение. В противном случае переходите по указателю. Это ваша точка зрения? - person Aviv Cohn; 25.04.2019
comment
@AvivCohn Это хороший вывод первого порядка. Тем не менее, это не жесткое правило, поскольку обстоятельства время от времени будут подталкивать к другому или, возможно, другим подходам. - person chux - Reinstate Monica; 26.04.2019