Мне пришлось испытать (еще одно) - для меня - неожиданное C поведение, на этот раз с sizeof
.
Моя цель - попытаться понять причины этого поведения и то, как я должен решить это. Меня не очень интересуют альтернативные решения, так как моя главная цель - понять, что здесь происходит и почему.
У меня есть строка, определенная с помощью макроса -процессора #define
- C (#define CONST "foobar"
) и использовать его в таких функциях, как:
senddata(uint8_t * data, uint32_t len)
.
Поскольку - в зависимости от реализации / архитектуры, но, по крайней мере, для x86 - по умолчанию подписывается char, я получаю предупреждение о «отличии [ence] в подписи», когда он называется так:
senddata(CONST, sizeof(CONST))
.
Так что мне придется разыграть его (senddata((uint8_t *)CONST, sizeof(CONST))
) на каждый senddata
- invocation.
Поскольку все случаи использования CONST в моем коде на самом деле будут приводиться к uint8_t
, я решил, что просто изменю определение:
#define CONST "foobar"
-> #define CONST ((uint8_t *)"foobar")
и больше не нужно беспокоиться о дальнейшем касте.
Хотя это действительно удаляет предупреждение, и все выглядит хорошо, мне пришлось изучить сложный путь, который в этих случаях sizeof () на самом деле больше не возвращает длину строки, а размер типа данных, в данном случае uint8_t *
.
Мне это не кажется очевидным.
Поэтому мой вопрос сложен в 2 раза:
- 1) Как бы Я делаю это правильно в приведенном выше сценарии?
- 2) Почему это так?
- 3) Как бы я мог узнать об этом? Это не означает (пассивно) агрессивно, а скорее: с каким предварительным знанием я должен был прийти к выводу, что это не работает таким образом?
Некоторая половина знаний, которые я выбрал где-то, что может сыграть в это, но я не совсем уверен, что из этого получится: sizeof () - это не обычная функция, а оператор (например, sizeof int
работает без скобок).
Еще одно предположение у меня: "foobar"
- массив символов, а (char *)"foobar"
- указатель.