Как предотвратить продвижение типа при использовании двух или более шаблонов, когда в следующий раз он реализует предыдуC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как предотвратить продвижение типа при использовании двух или более шаблонов, когда в следующий раз он реализует предыду

Сообщение Anonymous »

Я пишу реализацию журнала C ++ для встроенной системы. Идея состоит в том, чтобы использовать шаблоны для объявления идентификатора сообщения (тип) и обеспечения соблюдения аргументов. Существуют ограничения, что код, который я пишу, генерируется, включен и используется на нескольких устройствах. Идея состоит в том, чтобы назвать функцию как: < /p>

Код: Выделить всё

Log(arg1, arg2...);
< /code>
Вот где я: < /p>
enum EventId_e {
EventId_OverVoltageWarning = 0x01,
EventId_OverCurrentWarning = 0x02,
EventId_HumidityAndTempRead = 0x03,
};

logging::LoggingInterface logger_interface; // Declare the device specific implementation for sending and populating time

template 
static void LogMessage(const Args&... args) {
std::array log_msg = {0};
uint8_t* current_ptr =
log_msg.data() + sizeof(uint32_t) + sizeof(uint8_t);  // Offset for time

uint8_t* arg_ptrs[] = {reinterpret_cast(
const_cast(static_cast(&args)))...};
size_t arg_sizes[] = {sizeof(Args)...};

logger_interface.PopulateMsgTime(log_msg); // Put time in log message (first 5 bytes)

for (size_t i = 0; i < sizeof...(args); ++i) {
std::memcpy(current_ptr, arg_ptrs[i], arg_sizes[i]);
current_ptr += arg_sizes[i];
}

logger_interface.SendLog(log_msg); // Send log message
}

template 
static void Log(Args... args) {
LogMessage(static_cast(args)...);
}

template 
void Log(
uint16_t MaxVoltage, uint16_t MinVoltage, int16_t PeakCurrent) {
LogMessage(MaxVoltage, MinVoltage, PeakCurrent);
}

template 
void Log(
uint16_t MaxVoltage, uint16_t MinVoltage, int16_t PeakCurrent) {
LogMessage(MaxVoltage, MinVoltage, PeakCurrent);
}

template 
void Log(uint8_t Humidity, int16_t Temperature) {
LogMessage(Humidity, Temperature);
}
< /code>
Проблема, с которой я сталкиваюсь, - это два раза: < /p>

[*] Во -первых, значение не применяется при вызове журнала < EventId> 
, например, я могу предоставить uint32_t , когда функция ожидает uint16_t , и нет никакого предупреждения или ошибки компиляции.
Во -вторых, если я не буду. t укажите или составьте конкретный тип аргумента. Аргумент будет продвигаться до Int32. < /li>
< /ul>
Вот пример рабочих вызовов: < /p>

Код: Выделить всё

Log(static_cast(3200), static_cast(2900), static_cast(4200));
< /code>
или < /p>
uint16_t max_voltage = 3200;
uint16_t min_voltage = 2900;
uint16_t peak_current = 4000;

Log(max_voltage, min_voltage, peak_current);
В вышеуказанном коде arg_sizes будет 2, а массив будет заполнен должным образом. : < /p>

Код: Выделить всё

Log(3200, 2900, 4000);
В вышеприведенном вызове значения получают int (32bit) и при попытке собрать сообщение журнала в logmessage arg_sies будет 4 вместо 2. Что, в свою очередь, будет Segfault Device, поскольку оно попытается записать в пространство, которое не используется для этого массива сообщений журнала. Обеспечение соблюдения номера и размера аргумента, а также их распространяются в logmessage.

Подробнее здесь: https://stackoverflow.com/questions/794 ... xt-one-imp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»