Приведение, которое нарушает правила строгого наложения имен - PullRequest
6 голосов
/ 21 сентября 2010

У меня есть функция, которая принимает unsigned long * и должна передать ее во внешнюю библиотеку, которая принимает unsigned int *, а на этой платформе unsigned int / long имеют тот же размер.

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

Это генерирует предупреждение о нарушении правил строгого наложения имен.Есть ли обходные пути?

Спасибо

Редактировать: Я прошу прощения за то, что не ясно.Код является атомарным обновлением, поэтому обходить библиотеку для его хранения не вариант.Я мог бы перейти к сборке, но я хотел бы сделать это в C ++.

Ответы [ 3 ]

8 голосов
/ 21 сентября 2010
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
2 голосов
/ 21 сентября 2010

Это должно работать:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
1 голос
/ 19 августа 2016

Ничто в стандарте C не предусматривает, что int и long должны иметь одинаковый размер;кроме того, даже если они имеют одинаковый размер, в Стандартных мандатах нет ничего такого, что они имеют одинаковое представление (среди прочего, они могли бы иметь несовместимые комбинации битов заполнения и представлений прерываний, так что совмещение имен между этими двумя типами не могло бы служить любомуполезная цель).

Авторы Стандарта не хотели навязывать разработчикам средства нацеливания на платформы, в которых псевдонимы между int и long не имели бы смысла распознавать такие псевдонимы.Они также не хотели писать правила, которые были бы применимы к некоторым платформам (те, где псевдонимы будут служить цели), но не к другим (те, где это не будет).Вместо этого они полагали, что люди, пишущие качественные компиляторы, будут пытаться распознавать псевдонимы в тех случаях, когда это было полезно.

Возможность использовать указатели на один 32-разрядный тип для чтения и записи значений другого 32-разрядного типа, которыйТакое же представление явно полезно, особенно если API разделены по типу, который они ожидают.Если некоторые обычные API на платформе используют int* для 32-битных значений, а другие используют long*, универсальная реализация quality для этой платформы должна позволять доступ к данным любого типа с помощью указателейдругой.

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

...