Вопрос

У меня есть функция, которая принимает беззнаков с длинными * и должна передавать его в внешнюю библиотеку, которая требует unsigned int *, а на этой платформе int / 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 ++.

Это было полезно?

Решение

void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}

Другие советы

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

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top