在 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;
mem没有类型也没有存储,但应该是(int*)
类型
类型默认为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 = #
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 类型对象。
为什么这个代码:
#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;
mem没有类型也没有存储,但应该是(int*)
类型类型默认为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 = #
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 类型对象。