Вернуть «тип данных» в C - PullRequest
0 голосов
/ 03 марта 2020

Я хочу иметь простой

something Data() {
    return int;
}

или использовать char, long ... w / e

Как бы я go об этом?

Я не хочу возвращать число или строку, я хочу вернуть тип данных

Другой вариант, который я пробовал, - это использовать макрос

#define Data int

и использовать различные if и иначе, я мог бы использовать это вместо этого, но я не могу использовать указатели в макросах, так что это тоже проблема (мне нужно возвращать тип данных на основе числа, сохраненного в указателе).

Здесь это именно та проблема, с которой я столкнулся, и то, что я сделал до сих пор:

//Read/write any type from memory
#define MemRead(type, offset) (*((type*)(memory + (offset))))
#define MemSet(type, offset, value) (*((type*)(memory + (offset))) = (value))

//Get the index for type (0 - char, 1 - short, 2 - int ...)
#define TypeIndex (MemRead(unsigned short, 0) % 4)
//#if TypeIndex == 0
//#define TYPE char
//#elif TypeIndex == 1
//#define TYPE short
//#endif

//#define TYPE SOMETHING HERE maybe an if-else ...
//#if TypeIndex == 0 doesn't work, because I can't use * in macros

char *memory = NULL;

void memory_init() {

    memory = (char*)ptr;

    //Create a list of pointers
    int numOfPointers = 1, tsize = size - 3 * IntSize - START;
    while (tsize > 64) {
        tsize /= 4;
        MemSet(int, numOfPointers++ * IntSize - 3, 0);
    }

    int typeIndex = 0;
    if (size < power(2, (sizeof(short) * 8) - 1)) {
        typeIndex = 1;
    }
    else if (size < power(2, (sizeof(int) * 8) - 1)) {
        typeIndex = 2;
    }
    else {
        typeIndex = 3;
    }

    MemSet(unsigned char, 0, numOfPointers * 4 + typeIndex);
    MemSet(int, HEADER - IntSize, 0);

    int memAvailable = size - HEADER - 3 * IntSize;
    setBoundaries(HEADER + IntSize, memAvailable, memAvailable);
    MemSet(int, size - IntSize, 0);

    //Set beginning pointer
    MemSet(int, HEADER - IntSize, HEADER + IntSize);

    //Set pointers inside the free block
    MemSet(int, HEADER + IntSize, NULL);
    MemSet(int, HEADER + 2 * IntSize, HEADER - IntSize);
}


int main() {

    char region[500];
    memory_init(region, 500);
}

Я получил немного места в памяти, установил первый символ в качестве индекса, показывающего, какой тип данных я буду использовать и сколько указателей там будут списки (каждый список содержит свободные блоки разных размеров), и я не могу получить тип из TYPE.

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

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

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

void MemRead(int offset) {
    switch(flag something something) {
        case 1 //for char
        case 2 //for short etc etc
    }
}

Легко как то

0 голосов
/ 03 марта 2020

Вы не можете делать то, что хотите, без выбора switch или эквивалентной конструкции. В C типы данных не могут передаваться, как в примере в Java. Там нет отражения. C ++ имеет RTTI, который может помочь, или шаблоны, но с их использованием генерируется весь необходимый машинный код за кулисами. И вы явно попросили решение C. C является языком низкого уровня по сравнению с его преемниками.

Лучшей ставкой будет функция, которая получает все необходимые параметры и устанавливает соответствующий объем памяти.

Под Я уверен, что те языки, которые поддерживают то, что вы хотите, будут отправлять в другой код. Вам просто не нужно писать все строки.

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

Как насчет использования объединения? Компилятор позаботится о том, чтобы ваши типы данных были правильно выровнены.

typedef enum {
    T_CHAR, T_SHORT, T_INT,
} TYPE;

typedef struct {
    TYPE t;
    union {
        char c;
        short s;
        int i;
    }
} ENTRY;

void memory_init(ENTRY* memory) {
    // prepare as you like
    switch (memory.t) {
    case T_CHAR:
        memory.c = value;
        break;
    case T_SHORT:
        memory.s = value;
        break;
    case T_INT:
        memory.i = value;
        break;
    default:
        // error handling...
        break;
    }
}
...