Использование #define для части (суффикса) идентификатора
- Войдите на сайт для отправки комментариев
Чт, 13/10/2016 - 19:13
Есть блоки следующего вида:
firstVal_0 = ...
secondArray_0[...] =...
thirdFunction_0_a();
и
firstVal_1 = ...
secondArray_1[...] =...
thirdFunction_1_a();
понятно, что можно создать объект, куда запихать все свойства и методы, а поторм использовать массив объектов.
Но хочется данную последовательность инструкций запихнуть в include-файл, а перед этим определить фрагменты имен "_0" или "_1", чтобы выбирать те или иные переменные, массивы, функции.
Насколько я понимаю, в обычном случае можно определить только идентификатор целиком, а можно ли определить и использовать его часть (суффикс)? Если можно, как это будет выглядеть?
Да, конечно можно. Для этого используется операция ##
Спасибо, но что-то пошло не так:
Хочу получить:
new_note_0[0]
определяю:
#define LOC_INDEX 0 // индекс в массиве-очереди команд
#define V_INDEX 0 // номер голоса
#define GLUE(item, index) item##_##index
вставляю из файла:
if(GLUE(new_note, V_INDEX)[LOC_INDEX]) {
...
Synt_2560_04.ino:73:27: note: in definition of macro 'GLUE'
D:\Arduino\MySketches\Synt_2560_04\int_check_new_note.d:1:11: error: 'new_note_V_INDEX' was not declared in this scope
if(GLUE(new_note, V_INDEX)[LOC_INDEX]) {
^
Synt_2560_04.ino:73:27: note: in definition of macro 'GLUE'
Error compiling.
Перестановка местами дефайнов проблему не решает.
Ну, всё правильно. Она не делает подстановки перед конкатенацией, поэтому V_INDEX так и остаётся V_INDEX и не становится 0.
Напишите просто 0 - отлично всё сделается.
"0" написать не могу - нужна именно константа, переопределяемая снаружи.
Т.е. в том файле, где есть строка
if(GLUE(new_note, V_INDEX)[LOC_INDEX]) {
должен быть именно V_INDEX, но никак не "0", т.к. "0" задается снаружи - в другом файле.
Как поступить в этом случае?
Еще раз, чтобы было понятнее:
есть файл, в котором строчки:
#define LOC_INDEX 0 // индекс в массиве-очереди команд
#define V_INDEX 0 // номер голоса
#define GLUE(item, index) item##_##index
#include "abcd.d"
#define V_INDEX 1 // номер голоса
#include "abcd.d"
А в файле abcd.d есть строчка
if(GLUE(new_note, V_INDEX)[LOC_INDEX]) {
и нужно, чтобы при первом включении файла abcd.d получалось:
new_note_0[0]
а при втором:
new_note_1[0]
Я могу сделать так:
#define LOC_INDEX 0 // индекс в массиве-очереди команд
#define V_INDEX 0 // номер голоса
#define GLUE(item) item##_0
#include "abcd.d"
#define V_INDEX 1 // номер голоса
#define GLUE(item) item##_1
#include "abcd.d"
А в файле abcd.d:
if(GLUE(new_note)[LOC_INDEX]) {
Но это неизящно для одной и той же сущности (обозначенной V_INDEX) использовать два дефайна и, самое главное, следить за тем, чтобы они изменялись строго синхронно. Мне казалось, что дефайны для того и нужны, чтобы избавиться от необходимости отслеживать синхронные изменения ручками/глазками.
Не, ну, поймите, подстановка не происходит только если используется ##. В других случаях всё подставляется как обычно. Поэтому Вашу проблему надо решать промежуточным макросом в котором нет ## и всё подставится нормально. Промежуточный макрос просто вызывает основной, но передаёт ему уже "подставленные" значения своих параметров. Вот смотрите
Понятно?
У меня это нормально компилируется.
Спасибо, на первый взгляд заработало (правда, пока не понял, почему), а разбираться буду зав... нет, уже сегодня, но ближе ко второй половине дня.
Не за что. И должно было заработать. При разборе первого макроса вместо V_INDEX подставился ноль и уже нулём был передан второму макросу. Вот и вся хитрость. Удачи!
И правда "хитрость".
Спасибо.