在 main 外部分配变量:数据定义没有类型或存储 class

assigning variable outside main: data definition has no type or storage class

为什么这个代码:

#include <stdio.h>
#include <stdlib.h>

int *mem;
*mem = 3;
int main(){
    int *mem2 = malloc(4*4);
    mem=mem2;
    for(int i =0; i<4 ; i++)
        mem[i]=i;

    printf("%i\n",mem[2]);
}

发出此警告:

a.c:5:1: warning: data definition has no type or storage class
 *mem = 3;
 ^
a.c:5:2: warning: type defaults to ‘int’ in declaration of ‘mem’ [-Wimplicit-int]
 *mem = 3;
  ^~~
a.c:5:8: warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
 *mem = 3;
  1. mem没有类型也没有存储,但应该是(int*)

    类型
  2. 类型默认为int,但mem已有类型

为什么问题出在main外部?我没有函数和逻辑,只有简单的赋值,那为什么会出问题呢?组装后,mem 驻留在文本段,而不是数据段(奇怪),否则通常通过 rip-relative 模式访问它(e.q mov %rax, mem(%rip)),所以这里没有问题。

    .text
    .globl  mem
    .data
    .align 8
    .type   mem, @object
    .size   mem, 8
mem:
    .quad   3
    .section    .rodata
.LC0:
    .string "%i\n"
    .text
    .globl  main
    .type   main, @function
main:
    ...

以下是非法的。即使不是,这也是未定义的行为。

int *mem;
*mem = 3;
int main(){
}

如果必须,可以将其更改为如下所示:

int num = 3;
int *mem = &num;
int main(){
}

正如@bruno 所指出的,以下可能会按预期工作,但不可移植:

int *mem2 = malloc(4*4);

为了便于携带,将其更改为以下之一:

int *mem2 = malloc(4 * sizeof(int));
int *mem2 = malloc(4 * sizeof(*mem2));

第二个选项被认为更好,因为如果 mem2 的类型更改为 double,它不会导致运行时错误。

在任何函数之外,您只能使用声明。所以编译器试图解释这条语句

*mem = 3;

作为缺少类型说明符的声明。

a.c:5:1: warning: data definition has no type or storage class
 *mem = 3;
 ^

为了支持与旧 C 标准的向后兼容性,编译器默认使用类型说明符 int

如果要放置此代码段,请注意

int *mem;
*mem = 3;

尽管如此,在函数内部它会有未定义的行为,因为指针 mem 没有指向有效的 int 类型对象。