jjzjj

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

coder 2024-02-20 原文

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

  • 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/

有关c++ - 在ubuntu上用不同版本的gcc编译会产生不同的结果的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  5. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  6. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  7. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  8. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  9. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  10. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

随机推荐