Кастинг между структурами? - PullRequest
2 голосов
/ 06 ноября 2008

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

typedef struct {
    unsigned int hi, lo;
} int64;

Чтобы сделать этот тип полезным, все общие операции определены как функции, такие как

int64 int64_add(int64 x, int64 y);

На платформах, где доступен собственный 64-битный целочисленный тип, эти операции просто выглядят как

#define int64_add(x, y) ((x) + (y))

Во всяком случае, на вопрос. Я реализую некоторые функции, касающиеся времени, и я хочу представить свое время, используя 64-разрядное целое число:

typedef int64 mytime;

Я также хочу, чтобы все общие операции, доступные для типа int64, были доступны для моего типа времени:

#define mytime_add(x, y) (mytime) int64_add((int64) (x), (int64) (y))

Проблема в том, что приведение между типами mytime и int64 не разрешено в C (насколько я могу судить, так или иначе). Есть ли способ сделать это без переопределения всех функций add, sub, mul, div и т.д. для типа mytime?

Один из вариантов, конечно, никогда не делать typetime по умолчанию в mytime и просто использовать int64 везде, где мне нужно представлять время. Проблема в том, что я не уверен, всегда ли я хочу представлять время как 64-битное целое число. Также существует проблема читаемого кода ...: -)

Ответы [ 5 ]

4 голосов
/ 06 ноября 2008

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

#define mytime_add(x, y) int64_add((x), (y))

или если ваш компилятор C достаточно хорош для встраивания:

mytime mytime_add(mytime x, mytime y) { return int64_add(x, y); }
3 голосов
/ 06 ноября 2008

Тебе действительно нужен актерский состав? gcc компилирует следующий пример без каких-либо жалоб:


typedef struct int64 int64;

struct int64
{
    unsigned int hi, lo;
};

typedef int64 mytime;

int64
add_int64(int64 a, int64 b)
{
    int64 c;
    /* I know that is wrong */
    c.hi = a.hi + b.hi;
    c.lo = a.lo + b.lo;

    return c;
}

int
main(void)
{
    mytime a = {1, 2};
    mytime b = {3, 4};
    mytime c;

    c = add_int64(a, b);

    return 0;
}
1 голос
/ 06 ноября 2008

Взгляните на заголовочный файл stdint.h. Он содержит int64_t, uint64_t и т. Д. Это стандартный и переносимый способ, и вы избежите необходимости реализовывать математические функции:).

1 голос
/ 06 ноября 2008

Вы можете попробовать:

#define mytime int64

Вместо typedef.

Похоже, что вы получите прозрачное преобразование и удобство обслуживания, которое вы ищете.

0 голосов
/ 07 ноября 2008

Правильно, поэтому я использую typedefs, а не кастинг. Работает отлично. Кажется странным, что явное приведение не компилируется, а неявное приведение. Если неявное приведение на самом деле не приведение вообще, так как компилятор видит два типа как один и тот же тип, можно подумать, что при выполнении явного приведения будут работать одинаковые рассуждения ...

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