较新版本的GCC引发reinterpret

编程入门 行业动态 更新时间:2024-10-27 00:25:37
本文介绍了较新版本的GCC引发reinterpret_cast错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在开发一个嵌入式项目(在STM32上).我目前使用的是GCC 4.9.2,但我想切换到较新版本的工具链.不幸的是,我的代码在gcc 4.9.2上成功编译,在6.2.0或7.2.0版本上引发了reinpreted_cast错误,我也不知道为什么.看来,较新的gcc在将int转换为指针并返回int时遇到了一些问题-我认为这应该是正常的操作.

I am developing an embedded project (on STM32). I currently use GCC 4.9.2, but I would like to switch to newer version of my toolchain. Unfortunately my code which succesfully compiles on gcc 4.9.2, throws reinpreted_cast errors on version 6.2.0 or 7.2.0 and I have no idea why. It looks like that newer gcc sees some problems when casting int to pointer and back to int - which I think should be quite normal operation.

抛出错误消息:

1>STM32L4\CMSIS\stm32l4a6xx.h(1567,30): error : 'reinterpret_cast<ADC_TypeDef*>(1342439424)' is not a constant expression 1> #define ADC1 ((ADC_TypeDef *) ADC1_BASE) 1> ^ 1> Sources\CAdc.cpp(31,35): note: in expansion of macro 'ADC1' 1> case reinterpret_cast<uint32_t>ADC1: u32DMAChannel = LL_DMA_CHANNEL_1; break;

这是我的代码的一部分,该错误涉及以下内容:

Here is part of my code which error refers to:

switch ((uint32_t)adc) { case (uint32_t)ADC1: u32DMAChannel = LL_DMA_CHANNEL_1; break; case (uint32_t)ADC2: u32DMAChannel = LL_DMA_CHANNEL_2; break; case (uint32_t)ADC3: u32DMAChannel = LL_DMA_CHANNEL_3; break; }

和 adc 声明:

private: ADC_TypeDef *adc;

以下是所有宏的定义:

#define PERIPH_BASE (0x40000000UL) /*!< Peripheral base address */ #define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000UL) #define ADC1_BASE (AHB2PERIPH_BASE + 0x08040000UL) #define ADC1 ((ADC_TypeDef *) ADC1_BASE)

因此对于编译器,我的切换中转换如下:

So for compiler, my in-switch cast looks like this:

(uint32_t)((ADC_TypeDef *) (((0x40000000UL)+ 0x08000000UL)+ 0x08040000UL))

简单地将 unsigned long 强制转换为某些结构指针,然后返回到 unsigned long .怎么了我应该怎么做才能摆脱这个错误?对我而言,任何宏版本都是不可能的,因为它们是BSP库.

Simple cast of unsigned long to some struct pointer and back to unsigned long. What is wrong with it? Whould should I do to get rid of this error? Any macro edition is impossible for me because these are BSP libraries.

推荐答案

不是重新解释失败,而是重新解释的值不视为常量,因此不能用作大小写标签.

It is not the reinterpret that is failing, but rather the reinterpreted value is not regarded as a constant so therefore cannot be used as a case label.

大小写标签必须是常量表达式,而常量表达式是可以在编译时求值的任何表达式.在C ++中,对 reinterpret_cast 表达式的求值不是恒定表达式.

Case labels must be a constant expression, and a constant expression is any expression that can be evaluated at compile time. In C++ evaluation of a reinterpret_cast expression is not a constant expression.

此处的编译器行为发生了变化,即编译器将以前的蛮力C样式转换为限制性更强的C ++ reinterpret_cast .在 www.onlinegdb/上进行的测试表明,在C ++ 17编译时会发生此行为使用的是C ++ 14而不是C ++ 14,因此简单的无代码更改"解决方案是将编译设置为较早的标准-在任何情况下,为避免任何其他意外情况或麻烦,可以说是对旧代码的明智方法.

The compiler behaviour change here appears that the compiler translates the previously brute-force C-style cast into a more restrictive C++ reinterpret_cast. Testing at www.onlinegdb/ shows that this behaviour occurs when C++17 compilation is used but not C++14, so the simple "no code change" solution is to set the compilation to the earlier standard - arguably a sensible approach for legacy code in any case to avoid any other surprises or gotchas.

然而,似乎stm32l4a6xx.h标头已经提供了ADC基址的两种表示形式,一个表示整数( ADCx_BASE ),另一个表示指针( ADCx ).通常最好完全避免强制转换并使用目的的适当表示.在这种情况下:

It seems however that the stm32l4a6xx.h header already provides two representations of the ADC base address one an integer (ADCx_BASE) and the other a pointer (ADCx). It is generally better to avoid casts at all and use the appropriate representation of the purpose. In this case:

switch ((uint32_t)adc) { case ADC1_BASE: u32DMAChannel = LL_DMA_CHANNEL_1; break; case ADC2_BASE: u32DMAChannel = LL_DMA_CHANNEL_2; break; case ADC3_BASE: u32DMAChannel = LL_DMA_CHANNEL_3; break; }

更多推荐

较新版本的GCC引发reinterpret

本文发布于:2023-11-24 19:23:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1626499.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:新版本   GCC   reinterpret

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!