1

This question is a followup to this one: Question on Undefined Behaviour (UB) and loop optimization

When using https://godbolt.org/ online compiler (g++ 7.2, x86_64) with -O2 setting, the loop condition gets optimized out when the loop contains std::cout but not with an identical loop using printf.

Any idea why? Both code versions are compiled with the C++ compiler. Both versions produce an UB warning, but no warning without -O2, even though the code is still in UB land.

FWIW, I also tried the MIPS g++ compiler, that one does not seem to optimize out the loop condition even with std::cout code version and -O2.

I can provide the compiler outputs if necessary, but the std::cout version is quite long.

#include <stdio.h>
int main()
{
    for (int i = 0; i < 300; i++)
        printf("%d %d", i, i*12345678);
}

/*#include <iostream>                                                                                                                                                                                                                                                                     
int main()                                                                                                                                                                                                                                                                                
{                                                                                                                                                                                                                                                                                         
    for (int i = 0; i < 300; i++)                                                                                                                                                                                                                                                         
        std::cout << i << " " << i * 12345678 << std::endl;                                                                                                                                                                                                                               
}*/

UPDATE: On suggestion from the comments, I removed the UB, then even the printf version removes the loop condition, instead jumping out of the loop when i is 11 (very unsurprising), see below:

#include <stdio.h>
int main()
{
    for (int i = 0; i < 300; i++) {
        printf("%d %d", i, i*123); 
        if (i * 123 > 1230) break;
    }
}

// Generated assembly:

LC0:
.string "%d %d"
main:
  push rbp
  push rbx
  xor edx, edx
  xor esi, esi
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  sub rsp, 8
  mov ebp, 123
  xor ebx, ebx
  call printf
.L2:
  add ebx, 1
  mov edx, ebp
  xor eax, eax
  mov esi, ebx
  mov edi, OFFSET FLAT:.LC0
  add ebp, 123
  call printf
  cmp ebx, 11
  jne .L2
  add rsp, 8
  xor eax, eax
  pop rbx
  pop rbp
  ret
Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
  • so why multiply by such a big number? Did you need to do that to get the loop optimisation to differ? Sounds like it might be related to the UB to me; but then trying to comment on 'why' for any program with UB is futile. – UKMonkey Feb 13 '18 at 10:22
  • 4
    We cannot conclude anything from an UB. This is pointless. – YSC Feb 13 '18 at 10:26
  • would be an interesting question if you first fix the UB. In the presence of UB, afaik compiler is allowed to turn the whole loop into a noop, irrespective of `cout` or `printf` – 463035818_is_not_an_ai Feb 13 '18 at 10:28
  • The original question and accepted answer got a large number of upvotes, I think the optimization part is interesting even in spite of the UB. – Erik Alapää Feb 13 '18 at 10:31
  • 1
    i could imagine that it is the `...` in `int printf ( const char * format, ... );` that prevents the compiler from knowing that `i` wont change during the call to `printf` – 463035818_is_not_an_ai Feb 13 '18 at 10:33
  • "The original question... got a large number of upvotes" It also got downvotes. There was much discussion there about why UB optimisations isn't worth discussion. Why do you expect trying to continue the discussion will be a good question when it is, in fact a duplicate? – UKMonkey Feb 13 '18 at 10:42
  • 1
    @UKMonkey It is definitely not a duplicate. – Erik Alapää Feb 13 '18 at 10:43
  • I agree that the optimization part is interesting, but imho you are turning too many knobs at once. Why dont you first see what the compiler does when there is no UB and only then add UB? – 463035818_is_not_an_ai Feb 13 '18 at 10:53
  • @user463035818 Good point, removed UB, see updated question. – Erik Alapää Feb 13 '18 at 11:11
  • @UKMonkey The original UB question got 53 upvotes and 6 downvotes, so the verdict of the community is pretty clear. SO police, stay away from meddling with interesting questions :) – Erik Alapää Feb 13 '18 at 12:34
  • In a another question about gcc aggressive loop optimization [this was one possible explanation](https://stackoverflow.com/questions/32506643/c-compilation-bug#comment52886602_32506643) – Shafik Yaghmour Feb 13 '18 at 16:52

0 Answers0