#Initializer lists

63 messages · Page 1 of 1 (latest)

frail pivot
#
  1. What are the possible ways to declare an initializer list, and
  2. What's the difference between using an initializer list and using an lvalue to the array?
honest swanBOT
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

frail pivot
#

Like I know that you can write {1,2,[x]=3,4,5} to write an array

#

And you have to put (int[]) if you want to use it for anything but initialization

#

What else?

#

Are compound literals or initializer lists modifiable?

strong grove
#

I don't think struct obj obj(1,5,7,8); would work

frail pivot
strong grove
#

oh

graceful spear
#

I am not sure what you're asking about tbh, even accounting for that last nugget of information, that it's only about arrays

What are the possible ways to declare an initializer list
I'm not sure what you mean by "declare", as far as I know in C you don't really declare an initializer list and you cannot really manipulate it as an independent entity you can refer to later on. If this was C++ I'd be asking you meant std::initializer_list, but in C I'm confused by what you mean by "declaring an initializer list"

What's the difference between using an initializer list and using an lvalue to the array?
this also confuses me

Like I know that you can write {1,2,[x]=3,4,5} to write an array
And you have to put (int[]) if you want to use it for anything but initialization
when you write (int[]){1, 2, 3, 4, 5} you have a compound literal, I assume that's what you meant by "put (int[])"
I'm confused by the "use it for anything but initialization" though, when you're dealing with compound literals you have an lvalue expression, in the example I just wrote the object has type int[5] or "array to 5 int", so what do you by "it" when you say "use it for anything but initialization"? if you meant "initializer list" and if by initializer list you mean the {1, 2, 3, 4, 5} part, then my first comment is that this "initializer list" is "just" a piece of syntax, and this syntax is used specifically to specify the initial value of the object created by the compound literal, so you're still in an "initialization context"

What else?
I'm still not sure I understand your questions so it's hard to generalize to anything

Are compound literals or initializer lists modifiable?
initializer list are a piece of syntax and not objects or entities in and of themselves
a compound literal is an expression that refers to an object, that object may have its value modified under the correct circumstances

#

;compile

#include <stdio.h>

void foo(int* arr, int size)
{
    int* end = arr + size;
    for(int* ptr = arr; ptr != end; ++ptr)
        *ptr += 1;
}

int main(void)
{
    int* ptr =(int[]){1, 2, 3};
    foo(ptr, 3);
    printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]);
}
eager flintBOT
#
Program Output
2 3 4
frail pivot
graceful spear
#

by an lvalue to the array i mean like, the name of a variable or a dereferenced pointer

int arr1[]{1, 2, 3};
// arr1 -> lvalue to an array

int (*ptr_to_arr)[3] = &arr1;
// *ptr_to_arr -> lvalue to an array

if you mean that then we can be in agreement, but my confusion has more to do with the question in and of itself, lvalue to arrays and initializer list aren't comparable at all as far as I'm concerned
at this point I have convinced myself that we don't use the words "initializer list" to refer to the same thing

#

also what are the 'correct circumstances' to modify a compound literal?
well a compound literal is also a piece of syntax, so if you mean modify the object to which the compound literal expression refer, you need to be able to modify that object just like any other object

#

so the object must exist and not be const

#

granted I'm not up-to-date with the rules of C surrounding const and when you can/cannot bypass it without UB

frail pivot
#

here's one thing im still unclear on:
you can write char array[] = "test" or char *array = "test" but can you write either int array[] = {1,2,3} or int *array = {1,2,3}?

graceful spear
#

there are special rules for string literals

#

by default I would recommend to avoid char *array = "test"; because doing

char *array = "test";
array[0] = 'c';

is not allowed

violet nacelle
#

char *array = "test"
This is not an array

graceful spear
#

I'm not up to date with c syntax, but in c++ int array[] = {1,2,3}; would work yes, and I'm pretty sure it should work in c
I think the bit that works in c++ but not c is skipping the = as in int array[] {1,2,3}; but I'd have to ask a compiler to be sure
or read the c standard

as for int *array = {1,2,3}; that should be ill-formed and trigger a compile error

#

the pointer needs to point to something, and {1,2,3} is not a thing

#

{1,2,3} is a piece of syntax and that piece of syntax does not create an object on its own

frail pivot
violet nacelle
frail pivot
#

does that work in c++ though??

#

;compile c++int array[] {1,2,3}; int main(void){}

eager flintBOT
#
Compilation successful
frail pivot
#

that is so weird

graceful spear
# frail pivot strdup it then?

if you're gonna duplicate it, why assign the string literal to a pointer to a type that allows you to mistakenly try to modify the string literal

#

duplicate it outright without doing an ambiguously weird assignment

frail pivot
graceful spear
#

your example did

#

which is why I made the remark

frail pivot
#

ok then

graceful spear
#

"test" is a string literal

#

array is a variable of type char*

#

you initialize the pointer array with the string literal

#

well assuming char *array = "test"; with the semi colon at the end

frail pivot
#

right

#

then i suggested char *s = strdup("test");

#

and you said "why assign the string literal to a pointer to a type that allows you to mistakenly try to modify the string literal"

graceful spear
#

yes, because my point still stand, don't "assign" the string literal to a pointer and prefer using different constructs that don't rely on this "assignment"
duplicating the array via strdup or other means is such an alternative construct
there is a different discussion to be had about whether you should be using strdup specifically for purpose of this duplication, but that is a separate topic

frail pivot
#

fair enough

twilit ferry
#

Compound literals have object identity don’t they? I think they’re just scoped to the current scope? So you could take a pointer to it and assign it to a lhs pointer? It’s just that it doesn’t exist after the scope ends so you’d get a dangling pointer.? Or am I just wrong about this?

tribal siren
#

you can use them in a called function

#
foo(&(struct bar){"qux"});

^ the pointer is in scope whilst foo() is executing

graceful spear
#

I had a random example earlier with an array compound literal

#

I genuinely do not remember what the scope is, when you have a compound literal as part of a function call

#

by default I'd say the block in which the function call expression appears but I don't c enough to remember

frail pivot
#

oh is that a compound literal but a struct?

tribal siren
#

imagine the struct has a char const *s; member

twilit ferry
#
        struct Bar {
            int foo;
        };

        struct Bar b1 = { 42};                 // positional initializer
        struct Bar b2 = { .foo = 42};          // designated initializer.
        struct Bar b3 = (struct Bar){42};      // compound literal
        struct Bar b4 = (struct Bar){.foo=42}; // compound literal

b1 and b2 are using initializer lists to initialize the variables. This construct is "a piece of syntax that does not create an object on its own.
b3 and b4 are using compound literals to initialize the variables. These are actual objects at runtime created in the local scope.

small ember
#

are you sure you are not confusing c and c++

tribal siren