Существует ли альтернативный синтаксис для инициализации константного указателя на константные данные?

У меня есть встроенное программное обеспечение C, которое требует нескольких константных указателей для константных данных. До сих пор я повторял две строки кода для их инициализации:

const int data = 0xF0; // const int
const int* const buffer = &data; // const pointer to const int

Раньше я использовал множество приведений типов, но при проверке товарищами по команде обнаружил, что это слишком подвержено ошибкам. Я открыт для их использования, если смогу найти способ использовать их четко и последовательно. Мне также нужно избегать отбрасывания квалификатора const при переходе к функциям, поскольку его отбрасывание фактически уже привело к одной ошибке в разработке.

Вам действительно нужна переменная buffer? Почему бы не использовать &data, если вы в противном случае используете buffer?

Some programmer dude 13.06.2024 17:49

Возможно, #define DEFCONSTS(var, ptr, val, t) const t var = val; const t *const ptr = &var, который в вашем примере будет использоваться как DEFCONSTS(data, buffer, 0xF0, int);.

pmg 13.06.2024 17:52

Использование константных переменных-указателей не имеет смысла, почему вам нужен объект-указатель, который не может измениться. Вместо этого используйте объект, на который ссылаются. Они имеют смысл только как параметры функции.

0___________ 13.06.2024 18:04

«Раньше я использовал множество приведений типов, но обнаружил, что это слишком подвержено ошибкам». Вы можете показать, как вы использовали приведения типов. Это только для того, чтобы «удалить» квалификатор const?

Gerhardh 13.06.2024 18:11

«поскольку отказ от этого уже вызвал одну ошибку в разработке». Тогда использование указателей на значения const изначально некорректно. Но без более подробной информации о вашем использовании трудно предложить альтернативу.

Gerhardh 13.06.2024 18:12

@0___________ ты поднял ценную задачу по кадрам, спасибо. Требуется больше кофе.

ZeHolyQofPower 13.06.2024 18:13

Пожалуйста, опубликуйте код функции, которую необходимо const удалить.

chqrlie 13.06.2024 19:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте составной литерал:

const int * const buffer = (const int []) { 0xF0 };

или:

const int * const buffer = & (const int) { 0xF0 };
Ответ принят как подходящий

Вы можете определить указатель и данные в одном объявлении (хотя это нечитабельно и не рекомендуется:

const int data = 0xF0, * const buffer = &data;

Используя составные литералы C99, вы также можете написать:

const int * const buffer = (const int[]){ 0xF0 };

или

const int * const buffer = (const int[1]){ 0xF0 };

или

const int * const buffer = &(const int){ 0xF0 };

Обратите внимание, что порядок ключевых слов const и int не имеет значения, и, возможно, будет удобнее поместить ключевое слово const ближе к *, к которому оно относится:

int const * const buffer = (int const []) { 0xF0 };

Вопрос в следующем: зачем вообще нужен указатель? Если указатель постоянен, его нельзя изменить, чтобы он указывал на что-то другое, поэтому зачем определять указатель, если можно передать &data напрямую?

Удаление квалификатора const для вызовов функций является признаком недостатков проектирования: функция, принимающая указатель на данные, которые она не изменяет, должна иметь аргумент, определенный как whatevertype const *arg, и вам не нужно никакого приведения при передаче адреса данных, будь то const квалифицирован или нет. Если функция изменяет данные, на которые она получает указатель, передача ей данных, определенных как const, вызовет неопределенное поведение при изменении, поскольку данные могут находиться в памяти только для чтения.

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