Jump to content
    

Инициализация константного указателя (Си)

Похоже, запутался в трех соснах :)

Имеются объявления:

BusFrame busBufTx1[FRAMES_PER_BUF];
BusFrame busBufTx2[FRAMES_PER_BUF];

static BusFrame *const pxTxBuffers[] = {busBufTx1, busBufTx2};

Создаю вспомогательную структуру

static const struct dma_msg xDmaSettings[2] =
{
	{
		.txbuf = (uint32_t *)busBufTx1,
		...
};

Но когда я пытаюсь написать

.txbuf = (uint32_t *)pxTxBuffers[0]

компилятор ругается "initializer element is not constant".

Почему так, ведь pxTxBuffers[] - массив константных указателей?

Share this post


Link to post
Share on other sites

2 minutes ago, Arlleex said:
.txbuf = (uint32_t *)&pxTxBuffers[0]

Не понял.

pxTxBuffers[] - массив константных указателей, значит pxTxBuffers[0] - значение указателя. Именно его мне и нужно присвоить элементу структуры. А Вы предлагаете взять адрес этого указателя.

Share this post


Link to post
Share on other sites

44 минуты назад, Harvester сказал:

Почему так

А как у вас .txBuf объявлен в структуре dma_msg?

Share this post


Link to post
Share on other sites

28 minutes ago, MrBearManul said:

А как у вас .txBuf объявлен в структуре dma_msg?

Просто указатель

uint32_t *txbuf;

Share this post


Link to post
Share on other sites

1 час назад, Harvester сказал:

Почему так, ведь pxTxBuffers[] - массив константных указателей?

Потому что вы говорите компилятору "прочитай содержимое ячейки 0 массива pxTxBuffers". Это можно сделать в run-time. Может сделать компилируемый код. Но в compile-time содержимого массива pxTxBuffers ещё нет и компилятор (код компилятора) этого сделать не может.

Более того: на этапе компиляции значение busBufTx1 - не известно.

Почему бы не написать просто?:

.txbuf = (uint32_t *)busBufTx1;

Share this post


Link to post
Share on other sites

3 minutes ago, jcxz said:

Но в compile-time содержимого массива pxTxBuffers ещё нет и компилятор (код компилятора) этого сделать не может.

Как это нет, если я уже объявил и проинициализировал массив pxTxBuffers?

7 minutes ago, jcxz said:

Почему бы не написать просто?:

.txbuf = (uint32_t *)busBufTx1;

Я так и делаю, просто хочу понять, почему не работает сабж.

Share this post


Link to post
Share on other sites

2 минуты назад, Harvester сказал:

Как это нет, если я уже объявил и проинициализировал массив pxTxBuffers?

Подумайте немного, что такое "run-time", и что такое "compile-time". Погуглите хотя-бы.

2 минуты назад, Harvester сказал:

Я так и делаю

Да ну?! Думаете я читать разучился?

Сравните:

27 минут назад, jcxz сказал:

 

.txbuf = (uint32_t *)busBufTx1;

и:

1 час назад, Harvester сказал:

Но когда я пытаюсь написать

.txbuf = (uint32_t *)pxTxBuffers[0]

 

 

Share this post


Link to post
Share on other sites

9 минут назад, Harvester сказал:

если я уже объявил и проинициализировал массив pxTxBuffers?

Только на бумаге. Подумайте, кто и когда реально заполняет ваш массив) Прислушайтесь к уважаемому @jcxz. Он здесь прав.

Share this post


Link to post
Share on other sites

25 minutes ago, jcxz said:

Да ну?! Думаете я читать разучился?

Похоже, Вы меня неправильно поняли. 1-е выражение (предложенное Вами) - я так и делаю в своей программе. 2-е - как я хочу сделать, но не понимаю, почему не работает.

28 minutes ago, MrBearManul said:

Только на бумаге. Подумайте, кто и когда реально заполняет ваш массив) Прислушайтесь к уважаемому @jcxz. Он здесь прав.

Я и не спорю, просто не могу понять. :(

Получается, что инициализация

static BusFrame *const pxTxBuffers[] = {busBufTx1, busBufTx2};

происходит в рантайме? Я считал, что константы известны уже на этапе компиляции.

Share this post


Link to post
Share on other sites

53 minutes ago, Harvester said:

Я так и делаю, просто хочу понять, почему не работает сабж.

Потому что вам надо пользоваться компилятором, который знает, что такое compile-time optimization. В свежих C++ всё работает, там люди приложили кучу сил, чтобы множество действий, которые должны быть выполнены в процессе старта программы, выполнялись компилятором, и в программу попадало уже готовое значение.

https://godbolt.org/z/MbMGnxxGr

Share this post


Link to post
Share on other sites

48 минут назад, Harvester сказал:

происходит в рантайме? Я считал, что константы известны уже на этапе компиляции.

Инициализация смотря чего: const-значения инициализируются компоновщиком, а компоновка - следующий шаг после шага компиляции.

Но (как уже написали выше) - некоторые оптимизирующие компиляторы умеют некоторые действия выполнять в compile-time (видимо совмещая этап компиляции с этапом компоновки). Ваш видимо не умеет.

Share this post


Link to post
Share on other sites

15 часов назад, Harvester сказал:

Я считал, что константы известны уже на этапе компиляции.

А какой компилятор используете? А то может быть у вас какой-нибудь Code Vision AVR. Так тогда это вообще не компилятор))))))))))

15 часов назад, esaulenka сказал:

Потому что вам надо пользоваться компилятором

Не всегда разрабочик может выбрать компилятор. Поэтому не советуйте наобум.

Share this post


Link to post
Share on other sites

4 hours ago, MrBearManul said:

А какой компилятор используете?

riscv32-unknown-elf-gcc 7.1.1

И да, смена компилятора в планы не входит, по крайней мере, сейчас.

Share this post


Link to post
Share on other sites

1 час назад, Harvester сказал:

riscv32-unknown-elf-gcc 7.1.1

С GCC давно не работал. Но от коллег слышу "поросячий визг", что это "самый тру компайлер"... Сам работаю с IAR.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...