1

It's safe initialize pointers using compound literals in such way and it's possible at all?:

#include <stdio.h>
#include <string.h>

void numbers(int **p)
{
        *p = (int []){1, 2, 3};
}

void chars(char **p)
{
        *p = (char[]){'a','b','c'};
}

int main()
{
    int *n;
    char *ch;

    numbers(&n);
    chars(&ch);
    printf("%d %c %c\n", n[0], ch[0], ch[1]);
}

output:

1 a b

I don't understand exactly how it's works, does it's not the same as init pointer with local variable?

also if i try to print:

printf("%s\n", ch);

It's print nothing.

2 Answers2

5

A compound literal declared inside a function has automatic storage duration associated with its enclosing block (C 2018 6.5.2.5 5), which means its lifetime ends when execution of the block ends.

Inside numbers, *p = (int []){1, 2, 3}; assigns the address of the compound literal to *p. When numbers returns, the compound literal ceases to exist, and the pointer is invalid. After this, the behavior of a program that uses the pointer is undefined. The program might be able to print values because the data is still in memory, or the program might print different values because memory has changed, or the program might trap because it tried to access inaccessible memory, or the entire behavior of the program may change in drastic ways because compiler optimization changed the undefined behavior into something else completely.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    If `chars()` had instead contained `*p = "abc";` would this have behaved differently? – Tim Randall Oct 26 '18 at 12:36
  • 1
    @TimRandall Yes. String literals are a special case, as they are guaranteed to always have static storage duration (C17 6.4.5/6). String literals are "primary expressions" in C, part of the lexical elements of the language. Compound literals are rather to be regarded as variables declared through a special operator. They share some oddities with string literals though, such that each string or compound literal need not designate an unique object. Allowing for optimization techniques to save memory, such as "string pooling". – Lundin Oct 26 '18 at 13:16
3

It depends on where the compound literal is placed.

C17 6.5.2.5 §5

The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

That is, if the compound literal is at local scope, it works exactly like a local variable/array and it is not safe to return a pointer to it from a function.

If it is however declared at file scope, it works like any other variable with static storage duration, and you can safely return a pointer to it. However, doing so is probably an indication of questionable design. Plus you'll get the usual thread-safety issues in a multi-threaded application.

Lundin
  • 195,001
  • 40
  • 254
  • 396