我们目前正在开发用于MSP430系列单片机的应用程序,并遇到了一些奇怪的问题。我们发现,宣称阵列withing“正常”变量的声明后,范围有时会导致什么似乎是未定义的行为。像这样:

foo(int a, int *b);

int main(void)
{
    int x = 2;
    int arr[5];

    foo(x, arr);

    return 0;
}

FOO传递指针,作为第二变量,该<强>有时不指向 ARR 阵列。我们通过程序由单步执行验证这一点,并看到在主范围的ARR阵列作为一种指针变量的值是不相同的FOO范围的B指针变量的值。不,这是不是真的reproduceable,我们只是在观察了一会儿,一旦这种行为。

此执行FOO功能的单线连之前是可观察到的,所传递的指针参数(b)中根本就没有指向地址ARR是

更改例子似乎解决该问题,如下所示:

foo(int a, int *b);

int main(void)
{
    int arr[5];
    int x = 2;

    foo(x, arr);

    return 0;
}

没有任何人有任何输入或提示,为什么我们遇到此问题?或类似的经验? MSP430的编程指南指定代码应符合ANSI C89规范。所以我想知道如果它说,阵列已到之前非数组变量声明?

在此的任何输入,将不胜感激。

结果

<强>更新

@Adam Shiemke和tomlogic:

我想知道什么C89指定有关声明中初始化值的不同方式。你可以写这样的:

int bar(void)
{
    int x = 2;
    int y;

    foo(x);
}

如果是这样,怎么样:

int bar(int z)
{
    int x = z;
    int y;

    foo(x);
}

时,允许?我假定以下必须是非法C89:

int bar(void)
{
    int x = baz();
    int y;

    foo(x);
}

预先感谢。

结果

<强>更新2 问题解决了。基本上,我们在那里调用函数(富)之前和变量声明后,不能中断。我们在那里能够再现一个简单的例子的问题,而解决方案似乎是禁止中断通话后添加_NOP()语句。

如果任何人的爱好,我可以张贴完整的示例再现问题,和固定?

感谢您的所有输入上这一点。

有帮助吗?

解决方案

您应该能够确定它是否是基于所产生的汇编代码编译器故障。是国内组装不同的,当你改变的变量声明的顺序?如果您的调试器允许您通过组装尝试单步执行。

如果你找到一个编译器缺陷,另外,检查你的优化。我已经看到这样由优化引入错误。

其他提示

,看起来像一个编译错误。

如果你用你的第一个例子(有问题的),写你的函数调用为foo(x, &arr[0]);,你看到同样的结果?怎么样,如果你喜欢初始化的int arr[5] = {0};阵列?这些都不应该改变什么,但如果他们这样做将在编译器错误提示。

在更新的问题:

  

基本上,我们在那里调用函数(foo)之前和变量声明之后禁止中断。我们在那里能够再现一个简单的例子的问题,而解决方案似乎是禁止中断通话后添加_NOP()声明。

听起来好像关闭中断固有/功能/宏(或然而中断被禁止)可能会引起的指令是“跳过”或东西。我会调查这是否是编码/正常工作。

两个例子都看要符合C89我。应该有未访问超出阵列的边界的行为假设foo没有可观察到的差异。

有关C89,变量需要在范围的开始的列表之前的任何分配声明。 C99允许你混合分配的声明。所以:

{ 
    int x; 
    int arr[5];

    x=5;
...

是法律风格C89。我很惊讶你的编译器没有把对某种错误的,如果它不支持C99。

假设真正的代码要复杂得多,继承人有些事情我会检查,记住他们的猜测:

你能满溢之际堆栈?如果是的话这会是“堆防御”的一些神器由编译器/ UC?是否可预测的内存范围内不正确的值FOO下跌呢?如果这是否范围具有任何意义(堆栈等的内部)?

是否mcu430具有RAM和ROM寻址不同的范围?也就是说,对于16位的RAM,而程序地址空间的24位地址空间? PIC的有例如这样的架构。如果是的话这将是可行的ARR是越来越分配为ROM(24位)和函数需要一个指向RAM(16位)的代码将工作时的ARR中的地址空间中的第16位的被分配但砖如果高于该范围的。

也许你在你的程序的一些地方非法存储器写从而破坏你的筹码。

你看看拆卸?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top