Представление динамического контроля типов в C

В ее основе две модели о Разделении Проблем. Я хочу, чтобы мое Представление отделалось единственной Модели. Я хочу, чтобы моя Модель предметной области представила концептуальную модель, которую я создаю со специалистами по проблемной области. ViewModel часто имеет технические ограничения. Модель предметной области о ПОСТЕПЕННО, и не быть связанным техническими ограничениями или данных, показанных (Представление), или сохранилась (в DB или иначе).

предположим у меня есть три объекта, показанные на экране. Это означает, что я должен вызвать отношения между тремя? Или просто создайте объект компонента ViewModel, который содержит все три объекта. С отдельным ViewModel проблемы Представления разделяются от моего домена.

12
задан Imagist 28 September 2009 в 07:52
поделиться

5 ответов

См. Python PEP 3123 ( http://www.python.org/dev/peps/pep-3123/ ), чтобы узнать, как Python решает эту проблему с использованием стандартного C. Решение Python можно напрямую применить к вашей проблеме. По сути, вы хотите сделать следующее:

struct Object { struct Class* class; };
struct Integer { struct Object object; int value; };
struct String { struct Object object; size_t length; char* characters; };

Вы можете безопасно преобразовать Integer * в Object * и Object * в Integer * если вы знаете, что ваш объект является целым числом.

6
ответ дан 2 December 2019 в 06:45
поделиться

C дает вам достаточные гарантии, что ваш первый подход будет работать. Единственное изменение, которое вам нужно сделать, - это то, что для того, чтобы псевдоним указателя был в порядке, вы должны иметь в области видимости union , который содержит все структуры struct , между которыми вы выполняете приведение:

union allow_aliasing {
    struct Class class;
    struct Object object;
    struct Integer integer;
    struct String string;
};

(Вам не нужно когда-либо использовать объединение для чего-либо - он просто должен входить в область действия)

Я считаю, что соответствующая часть стандарта такова:

[# 5] За одним исключением, если значение члена объединенного объекта используется когда самый последний магазин в объект был к другому члену, поведение определяется реализацией. На заказ предоставляется одна специальная гарантия для упрощения использования союзов: если union содержит несколько структур, которые имеют общую начальную последовательность (см. ниже), и если объект объединения в настоящее время содержит один из этих конструкции, разрешено осматривать общая начальная часть любого из них везде, где декларация законченный вид союза видимый. Две структуры имеют общий начальная последовательность, если соответствует члены имеют совместимые типы (и, для битовых полей одинаковой ширины) для последовательность одного или нескольких начальных члены.

(Это не напрямую говорит, что это нормально, но я считаю, что это действительно гарантирует, что если две struct имеют общую начальную последовательность и помещены в объединение вместе, они будут размещены в памяти таким же образом - во всяком случае, это определенно было идиоматическим C долгое время предполагать это).

7
ответ дан 2 December 2019 в 06:45
поделиться

В разделе 6.2.5 ISO 9899: 1999 (стандарт C99) говорится:

Тип структуры описывает последовательно выделенный непустой набор объектов-членов (и, в определенных обстоятельствах, неполный array), каждый из которых имеет необязательно указанное имя и, возможно, отдельный тип.

Раздел 6.7.2.1 также говорит:

Как обсуждалось в 6.2.5, структура - это тип, состоящий из последовательности членов, хранилище которых выделяется в упорядоченной последовательности, а объединение - это тип, состоящий из последовательности элементов, хранилище которых перекрывается.

[...]

Внутри объекта структуры, элементы небитового поля и единицы, в которых битовые поля проживают имеют адреса, увеличивающиеся в порядке их объявления. Указатель на объект структуры, преобразованный соответствующим образом, указывает на свой начальный член (или, если этот член является bit-field, затем к модулю, в котором оно находится), и наоборот. Может быть безымянный заполнение внутри объекта структуры, но не в его начале.

Это гарантирует то, что вам нужно.

В вопросе, который вы говорите:

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

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

Но на другой платформе struct String Integer может хранить значение перед классом и когда я обращался к классу foo-> в приведенном выше Я бы действительно получил доступ к foo-> value, что, очевидно, плохо. Переносимость здесь является большой целью.

Ни один совместимый компилятор не может этого сделать. [ Я заменил String на Integer, предполагая, что вы имели в виду первый набор объявлений. При ближайшем рассмотрении Вы могли иметь в виду структуру со встроенным объединением. Компилятору по-прежнему не разрешено переупорядочивать класс и значение . ]

3
ответ дан 2 December 2019 в 06:45
поделиться

Проблема в том, что, насколько мне известно, стандарт C не дает никаких обещаний относительно того, как хранятся структуры. На моей платформе это работает. Но на другой платформе struct String может хранить значение перед class , и когда я получу доступ к foo-> class в приведенном выше примере, я действительно буду доступ к foo-> value , что явно плохо. Переносимость - большая цель здесь.

Я считаю, что вы ошибаетесь. Во-первых, потому что ваша структура struct String не имеет члена value . Во-вторых, потому что я считаю, что C действительно гарантирует размещение в памяти членов вашей структуры. Вот почему следующие разные размеры:

struct {
    short a;
    char  b;
    char  c;
}

struct {
    char  a;
    short b;
    char  c;
}

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

2
ответ дан 2 December 2019 в 06:45
поделиться

Я ценю педантичные проблемы, поднятые этим вопросом и ответами, но я просто хотел упомянуть, что CPython использовал аналогичные приемы «более или менее навсегда» и десятилетиями работал с огромным разнообразием. компиляторов C. В частности, см. object.h , макросы типа PyObject_HEAD , структуры типа PyObject : все виды объектов Python (ниже уровня C API) получают указатели на их навсегда бросать туда и обратно в / из PyObject * без какого-либо ущерба. Прошло некоторое время с тех пор, как я в последний раз играл в морского юриста со стандартом ISO C, до такой степени, что у меня нет под рукой копии (!), Но я действительно считаю, что там есть некоторые ограничения, которые должны заставить это работать, как это было почти 20 лет ...

2
ответ дан 2 December 2019 в 06:45
поделиться
Другие вопросы по тегам:

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