gpt4 book ai didi

C 交叉编译器链接外部声明为静态?

转载 作者:太空狗 更新时间:2023-10-29 12:18:12 25 4
gpt4 key购买 nike

我在尝试将一些文件从 Debian 交叉编译到 arm-linux 目标时遇到了一些奇怪的行为(嗯,我想它有一个解释),使用:

$ arm-linux-gnueabi-gcc --version

$ arm-linux-gnueabi-gcc (Debian 4.3.5-4) 4.3.5

编译时我收到这些错误消息:

dsblock1.c:167: error: non-static declaration of ‘HaveEventIterated_’ follows static declaration
ss2dym.c:778: error: previous declaration of ‘HaveEventIterated_’ was here

对应的行是:

ss2dym.c:778 :
extern long HaveEventIterated_;

"redeclaration" dsblock1.c:167:
long HaveEventIterated_=0;

所以这是我没有得到的东西:据我所知,首先声明为 extern 的变量是非静态的。

但是:“extern”声明在一个静态函数中。所以我的猜测是,这是某种遗传行为?!

下面是问题: - 如果我的猜测是正确的,有人可以解释背景故事吗? - 有没有简单的方法来解决这个问题,例如有一个棘手的编译器标志,允许嵌套范围转移或其他魔法?

我知道很可能会创建一个 header 并将所有这些外部声明放入中性空间,但我遇到了数百个这样的错误和几个文件。而且我已经看到这段代码使用 MSVC++ 编译得很好(我知道它有其他范围限制,但我在使用 arm-g++ 时遇到了很多问题)所以必须有某种解决方案,比重写所有这些部分更容易...

顺便说一句:有一种简单的方法可以更改所有这些“重新声明”的范围,因为我在所有这些声明前面都有一个宏,例如:

MY_MACRO long HaveEventIterated_=0;

我用 -DMY_MACRO= 编译 atm

有人吗? :)

最佳答案

extern 关键字为标识符提供与先前可见声明相同的链接1,或者如果没有先前可见声明则为外部链接。 (可以肯定的是,这是一种奇怪的语言怪癖。)

因此,问题很可能是由于 HaveEventIterated_第三个​​(或者我应该说“第一个”)声明而发生的,编译器在它之前到达到达 ss2dym.c 的第 778 行。第三个(或第一个)声明使用 static 关键字来提供标识符内部链接。第二个声明,使用 extern,然后给出相同的变量内部链接,第三个声明——没有存储类关键字来指定链接——给出变量外部链接,导致错误。

这是一个重现问题的简短示例(在不同的 gcc 中,但行为相同):

$ cat foo2.c
static int var;
extern int var;
int var = 0;
$ gcc -c foo2.c
foo2.c:3: error: non-static declaration of 'var' follows static declaration
foo2.c:2: error: previous declaration of 'var' was here

1旁注:如果之前的可见声明没有链接,您将获得外部链接。只有在 block 内重新声明变量时才会发生这种情况,其中 block 外的变量具有自动持续时间,即函数内的“本地”或“堆栈”变量:

void f(void) {
int v;
{
extern int v;

这里有一个没有链接的先前可见声明,所以最里面的 v 有外部链接。如果在同一翻译单元中存在带有内部链接的 v,则效果未定义。 (当然,无论如何,任何人都不应该一开始就编写像 f() 这样的代码 :-) )

关于C 交叉编译器链接外部声明为静态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19156573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com