gpt4 book ai didi

c++ - 在ubuntu上用不同版本的gcc编译会产生不同的结果

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:49:52 24 4
gpt4 key购买 nike

所以我有一个像这样的项目设置:

  • myfile.cpp包括:
    • fsl_clock.h

其中 myfile 是一个 C++ 文件,fsl_clock.h 是来自 NXP 的纯 C 头文件,其中可以看到它的一个版本 here

我的文件看起来像:

#include "fsl_clock.h"

现在我的文件中确实有更多内容,但我清空了它,直到只剩下这些内容为止。

以下是我尝试过的编译结果:

  • 用arm交叉编译器arm-none-eabi-g++这编译得很好。
  • 使用主机 (x86Linux) g++ --version 7.3.0-16ubuntu3它工作正常
  • 使用主机 (x86Linux) g++ --version 7.3.0-27ubuntu1~18.04它会产生大量奇怪的错误。

我得到的错误是这样的:

device/MIMX8MQ6_cm4.h8856:51: error 'reinterpret_cast<CMM_Type*>(808976384)' is not a constant expression

代码行是纯 C 的,看起来像:

kCLOCK_RootM4 = (uint32_t)(&(CCM)->ROOT[1].TARGET_ROOT)

CCM 定义为:

#define CCM_BASE (0x30380000u)
#define CCM ((CCM_Type*)CCM_BASE)

所以它看起来像更新的 g++ 7.3.0-27ubuntu1~18.04 (也许是正确的)在 C 风格包含的头代码中做 C++ 事情(例如 reinterpret_cast)。较旧的编译器 7.3.0-16ubuntu3行为方式不同 - 编译正常。

谁能说出这两个编译器之间的区别是什么以及为什么一个编译器可以工作而另一个不能工作?两个编译器 gnu g++ 都具有相同的 g++ 版本 7.3.0。但是我不太明白后缀16ubuntu3对比27ubuntu1~18.04以及为什么这可能会改变行为......

注意 现在,我知道对于我的主机构建,我真的不想在我的主机构建中包含板特定代码,但这是另一回事。我现在更感兴趣的是了解为什么这两个编译器之间存在差异。

更新

对于主机构建,编译器行如下所示:

g++ -w -Isource/drivers -Isource/board -Isource/device -m32 -g -std=c++11 -c source/myfile.cpp -o out.o 

CMM_Type(必须手动复制它,因为原件埋在 NXP 网站中)看起来像(注意它的缩写,因为有太多要复制 - 但它的 uint32_t 结构):

typedef struct {
volatile uint32_t GPR0;
volatile uint32_t GPR0_SET;
struct {
:
} PLL_CTRL[39];
:
struct {
volatile uint32_t TARGET_ROOT;
volatile uint32_t TARGET_ROOT_SET;
volatile uint32_t TARGET_ROOT_CLR;
:
} ROOT[142];
} CCM_Type;

最小示例 - 在线 GDB我做了一个最小的例子——它不使用在线 GDB 编译,但它确实产生了我在编译器上解释的错误。链接是here

最小 - 魔杖盒与在线 GDB 示例完全相同的代码,但这实际上显示了我得到的相同错误:here

最小示例代码

#include <stdint.h>

typedef struct {
struct {
volatile uint32_t TARGET_ROOT;
} ROOT[4];
} CCM_Type;

#define CCM_BASE (0x30380000u)
#define CCM ((CCM_Type *)CCM_BASE)

typedef enum _clock_root_control
{
kCLOCK_RootM4 = (uint32_t)(&(CCM)->ROOT[1].TARGET_ROOT)
} clock_root_control_t;

int main()
{
return 0;
}

最佳答案

typedef enum _clock_root_control
{
kCLOCK_RootM4 = (uint32_t)(&(CCM)->ROOT[1].TARGET_ROOT)
} clock_root_control_t;

此代码在 C 或 C++ 中均无效。

在 C++ 中,枚举数必须是常量表达式。常量表达式不能涉及 reinterpret_cast。从指针到整数的 C 风格转换等同于 reinterpret_cast

在 C 中,枚举数必须是整数常量表达式。整数常量表达式不能涉及指针操作数。

解决这个问题的方法是用等效的常量表达式替换表达式,例如

CCM_BASE + offsetof(CCM_Type, ROOT[1].TARGET_ROOT)

Live example

关于c++ - 在ubuntu上用不同版本的gcc编译会产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54691017/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com