1

foo在 C 文件中声明了一个数组,然后extern在相应的头文件中声明该数组。然后我foo从另一个文件访问,但是数组中第一个元素的地址是无效地址,并且与foo定义的编译单元中的地址不同。这是使用 ARM CodeSourcery 编译器从 Pebble SDK 构建的。

示例代码:

测试1.h

extern int foo[];
void testRoutine();

测试1.c

#include <pebble.h>
#include "test1.h"

void testRoutine()
{
    APP_LOG(APP_LOG_LEVEL_INFO, "Hello World! foo: 0x%x", (unsigned int)&foo[0]);
}

int foo[] = {1,2,3,4,5,6};

主程序

#include <pebble.h>
#include "test1.h"

int main()
{
    APP_LOG(APP_LOG_LEVEL_INFO, "Start of test");
    testRoutine(); // Print the address of foo from the perspective of test1.c
    APP_LOG(APP_LOG_LEVEL_INFO, "foo: 0x%x", (unsigned int)&foo[0]);

    return 0;
}

预期输出:

Start of test
Hello World! foo: 0x12345678
foo: 0x12345678

实际输出:

Start of test
Hello World! foo: 0x20081234
foo: 0x21941234 (placeholders, I can't get the real addresses right now)

此代码在标准 x86 GCC 中按预期工作,但在 ARM 编译器上不起作用。我把代码弄乱了,还是这里有编译器错误?

4

1 回答 1

0

我试图在 Debian 64 位上重现您的问题但没有成功:

主要.c:

#include <stdio.h>
#include "test1.h"

int main()
{
    testRoutine(); // Print the address of foo from the perspective of test1.c
    printf("foo: 0x%x\n", (unsigned int)&foo[0]);
    return 0;
}

测试1.h:

extern int foo[];
void testRoutine();

测试1.c:

#include <stdio.h> 
#include "test1.h"                                                    

void testRoutine()                                                    
{                                                                     
    printf("Hello World! foo: 0x%x\n", (unsigned int)&foo[0]);        
}                                                                     

int foo[] = {1,2,3,4,5,6};

结果是:

$ ./program 
Hello World! foo: 0x600970
foo: 0x600970

但是 gcc 警告是明确的:

test1.c:7:38: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

你应该尝试:

APP_LOG(APP_LOG_LEVEL_INFO, "foo: 0x%p", &foo[0]);

编辑:既然你说你在 sizeof(unsigned int)==sizeof(int *) 的 32 位平台上运行它,所以演员表不是问题。您的程序中还有一些与此代码无关的其他问题(堆栈损坏?)。

于 2014-11-30T11:09:24.273 回答