Блог пользователя Xiaohuba

Автор Xiaohuba, история, 3 месяца назад, По-английски

UPD: It is a compiler bug, and is resolved since gcc 12.3. Further information is on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116459.

[Apologize for my poor English.]

The code at https://godbolt.org/z/PP1TTdhxf outputs 1. However, if you simulate the code, the answer is obviously 20.

Further exploration showed that the compiler compiled function qpw, but did not call it. Uncomment line 22 solves the issue, surprisingly. Further more, the bug seems to only occur on gcc12.1 and gcc12.2, with -O2 enabled.

I believe the code does not contain any undefined / unspecified behavior.

  • Проголосовать: нравится
  • +15
  • Проголосовать: не нравится

»
3 месяца назад, # |
Rev. 2   Проголосовать: нравится -15 Проголосовать: не нравится

It was because when O2 enabled it does run faster however every variable you create if you don't have a value for it, it will be undefined instead of 0 like default. So therefore, you must define every variables before working on it. (So uncomment line 22 will actually solve the issue)

  • »
    »
    3 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Please read the code carefully. On line 9, I cleared up every variable in mat, and since it's a constructor, no undefined value is envolved during calculation.

    • »
      »
      »
      3 месяца назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      oh yeah I'm sorry about that, and I just find out that if you add cout<<b.mat[0][0]<<" "<<b.mat[0][1]<<" "<<b.mat[1][0]<<" "<<b.mat[1][1]<<"\n"; in your operator * (Matrix b) you will get 20

  • »
    »
    3 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Uncommenting line 22 makes a side affect, and avoids the compiler to (wrongly) optimize out the function call.

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

It seems like the compiler used qpw function as a constexpr one to optimize the call out, but it is not marked as constexpr. Very strange, maybe it is a bug indeed.

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I added an operator= function which works just fine. https://godbolt.org/z/vjb4vdczc

  • »
    »
    3 месяца назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Yes, the original code does have undefined behavior.

    The default behavior of Matrix= is to copy the pointer mat, so the function qpw creates the matrix st * res on the stack, copies it's pointer into the global object, but then after the function executes the pointer dangles.

    I'm a bit surprised the compiler can do this. I'll investigate more.

    • »
      »
      »
      3 месяца назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      The standard says that the default behavior of copy assignment is to do memberwise copy-assignment for arrays, which will copy the entire data instead of a pointer.

»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by Xiaohuba (previous revision, new revision, compare).