GCC C ++(ARM)和const指向struct字段的指针 [英] GCC C++ (ARM) and const pointer to struct field

查看:274
本文介绍了GCC C ++(ARM)和const指向struct字段的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们假设有一个简单的测试代码

  typedef struct 
{
int first;
int second;
int third;
} type_t;

#define ADDRESS 0x12345678

#define REGISTER((type_t *)ADDRESS)

const int data =(int)(& REGISTER- >秒)×2;

int main(void)
{
volatile int data_copy;

data_copy = data;

while(1){};
}

这是在CodeSourcery G ++(gcc 4.3.2) 。它还有一个非常标准的链接描述文件。



当编译为C(作为main.c)对象data进入Flash,如预期。当在C ++(作为main.cpp)中编译时,此对象进入RAM,并且添加额外的代码,这只是将值从Flash复制到RAM(该值已经计算,只是复制!所以编译器可以计算地址,但不知何故不想只是
使用它。问题的根源是地址的乘法 - 没有* 2乘法两个版本按预期工作 - 数据放置在闪存中。当data被声明为:

  const int data =(int)(REGISTER)* 2; 

也一切正常。



C和C ++编译的文件是完全相同的,唯一的区别是调用编译器 - g ++用于main.cpp,gcc用于main.c(在警告级别上有差异,而c ++有RTTI和异常被禁用)。



有没有一种简单而优雅的方式来克服这个C ++问题?我需要这样的操作来创建Cortex-M3的位带区域中的位的地址的const数组。这是一个错误,或者也许是C ++编译器的一些奇怪的限制?



我知道我可以在C文件中创建数据对象,只是extern - 包括他们在C + +,但这不是很优雅[;



谢谢你的帮助!

正确的解决方案是使用 offsetof()

 <$ c $ 

c> const int data =(int)(& REGISTER-> second)* 2;

必须替换为

  #include< stddef.h> 
const int data =(int)(REGISTER + offsetof(type_t,second))* 2;

然后将对象放置在C和C ++的Flash中。


Let's say there is a simple test code

typedef struct
{
    int first;
    int second;
    int third;
} type_t;

#define ADDRESS 0x12345678

#define REGISTER ((type_t*)ADDRESS)

const int data = (int)(&REGISTER->second)*2;

int main(void)
{
    volatile int data_copy;

    data_copy = data;

    while(1) {};
}

Which is compiled in CodeSourcery G++ (gcc 4.3.2) for bare metal ARM. It also has a very standard linker script.

When compiled in C (as main.c) the object "data" goes into Flash, as expected. When compiled in C++ (as main.cpp) this object goes into RAM, and additional code is added which does nothing more than copy the value from Flash to RAM (the value is already calculated, just copy!). So the compiler can calculate the address, but somehow doesn't want to "just use it". The root of the problem is the multiplication of the address - without "*2" multiplication both versions work as expected - "data" is placed in Flash. Also - when "data" is declared as:

const int data = (int)(REGISTER)*2;

also everything is fine.

All files for C and C++ compilation are identical, the only difference is the call to compiler - g++ for main.cpp, gcc for main.c (with differences in the level of warnings, and c++ has RTTI and exceptions disabled).

Is there any easy and elegant way to overcome this "C++ problem"? I do require such operations for creating const arrays of addresses of bits in bitband region of Cortex-M3. Is this a bug, or maybe that is some strange limitation of the C++ compiler?

I know that I can create data objects in "C" files and just "extern"-include them in C++, but that's not very elegant [;

Thank you for all help!

解决方案

The right solution is using the offsetof() macro from the stddef.h header.

Basically this:

const int data = (int)(&REGISTER->second)*2;

has to be replaced with

#include <stddef.h>
const int data = (int)(REGISTER + offsetof(type_t,second))*2;

And then the object is placed in Flash both for C and C++.

这篇关于GCC C ++(ARM)和const指向struct字段的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆