2

I know that declaring a ststic variable and initializing it in this waystatic int *st_ptr = malloc(sizeof(int)); will generate a compile error message(Type initializer element is not constant),and solving this by using separate statements in this way static int *st_ptr; st_ptr = malloc(5*sizeof(int));


i need to understand the difference between initialization operator and assignment operator in this case ?and why this way solved the problem ?

5
  • both of them are highly dangerous and aside of learning , they should be avoided. Commented Apr 1, 2015 at 10:20
  • 1
    Your second example will compile, but it's still wrong: it'll allocate new storage every time the function is called, leaking the old. Initialize the variable to NULL, and check for NULL before calling malloc so that it's only called once. Commented Apr 1, 2015 at 10:31
  • @DavidHaim: What exactly are you talking about? Commented Apr 1, 2015 at 10:43
  • @DavidHaim: you should anyway add what you are refering to here. as the OP doesn't even contain a real snippet, and your comment did sound like "both, cases should be avoided" (So it sounded like you advise to avoid malloc at all) Because As he just throw in some code I wasn't thinking about, what he may could have forgotten. So to get what you are warning about is not well stated ;) Commented Apr 1, 2015 at 10:52
  • @Wyzard you added new concepts to me thanks Commented Apr 1, 2015 at 11:09

3 Answers 3

7

First, let's have a brief on initialization vs. assignment.

  • Initialization:

This is used to specify the initial value of an object. Usually, this means, only at the time of defining a variable, initialization takes place. The value to initialize the object is called an initalizer. From C11 , chapter 6.7.9,

An initializer specifies the initial value stored in an object.

  • Assignment:

Assignment is assigning (or setting) the value of a variable, at any (valid) given point of time of execution. Quoting the standard, chapter 6.5.16,

An assignment operator stores a value in the object designated by the left operand.

In case of simple assignment (= operator),

In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.


That said, I think, your query has to do with the initialization of static object.

For the first case,

static int *st_ptr = malloc(sizeof(int)); 

Quoting from C11 standard document, chapter §6.7.9, Initialization, paragraph 4,

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

and regarding the constant expression, from chapter 6.6 of the same document, (emphasis mine)

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

clearly, malloc(sizeof(int)); is not a constant expression, so we cannot use it for initialization of a static object.

For the second case,

static int *st_ptr;
st_ptr = malloc(5*sizeof(int));

you are not initializing the static object. You're leaving it uninialized. Next instruction, you're assigning the return value of malloc() to it. So your compiler does not produce any complains.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm starting to have the impression you are my competitor.... the second time today, you post exactly what I was trying to cite out of the standard just a bit faster then me. +1 for content anyway (You may flag this if you want to^^)
@Zaibis Don't worry, next time, maybe i'll be the one posting this very comment. :-)
3

when a variable is declared static inside a function , it is created in either the "data segment" or the "bss segment" , depends if it were initialized or not.
this variable is created in the binaries and must have a constant value - remember - static variables inside a function are created when the program goes on even before the main() starts , it can't be initialized with any function since the program does not 'run' yet(there is no kind of evaluations or function calls)
so the initializer must be constant or not initialize at the first place.

static int *st_ptr = malloc(sizeof(int));

here, you bind the creation of st_ptr with malloc , but since malloc is a function that needs to run and st_ptr must be created before any other function runs - this creates impossible state

static int *st_ptr;
 st_ptr = malloc(5*sizeof(int));

here, the st_ptr is created and left un-initialize, the creation of it is not bound to any function. each time the function runs - malloc takes place. so the activation of malloc and creation st_ptr are not depended.

but as I stated in the comment - this is extremely dangerous practice. you allocate more and more memory on the same variable. the only way to avoid it is to free(st_ptr) in the end of every function. this said - you don't need it to be static at the first place

Comments

-1

Roughly, initialization in C is when the compiler outputs binary data to executable file; assignment is the operation performed by actual executable code.

So, static int i = 5 makes the compiler to output data word 5 to executable file's data section; while int i = func() makes the compiler to generate several CPU instructions as call to call subroutine and mov to store the result.

Thus the expression static int i = func() requires both 1) to be calculated earlier than main() (as this is an initialization), 2) a piece of user code to execute (which may only make sense in the context of the new program instance). It's possible to solve that issue by creating some hidden initialization subroutine which executes before main(). Actually, C++ does this. But C has no such feature, so static variables may be initialized only with constants.

3 Comments

int i = func() would be ok, whilest the case stated by OP is invalid. So -1 for not really beeing related to OP's question. (Correct me if I'm wrong)
@Zaibis From what is said above, it's obvious (I hope) why static int i = func() is invalid - it needs code to execute, while it should be calculated before anything else (as initialization requires). C++ solves this issue by using hidden initialization subroutines, yet pure C has no such feature - user code cannot be executed before main(). This is why C allows only constants as initialization.
Ah, ok. Anyway you should rephrase it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.