Exceptions to array decaying into a pointer?
Asked Answered
G

1

97

I have seen in many posts that "in most of the cases array names decay into pointers".
Can I know in what cases/expressions the array name doesn't decay into a pointer to its first elements?

Gilding answered 19/7, 2013 at 18:21 Comment(5)
More context is required: Are you working in a specific language? Do you have an example?Chelsiechelsy
consider C language. And i'm looking for an example where array names doesn't decay into pointer.Gilding
@TheJoker I given here an answer in which I show this casesBoccie
Re H2Co3's second point, i.e. with sizeof, I'm reading Head First C, and it first illustrates pointer decay using sizeof(msg) inside a function where msg was passed in as an argument. They had a little box explaining that an array variable decays to a pointer when it's passed into a function as an argument (paraphrasing) so you get 4 or 8 (bytes), not array size. I got confused because in the next chapter on the string library, they introduce strlen() and use it the same way they'd used sizeof(). I came here to straighten my head out and now you twisted it up a little more. :PAntihalation
This answer has all the exceptions with examples.Victuals
P
80

Sure.

In C99 there are three fundamental cases, namely:

  1. when it's the argument of the & (address-of) operator.

  2. when it's the argument of the sizeof operator.

  3. When it's a string literal of type char [N + 1] or a wide string literal of type wchar_t [N + 1] (N is the length of the string) which is used to initialize an array, as in char str[] = "foo"; or wchar_t wstr[] = L"foo";.

Furthermore, in C11, the newly introduced alignof operator doesn't let its array argument decay into a pointer either.

In C++, there are additional rules, for example, when it's passed by reference.

Pyrophyllite answered 19/7, 2013 at 18:26 Comment(16)
I'm sorry, but could you explain the 3rd case more clearly? I mean isn't the str in the third case used to refer to the memory location of the string? Hence a pointer again?Gilding
@TheJoker No, that would be const char *str_ptr = "literal";. In my example, str is declared as an array, hence it is an array.Pyrophyllite
@H2CO3 did you get me? actually I refer your answer in my linked answer. :)Boccie
3rd case is not a case. It's just one of the cases for array initialization syntax when it's an array of char. The right side of an array initialization statement doesn't even take an expression, so it doesn't make sense as an answer to this question.Kattiekatuscha
@Kattiekatuscha I suggest you read the relevant section of the C standard - literally these cases are enumerated. Furthermore, in an array initialization, if and only if the RHS is a string literal, then it is an expression (of array type), not an initializer list.Pyrophyllite
@H2CO3: First of all, for initialization it specifically says "string literal". It does not say anything about "array expression" or "expression" at all. So the string literal syntax just happens to be used in two places: as the right side of an initialization, and also as an expression. That does not mean the right side of initialization is an expression. Plus, the question specifically asked about "array name", and a string literal is not an array name, and you cannot put an array name (or any other array expression except a string literal) on the right side of an initialization for array.Kattiekatuscha
I agree with @newacct, it doesn't make sense to initialize and array with an expression, since array initialization is essentially about initializing all the elements of the array that you are trying to initialize, and that's why we use brace-enclosed initializer or in the case of an array of char a string literal syntax. So the string literal for example "hello" is a syntax that is used for two different things depending on the context: 1) as unnamed static array of constant char. 2) as a syntax in the right side of an array of char initialization.Mitsukomitt
@Mitsukomitt possibly. nevertheless, string literals are of array type.Pyrophyllite
@H2CO3 If string literals were of array type, then this should fail to compile, char c[10]="hi"; because you are assigning char[3] to char[10], but in reality it does compile just fine. With that being said, when I was referring to 'string literals' in my last comment, I meant by it a syntax by which it's meaning change depending on its context. so string literals are not always of array type.Mitsukomitt
@Mitsukomitt I know it compiles, and I accept that array initialization with string literals is a special syntax. However, if we accept the presence of special syntax and exceptions, then we can as well accept that const char foo[] = <another array>; is fine -- only if the array is a string literal.Pyrophyllite
@Mitsukomitt By the way, the standard is ambiguous at best as to what a string literal really is. It says "A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes", and that it "is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.". Furthermore, later it says "It is unspecified whether these arrays are distinct". So once string literals are arrays, once they are not... then who knows what they are?Pyrophyllite
@H2CO3 that's a different thing, but it is also possible if the standard choosed to do so, but it's not the case. I will explain why it is different, when you you do char c[]="hello"; the exception here is about how to implement the string literal "hello". But to do something like ` const char foo[] = <another array>; ` the compiler must have an implementation of how to initialize an array with another array which was not possible before, after all array are kind of second class-citizens.Mitsukomitt
This answer misses the _Alignof operator that has been added in C11.Vainglory
@JensGustedt; Nope. It shouldn't be added there!Brahe
Upcoming C23 standard will add typeof and typeof_unqual. Both don't decay their array operand.Encarnalize
_Alignof does not take an expression operand, so it is not possible to give it an array. (It only takes a type name enclosed in parentheses.)Shorthand

© 2022 - 2024 — McMap. All rights reserved.