重新定义全局范围中的指针

时间:2014-01-16 02:24:03

标签: c

this question中,我对C这个看似基本的方面感到十分困惑。请考虑以下两行代码:

int *ptr;
*ptr = 2;

gcc将发出以下警告:

main.cpp:4:1: warning: data definition has no type or storage class [enabled by default]

 *ptr = 2;
 ^
main.cpp:4:2: warning: type defaults to 'int' in declaration of 'ptr' [enabled by default]

 *ptr = 2;
  ^
main.cpp:4:8: warning: initialization makes pointer from integer without a cast [enabled by default]

 *ptr = 2;
        ^

ptr默认为哪种类型,intint*(如,ptr是指针,还是int)?如果是这样,这是否意味着ptr指向地址2,或者是否保持不变?我会认为它已被更改,因为除非您给ptr一个有效的地址,否则它会崩溃。

int i = 5;
int *ptr;
*ptr = &i;

int main(){
    printf("%d", *ptr); // 5
}

我知道未定义行为的可能性,你不应该忽略警告,但我试图看看这里发生了什么。

有关上下文,请参阅此answer下的评论链。

1 个答案:

答案 0 :(得分:12)

以下是正在发生的事情:由于您显示的两行是在文件范围内(而不是本地范围),因此两行都被视为声明,而不是声明和转让声明。这是因为在文件范围内可能没有语句 - 只允许声明和定义。

旧C规则允许类型int的声明完全省略类型。因此,第二行是

  • ptr
  • 的声明/定义
  • ...这是一个指针,因为它有一个星号
  • ...它也是指向int的指针,因为缺少类型。

最后一条规则非常陈旧,并且已在语言标准的ANSI版本中弃用。这就是你得到警告的原因。如果您将代码更改为

int *ptr;
int *ptr = &i;

您的代码将编译并运行(demo)。

现在还有一个问题:编译器怎么不抱怨重复的声明?事实证明,编译器会将多个相同的声明视为同一个声明,只要它们完全相同即可。