-6

Acording to the Post: With arrays, why is it the case that a[5] == 5[a]?

Where is claimed, that a[5] is equal to 5[a].

I'm asking my self, is this true?

While I aggree that E1[E2] is identical to (*((E1)+(E2)))

But I would claim: Given a declaration of

int a[sizeI];

where if (sizeI > 5) has to be true

I would aggree that a[5] is ok.

But related to the cite from ISO/IEC:9899

Apendix J.2 Undefined behavior:

— An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

Is (if I get it correct from the document) 5[a] "apparently accessible" but the "array subscript is out of range" So I would overall disaggree to the OP I linked, as that a[5] is in the given case well defined and 5[a] is undefined behaviour.

So, am I right? Or have I forgotten to consider something important?

EDIT:

my claim doesn't imply that

E1[E2] is identical to (*((E1)+(E2)))

would be incorrect.

and also 6.5.2.1 Array subscripting point 2

just says that they are arithmeticaly identical. But nothing is said like: (*((E1)+(E2))) can't achive UB.

So while I know this section, I can't find there anything thatdestroys my claim

Also Note:

As you allready should see in my first sentence, I'm asking a different question to the related to the "problem" stated by

With arrays, why is it the case that a[5] == 5[a]?

So please stop marking it as duplicate of that one.

Community
  • 1
  • 1
dhein
  • 6,431
  • 4
  • 42
  • 74
  • 1
    Duplicate https://stackoverflow.com/questions/381542/with-c-arrays-why-is-it-the-case-that-a5-5a – Lydia Ralph Apr 01 '15 at 11:57
  • Why -1?.... explain please... – dhein Apr 01 '15 at 11:59
  • @alex: yeah, but thats because it is related to that post, as My claim is, the claim of that post is wrong and I'm asking for support or guidance. – dhein Apr 01 '15 at 12:01
  • 2
    I honestly got lost in the question and had to reread it. Please consider making it more concise. Are you asking whether 5[a] is UB? – Andrey Apr 01 '15 at 12:02
  • @Andrey: In short term: yes. – dhein Apr 01 '15 at 12:03
  • 2
    This shows some effort at a quick glance. I suspect you'll need to edit the title to make it really clear that it's not a dup though to avoid getting buried. :P – Ulfalizer Apr 01 '15 at 12:03
  • `a[5] == *(a + 5) == *(5 + a) == 5[a]`. See 6,5,2.1/2. – John Bode Apr 01 '15 at 12:03
  • 1
    The standard explicitly says `The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).` – teppic Apr 01 '15 at 12:06
  • @JohnBode: I'm not quite sure about that. Because `a[1][8]` == `*(a + (1 * 8))` what should be equal to `a[2][4]` == `*(a + (2 * 4))`, but my cite quotes it sin't. – dhein Apr 01 '15 at 12:07
  • 3
    `a[1][8]` is not equivalent to `*(a + (1 * 8))` as you claim. It is equivalent to `*(*(a + 1) + 8)`. – interjay Apr 01 '15 at 12:10
  • @Zaibis your quote is double index, which is not exactly same as single index. shortly X[i][j] = X + i*(size of row) + j – Andrey Apr 01 '15 at 12:10
  • I did a quick edit to the title to make it look less dup'ey. – Ulfalizer Apr 01 '15 at 12:20
  • @interjay: would it really be `*(*(a + 1) + 8)` or had it to be something like `*(*(a[] + 1) + 8)` by syntax? – dhein Apr 01 '15 at 12:47
  • @Zaibis `a[]` is not valid syntax. I don't know why you think it's correct. – interjay Apr 01 '15 at 13:16
  • @interjay: I dont do so, I said "something like" because I know it isn't that way valid. But regarding to array decay, it felt wrong for me to not append anything to `a` in yur snippet – dhein Apr 01 '15 at 13:19

3 Answers3

2

To see why the note in Appendix J.2 is compatible with a[b] being the same as *(a + b), consider how an expression like a[1][7] is interpreted (assuming the declaration int a[4][5], like in the appendix):

a[1][7] is the same as *(a[1] + 7). Each element of the array a is a five-element array, so that a[1] evaluates to a pointer to the first element of a five-element array. If you add 7 to such a pointer, then the resulting pointer will point outside the five-element array, meaning you are not allowed to dereference it (standards-wise -- it might work in practice). But that's exactly what the above expression does.

The note in Appendix J.2 has nothing to do with a[5] vs. 5[a] by the way. If the array has at least six elements, then it would be reasonable to call the element "apparently accessible" in both of those expressions. They're only trying to clarify that you're not allowed to access a multidimensional array with overflow in any of the indices, even when it looks like it shouldn't overflow the boundaries of the multidimensional array. It's just a note -- you can derive it independently (as above).

Ulfalizer
  • 4,664
  • 1
  • 21
  • 30
  • Ah, that revealed the black magic behind the scene for me. Didn't know thats the way it gets unnested. – dhein Apr 01 '15 at 12:39
  • @Zaibis: Yeah, multidimensional arrays in C are just arrays of arrays, so it works consistently that way. – Ulfalizer Apr 01 '15 at 12:47
  • "you can derive it independently (as above)." You are the only one who respected this. thats why I will accept your answer. But I will wait a bit, that it gets more attention, as this would be well to know for others too, I would suggest. – dhein Apr 01 '15 at 12:49
  • @Zaibis: Provided it doesn't get deleted :/. Maybe you could mention "appendix" or "note" or the like in the title too. – Ulfalizer Apr 01 '15 at 12:52
  • I have trouble in phrasing complex sentences. I don't know how to improve it that it gets even more viewable that I'm asking what I ask. :/ – dhein Apr 01 '15 at 12:54
  • I guess the question I actually answered was how the note in the appendix is compatible with `a[b] == *(a + b)`. For the `5[a]` part, you do get an object if you do that, so the subscript `a` isn't out of range. Can't really edit questions to turn them into a different question though. :P – Ulfalizer Apr 01 '15 at 13:01
1

5 is not an array, so 5[a] is not an array subscript.

Either way, Annex J is informative which means that it is meant for extra helpfulness and not as a part of the specification. So we cannot make any claims about undefined behaviour solely based on what J.2 says.

The normative section about pointer arithmetic is 6.3.2.3 which includes the proof that 5[a] and a[5] are identical.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Not to 100% addressing my question. – dhein Apr 01 '15 at 12:42
  • 1
    @Zaibis your question seems unclear. Addressing the sentences with question mark: "I'm asking my self, is this true?" - yes. "So, am I right?" - no. "Or have I forgotten to consider something important?" - yes, Annex J is non-normative. "Why `5[a]` with C arrays isn't out of range?" - it depends on what `a` is. For example If `a` is a 4-element array then it certainly is out of range. – M.M Apr 01 '15 at 12:52
  • "I'm asking my self" I'm not asking the audience (so introductive related to what made my feel to have to post this). "So, am I right? Or have I forgotten to consider something important?" Is a single quote which expects the one or the other hand. (you splitted it in 2 quotes). "it depends on what `a` is." -> Thats why I gave a strict declaration for `a`. So after all there is just ONE question. where "You forgot Annex J is non-normative." Isn't 100% related to my problem, because as @Ulfalizer sated correct: the Annex J cite isn't incompatible with my claim. – dhein Apr 01 '15 at 13:00
  • @Zaibis given that definition of `a`, then `5[a]` is correct . What is "your claim" exactly? You say "But I would claim... `a[5]` is ok". If your claim is that `a[5]` is OK then nobody is disagreeing. Is this whole thread an april fool? – M.M Apr 01 '15 at 13:03
  • My claim is that a[5] is true while in the given case 5[a] isn't. My claim is wrong. Thats related to my post and correct by your answer (that's why I didn't downvote it) But the reason you gave (The last sentence of your answer) doesn't explain WHY it is identical. (As I said in my OP I also knew that section 6.3.2.3 but probably just didn't get it right. so just pointing me to that section doesn't fit my needs by 100%) – dhein Apr 01 '15 at 13:08
  • @Zaibis the answers on the [other question you linked](http://stackoverflow.com/q/381542/2003898) explain why `a[5]` and `5[a]` are identical; and it is elementary logic to say that if two things are identical and one is true, then the other one is also true. – M.M Apr 01 '15 at 13:12
  • Anyway that didn't address (both, you and the answers there) WHY it is identical and anyway not incompatible with J.2 (As accepted answer states it isn't incompatible with J.2) and you say it IS incompatible. And that is just my point. – dhein Apr 01 '15 at 13:16
  • @Zaibis The other question does address exactly why it is identical. The J.2 is irrelevant because it is non-normative. Judging by the voting, I don't think anybody can figure out what your point is. – M.M Apr 01 '15 at 13:19
  • I think so too, thats why I try to clarify, but obviously, I'm not able to. – dhein Apr 01 '15 at 13:22
  • Well, I give it a last try: Appendix J.2 isn't normative. AFAIK that means it only "triggers" if there is nothing else saying something different. According to my cite (which was irrelevant, but I didn't knew at that point, why it isn't rellevant) I wanted to get to know, why `5[a]` isn't out of range in view of the appendix part I cited. And my trouble was: Just mentioning it is irrelevant doesn't solve my trouble in understanding why it isn't. And thats why finally @Ulfalizer hitted my point, as he explained why the way it evaluates isn't in relation to my cite of J.2. I hope its now clear. – dhein Apr 01 '15 at 13:33
  • @Zaibis: "Not normative" means that those parts contain no requirements at all. Think of it as clarifications and "for your information"-type stuff. – Ulfalizer Apr 01 '15 at 13:51
-2

I think that it is true. Probably it is okay because it makes the same calculation like:

 *(arr + 4) // For the arr[4]
 *(4 + arr) // For the 4[arr]

Which concludes on the same result.

#include <stdio.h>

int main(void)
{
    int arr[5] = {1,2,3,4,5};
    printf("\n%d %d\n", arr[4], 4[arr]);
    printf("\n%d %d\n", arr[5], 5[arr]);
    printf("\n%d %d\n\n", arr[6], 6[arr]);

    return 0;
}

In each printf the behaviour will be as expected.

L0aD1nG
  • 111
  • 1
  • 10