Возврат массива из функции BY VALUE и что происходит, когда вы возвращаете структуру?

Мой прием с использованием (слишком много?) словарей:

def serialize(_query):
#d = dictionary written to per row
#D = dictionary d is written to each time, then reset
#Master = dictionary of dictionaries; the id Key (int, unique from database) from D is used as the Key for the dictionary D entry in Master
Master = {}
D = {}
x = 0
for u in _query:
    d = u.__dict__
    D = {}
    for n in d.keys():
        if n != '_sa_instance_state':
            D[n] = d[n]
    x = d['id']
    Master[x] = D
return Master

Работа с флягой (включая jsonify) и flask_sqlalchemy для вывода на печать в виде JSON.

Вызвать функцию с помощью jsonify (serialize ()).

Работает со всеми запросами SQLAlchemy, которые я пробовал до сих пор (работает SQLite3)

-2
задан Galaxy 13 July 2018 в 05:12
поделиться

1 ответ

Точный механизм зависит от платформы. Но наиболее распространенным механизмом является то, что вызывающий абонент выделяет пространство в своем стеке для возвращаемой структуры и передает адрес этого пространства в качестве дополнительного аргумента, обычно перед всеми реальными аргументами.

На многих платформах, структуры, достаточно маленькие, чтобы вписаться в регистр, будут возвращены, как если бы они были единственным значением. Это применимо к x86-64 для структуры, состоящей из двух 32-разрядных int s, поскольку они могут быть возвращены в одном 64-битном регистре. Как большая структура может быть обработана таким образом, будет варьироваться от платформы к платформе.

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

struct MyThingy blob = blobMaker();

, компилятор, скорее всего, передаст blobMaker адрес переменной blob вместо выделения временной переменной, а затем скопирует временное значение в blob после функция возвращается. Вызываемая функция также может избежать копирования:

struct MyThingy blobMaker(void) {
  struct MyThingy retval;
  // ...
  retval.member1 = some_calc(42);
  // ...
  retval.member2 = "Hello";
  // ...
  return retval;

Здесь компилятор мог бы не выделять retval в стек стека вызываемой функции, а вместо этого просто использовать хранилище, переданное в невидимом аргумент напрямую, тем самым избегая копирования на return. Комбинация этих двух оптимизаций (когда это возможно) делает возвращающие структуры почти бесплатными.

Стандарт C ++ обеспечивает эти оптимизации, явно разрешая их даже в тех случаях, когда разрешенные копии могли вызвать побочные эффекты в копии объекта конструктор. (Очевидно, этот случай не существует в C.)

0
ответ дан rici 17 August 2018 в 13:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: