Хитрость заключается в том, чтобы изначально использовать массив uint32_t
соответствующего размера (он может быть выделен динамически, см. ниже мою первую идею, но не обязательно). К любому объекту можно получить доступ на уровне байтов, поэтому вы можете преобразовать это uint32_t *
в uint8_t *
и обработать его как символьный буфер: вы получаете доступ к исходному массиву uint32_t
на уровне байтов, что разрешено строгим правилом псевдонимов.
Когда вам понадобится uint32_t *
, просто откиньте назад. Поскольку вы получили доступ к исходному массиву только на уровне байтов, время жизни массива не закончилось, и uint32_t *
указывает на допустимый массив.
Старое и не очень хорошее решение
Хитрость здесь заключалась бы в том, чтобы выделить буфер с помощью malloc
. Стандарт C говорит в части, ссылающейся на стандартную библиотеку C, которая явно доступна из программы C++ (*): 7.20.3 Функции управления памятью
... Указатель, возвращаемый в случае успешного выделения, соответствующим образом выровнен, чтобы его можно было назначить указателю на объект любого типа, а затем использовать для доступа к такому объекту или массиву таких объектов в выделенном пространстве...
Это означает, что при условии, что buffer
является возвращаемым значением вызова malloc
, стандарт гарантирует, что его можно безопасно привести к любому другому типу указателя.
Если вы этого не сделаете, вы рискуете столкнуться с проблемой выравнивания, потому что выравнивание для uint32_t
выше, чем для uint8_t
, а использование плохо выровненного указателя явно означает неопределенное поведение.
Можно возразить, что здесь мы нарушаем строгое правило алиасинга. Но с ним подойдет любая обычная реализация (это нарушило бы слишком много существующего кода, чтобы отклонить его), и единственным строго совместимым способом было бы использование полной памяти буфера... чтобы закончить точно такой же последовательностью байтов с совместимый расклад!
(*) Я знаю, что C и C++ — разные языки, но стандартное справочное руководство C++ говорит в 1.2 Нормативные ссылки [intro.refs]
1 Для применения настоящего документа необходимы следующие ссылочные документы...
— ISO/IEC 9899:1999, Языки программирования — C
...
2 Библиотека, описанная в разделе 7 ISO/IEC 9899:1999 и пункт 7 ISO/IEC 9899:1999/Cor.1:2001 и пункт 7 ISO/IEC 9899:1999/Cor.2:2003 в дальнейшем называются стандартной библиотекой C.1
...
1) С оговорками, отмеченными в разделах с 18 по 30 и в C.3, стандартная библиотека C является подмножеством стандартной библиотеки C++.
person
Serge Ballesta
schedule
27.01.2017
count
, вероятно, является количеством байтов (элементовuint8_t
) для записи, верно? И если функцияBSP_SD_WriteBlocks
пишет 32-битные слова, то вам нужно разделитьcount
на четыре, иначе она будет писать слишком много (и выйдет за пределы вашего буфера). - person Some programmer dude   schedule 27.01.2017