# Can Clang produce smaller DWM than GCC?



## sw2wolf (Jun 17, 2013)

```
CC       = clang
creating config.h from config.def.h
CC drw.c
In file included from drw.c:5:
In file included from /usr/X11R6/include/X11/Xlib.h:47:
/usr/X11R6/include/X11/Xfuncproto.h:134:24: warning: named variadic macros are a GNU
      extension [-pedantic,-Wvariadic-macros]
#define _X_NONNULL(args...)  __attribute__((nonnull(args)))
                       ^
1 warning generated.
CC dwm.c
In file included from dwm.c:36:
In file included from /usr/X11R6/include/X11/Xlib.h:47:
/usr/X11R6/include/X11/Xfuncproto.h:134:24: warning: named variadic macros are a GNU
      extension [-pedantic,-Wvariadic-macros]
#define _X_NONNULL(args...)  __attribute__((nonnull(args)))
                       ^
In file included from dwm.c:289:
./config.h:45:82: warning: multi-line // comment [-pedantic,-Wcomment]
  ...MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
                                                                                 ^
./config.h:129:30: warning: initializing 'char *const' with an expression of type
      'const char *' discards qualifiers [-Wincompatible-pointer-types]
        execv(p, (char * const []) {p, NULL});
                                    ^
3 warnings generated.
CC util.c
CC -o dwm
~/RnD/dwm $ ls -l dwm
-rwxr-xr-x   1 sw2wolf        wheel       31532  6 17 11:34 dwm


----------------------------

CC       = cc
creating config.h from config.def.h
CC drw.c
In file included from /usr/X11R6/include/X11/Xlib.h:47,
                 from drw.c:5:
/usr/X11R6/include/X11/Xfuncproto.h:134:24: warning: ISO C does not permit named variadic macros
CC dwm.c
In file included from /usr/X11R6/include/X11/Xlib.h:47,
                 from dwm.c:36:
/usr/X11R6/include/X11/Xfuncproto.h:134:24: warning: ISO C does not permit named variadic macros
In file included from dwm.c:289:
config.h:45:2: warning: multi-line comment
In file included from dwm.c:289:
config.h: In function 'self_restart':
config.h:129: warning: initialization discards qualifiers from pointer target type
CC util.c
CC -o dwm
~/RnD/dwm $ ls -l dwm
-rwxr-xr-x   1 sw2wolf        wheel       27844  6 17 11:36 dwm
```
Seems GCC wins*?*

Regards!


----------



## Crivens (Jun 17, 2013)

For proper (well, a more "proper") comparison - please also post the size of the DWM created by GCC. Your system can be i386, amd64 or any other supported platform. From this post, no one can tell.

Then, when you have both binaries, please use `objdump -hp <file>` to check the size of the sections.


----------



## sw2wolf (Jun 17, 2013)

Crivens said:
			
		

> For proper (well, a more "proper") comparison - please also post the size of the DWM created by GCC. Your system can be i386, amd64 or any other supported platform. From this post, no one can tell.
> 
> Then, when you have both binaries, please use `objdump -hp <file>` to check the size of the sections.




```
$ uname -a
FreeBSD mybsd.zsoft.com 9.0-RELEASE-p7 FreeBSD 9.0-RELEASE-p7 #1: Fri May 10 13:16:28 CST 2013     sw2wolf@mybsd.zsoft.com:/usr/obj/usr/src/sys/MYKERNEL  i386
```

BTW, the size is already in post.

`$objdump -hp ~/bin/dwm-gcc`


```
/home/sw2wolf/bin/dwm-gcc:     file format elf32-i386-freebsd

Program Header:
    PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
         filesz 0x00000100 memsz 0x00000100 flags r-x
  INTERP off    0x00000134 vaddr 0x08048134 paddr 0x08048134 align 2**0
         filesz 0x00000015 memsz 0x00000015 flags r--
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x0000600c memsz 0x0000600c flags r-x
    LOAD off    0x0000600c vaddr 0x0804f00c paddr 0x0804f00c align 2**12
         filesz 0x00000444 memsz 0x0000065c flags rw-
 DYNAMIC off    0x00006020 vaddr 0x0804f020 paddr 0x0804f020 align 2**2
         filesz 0x000000d0 memsz 0x000000d0 flags rw-
    NOTE off    0x0000014c vaddr 0x0804814c paddr 0x0804814c align 2**2
         filesz 0x00000018 memsz 0x00000018 flags r--
EH_FRAME off    0x00005fc0 vaddr 0x0804dfc0 paddr 0x0804dfc0 align 2**2
         filesz 0x00000014 memsz 0x00000014 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rw-

Dynamic Section:
  NEEDED      libX11.so.6
  NEEDED      libc.so.7
  INIT        0x8049518
  FINI        0x804daec
  HASH        0x8048164
  STRTAB      0x8048b88
  SYMTAB      0x80484a8
  STRSZ       0x56b
  SYMENT      0x10
  DEBUG       0x0
  PLTGOT      0x804f0f0
  PLTRELSZ    0x320
  PLTREL      0x11
  JMPREL      0x80491f8
  REL         0x80491f0
  RELSZ       0x8
  RELENT      0x8
  VERNEED     0x80491d0
  VERNEEDNUM  0x1
  VERSYM      0x80490f4

Version References:
  required from libc.so.7:
    0x077a28b0 0x00 02 FBSD_1.0

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000015  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000018  0804814c  0804814c  0000014c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000344  08048164  08048164  00000164  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       000006e0  080484a8  080484a8  000004a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       0000056b  08048b88  08048b88  00000b88  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  000000dc  080490f4  080490f4  000010f4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  080491d0  080491d0  000011d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000008  080491f0  080491f0  000011f0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000320  080491f8  080491f8  000011f8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000011  08049518  08049518  00001518  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000650  0804952c  0804952c  0000152c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00003f6c  08049b80  08049b80  00001b80  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000000c  0804daec  0804daec  00005aec  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       000004c8  0804daf8  0804daf8  00005af8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame_hdr 00000014  0804dfc0  0804dfc0  00005fc0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame     00000038  0804dfd4  0804dfd4  00005fd4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .ctors        00000008  0804f00c  0804f00c  0000600c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .dtors        00000008  0804f014  0804f014  00006014  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .jcr          00000004  0804f01c  0804f01c  0000601c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .dynamic      000000d0  0804f020  0804f020  00006020  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got.plt      0000019c  0804f0f0  0804f0f0  000060f0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         000001c4  0804f28c  0804f28c  0000628c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000218  0804f450  0804f450  00006450  2**2
                  ALLOC
 23 .comment      000002b1  00000000  00000000  00006450  2**0
                  CONTENTS, READONLY
```

`$objdump -hp ~/bin/dwm-clang`


```
/home/sw2wolf/bin/dwm-clang:     file format elf32-i386-freebsd

Program Header:
    PHDR off    0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
         filesz 0x00000100 memsz 0x00000100 flags r-x
  INTERP off    0x00000134 vaddr 0x08048134 paddr 0x08048134 align 2**0
         filesz 0x00000015 memsz 0x00000015 flags r--
    LOAD off    0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
         filesz 0x00006b38 memsz 0x00006b38 flags r-x
    LOAD off    0x00007000 vaddr 0x0804f000 paddr 0x0804f000 align 2**12
         filesz 0x00000440 memsz 0x00000660 flags rw-
 DYNAMIC off    0x00007014 vaddr 0x0804f014 paddr 0x0804f014 align 2**2
         filesz 0x000000d0 memsz 0x000000d0 flags rw-
    NOTE off    0x0000014c vaddr 0x0804814c paddr 0x0804814c align 2**2
         filesz 0x00000018 memsz 0x00000018 flags r--
EH_FRAME off    0x00006aec vaddr 0x0804eaec paddr 0x0804eaec align 2**2
         filesz 0x00000014 memsz 0x00000014 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rw-

Dynamic Section:
  NEEDED      libX11.so.6
  NEEDED      libc.so.7
  INIT        0x8049518
  FINI        0x804e62c
  HASH        0x8048164
  STRTAB      0x8048b88
  SYMTAB      0x80484a8
  STRSZ       0x56c
  SYMENT      0x10
  DEBUG       0x0
  PLTGOT      0x804f0e4
  PLTRELSZ    0x320
  PLTREL      0x11
  JMPREL      0x80491f8
  REL         0x80491f0
  RELSZ       0x8
  RELENT      0x8
  VERNEED     0x80491d0
  VERNEEDNUM  0x1
  VERSYM      0x80490f4

Version References:
  required from libc.so.7:
    0x077a28b0 0x00 02 FBSD_1.0

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000015  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000018  0804814c  0804814c  0000014c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         00000344  08048164  08048164  00000164  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       000006e0  080484a8  080484a8  000004a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       0000056c  08048b88  08048b88  00000b88  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  000000dc  080490f4  080490f4  000010f4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  080491d0  080491d0  000011d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000008  080491f0  080491f0  000011f0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000320  080491f8  080491f8  000011f8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000011  08049518  08049518  00001518  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000650  0804952c  0804952c  0000152c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00004aac  08049b80  08049b80  00001b80  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000000c  0804e62c  0804e62c  0000662c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       000004b4  0804e638  0804e638  00006638  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame_hdr 00000014  0804eaec  0804eaec  00006aec  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame     00000038  0804eb00  0804eb00  00006b00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .ctors        00000008  0804f000  0804f000  00007000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .dtors        00000008  0804f008  0804f008  00007008  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .jcr          00000004  0804f010  0804f010  00007010  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .dynamic      000000d0  0804f014  0804f014  00007014  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got.plt      0000019c  0804f0e4  0804f0e4  000070e4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         000001c0  0804f280  0804f280  00007280  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000220  0804f440  0804f440  00007440  2**3
                  ALLOC
 23 .comment      0000022a  00000000  00000000  00007440  2**0
                  CONTENTS, READONLY
```

Regards!


----------



## throAU (Jun 27, 2013)

sw2wolf said:
			
		

> Seems GCC wins?



For some definition of "win". There is more to "win" than code-size. Which runs faster?  Which compiled faster?  clang generates better compiler output.


----------



## sw2wolf (Jun 28, 2013)

throAU said:
			
		

> For some definition of "win". There is more to "win" than code-size. Which runs faster?  Which compiled faster?  clang generates better compiler output.


You are right!  *I* am using _a_ kernel generated by _C_lang now. It is a bit bigger but works great though.

```
[CMD=$]du -sh /boot/kernel/[/CMD]
 62M	/boot/kernel/

[CMD=$]du -sh /boot/kernel.old/[/CMD]
 57M	/boot/kernel.old/

$uname -a
FreeBSD mybsd.zsoft.com 9.1-RELEASE-p4 FreeBSD 9.1-RELEASE-p4 #3: Thu Jun 27 20:00:17 CST 2013     [email]sw2wolf@mybsd.zsoft.com[/email]:/usr/obj/usr/src/sys/MYKERNEL  i386

$ clang -v
FreeBSD clang version 3.1 (branches/release_31 156863) 20120523
Target: i386-unknown-freebsd9.0
Thread model: posix
```

Regards!


----------



## jozze (Jun 28, 2013)

throAU said:
			
		

> For some definition of "win". There is more to "win" than code-size. Which runs faster?  Which compiled faster?  clanggenerates better compiler output.



By compiler output I suspect you're referring to the errors and warnings that are displayed, not the produced binaries. I must agree with you. I am using clang for my own code, and it was really a saver in many situations.

I know this thread has been marked as "solved", but if you will allow me one last question (or rather a small set of questions), since it fits the topic:

On the binary performance side, I've only been able to find this "test". Does anyone know if there are better benchmarks regarding how different compiler impacts the binary performance? I don't care that much about size/speed-of-compilation but whether or not produced binaries are faster and still stable. I'd like to measure for example an impact on the kernel built with varying degrees of -O? optimizations. Any recommendations? I was thinking about measuring boot-time, but this seems too machine/external-configuration dependent.

BTW @sw2wolf, which clang version did you use? The base system has clang-3.2, but in ports clang-3.3 is available, which (according to that previous link) beats gcc-built-binaries on all optimization levels.


----------



## throAU (Jun 28, 2013)

jozze said:
			
		

> By compiler output I suspect you're referring to the errors and warnings that are displayed, not the produced binaries. I must agree with you. I am using clang for my own code, and it was really a saver in many situations.



Yes, exactly - compiler warnings that actually help quite a lot.

As far as measuring performance goes - boot time is a bit of a horrible metric as that will be largely determined by disk I/O and waiting for devices to initialize.  And really, when your machine is up for months or years at a time, who cares if it takes a few seconds more/less to boot? 

Maybe network firewall throughput (with a fairly complex rule-set to make the CPU bottleneck)?  Crypto throughput?

From what I've seen the performance crown tends to waver between the two compilers from release to release (and likely depends on the particular CPU family you are benchmarking on).  IMHO they're both close enough to render it moot.

If nothing else though I'd like to see clang become the standard compiler because more relevant, easier to understand warnings will likely encourage safer, less expoitable code.  Personally I'm more than willing to pay a performance penalty of say 15-20 percent for 10 percent fewer vulnerabilities to patch, or deal with when they are exploited.

I can throw more/bigger CPUs at the problem to improve performance if required - I can't do that to fix bugs.


----------



## Crivens (Jun 28, 2013)

You may have a look at this here for a project which checks for compiler regressions. Some interesting stuff to read. But as usual: so many interesting things, so little free time 

Maybe something like that framework would give good results for compiler comparison.


----------

