Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialization of int pointer in C

A very simple question regarding initializing an int pointer in C. I was just informed that:

int *varname = {0};  

Is not valid.

I have not yet been able to find the explicit reference that points this out, but have confidence (based on commenters rep) that it probably is not valid, Even though it compiles, builds and accepts memory from calloc/malloc statements okay.

Can someone please point out the specifics of why the above expression is not valid?

like image 596
ryyker Avatar asked Jun 30 '26 13:06

ryyker


2 Answers

This is valid, we can see this by going to the C99 draft standard section 6.7.8 Initialization paragraph 11 which says:

The initializer for a scalar shall be a single expression, optionally enclosed in braces. [...]

So:

int *varname = {0}; 

will initialize varname to a null pointer, since 0 is a null pointer constant as per section 6.3.2.3 Pointers:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer [...]

and for completeness sake we know pointers are scalar types based on section 6.2.5 Types:

Arithmetic types and pointer types are collectively called scalar types [...]

like image 105
Shafik Yaghmour Avatar answered Jul 03 '26 03:07

Shafik Yaghmour


As Grzegorz Szpetkowski's answer says, that syntax:

int *varname = {0};

is valid. It just doesn't do what I suspect you think it should do. It's equivalent to

int *varname = 0;

which is equivalent to

int *varname = NULL

(assuming NULL is visible).

If my guess about what you're trying to do is wrong, the rest of this answer doesn't apply.


Based on the comments, it looks like that's not what the OP was trying to do. Not sure whether to delete this answer or not; it could be a good answer to some other question.


You can initialize a char* pointer to point to a string literal:

char *cptr = "hello";

The string literal "hello" implicitly creates an anonymous array object with static storage duration; the initialization causes cptr to point to that array's initial element.

Prior to C99, there was no equivalent syntax for defining a non-character pointer and simultaneously creating something for it to point to.

C99 added compound literals. For example, this:

(int){42}

creates an int object with the value 42. Unlike a literal 42, this actually creates an object, not just a value -- which means it has an address. So this:

int *iptr = &((int){42});

creates an anonymous int object with an initial value of 42, and initializes iptr to point to it. (If your compiler supports compound literals.)

Compound literals are usually used for array and structure types, but they're also valid for scalar types.

One thing to watch out for: the array created by a string literal always has static storage duration, meaning it exists during the entire execution of the program. The storage duration of the anonymous object created by a compound literal depends on where it appears. If it's inside a function, the object has automatic storage duration, which means it ceases to exist as soon as execution leaves the nearest enclosing block.

So given:

char *cptr = "hello";

you can safely return the value of cptr from a function, and it will continue to be valid. But given:

int *iptr = &((int){42});

returning the value of iptr from a function would be dangerous, since the object it points to will cease to exist before the caller gets the pointer value.

A simpler way to do this kind of thing is to define the object yourself:

int obj = 42;
int *iptr = &obj;

You can define obj as static if necessary.

like image 20
Keith Thompson Avatar answered Jul 03 '26 03:07

Keith Thompson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!