市民、幸せなのは義務なのです（コンパイラの最適化でメンバ関数の評価も消えるかな？）

# 市民、幸せなのは義務なのです（コンパイラの最適化で評価は消えるかな？）

ちょっと気になった。C++なんかであるクラスのメンバ関数が常にfalseを返す場合、最適化オプションによってその関数はリンク時に消えるのだろうか？それとも…？　ということで、確認してみた。

## TL;DR 最適化オプションによって、常にfalseを返すメンバ関数は無かったことにされる。

- class内でfalseを常に返すようにしたところ、O2オプションで当該関数の存在そのものが無かったことにされました。

## はじめに

下記ツイートを見て、当該コードを動かしたい衝動にかられた。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">if (you.areHappy()) {<br> you.clapHands();<br>}<br>if (you.areHappy()) {<br> you.clapHands();<br>}<br>if (you.areHappy()) {<br> you.expressEmotion();<br>}<br>everyone.clapHands();</p>&mdash; ぼて (@fujikenbotebote) <a href="https://twitter.com/fujikenbotebote/status/1357855367053463553?ref_src=twsrc%5Etfw">February 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">コンパイラ「最適化かけたら、 everyone.clapHands();だけになった…」</p>&mdash; (*´▽｀*) (@hon_no_mushi) <a href="https://twitter.com/hon_no_mushi/status/1357886522091970564?ref_src=twsrc%5Etfw">February 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">かなしいなぁ<br><br>class Human {<br> boolean areHappy() {<br> return false;<br> }<br>}</p>&mdash; ぼて (@fujikenbotebote) <a href="https://twitter.com/fujikenbotebote/status/1357888357418717186?ref_src=twsrc%5Etfw">February 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 実験環境

![clang++-11.0.0](https://img.shields.io/badge/clang\+\+-11.0.0-green)

```
kmtr@ubuntu2010:~/work/clap$ clang++ --version
Ubuntu clang version 11.0.0-2
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```


## ソースコード

```cpp:main.cpp
#include <iostream>
#include <vector>

class Human {
private:
    std::string mName;
public:
    Human(std::string name): mName(name) {};
    bool areHappy() {
        return false;
    }
    void clapHands() {
        std::cout << mName << " PAN PAN!" << std::endl;
    }
    void expressEmotion(){
        std::cout << mName << " I'm happy!!" << std::endl;
    }
};

class HumanGroups {
private:
    std::vector < Human* > members;
public:
    void assign(Human *target){
        members.push_back( target );
    }

    void clapHands(){
        for(auto&& it : members ){
            it->clapHands();
        }
    }
};

int main(){
  Human me("me");
  Human you("you");
  HumanGroups everyone;
  everyone.assign(&me);
  everyone.assign(&you);

  if (you.areHappy()) {
    you.clapHands();
  }
  if (you.areHappy()) {
    you.clapHands();
  }
  if (you.areHappy()) {
    you.expressEmotion();
  }
  everyone.clapHands();
}
```

# 実行結果

物悲しいですが、ここまでは想定の結果…

```
kmtr@ubuntu2010:~/work/clap$ ./a.out
me PAN PAN!
you PAN PAN!
```

# 確認：最適化オプションは、我々が幸福であるかの確認さえもなくするのか？

さて、常にfalseが帰るareHappy()の結果、更にその結果で呼ばれるclapHands()は消去されるのでしょうかね（想定通り）。

```
kmtr@ubuntu2010:~/work/clap$ readelf -W -s a.out.O0 | grep areH
    53: 00000000004015b0    17 FUNC    WEAK   DEFAULT   13 _ZN5Human8areHappyEv
kmtr@ubuntu2010:~/work/clap$ readelf -W -s a.out.O2 | grep areH
kmtr@ubuntu2010:~/work/clap$
```

無くなってしまいました。

# まとめ：最適化オプションによって、常にfalseを返すメンバ関数は無かったことにされる。
- class内でfalseを常に返すようにしたところ、O2オプションで当該関数の存在そのものが無かったことにされました。

以上になります。


# おまけ

## O0オプション時
```nasm:objdump結果(O0)
00000000004012c0 <main>:
  4012c0:       55                      push   %rbp
  4012c1:       48 89 e5                mov    %rsp,%rbp
  4012c4:       48 81 ec e0 00 00 00    sub    $0xe0,%rsp
  4012cb:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
  4012d2:       48 8d 45 b0             lea    -0x50(%rbp),%rax
  4012d6:       48 89 c7                mov    %rax,%rdi
  4012d9:       48 89 85 38 ff ff ff    mov    %rax,-0xc8(%rbp)
  4012e0:       e8 7b fe ff ff          callq  401160 <_ZNSaIcEC1Ev@plt>
  4012e5:       be 04 30 40 00          mov    $0x403004,%esi
  4012ea:       48 8d 7d b8             lea    -0x48(%rbp),%rdi
  4012ee:       48 8b 95 38 ff ff ff    mov    -0xc8(%rbp),%rdx
  4012f5:       e8 16 fe ff ff          callq  401110 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@plt>
  4012fa:       e9 00 00 00 00          jmpq   4012ff <main+0x3f>
  4012ff:       48 8d 7d d8             lea    -0x28(%rbp),%rdi
  401303:       48 8d 75 b8             lea    -0x48(%rbp),%rsi
  401307:       e8 34 02 00 00          callq  401540 <_ZN5HumanC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>
  40130c:       e9 00 00 00 00          jmpq   401311 <main+0x51>
  401311:       48 8d 7d b8             lea    -0x48(%rbp),%rdi
  401315:       e8 76 fd ff ff          callq  401090 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
  40131a:       48 8d 7d b0             lea    -0x50(%rbp),%rdi
  40131e:       e8 dd fd ff ff          callq  401100 <_ZNSaIcED1Ev@plt>
  401323:       48 8d 85 58 ff ff ff    lea    -0xa8(%rbp),%rax
  40132a:       48 89 c7                mov    %rax,%rdi
  40132d:       48 89 85 30 ff ff ff    mov    %rax,-0xd0(%rbp)
  401334:       e8 27 fe ff ff          callq  401160 <_ZNSaIcEC1Ev@plt>
  401339:       be 07 30 40 00          mov    $0x403007,%esi
  40133e:       48 8d bd 60 ff ff ff    lea    -0xa0(%rbp),%rdi
  401345:       48 8b 95 30 ff ff ff    mov    -0xd0(%rbp),%rdx
  40134c:       e8 bf fd ff ff          callq  401110 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@plt>
  401351:       e9 00 00 00 00          jmpq   401356 <main+0x96>
  401356:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  40135a:       48 8d b5 60 ff ff ff    lea    -0xa0(%rbp),%rsi
  401361:       e8 da 01 00 00          callq  401540 <_ZN5HumanC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>
  401366:       e9 00 00 00 00          jmpq   40136b <main+0xab>
  40136b:       48 8d bd 60 ff ff ff    lea    -0xa0(%rbp),%rdi
  401372:       e8 19 fd ff ff          callq  401090 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
  401377:       48 8d bd 58 ff ff ff    lea    -0xa8(%rbp),%rdi
  40137e:       e8 7d fd ff ff          callq  401100 <_ZNSaIcED1Ev@plt>
  401383:       48 8d 85 40 ff ff ff    lea    -0xc0(%rbp),%rax
  40138a:       48 89 c7                mov    %rax,%rdi
  40138d:       48 89 85 28 ff ff ff    mov    %rax,-0xd8(%rbp)
  401394:       e8 c7 01 00 00          callq  401560 <_ZN11HumanGroupsC2Ev>
  401399:       48 8d 75 d8             lea    -0x28(%rbp),%rsi
  40139d:       48 8b bd 28 ff ff ff    mov    -0xd8(%rbp),%rdi
  4013a4:       e8 d7 01 00 00          callq  401580 <_ZN11HumanGroups6assignEP5Human>
  4013a9:       e9 00 00 00 00          jmpq   4013ae <main+0xee>
  4013ae:       48 8d bd 40 ff ff ff    lea    -0xc0(%rbp),%rdi
  4013b5:       48 8d 75 80             lea    -0x80(%rbp),%rsi
  4013b9:       e8 c2 01 00 00          callq  401580 <_ZN11HumanGroups6assignEP5Human>
  4013be:       e9 00 00 00 00          jmpq   4013c3 <main+0x103>
  4013c3:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  4013c7:       e8 e4 01 00 00          callq  4015b0 <_ZN5Human8areHappyEv>
  4013cc:       88 85 27 ff ff ff       mov    %al,-0xd9(%rbp)
  4013d2:       e9 00 00 00 00          jmpq   4013d7 <main+0x117>
  4013d7:       8a 85 27 ff ff ff       mov    -0xd9(%rbp),%al
  4013dd:       a8 01                   test   $0x1,%al
  4013df:       0f 85 05 00 00 00       jne    4013ea <main+0x12a>
  4013e5:       e9 8e 00 00 00          jmpq   401478 <main+0x1b8>
  4013ea:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  4013ee:       e8 dd 01 00 00          callq  4015d0 <_ZN5Human9clapHandsEv>
  4013f3:       e9 00 00 00 00          jmpq   4013f8 <main+0x138>
  4013f8:       e9 7b 00 00 00          jmpq   401478 <main+0x1b8>
  4013fd:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  401401:       89 55 a4                mov    %edx,-0x5c(%rbp)
  401404:       e9 10 00 00 00          jmpq   401419 <main+0x159>
  401409:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  40140d:       89 55 a4                mov    %edx,-0x5c(%rbp)
  401410:       48 8d 7d b8             lea    -0x48(%rbp),%rdi
  401414:       e8 77 fc ff ff          callq  401090 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
  401419:       48 8d 7d b0             lea    -0x50(%rbp),%rdi
  40141d:       e8 de fc ff ff          callq  401100 <_ZNSaIcED1Ev@plt>
  401422:       e9 09 01 00 00          jmpq   401530 <main+0x270>
  401427:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  40142b:       89 55 a4                mov    %edx,-0x5c(%rbp)
  40142e:       e9 13 00 00 00          jmpq   401446 <main+0x186>
  401433:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  401437:       89 55 a4                mov    %edx,-0x5c(%rbp)
  40143a:       48 8d bd 60 ff ff ff    lea    -0xa0(%rbp),%rdi
  401441:       e8 4a fc ff ff          callq  401090 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
  401446:       48 8d bd 58 ff ff ff    lea    -0xa8(%rbp),%rdi
  40144d:       e8 ae fc ff ff          callq  401100 <_ZNSaIcED1Ev@plt>
  401452:       e9 d0 00 00 00          jmpq   401527 <main+0x267>
  401457:       48 89 45 a8             mov    %rax,-0x58(%rbp)
  40145b:       89 55 a4                mov    %edx,-0x5c(%rbp)
  40145e:       48 8d bd 40 ff ff ff    lea    -0xc0(%rbp),%rdi
  401465:       e8 86 02 00 00          callq  4016f0 <_ZN11HumanGroupsD2Ev>
  40146a:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  40146e:       e8 9d 02 00 00          callq  401710 <_ZN5HumanD2Ev>
  401473:       e9 af 00 00 00          jmpq   401527 <main+0x267>
  401478:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  40147c:       e8 2f 01 00 00          callq  4015b0 <_ZN5Human8areHappyEv>
  401481:       88 85 26 ff ff ff       mov    %al,-0xda(%rbp)
  401487:       e9 00 00 00 00          jmpq   40148c <main+0x1cc>
  40148c:       8a 85 26 ff ff ff       mov    -0xda(%rbp),%al
  401492:       a8 01                   test   $0x1,%al
  401494:       0f 85 05 00 00 00       jne    40149f <main+0x1df>
  40149a:       e9 13 00 00 00          jmpq   4014b2 <main+0x1f2>
  40149f:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  4014a3:       e8 28 01 00 00          callq  4015d0 <_ZN5Human9clapHandsEv>
  4014a8:       e9 00 00 00 00          jmpq   4014ad <main+0x1ed>
  4014ad:       e9 00 00 00 00          jmpq   4014b2 <main+0x1f2>
  4014b2:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  4014b6:       e8 f5 00 00 00          callq  4015b0 <_ZN5Human8areHappyEv>
  4014bb:       88 85 25 ff ff ff       mov    %al,-0xdb(%rbp)
  4014c1:       e9 00 00 00 00          jmpq   4014c6 <main+0x206>
  4014c6:       8a 85 25 ff ff ff       mov    -0xdb(%rbp),%al
  4014cc:       a8 01                   test   $0x1,%al
  4014ce:       0f 85 05 00 00 00       jne    4014d9 <main+0x219>
  4014d4:       e9 13 00 00 00          jmpq   4014ec <main+0x22c>
  4014d9:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  4014dd:       e8 3e 01 00 00          callq  401620 <_ZN5Human14expressEmotionEv>
  4014e2:       e9 00 00 00 00          jmpq   4014e7 <main+0x227>
  4014e7:       e9 00 00 00 00          jmpq   4014ec <main+0x22c>
  4014ec:       48 8d bd 40 ff ff ff    lea    -0xc0(%rbp),%rdi
  4014f3:       e8 78 01 00 00          callq  401670 <_ZN11HumanGroups9clapHandsEv>
  4014f8:       e9 00 00 00 00          jmpq   4014fd <main+0x23d>
  4014fd:       48 8d bd 40 ff ff ff    lea    -0xc0(%rbp),%rdi
  401504:       e8 e7 01 00 00          callq  4016f0 <_ZN11HumanGroupsD2Ev>
  401509:       48 8d 7d 80             lea    -0x80(%rbp),%rdi
  40150d:       e8 fe 01 00 00          callq  401710 <_ZN5HumanD2Ev>
  401512:       48 8d 7d d8             lea    -0x28(%rbp),%rdi
  401516:       e8 f5 01 00 00          callq  401710 <_ZN5HumanD2Ev>
  40151b:       8b 45 fc                mov    -0x4(%rbp),%eax
  40151e:       48 81 c4 e0 00 00 00    add    $0xe0,%rsp
  401525:       5d                      pop    %rbp
  401526:       c3                      retq
  401527:       48 8d 7d d8             lea    -0x28(%rbp),%rdi
  40152b:       e8 e0 01 00 00          callq  401710 <_ZN5HumanD2Ev>
  401530:       48 8b 7d a8             mov    -0x58(%rbp),%rdi
  401534:       e8 17 fc ff ff          callq  401150 <_Unwind_Resume@plt>
  401539:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

```

## O2オプション時

```nasm:objdump結果(O2)
0000000000401200 <main>:
  401200:       41 57                   push   %r15
  401202:       41 56                   push   %r14
  401204:       41 55                   push   %r13
  401206:       41 54                   push   %r12
  401208:       53                      push   %rbx
  401209:       48 81 ec 80 00 00 00    sub    $0x80,%rsp
  401210:       48 8d 44 24 50          lea    0x50(%rsp),%rax
  401215:       48 89 44 24 40          mov    %rax,0x40(%rsp)
  40121a:       66 c7 44 24 50 6d 65    movw   $0x656d,0x50(%rsp)
  401221:       48 c7 44 24 48 02 00    movq   $0x2,0x48(%rsp)
  401228:       00 00
  40122a:       c6 44 24 52 00          movb   $0x0,0x52(%rsp)
  40122f:       4c 8d 64 24 10          lea    0x10(%rsp),%r12
  401234:       4c 89 24 24             mov    %r12,(%rsp)
  401238:       66 c7 44 24 10 6d 65    movw   $0x656d,0x10(%rsp)
  40123f:       48 c7 44 24 08 02 00    movq   $0x2,0x8(%rsp)
  401246:       00 00
  401248:       c6 44 24 12 00          movb   $0x0,0x12(%rsp)
  40124d:       48 8d 44 24 70          lea    0x70(%rsp),%rax
  401252:       48 89 44 24 60          mov    %rax,0x60(%rsp)
  401257:       c7 44 24 70 79 6f 75    movl   $0x756f79,0x70(%rsp)
  40125e:       00
  40125f:       48 c7 44 24 68 03 00    movq   $0x3,0x68(%rsp)
  401266:       00 00
  401268:       4c 8d 6c 24 30          lea    0x30(%rsp),%r13
  40126d:       4c 89 6c 24 20          mov    %r13,0x20(%rsp)
  401272:       c7 44 24 30 79 6f 75    movl   $0x756f79,0x30(%rsp)
  401279:       00
  40127a:       48 c7 44 24 28 03 00    movq   $0x3,0x28(%rsp)
  401281:       00 00
  401283:       bf 08 00 00 00          mov    $0x8,%edi
  401288:       e8 e3 fd ff ff          callq  401070 <_Znwm@plt>
  40128d:       49 89 c7                mov    %rax,%r15
  401290:       48 89 e0                mov    %rsp,%rax
  401293:       49 89 07                mov    %rax,(%r15)
  401296:       bf 10 00 00 00          mov    $0x10,%edi
  40129b:       e8 d0 fd ff ff          callq  401070 <_Znwm@plt>
  4012a0:       48 89 c3                mov    %rax,%rbx
  4012a3:       48 8d 44 24 20          lea    0x20(%rsp),%rax
  4012a8:       48 89 43 08             mov    %rax,0x8(%rbx)
  4012ac:       49 8b 07                mov    (%r15),%rax
  4012af:       48 89 03                mov    %rax,(%rbx)
  4012b2:       4c 89 ff                mov    %r15,%rdi
  4012b5:       e8 a6 fd ff ff          callq  401060 <_ZdlPv@plt>
  4012ba:       48 8b 3b                mov    (%rbx),%rdi
  4012bd:       e8 7e 00 00 00          callq  401340 <_ZN5Human9clapHandsEv>
  4012c2:       48 8b 7b 08             mov    0x8(%rbx),%rdi
  4012c6:       e8 75 00 00 00          callq  401340 <_ZN5Human9clapHandsEv>
  4012cb:       48 89 df                mov    %rbx,%rdi
  4012ce:       e8 8d fd ff ff          callq  401060 <_ZdlPv@plt>
  4012d3:       48 8b 7c 24 20          mov    0x20(%rsp),%rdi
  4012d8:       4c 39 ef                cmp    %r13,%rdi
  4012db:       74 05                   je     4012e2 <main+0xe2>
  4012dd:       e8 7e fd ff ff          callq  401060 <_ZdlPv@plt>
  4012e2:       48 8b 3c 24             mov    (%rsp),%rdi
  4012e6:       4c 39 e7                cmp    %r12,%rdi
  4012e9:       74 05                   je     4012f0 <main+0xf0>
  4012eb:       e8 70 fd ff ff          callq  401060 <_ZdlPv@plt>
  4012f0:       31 c0                   xor    %eax,%eax
  4012f2:       48 81 c4 80 00 00 00    add    $0x80,%rsp
  4012f9:       5b                      pop    %rbx
  4012fa:       41 5c                   pop    %r12
  4012fc:       41 5d                   pop    %r13
  4012fe:       41 5e                   pop    %r14
  401300:       41 5f                   pop    %r15
  401302:       c3                      retq
  401303:       49 89 c6                mov    %rax,%r14
  401306:       4c 89 fb                mov    %r15,%rbx
  401309:       eb 08                   jmp    401313 <main+0x113>
  40130b:       49 89 c6                mov    %rax,%r14
  40130e:       eb 0b                   jmp    40131b <main+0x11b>
  401310:       49 89 c6                mov    %rax,%r14
  401313:       48 89 df                mov    %rbx,%rdi
  401316:       e8 45 fd ff ff          callq  401060 <_ZdlPv@plt>
  40131b:       48 8b 7c 24 20          mov    0x20(%rsp),%rdi
  401320:       4c 39 ef                cmp    %r13,%rdi
  401323:       74 05                   je     40132a <main+0x12a>
  401325:       e8 36 fd ff ff          callq  401060 <_ZdlPv@plt>
  40132a:       48 8b 3c 24             mov    (%rsp),%rdi
  40132e:       4c 39 e7                cmp    %r12,%rdi
  401331:       74 05                   je     401338 <main+0x138>
  401333:       e8 28 fd ff ff          callq  401060 <_ZdlPv@plt>
  401338:       4c 89 f7                mov    %r14,%rdi
  40133b:       e8 90 fd ff ff          callq  4010d0 <_Unwind_Resume@plt>
```