Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187

constexpr и union

15.03.2020, 21:08. Показов 2244. Ответов 15

Студворк — интернет-сервис помощи студентам
Добрый день! Подскажите пожалуйста, можно ли использовать constexpr для расчета на этапе компиляции с объединением (union). Мне нужен доступ к отдельным именованным битам uint32 и на выходе я хочу получить число uint32 с выставленными мною битами для записи в регистр.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdint.h>
union bf {
    struct bit {
        unsigned AFIOEN : 1;
        unsigned : 1;
        unsigned IOPAEN : 1;
        unsigned IOPBEN : 1;
        unsigned IOPCEN : 1;
        unsigned IOPDEN : 1;
        unsigned IOPEEN : 1;
        unsigned : 2;
        unsigned ADC1EN : 1;
        unsigned ADC2EN : 1;
        unsigned TIM1EN : 1;
        unsigned SPI1EN : 1;
        unsigned : 1;
        unsigned USART1EN : 1;
        unsigned : 1;
    } b;
    uint32_t B;
};
constexpr uint32_t foo() {
    bf reg{ 0 };
    reg.b.USART1EN = 1;
    reg.b.ADC1EN = 1;
    return reg.B;
}
int main() {
    constexpr uint32_t tmp = foo();
}
Миниатюры
constexpr и union   constexpr и union  
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.03.2020, 21:08
Ответы с готовыми решениями:

Присваивание constexpr к non-constexpr
constexpr float pi = 3.14159265; void some_fun() { float angle = 45.0f*(pi/180.0f); std::cout &lt;&lt; angle; } В консоли...

union как определить из какой таблице запись после UNION?
Подскажите пожалуйста! Вот например две таблице (TEBLE_1) у которой поля row_1(BIGINT) и (TABLE_2) у которой поля row_2(TEXT) Я ИХ...

Constexpr
В программе внутри конструкции switch case, встретился с шибкой the value of 'str' is not usable in a constant expression

15
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
15.03.2020, 21:13
Цитата Сообщение от Pavel250 Посмотреть сообщение
я хочу получить число uint32 с выставленными мною битами
union не для этого. Собственно, в подсказке и говорится о том, что вы пытаетесь читать из неактивного члена объединения.

P.S. Могу ошибаться, но и порядок расположения битовых полей тоже неопределен.
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
15.03.2020, 21:21  [ТС]
Croessmah, union работает нормально, для такой реализации. Но провернуть такое на этапе компиляции видимо нельзя. Просто очень удобно настраивать регистры микроконтроллера таким способом, нежели битовой логикой reg |=1<<(n бита)
Миниатюры
constexpr и union  
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
15.03.2020, 22:34
Лучший ответ Сообщение было отмечено Pavel250 как решение

Решение

Не по теме:

Цитата Сообщение от Pavel250 Посмотреть сообщение
Но провернуть такое на этапе компиляции видимо нельзя.
Потому что читаете из неактивного члена объединения, что, как бы нельзя делать. То, что это у вас в рантайме работает, не означает, что это разрешено.



Добавлено через 56 минут
Цитата Сообщение от Pavel250 Посмотреть сообщение
нежели битовой логикой reg |=1<<(n бита)
Можно как-то так попробовать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <stdint.h>
 
 
enum BitNums: uint32_t
{
    //...
    TIM1EN = 11,
    SPI1EN = 12,
    USART1EN = 14
};
 
 
template<uint32_t ... Bits>
struct BitFlag;
 
template<uint32_t FBit, uint32_t ... Bits>
struct BitFlag<FBit, Bits...>
{
    static constexpr uint32_t value = (uint32_t(1) << FBit) | BitFlag<Bits...>::value;
};
 
template<>
struct BitFlag<>
{
    static constexpr uint32_t value = 0;
};
 
constexpr uint32_t foo()
{
    return BitFlag<USART1EN, SPI1EN>::value;//Устанавливает биты USART1EN(14) и SPI1EN(13) в единицу
}
 
int main() {
    constexpr uint32_t tmp = foo();
    std::cout << tmp << std::endl;
}
2
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.03.2020, 23:04
без рекурсии
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <stdint.h>
 
enum BitNums : uint32_t
{
    //...
    TIM1EN = 11,
    SPI1EN = 12,
    USART1EN = 14
};
 
template<uint32_t ... Bits>
struct BitPack {};
 
 
template<uint32_t ... Bits>
constexpr uint32_t foo(BitPack<Bits...>)
{
    return (uint32_t(0) | ... | (uint32_t(1) << Bits));
}
 
int main() {
    
    static_assert(foo<USART1EN, SPI1EN>({}) == 20480u);
    
}
1
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
15.03.2020, 23:09  [ТС]
Croessmah, круто, работает Спасибо! Буду разбираться завтра. А на с++14 будет работать? Это потолок пока.
zayats80888, выражения свертки добавили же в с++17, пока не могу использовать.
Миниатюры
constexpr и union  
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
15.03.2020, 23:19
Цитата Сообщение от zayats80888 Посмотреть сообщение
return (uint32_t(0) | ... | (uint32_t(1) << Bits));
return ((uint32_t(1) << Bits) | ...);
Цитата Сообщение от Pavel250 Посмотреть сообщение
А на с++14 будет работать?
Да.
0
15.03.2020, 23:21

Не по теме:

Croessmah, т.е. там 0 в конце итак добавится?
просто я смотрю

When a unary fold is used with a pack expansion of length zero, only the following operators are allowed:

1) Logical AND (&&). The value for the empty pack is true
2) Logical OR (||). The value for the empty pack is false
3) The comma operator (,). The value for the empty pack is void()

0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
15.03.2020, 23:25
zayats80888, да.

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
zayats80888, да.
Нет. Там же побитовый...
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.03.2020, 23:30
Цитата Сообщение от Croessmah Посмотреть сообщение
Нет. Там же побитовый...
я всмысле для такого вызова тогда ругается foo({}), но это в принципе не страшно
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
16.03.2020, 08:54  [ТС]
Croessmah, Вроде все понял с рекурсией, а зачем ранее объявление структуры? Я понимаю что без этого ругается. Но не понимаю почему.
C++
1
2
template<uint32_t ... Bits>
struct BitFlag;
В реализации с union можно было делать поля и по несколько бит, нужно попробовать и тут так сделать.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
16.03.2020, 09:49
Цитата Сообщение от Pavel250 Посмотреть сообщение
ранее объявление структуры?
Оно задает основной шаблон. Раннее или не раннее тут не особо важно, главное чтобы было объявление основного шаблона. Если этого нет перед специализацией, то не ясно что специализируется.
1
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
16.03.2020, 10:23  [ТС]
Croessmah,
Цитата Сообщение от Croessmah Посмотреть сообщение
Можно как-то так попробовать:
Добавил namespace, чтобы были подсказки, очень удобно, так как такие enumы будут на каждый регистр, а их overмного и лезть смотреть каждый в datasheet долго. Один раз описал и все. Огромное вам спасибо!
Миниатюры
constexpr и union  
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
16.03.2020, 10:25  [ТС]
Для битовых полей с несколькими битами будет как-то так, наверно (то что подряд нумеровать не буду).
C++
1
2
3
4
5
6
7
8
9
10
11
namespace RCC {
    enum BitNums : uint32_t
    {
        //...
        TIM1EN = 11,
        SPI1EN = 12,
        USART1EN_b1 = 14,
        USART1EN_b2 = 15,
        USART1EN_b3 = 16
    };
}
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
16.03.2020, 11:18  [ТС]
Отличное решение для настройки регистров embedded systems от Croessmah,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <stdint.h>
 
namespace RCC_APB2ENR {
    enum reg : uint32_t
    {
        TIM1EN = 11,
        SPI1EN = 12,
        USART1EN = 14
    };
}
 
template<uint32_t ... Bits>
struct BitField;
 
template<uint32_t FBit, uint32_t ... Bits>
struct BitField<FBit, Bits...>
{
    static constexpr uint32_t value = (uint32_t(1) << FBit) | BitField<Bits...>::value;
};
template<>
struct BitField<>
{
    static constexpr uint32_t value = 0;
};
 
int main() {
    constexpr uint32_t tmp = BitField<RCC_APB2ENR::USART1EN, RCC_APB2ENR::SPI1EN>::value;;
    std::cout << tmp << std::endl;
}
В ассемблере это уже выглядит так:
Миниатюры
constexpr и union  
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
17.03.2020, 09:05
Цитата Сообщение от Pavel250 Посмотреть сообщение
В реализации с union можно было делать поля и по несколько бит, нужно попробовать и тут так сделать.
Нужно попробовать.
Первое что в голову залезло
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <bitset>
#include <iostream>
//----------------------------------------------------------------
#include <cstdint>
 
template<uint32_t ... Bits>
struct BSeq32
{
    template<uint32_t ... TBits>
    using AppendBits = BSeq32<Bits..., TBits...>;
};
 
 
namespace details
{
 
template<typename ... Types>
struct CombineBSeq;
 
template<typename ... Types, uint32_t ... Bits>
struct CombineBSeq<BSeq32<Bits...>, Types...>
{
    using type = typename CombineBSeq<Types...>::type::template AppendBits<Bits...>;
};
 
template<uint32_t ... Bits>
struct CombineBSeq<BSeq32<Bits...>>
{
    using type = BSeq32<Bits...>;
};
 
template<>
struct CombineBSeq<>
{
    using type = BSeq32<>;
};
 
 
template<uint32_t ... Bits>
struct BitField;
 
template<uint32_t FBit, uint32_t ... Bits>
struct BitField<FBit, Bits...>
{
    static constexpr uint32_t value = (uint32_t(1) << FBit) | BitField<Bits...>::value;
};
 
template<>
struct BitField<>
{
    static constexpr uint32_t value = 0;
};
 
 
template<typename BPack>
struct MakeValueFromBSeq{};
 
template<uint32_t ... Bits>
struct MakeValueFromBSeq<BSeq32<Bits...>>: BitField<Bits...>
{
};
 
 
}//namespace details
 
 
 
template<typename ... Types>
struct MakeValue
{
    static constexpr uint32_t value = ::details::MakeValueFromBSeq<typename ::details::CombineBSeq<Types...>::type>::value;
};
//----------------------------------------------------------------
 
namespace RCC_APB2ENR {
 
    using TIM1EN = BSeq32<11>;
    using SPI1EN = BSeq32<12>;
    using USART1EN = BSeq32<13>;
    using TEST1 = BSeq32<4, 5, 18, 31>;
}
 
constexpr uint32_t foo()
{
    return MakeValue<         //Устанавливаем биты
        RCC_APB2ENR::TIM1EN , //11
        RCC_APB2ENR::SPI1EN , //12
        RCC_APB2ENR::TEST1,   //4, 5, 18, 31
        BSeq32<0, 1>          //0, 1
    >::value;
}
 
 
int main() {
    constexpr uint32_t tmp = foo();
    std::cout << tmp << std::endl;
    //std::cout << std::bitset<32>(tmp) << std::endl;
    return 0;
}
https://gcc.godbolt.org/z/AsTjSy

Но всё же, проще будет битовыми операциями.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.03.2020, 09:05
Помогаю со студенческими работами здесь

Constexpr конструктор
Добрый день, что означает constexpt конструктор? class Foo { public: constexpr Foo() noexcept = default; }; int main() ...

Constexpr функции
В продолжении моего вопроса в этой теме - https://www.cyberforum.ru/cpp-beginners/thread1913846.html Хотел бы уточнить. У нас есть вот...

Аргументы constexpr функций
Всем привет! Почему код не компилируется ??? https://rextester.com/YESWZ66863 #include &lt;iostream&gt; template&lt;class...

Пример применения constexpr
Здравствуйте, можете привести и объяснить, какой нибудь простенький пример, уместного использования спецификатора constexpr. А то придумать...

Использование constexpr vs const
Добрый вечер, есть 2 кода: Первый: constexpr float FIXED_FPS = 45.0f; constexpr float FIXED_DT = 1.0f / FIXED_FPS; Второй: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Ниже машинный перевод статьи The Thinkpad X220 Tablet is the best budget school laptop period . Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы,. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru