1

Let's say I have the following struct and two versions to initialize it:

#include <stdio.h>

typedef struct Car *CarPtr;
typedef struct Car {
        const char*     name;
        unsigned int    price;
} Car;

int main(void) {

    Car ford = {
        .name = "Ford F-150",
        .price = 25000
    };
    print_struct(&ford);

    // is this possible to do in a single assignment?
    CarPtr jeep = {
        .name = "Jeep",
        .price = 40000
    };
    print_struct(jeep);

}

Is the second version possible to do directly? Or do I need to do something along the lines of:

CarPtr jeep;
jeep->name = "Jeep";
jeep->price = 40000;

Or what's the proper way to initialize the CarPtr type directly?

5
  • Pointers need to be allocated before the pointee can be initialized/assigned Commented Jan 6, 2021 at 22:00
  • You might want to read this stackoverflow.com/questions/750178/… Commented Jan 6, 2021 at 22:03
  • 1
    @AdnanAhmed new is C++. This is tagged C Commented Jan 6, 2021 at 22:06
  • @Heal Sorry i had overlooked that. The comment had been edited. Commented Jan 6, 2021 at 22:11
  • Since its a pointer you will have to use malloc for CarPtr also you haven't assigned any Car type variable's address to CarPtr in the last example in code and using a constructor function such as Car_new that uses malloc is recommended for initialization. Commented Jan 6, 2021 at 22:13

2 Answers 2

2

Pointers, other than null pointers, need to point to objects that exist (which can be memory that has been allocated but not yet filled in). You can define a pointer and initialize it to an object you create at the same time, using a compound literal:

CarPtr jeep = & (Car) { .name = "Jeep", .price = 40000 };

This is a special syntax, with the type name in parentheses followed by braces containing initializers just as in a definition. (It is not a cast.)

You can also pass a compound literal or its address directly to a function:

print_struct(& (Car) { .name = "Jeep", .price = 40000 });

However, this has limited uses, as, if this is done inside a function, the object is temporary; its lifetime lasts only as long as the current function execution lasts. You can use a compound literal outside a function, and then it lasts for all of program execution. You should have a general understanding and awareness of the properties of compound literals before using them.

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

1 Comment

I see -- thanks for that! I was trying to do &{ .name = "Jeep", .price = 40000} directly but I think I need to explicitly say that the struct is a Car for that to work.
1

CarPtr is a pointer (scalar object) that may be initialized by a braced list containing only a single expression.

So this initialization

CarPtr jeep = {
    .name = "Jeep",
    .price = 40000
};

is incorrect.

Something similar to what you are trying to achieve looks with using a compound literal the following way.

#include <stdio.h>

typedef struct Car *CarPtr;
typedef struct Car {
        const char*     name;
        unsigned int    price;
} Car;

int main( void )
{
    CarPtr jeep = &( Car ){ .name = "Jeep", .price = 40000 };
    
    printf( "%s - %u\n", jeep->name, jeep->price );
}

The program output is

Jeep - 40000

Pay attention to that you shall not free the pointed object by using the standard function free because the compound literal has automatic storage duration in this context.

Comments

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.