Зачем использовать C typedefs вместо #defines?

В чем преимущество (если есть) использовать typedef вместо #define в C-коде?

В качестве примера можно ли использовать

typedef unsigned char UBYTE

над

#define UBYTE unsigned char

когда оба могут использоваться как

void func()
{
        UBYTE byte_value = 0;

        /* Do some stuff */

        return byte_value;
}

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

Ответ 1

Если вы делаете typedef типа массива, вы увидите разницу:

typedef unsigned char UCARY[3];
struct example { UCARY x, y, z; };

Выполняя это С#define... нет, не помещайте туда.

[EDIT]: Еще одно преимущество заключается в том, что отладчики обычно знают о typedefs, но не #defines.

Ответ 2

Ну, исходя из С++, перспектива, программист на С++, использующий ваш код, может иметь что-то вроде:

template<typename T> class String
{
     typedef T char_type;
     // ...
};

Теперь, если в вашем коде на C вы написали что-то вроде:

#define char_type uint32_t // because I'm using UTF-32

Хорошо, вы будете создавать серьезные проблемы для пользователей вашего файла заголовка. С помощью typedefs вы можете изменить значение typedef в разных областях... в то время как области не соблюдаются С#defines.

Я знаю, что вы отметили этот C, но программисты C и программисты на С++ должны понимать, что их заголовки могут использоваться друг другом... и это одна из тех вещей, которые нужно иметь в виду.

Ответ 3

С #define все, что вы получаете, это подстановка строк во время предварительной обработки. typedef вводит новый тип. Это облегчает поиск возможных проблем в вашем коде, а в случае компилятора может быть предоставлена ​​более подробная информация.

Ответ 4

1) Вероятно, большим преимуществом является более чистый код. Обычно злоупотребление макросами преобразует код в недостижимый беспорядок, известный как "макрос суп".

2) С помощью typedef вы определяете новый тип. Используя макрос, вы фактически заменяете текст. Компилятор, безусловно, более полезен при работе с ошибками typedef.

Ответ 5

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