Search code examples
cmemorymalloclanguage-design

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


Why this code:

#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]);
}

Is giving this warnings:

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 has no type or storage, but it should be of type (int*)

  2. type defaults to int, but the mem already has type

Why is the problem it is outside main? I have no function or logic, only simple assignment, then why is it problem? Having it assembled, the mem resides in text segment, not data segment (strange), otherwise it is normally accessed via rip-relative mode (e.q mov %rax, mem(%rip)), so no problem here.

    .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:
    ...

Solution

  • Outside any function you may use only declarations. So the compiler tries to interpret this statement

    *mem = 3;
    

    as a declaration where a type specifier is absent.

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

    To support the backward compatibility with the old C Standard the compiler by default uses the type specifier int.

    Pay attention to that if you will place this code snippet

    int *mem;
    *mem = 3;
    

    inside a function nevertheless it will have undefined behavior because the pointer mem does not point to a valid object of the type int.