Initializing an int pointer in C

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

int *varname = {0};  

      

Not valid.

I have not yet been able to find an explicit link that points to this, but have confidence (based on the comments of the commenters) that it is probably not valid, although it compiles, builds and takes memory from calloc / malloc statements in order.

Can anyone please point out why the above expression is not valid?

+3


source to share


3 answers


:

int *varname = {0};

      

just equivalent to:

int *varname = 0;

      

This is one of the valid object macro replacements NULL

(either as an 0

integer constant, or such a constant attached to the type void *

).

N1570 (draft C11), 6.3.2.3/3:



An integer constant expression with a value of 0, or such a cast to type expression void *

, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unevenly with a pointer to any object or function.

Example ( http://ideone.com/9917zk ):

#include <stdio.h>

int main(void)
{
    int *varname = {0};

    printf("%p\n", (void *) varname);

    return 0;
}

      

Its conclusion:

(nil)

      

(as a bonus, note that the term nil

was invented by Alfred Tarski )

+2


source


This is fair, we can see it by going to the C99 Draft Project Initialization 6.7.8

Parameter 11

which reads:

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

So:

int *varname = {0}; 

      



initializes to a varname

null pointer, since it 0

is a null pointer constant according to the 6.3.2.3

Pointers section :

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

and for completeness, we know that pointers are scalar types based on the 6.2.5

Types section :

Arithmetic and pointer types are collectively referred to as scalar types [...]

+4


source


As Grzegorz Sppetkowski says, this syntax:

int *varname = {0};

      

... He just doesn't do what I suspect, you think he should. This is equivalent to

int *varname = 0;

      

which is equivalent

int *varname = NULL

      

(assumed to be displayed NULL

).

If my guess about what you are trying to do is wrong, the rest of this answer does not apply.


Based on the comments, it looks like this is not what the OP was trying to do. Not sure if to delete this answer or not; this might be a good answer to some other question.


You can initialize the pointer char*

to point to a string literal:

char *cptr = "hello";

      

A string literal "hello"

implicitly creates an anonymous array object with static storage duration; initialization forces cptr

to point to that original array element.

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

C99 added complex literals. For example, this:

(int){42}

      

creates an object int

with a value 42

. Unlike a literal 42

, this actually creates an object, not just a value, which means it has an address. So:

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

      

creates an anonymous object int

with an initial value 42

and initializes iptr

to point to it. (If your compiler supports complex literals.)

Component literals are commonly used for array and structure types, but they are also valid for scalar types.

Beware: an array created by a string literal always has a static storage duration, that is, it exists throughout the entire execution of the program. The length of time an anonymous object created by a compound literal is stored depends on where it appears. If it is inside a function, the object has automatic storage duration, which means that it ceases to exist as soon as execution exits from the nearest closing block.

So, given:

char *cptr = "hello";

      

you can safely return the value cptr

from the function and it will continue to act. But given:

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

      

returning a value iptr

from a function would be dangerous because the object it points to will cease to exist before the caller receives the pointer value.

An easier way to do this is to define the object yourself:

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

      

You can define obj

how static

if needed.

+2


source







All Articles