【问题标题】:why am i getting compilation error "error: conflicting types for ‘ptr’ " for the following code? static int val=33; int *ptr;//=&val; ptr=&val; [duplicate]为什么我收到以下代码的编译错误“错误:'ptr'的类型冲突”?静态 int val=33; int *ptr;//=&val; ptr=&val; [复制]
【发布时间】:2019-09-29 04:11:02
【问题描述】:

我的目标是使静态变量“val”可用于不同的 .c 文件(仅用于实验)。

所以我创建了一个全局指针来保存静态变量的地址,通过这个全局指针,我试图在另一个文件中访问静态变量的值。

但是,

static int val=33;
int *ptr;
ptr = &val;

给我错误。

如果我这样做,它会起作用。

static int val=33;
int *ptr = &val;

为什么?

【问题讨论】:

  • @SouravGhosh:原来这是minimal reproducible example。将显示的代码放在一个文件中并用他们的编译器编译它会产生显示的消息。
  • 警告ptr = &val;这个形式的含义取决于它在哪里,看我的回答

标签: c pointers static int


【解决方案1】:

在做

static int val=33;
int *ptr;
ptr = &val; /* define a global variable with an init value */

global 范围内定义全局变量,对于编译器,ptr 的隐式类型是 ptr = &val; 行中的 int 所以这个与int* 不兼容。您不能在全局范围内进行赋值,这就是为什么 ptr = &val; 不是先前定义的 ptr 的赋值,而是具有初始值的全局变量的定义。

将代码放在本地范围内没有问题,例如

int main()
{
  static int val=33;
  int *ptr;
  ptr = &val; /* an assignment of ptr */
}

编译没有问题

【讨论】:

  • 将代码放在块范围内会破坏 OP 在外部对象中提供地址的目标。他们应该使用他们的第二个代码,在文件范围内初始化。或者,他们可以将声明留在文件范围内,但将赋值放在块范围内。
  • @EricPostpischil 我添加了第二种情况来解释相同的形式可能具有不同的含义,具体取决于它的位置,在当前情况下,定义全局变量和分配局部变量之间的区别;-)
【解决方案2】:

您使用的是旧的或质量差的编译器,它假定int 缺少类型。

在文件范围内,ptr = &val; 等表达式语句不是标准 C 的一部分。编译器试图将其视为声明语句。为此,它假定int 的类型,就好像语句是:

int ptr = &val;

由于 ptr 之前声明为 int *,因此此类型为 int 的新声明发生冲突,编译器报告存在冲突类型。

C 2018 6.7.2 2 为声明指定了一个约束

在每个声明的声明说明符中,以及每个结构声明和类型名称的说明符-限定符列表中,至少应给出一个类型说明符。

当违反约束时,编译器应发出有关它的诊断消息。因此,一个好的编译器会警告缺少类型说明符(而不仅仅是生成的默认类型与先前的声明冲突)。

【讨论】:

  • gcc version 6.3.0 是不是质量很差的编译器? ^^(是我在raspberrypi下的那个)
  • @bruno:它很旧,而且没有正确的开关,质量很差。我至少推荐-Wmost -std=c11,最重要的是-Wpedantic。但是,即使没有开关,它也会发出警告:“警告:数据定义没有类型或存储类”和“警告:在 'ptr' 的声明中类型默认为 'int'”。
  • 这主要是个玩笑,你宣扬了一个信念,我在编译时使用-pedantic -Wall -Wextra,正如你在我使用编译器的答案中看到的那样;-)
猜你喜欢
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多