3

this is my code which I expect to see

7, 3, 5, 1, 9

as output but it prints

0, 7, 3, 5, 1

#include <stdio.h>
#define LEN 5

int main(int argc, char const *argv[])
{
    int arr[LEN];
    int index;
    arr[0] = 7;
    arr[1] = 3;
    arr[2] = 5;
    arr[3] = 1;
    arr[4] = 9;

    int ITM;
    for(int IDX = 0; IDX < sizeof(arr) / sizeof(int); ITM = arr[IDX++]){
        printf("%d, ", ITM);    
    }

    return 0;
}

what is wrong with this code?

BTW, I know that I can move "ITM = arr[IDX++]" into loop body!

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
sepisoad
  • 2,201
  • 5
  • 26
  • 37
  • 1
    So... what do you know about the `for` statement? – Amit Oct 05 '16 at 08:07
  • 2
    I agree - there *is* nothing wrong with this question. It's well-written, has a code snippet, and expected and actual output. What could be better? Please do not downvote on grounds of obviousness. – Bathsheba Oct 05 '16 at 08:13
  • 2
    @Bathsheba, Ashish, sepisoad - In a community based system, the community controls the content, and in the SO community that means voting. The voting system is to be used at the discretion of us all, and we all have the right (obligation if you ask me) to use it how we see fit. As for the closing reason - I think minimal effort is a prerequisite for posting a question. This was clearly not demonstrated in this question. and is what I expressed in my close reason. I don't see any of that as being "not nice", and the one comment that does use foul language (sepisoad's) is the one to criticize. – Amit Oct 05 '16 at 08:27
  • Simply uncrappify the loop so that the 3 loop conditions are only related to the loop iterator, without non-related side-effects: `for(int IDX = 0; IDX < sizeof(arr)/sizeof(*arr); IDX++){ ITM = arr[IDX]; printf("%d, ", ITM); }` – Lundin Oct 05 '16 at 09:00
  • 1
    @Amit: we do ask you to come up with a valid off-topic reason; not enough research is not one of those, that's what the downvote option is for. – Martijn Pieters Oct 05 '16 at 10:00
  • @MartijnPieters - would you be so kind to explain ["*Any background research you've tried but wasn't enough to solve your problem*"](http://stackoverflow.com/help/quality-standards-error) than (and the information in [here](http://meta.stackexchange.com/questions/92074/what-can-i-do-when-getting-it-does-not-meet-our-quality-standards))? Unfortunately, "low quality" is not a predefined close reason, so I tried to make the most of what is available... – Amit Oct 05 '16 at 10:18
  • 1
    @Amit: again, quality is **not** an off-topic reason. Low quality can be improved on by editing. The information you are linking to prevents posts that don't meet a minimum bar from being posted, but that doesn't mean that those posts would otherwise be off-topic. – Martijn Pieters Oct 05 '16 at 10:22
  • 1
    @Amit: if you have further questions about this, you can come to [chat] or take it to [meta]. – Martijn Pieters Oct 05 '16 at 10:23

3 Answers3

3

The last statement of the for loop is executed after the first iteration (or IDX would be 1 at once)

So at first ITM is just undefined.

EDIT: after providing a potentially unsafe macro, I removed it from my post. I suppose that if you want to use foreach stuff, switch to C++ 11.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • actually I wanted to write a foreach macro using this loop, is there a workaround? – sepisoad Oct 05 '16 at 08:09
  • 2
    strictly speaking, `i=a[++IDX]` is UB for the last iteration with IDX == number of elements - 1 – Ingo Leonhardt Oct 05 '16 at 08:37
  • 2
    Please don't recommend to use such ugly, unsafe macros. This is very bad programming practice. Overall, re-inventing the C language and replacing it with your private, secret macro language is a genuinely bad idea. – Lundin Oct 05 '16 at 09:02
  • `FOREACH(my_incorrect_type, arr)` Halt and catch fire. `FOREACH(ITM, incorrect_array_type)` Halt and catch fire. `FOREACH(IDX, arr)` Halt and catch fire. `FOREACH(ITM, pointer)` Halt and catch fire. I'm starting to notice a use-case pattern here... – Lundin Oct 05 '16 at 09:10
  • you're both right. It was fun but I'll edit it out because of UB. – Jean-François Fabre Oct 05 '16 at 09:16
3

The behaviour of your program is undefined due to your reading the unitialised variable ITM on the first iteration of the for loop.

ITM is not set to anything until ITM = arr[IDX++] is evaluated, and that doesn't happen until program control gets to the closing } of the for loop.

Writing flashy code like this is occasionally useful, but you need to be aware of the pitfalls.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0
#define LEN 5

int main(int argc, char const *argv[])
{
    int arr[LEN];
    int index;
    arr[0] = 7;
    arr[1] = 3;
    arr[2] = 5;
    arr[3] = 1;
    arr[4] = 9;

    for(int i = 0; i < sizeof(arr) / sizeof(int); i++){
        printf("%d, ", arr[i]);
    }
    printf("\n");


    return 0;
}

if you want to use foreach in c read that

Community
  • 1
  • 1
Michael1248
  • 150
  • 1
  • 12