-1
  1. inside main() -- no error

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 4
    
    typedef struct
    {
        int vertex;
        int **matrix;
    }graph;
    graph ygraph={.vertex=MAX};
    
    int main()
    {
        ygraph.matrix=(int**)malloc(sizeof(int)*MAX*MAX);
        return 0;
    }
    
  2. outside main() -- error//

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 4
    
    typedef struct
    {
        int vertex;
        int **matrix;
    }graph;
    graph ygraph={.vertex=MAX};
    ygraph.matrix=(int**)malloc(sizeof(int)*MAX*MAX);
    
    int main()
    {
        return 0;
    }    
    

what is difference...? I can't initialize global variable outside main()? I think both have no error...

  • 2
    The problem is not initialization itself, but calling any function outside of main. – Gerhardh Jan 22 '20 at 07:54
  • You can't have general statements (like your assignment statement) outside of functions. Only declarations and definitions are allowed. – Some programmer dude Jan 22 '20 at 07:54
  • 2
    On an unrelated note, in C you [don't have to (and really shouldn't) cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). And that allocation seems wrong for the type (your `malloc` call allocates a contiguous chunk of memory, but a pointer to pointer matrix isn't naturally contiguous). – Some programmer dude Jan 22 '20 at 07:56
  • 2
    `sizeof(int)*MAX*MAX` allocates memory for a number of `int` objects, but you are assigning the pointer to a variable expecting a pointer to `int*` objects. (Bug!) – ikegami Jan 22 '20 at 08:17
  • You mean outside of main() only can declaration. like constant number. not variable or call functions? how about initialized variable???? – isanghaessi Jan 22 '20 at 08:52

2 Answers2

2

Quoting a passage from the C reference at cppreference.com:

When initializing an object of static or thread-local storage duration, every expression in the initializer must be a constant expression or string literal.

Initializers for static objects (such as graph) must be known at compile-time since the initialized memory for these variables is found in the object file generated by the compiler. As such, they can't contain function calls.

$ cat a.c
int a = 7;
int b = 8;
int c = 9;

$ gcc -c a.c

$ objdump -t -s -j .data a.o

a.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 g     O .data  0000000000000004 a
0000000000000004 g     O .data  0000000000000004 b
0000000000000008 g     O .data  0000000000000004 c


Contents of section .data:
 0000 07000000 08000000 09000000           ............

Assignments in functions are evaluated during a call to the function (if at all), and thus may contain function calls.

ikegami
  • 367,544
  • 15
  • 269
  • 518
1

Static objects Initializers have to be constant expressions. Function call is not one if them

Your malloc is also wrong. If you use double pointer you need to malloc pointers to int and then for each allocated pointer, space for the integers

Object with automatic storage duration can be initialized using non constant expressions.

int *foo(size_t size)
{
    int *x = malloc(size * sizeof(*x));
    // some ops
    return x;
}
0___________
  • 60,014
  • 4
  • 34
  • 74