Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
#1

Сравнение в препроцессоре - C++

21.06.2016, 10:24. Просмотров 586. Ответов 22
Метки нет (Все метки)

нужна условная компиляция
корректна ли такая конструкция (утрирую)
C++
1
2
3
4
5
6
#define A 10
#define B 10
#if A==B
 
..............
#endif
Добавлено через 8 минут
не получилось утрировать
на такую конструкцию Keil не ругается
вот кусок реального кода
где то в заголовочных файлах
C++
1
#define USART3              ((USART_TypeDef *) USART3_BASE)
еще где то
C++
1
2
3
4
5
#define PERIPH_BASE           ((uint32_t)0x40000000)
//....................................
#define APB1PERIPH_BASE       PERIPH_BASE
// ...............................................
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)

мой файл
C++
1
2
3
4
5
#define USARTDMX USART3
 
#if USARTDMX == USART3
//......................
#endif
ругается собака из за того что указатели?

Добавлено через 7 минут
вот ошибки
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(14): error: #29: expected an expression
#if USARTDMX==USART3
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(14): error: #59: function call is not allowed in a constant expression
#if USARTDMX==USART3
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(14): error: #18: expected a ")"
откуда он функцию взял?
такое ошушенье, что со скобками запутался
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.06.2016, 10:24     Сравнение в препроцессоре
Посмотрите здесь:

Сравнение скорости C++ Builder
сравнение символа C++
C++ Сравнение 2 строк
Сравнение по модулю C++
ЛР: Сравнение сортировок C++
Сравнение строк C++
C++ Сравнение изображений
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
3021 / 1823 / 189
Регистрация: 13.01.2012
Сообщений: 6,910
21.06.2016, 10:58     Сравнение в препроцессоре #2
ValeryS, у меня вот так вот все работает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef int uint32_t;
struct USART_TypeDef {};
 
#define PERIPH_BASE           ((uint32_t)0x40000000)
#define APB1PERIPH_BASE       PERIPH_BASE
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)
#define USART3              ((USART_TypeDef *) USART3_BASE)
#define USARTDMX USART3
 
#if USARTDMX == USART3
#define XXX 123
#else
#define XXX 000
#endif
 
//...
int xxx = XXX; //тут в дебагере я вижу 123
Добавлено через 1 минуту
возможно у вас не определен тип uint32_t или USART_TypeDef
SatanaXIII
Супер-модератор
Эксперт С++
5578 / 2612 / 239
Регистрация: 01.11.2011
Сообщений: 6,422
Завершенные тесты: 1
21.06.2016, 11:03     Сравнение в препроцессоре #3
Да вроде должно работать. Попробуйте вот так обернуть:
C++
#if (USARTDMX) == (USART3)
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 11:08     Сравнение в препроцессоре #4
ValeryS, == в директиве не годится для типов, или вычисляемых на этапе компиляции констант. Почему? Потому что препроцессор отрабатывает до того, как вычислились все эти языковые выражения.
Здесь больше подошли бы языковые средства, в частности шаблоны.

Цитата Сообщение от ValeryS Посмотреть сообщение
мой файл
Можешь объяснить зачем это тебе нужно?
elch10
37 / 20 / 3
Регистрация: 27.04.2015
Сообщений: 162
Завершенные тесты: 2
21.06.2016, 11:10     Сравнение в препроцессоре #5
C++
1
2
3
4
#include<cstdint>
struct USART_TypeDef {};
//......
#define PERIPH_BASE           ((uint32_t)0x40000000) //тут ругается
vxg, у меня ругается
Код
||=== Build: Debug in Test (compiler: GNU GCC Compiler) ===|
error: missing binary operator before token "0x40000000"|
note: in expansion of macro 'PERIPH_BASE'|
note: in expansion of macro 'APB1PERIPH_BASE'|
note: in expansion of macro 'USART3_BASE'|
note: in expansion of macro 'USART3'|
note: in expansion of macro 'USARTDMX'|
||=== Build failed: 1 error(s), 1 warning(s) (0 minute(s), 1 second(s)) ===|
vxg
Модератор
3021 / 1823 / 189
Регистрация: 13.01.2012
Сообщений: 6,910
21.06.2016, 11:19     Сравнение в препроцессоре #6
elch10, вы четко то что я написал пробовали исполнить? я просто не знаю/не верю что у вас в cstdint
elch10
37 / 20 / 3
Регистрация: 27.04.2015
Сообщений: 162
Завершенные тесты: 2
21.06.2016, 11:21     Сравнение в препроцессоре #7
vxg, вот что у меня
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<cstdint>
 
using namespace std;
struct USART_TypeDef {};
 
#define USART3 (USART_TypeDef* USART3_BASE)
#define PERIPH_BASE ((uint32_t) 0x40000000)
//....................................
#define APB1PERIPH_BASE PERIPH_BASE
// ...............................................
#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
#define USARTDMX USART3
 
#if USARTDMX == USART3
//......................
#endif
int main()
{
 
    return 0;
}
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
21.06.2016, 15:29  [ТС]     Сравнение в препроцессоре #8
Цитата Сообщение от vxg Посмотреть сообщение
возможно у вас не определен тип uint32_t или USART_TypeDef
определен
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Попробуйте вот так обернуть:
пробовал
Цитата Сообщение от DrOffset Посмотреть сообщение
ValeryS, == в директиве не годится для типов, или вычисляемых на этапе компиляции констант.
так нет там констант, одни дефайны
Цитата Сообщение от DrOffset Посмотреть сообщение
Здесь больше подошли бы языковые средства, в частности шаблоны.
боюсь, камень не потянет
Цитата Сообщение от DrOffset Посмотреть сообщение
Можешь объяснить зачем это тебе нужно?
могу у микроконтроллера есть от одного до пяти последовательных портов( в зависимости от модификации)
вот и пытаюсь написать написать что то типа библиотеки, чтобы "легким движением руки" мог бы настроить любой порт на любом камне
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 15:51     Сравнение в препроцессоре #9
Цитата Сообщение от ValeryS Посмотреть сообщение
так нет там констант, одни дефайны
Как же нет? Константа времени компиляции, полученная в результате вычисления выражения времени компиляции. После раскрытия макросов выражение приобретает вид:
C++
1
(uint32_t)0x40000000 + 0x4800
Макрос результат выражения не знает, т.к. оно посчитается на этапе компиляции. А препроцессор работает до этого. Это же базовая матчасть, собственно.

Цитата Сообщение от ValeryS Посмотреть сообщение
боюсь, камень не потянет
Ну здрасти Камень-то тут причем? Шаблон же - это средство времени компиляции. Тем более такие проверки вообще в бинарный код никогда не попадают. Т.е. главное тут, чтобы компилятор это поддерживал, а на производительность скомпилированного кода это влиять не будет вообще.

Добавлено через 14 минут
ValeryS, ты можешь попытаться заставить его работать, если перенесешь вычисление на плечи препроцессора. Для упрощения:
C++
1
2
3
4
5
6
7
8
9
10
11
#if ((7) == (7))
// работает
#endif
 
#if ((7 + 1) == (7 + 1))
// работает
#endif
 
#if ((1 + 7) == (7 + 1))
// работает
#endif
Т.е. убери все приведения типов, и т.п. Чтобы дать препроцессору посчитать результат.
vxg
Модератор
3021 / 1823 / 189
Регистрация: 13.01.2012
Сообщений: 6,910
21.06.2016, 15:51     Сравнение в препроцессоре #10
DrOffset, как тогда объяснить что у меня вся эта конструкция работает?
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 15:57     Сравнение в препроцессоре #11
Цитата Сообщение от vxg Посмотреть сообщение
как тогда объяснить что у меня вся эта конструкция работает?
Можно код целиком, который работает, версию компилятора и хостовой операционной системы?
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
21.06.2016, 16:01  [ТС]     Сравнение в препроцессоре #12
Цитата Сообщение от DrOffset Посмотреть сообщение
Макрос результат выражения не знает, т.к. оно посчитается на этапе компиляции. А препроцессор работает до этого. Это же базовая матчасть, собственно.
а как тогда вот это
C++
1
2
3
4
5
6
7
8
9
10
11
12
#define A  10
#define B  A+10
#define C  A+B
#if A==B
#endif
 
#if C==A+B
#warning "Work1"
#endif
#if C==30
#warning "Work2"
#endif
прекрасно вычисляет
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(15): warning: #1215-D: #warning directive: "Work1"
#warning "Work1"
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(18): warning: #1215-D: #warning directive: "Work2"
#warning "Work2"
Цитата Сообщение от DrOffset Посмотреть сообщение
Шаблон же - это средство времени компиляции.
вот я и боюсь что такого накомпилирует да и файлик хочу универсальный, чтобы и на Си и на плюсах тянул
пока вышел из положения так
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 <stm32f10x.h>
 
 
#define DMX__USART 1
//#define DMX__USART 2
//#define DMX__USART 3
 
#if DMX__USART==1
    #define IRQDMX
        #define PortDmx GPIOA
        #define PinDmx_TX GPIO_Pin_9
        #define PinPmx_RX GPIO_Pin_10
        #define USARTDMX USART1
 
    #define  RCC_UART_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1,ENABLE)
        #define  RCC_GPIO_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE)
    
 #elif DMX__USART==2
    #define IRQDMX
        #define PortDmx GPIOA
        #define PinDmx_TX GPIO_Pin_2
        #define PinPmx_RX GPIO_Pin_3
        #define USARTDMX USART2
    #define  RCC_UART_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2,ENABLE)
        #define  RCC_GPIO_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE)
#elif DMX__USART==3
    #define IRQDMX
        #define PortDmx GPIOB
        #define PinDmx_TX GPIO_Pin_10
        #define PinPmx_RX GPIO_Pin_11
        #define USARTDMX USART3
    #define  RCC_UART_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART3,ENABLE)
        #define  RCC_GPIO_ENABLE()   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB ,ENABLE)
#else 
#error "uncorrect USART"
 
#endif
ввел еще один дефайн

но просто интересно это Keil дурит или не стандартно все
у кого то ведь работает

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е. убери все приведения типов, и т.п. Чтобы дать препроцессору посчитать результат.
не могу, это базовый файл, от производителя микроконтроллера
изменив здесь, получу приключений в других местах
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 16:10     Сравнение в препроцессоре #13
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от ValeryS Посмотреть сообщение
а как тогда вот это прекрасно вычисляет
Ну препроцессор может оперировать вычислениями в целых числах, если это просто константы, без типизации и т.п. Как только в дело входит типизация, то лавочка сворачивается Типизация - дело компилятора.
Посмотри, я там дополнил пост насчет этого.

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
ввел еще один дефайн
В принципе самый нормальный вариант, если страшно связываться с С++.

Добавлено через 4 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
но просто интересно это Keil дурит или не стандартно все
Ну вот три распространенных компилятора, короткие примеры:
1) http://rextester.com/XOK79465
2) http://rextester.com/EMBZ88902
3) http://rextester.com/AOGNP50134
Ни один не работает.
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
21.06.2016, 16:11  [ТС]     Сравнение в препроцессоре #14
Цитата Сообщение от DrOffset Посмотреть сообщение
Как только в дело входит типизация, то лавочка сворачивается Типизация - дело компилятора.
не знал
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 16:12     Сравнение в препроцессоре #15
Причем пишет же ясно:
token is not a valid binary operator in a preprocessor subexpression
О чем и я речь веду.
ValeryS
Модератор
6482 / 4948 / 455
Регистрация: 14.02.2011
Сообщений: 16,389
21.06.2016, 16:18  [ТС]     Сравнение в препроцессоре #16
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну вот три распространенных компилятора, короткие примеры:
missing binary operator before token "0x40000000"
fatal error C1017: invalid integer constant expression
token is not a valid binary operator in a preprocessor subexpression
ну и мой
C:\STM\project\RadioDMX\MyFile\UART_DMX.c(14): error: #29: expected an expression
поди догадайся че он хочет не люблю я макросы
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
21.06.2016, 16:20     Сравнение в препроцессоре #17
Цитата Сообщение от ValeryS Посмотреть сообщение
поди догадайся че он хочет
Это да.

Цитата Сообщение от ValeryS Посмотреть сообщение
token is not a valid binary operator in a preprocessor subexpression
Вот, называется почувствуй качество диагностики Сlang. Все четко и ясно Везде бы так было.
_liv_
163 / 163 / 61
Регистрация: 07.10.2015
Сообщений: 478
Завершенные тесты: 1
21.06.2016, 16:30     Сравнение в препроцессоре #18
Цитата Сообщение от ValeryS Посмотреть сообщение
из за того что указатели?
ValeryS, похоже, что у компилятора "заходят шарики за ролики" ,
когда разбирается конструкция #if, у которой и в левой, и в правой частях стоят макросы

Я бы порекомендовал несколько упростить задачу для компилятора.

#define USARTDMX USART3
#define USARTNUM 3

#if USARTNUM == 3

Добавлено через 3 минуты
ValeryS, собственно, так и было сделано... Слегка опоздал...
vxg
Модератор
3021 / 1823 / 189
Регистрация: 13.01.2012
Сообщений: 6,910
21.06.2016, 16:35     Сравнение в препроцессоре #19
Цитата Сообщение от DrOffset Посмотреть сообщение
Можно код целиком, который работает, версию компилятора и хостовой операционной системы?
код целиком я привел вот он еще разок
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef int uint32_t;
struct USART_TypeDef {};
 
#define PERIPH_BASE           ((uint32_t)0x40000000)
#define APB1PERIPH_BASE       PERIPH_BASE
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)
 
#define USART3              ((USART_TypeDef *) USART3_BASE)
 
#define USARTDMX USART3
 
#if USARTDMX == USART3
#define XXX 123
#else
#define XXX 000
#endif
 
//далее в тексте программы (у меня - в конструкторе формы - слепил приложение в одни клик - поэтому приводить специфический код думаю смысла нет) идет
int xxx = XXX;
Borland C++ Builder 6 Windows XP SP 3
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2016, 16:48     Сравнение в препроцессоре
Еще ссылки по теме:

C++ Builder Сравнение звуков в c++
C++ Сравнение C++ с С#
C++ сравнение строк
C++ "Циклы" на препроцессоре
Побитовое сравнение C++

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

Или воспользуйтесь поиском по форуму:
_liv_
163 / 163 / 61
Регистрация: 07.10.2015
Сообщений: 478
Завершенные тесты: 1
21.06.2016, 16:48     Сравнение в препроцессоре #20
ValeryS, вот так работает:
C++
1
#if (uint32_t)USARTDMX == (uint32_t)USART3
Добавлено через 7 минут
ValeryS, хотя нет, погорячился, не работает...
Yandex
Объявления
21.06.2016, 16:48     Сравнение в препроцессоре
Ответ Создать тему
Опции темы

Текущее время: 18:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru