【问题标题】:Initialization of global structure in C (GCC 4.5.2) [closed]C中全局结构的初始化(GCC 4.5.2)[关闭]
【发布时间】:2012-11-07 07:06:14
【问题描述】:

我正在使用 CodeSourcery GCC 4.5.2 for ARM 为 STM32 编写 C 代码。我在初始化全局结构时遇到问题。代码如下。

在 struct.h 中

typedef struct
{
  int foo;
  ...
  int bar;
} mystruct;

extern mystruct example; 

在 struct.c 中

mystruct example = {100,200 ..., 1000};

在 Main.c 中

#include "struct.h"

int temp;
temp = example.foo;

代码编译没有任何问题。但是在调试的时候,我发现这个结构已经被所有的垃圾值初始化了!! temp 的值应该是 100,但它总是被证明是一个垃圾值。我在 PC 上使用 eclipse + openOCD + GDB 硬件调试,在硬件端使用 Olimex JTAG。

这是编译器的问题吗?还是我在这里遗漏了什么?

【问题讨论】:

  • 注意:在 struct.c 我已经包含了 struct.h
  • 那么,这是在文件范围内吗?国际温度; temp = example.foo;你说它编译......这很有趣,因为编译器应该拒绝它。这是编译器中的一个错误,它甚至可以编译,除非这里有一些奇怪的扩展。您只能在文件范围内初始化变量以编译时间常量: int temp = 0x14;
  • “编译”是指“编译和链接”吗?您需要来自Main.cstruct.c 的目标代码。
  • 等等,什么?声明一个变量然后给它赋值是完全合法的。
  • 变量的值设置为全局变量是非法的。全局变量只能用常量@AdamLiss 初始化

标签: c struct initialization arm


【解决方案1】:

struct 对象的赋值发生在运行时,与编译时相反,因为全局变量在编译时初始化。如果编译器没有捕捉到错误,它将用垃圾值初始化全局变量。 Bugfree 编译器会捕捉到这个错误

【讨论】:

  • 这个答案难以理解。
  • 对不起上一个,点赞
  • 感谢@icepack 我不知道真正的问题是什么。
【解决方案2】:

问题已解决。我正在为 STM32 使用自定义链接器脚本,它增加了对 C++ 的支持。我在链接器文件中注释掉了以下几行,然后神奇地开始使用提供的值初始化全局结构!

__exidx_start = .;
.ARM.exidx : 
{
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
} >flash
__exidx_end = .;

.preinit_array : {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash

.init_array : {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
} >flash

.fini_array : {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(.fini_array*))
    KEEP (*(SORT(.fini_array.*)))
    PROVIDE_HIDDEN (__fini_array_end = .);
} >flash

我不知道以上几行到底是做什么的(除了它们是 C++ 构造函数工作所必需的)。我仍然想知道,即使项目中的所有源文件都没有任何 C++ 代码,链接器文件中的这个特定代码是做什么的,以至于我的全局结构被初始化为垃圾值?

【讨论】:

    【解决方案3】:

    只要确保在编译和制作过程中同时提供.c 文件就可以了 只能执行。 我尝试使用我的 gcc 4.5.2

    主文件:

    cat gst.c
    #include<stdio.h>
    #include "gst.h"
    int main()
    {
    int temp;
    temp = example.foo;
    printf("%d\n",temp);
    return 0;
    }
    

    另一个文件c文件

    cat ggst.c
    #include"gst.h"
    mystruct example = {100,200};
    

    gst.h 文件:

    typedef struct
    {
      int foo;
      int bar;
    } mystruct;
    
    extern mystruct example;
    

    gcc -Wall -Werror gst.c ggst.c -o g

    ./g

    输出为 100

    【讨论】:

    • 我觉得没有问题
    • 你的答案和我的有什么不同?
    • @Aniket :实际上我没有看到你的答案,我只是这样做并粘贴在这里..对不起
    • 我尝试使用 -Wall -Werror 选项@Aniket
    • 他在嵌入式 arm 平台上(您可能在桌面 linux 或其他东西上进行了测试),因此填充/对齐和许多其他可能的事情可能会导致差异。
    猜你喜欢
    • 2011-02-01
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多