-2

I've already broken my head over what's wrong here. In the output I literally get nothing. It is very strange that nothing is output through a normal cout.

Help me please! Thank you.

int main() {
    int x = 111111;
    array<int, 10> numbers;
    numbers.fill(8);
    const auto numbers_copy = numbers;
    int y = 222222;
    
    for (int* i = &y; i <= &x; i++) {
        cout << *i << ' ';
    }
    cout << endl;
}

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
toiepp
  • 85
  • 6
  • 3
    The code has undefined behavior. – Vlad from Moscow Jul 28 '20 at 21:52
  • 4
    What are you actually trying to do in that for loop? – Michael Dorgan Jul 28 '20 at 21:54
  • @MichaelDorgan iterate over stack – toiepp Jul 28 '20 at 21:57
  • @toiepp: That's not a thing C++ allows you to do. Not with well-defined behavior. – Nicol Bolas Jul 28 '20 at 22:08
  • @NicolBolas thats not my code, i just saw it in Coursera course and in this course this code works. Thatswhy I'm so confused. – toiepp Jul 28 '20 at 22:11
  • @NicolBolas in that course this code gave `222222 8 8 8 8 8 8 8 8 8 8 123 0 11111` in output – toiepp Jul 28 '20 at 22:13
  • 1
    If this code is claimed to be correct, then I strongly suggest finding some other learning material. – cigien Jul 28 '20 at 22:15
  • @cigien thank you for your advice – toiepp Jul 28 '20 at 22:17
  • 2
    You are in trouble if X and Y are registers. However, since you take the address of them, they can't be in registers. They can be in different memory segments, not necessarily the stack. – Thomas Matthews Jul 28 '20 at 22:35
  • To follow up, if you wanted to iterate overall all those elements, they would need to be in a stucture together. Also not 100% certain at all the array<> doesn't have some glue structures that would prevent this from working. Then you could take the address of the first element and increment the pointer until it is equal to the last - providing array<> doesn't have a unaligned memory that would cause this to fail. All told, not at all a good example to be following. – Michael Dorgan Jul 29 '20 at 00:20
  • While iterating over stack is not well defined in general, I see how this is still a useful exercise to understand how the call stack works – Yuri Feldman Jul 30 '20 at 05:04

1 Answers1

3

This loop:

for (int* i = &y; i <= &x; i++) {

has undefined behavior (UB).

Comparing pointers to unrelated objects has unspecified results. In this case i is pointing to 2 different int objects, x and y, so the first comparison may or may not be true, because there is no guarantee that 2 objects on the stack will be placed one after the other contiguously in memory, or in any particular order.

The same applies to the second iteration of the loop. In the second iteration, when you do i++ for the second time, this is undefined behavior, since you can't increment i that far when it points to an int.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • But these are local variables allocated on the stack, so i should be traversing the stack, no? What am I missing? – Yuri Feldman Jul 28 '20 at 21:54
  • you can compare them but you can get either result. UB is inrementing i – 463035818_is_not_an_ai Jul 28 '20 at 21:55
  • 3
    @YuriFeldman You are comparing pointers of unrelated variables. There is no guarantee to what order variables on the stack are placed. You are *assuming* that `y` has a lower memory address than `x`, but that may not actually be true. Only memory addresses of elements belonging to the same array can be traversed like this in a well-defined way. Otherwise, put the variables into a `class`/`struct` instead, and then traverse the memory of that object as needed. – Remy Lebeau Jul 28 '20 at 21:56
  • But they normally are, aren't they? So possibly on OP's machine stack grows the other way around? Thanks! – Yuri Feldman Jul 28 '20 at 21:58
  • not sure but I interpret this https://eel.is/c++draft/expr.rel#4.3 as you can get true or false, but comparing them is valid – 463035818_is_not_an_ai Jul 28 '20 at 21:58
  • @idclev463035818 Hmm, interesting. The increment of `i` is allowed once actually, it's considered one past the end. Not sure about the comparison. – cigien Jul 28 '20 at 22:01
  • @idclev463035818 Edited the answer to explain where the UB actually comes from. – cigien Jul 28 '20 at 22:06