0

I have a simple for loop (though it is not the only component within the method) that is compiled with GNU 4.8.1.10 compiler with debugging option is off and optimization levels O-0, O-2 and O-3 distinctively. The loop is as below:

const int iMyConst = 10; // defined in another header
void myFunc(uint8_t ui8InputNum)
{
  // some stuff 
  for(int i=static_cast<int>(ui8InputNum); i<iMyConst; i++)
  { // loop content
   }
}

What happens is that, when I call myFunc(10) (equal to iMyConst), the for loop is executed. This is not the expected behaviour. Inside the loop I printed the variable values as well. They are printed as expected but with an exception: i<iMyConst came out to be true where i was printed as 10. Moreover, I forced all process to run on single core, the unexpected behaviour happened again.

I ran the code in debug mode, and saw that the loop is not executed as expected. Then I defined the loop variable as volatile int i, this time the loop is not executed as well.

The problem might sound odd but it is all what happened. What is the cause of this problem? The system is 64-bit and has 12 cores.

// main.cpp
//============================================================================
// Name        : loopProblem.cpp
//============================================================================
#include "a.h"
#include "b.h"
#include <iostream>


int main() {
    a* myA = new a;
    b* myB = new b;
    myB->itsA = myA;
    myB->dummyFunc();
    delete myA;
    delete myB;
    return 0;
}
// a.h
#ifndef A_H_
#define A_H_

#include <stdint.h>
// #include <cstdint> not available in c++03

class a
{
    public:
        a();
        ~a();

        void myFunc(uint8_t ui8InputNum);
};



#endif /* A_H_ */
// a.cpp
#include "a.h"
#include "c.h"
#include <cstdio>

a::a()
{
}

a::~a()
{
}

void a::myFunc(uint8_t ui8InputNum)
{
    // some stuff

    for(int i=static_cast<int>(ui8InputNum); i<iMyConst; i++)
    {
        printf("i: %d, comp: %d\n", i, (i<iMyConst));
    }
}
// b.h
#ifndef B_H_
#define B_H_

class a;

class b {
public:
    b();
    ~b();
    a* itsA;

    void dummyFunc();
};

#endif /* B_H_ */
// b.cpp
#include "b.h"
#include "a.h"
#include <cstddef>

b::b() : itsA(NULL)
{
}

b::~b()
{
}

void b::dummyFunc() {
    itsA->myFunc(10);
}
// c.h
#ifndef C_H_
#define C_H_

const int iMyConst = 10;

#endif /* C_H_ */
Erdem Tuna
  • 500
  • 4
  • 18
  • 3
    The nastier the bizarre behaviour, the more likely a [mre] is a must to get to the bottom of the problem. For all we know there's a race condition that exposes a bit of UB that just happens to alter the value of `i`. The missing return type on `myFunc` probably doesn't help, though. – user4581301 Nov 26 '20 at 18:35
  • 2
    Shall we assume the function is declared properly with a specified return type? Submit a proper [mcve]. And don't be surprised if you discover the issue yourself whilst building it. The fact that you mentioned several times the core-count and SMP nature of the runtime conditions suggests there's a helluvalot more going on here than you're hinting at. The function as-shown has no reentrancy issues, but for all we know you're grasping and SMP has nothing to do with any of this. – WhozCraig Nov 26 '20 at 18:35
  • 3
    This sort of thing is often what happens when you have some form of "undefined behaviour" and the optimizer makes assumptions that aren't true. In this case, it seems like the optimizer thinks the loop always runs at least once. Can you show us the assembly code for your loop? – user253751 Nov 26 '20 at 18:44
  • @user4581301 @WhozCraig , I checked it several times, the return type and declaration should be fine and it is `void` indeed. I will try to generate an example set of files. – Erdem Tuna Nov 26 '20 at 18:44
  • @user253751 , I didn't check the assembly code, but I can go through that in debug mode with instruction stepping I suppose? – Erdem Tuna Nov 26 '20 at 18:45
  • "Inside the loop I printed the variable values as well" let us see that code. Currently we are looking at code that is different from yours and probably has completely different behavior. Consider that you don't know where the problem really is, so leaving out seemingly unrelated stuff might be just where the actual problem is. [mcve] please – 463035818_is_not_an_ai Nov 26 '20 at 18:45
  • 1
    https://stackoverflow.com/questions/22769246/how-to-disassemble-one-single-function-using-objdump – user253751 Nov 26 '20 at 18:46
  • 1
    I added the example code, if anyone interested. @idclev463035818 – Erdem Tuna Nov 26 '20 at 19:10
  • 1
    [Can't preproduce](https://godbolt.org/z/noK3en) - what if you print `iMyConst` in the function? Does it print `10`? – Ted Lyngmo Nov 26 '20 at 20:32
  • @tedLyngmo yes it printed correctly 10. – Erdem Tuna Nov 26 '20 at 21:18
  • 1
    @ErdemTuna Odd. I used the same compiler version and options. Can you try to declare `extern const int iMyConst;` in `c.h` and move the definition of `iMyConst` into `c.cpp`? It's just a shot in the dark, but worth trying. It shouldn't be a problem in this case, but ... – Ted Lyngmo Nov 26 '20 at 21:53
  • @TedLyngmo I tried that as well, didnt work... – Erdem Tuna Nov 27 '20 at 19:07
  • Can out of bounds read/write of an array at an earlier point in the code cause such a problem? – Erdem Tuna Nov 27 '20 at 19:08
  • 1
    Can you reproduce it with a fresh installation of the toolkit? – Ted Lyngmo Nov 27 '20 at 19:11
  • @TedLyngmo I didn't try to reinstall the toolkit, but I will try that, thank you for the suggestion. If it fails either, then it is related with runtime behaviour... – Erdem Tuna Nov 27 '20 at 19:19
  • 1
    I see that I missed a part of the question: "_Can out of bounds read/write of an array at an earlier point in the code cause such a problem?_" - Yes, it can. In fact, that could gravitate a black hole close enough to swollow the entire multiverse. The C++ specification does not exclude that scenario. If your code contains more than you've shown - it may have been subjected to such a scenario. (undefined behavior) – Ted Lyngmo Nov 28 '20 at 00:39
  • 1
    I didn't realize such a thing until the very last minute, something popped in my mind. I might have missed that, I will check it and update the situation @TedLyngmo. – Erdem Tuna Nov 28 '20 at 16:33
  • @TedLyngmo there is an out of bound read in myFunc before the if check. – Erdem Tuna Nov 30 '20 at 08:33
  • 1
    @ErdemTuna Ok. Do you still have the same problem after having fixed that bug? – Ted Lyngmo Nov 30 '20 at 08:34
  • 1
    @TedLyngmo The behaviour is now as expected after fixing the bug. Thank you for your help. – Erdem Tuna Nov 30 '20 at 08:55

0 Answers0