Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Embeddable GCC

Name: Anonymous 2016-09-08 14:56

Is there a small version of GCC for shipping with Windows program? Because Mingw installation takes frigging gigabyte, including a lot of bloat, like C++ and fortran compiler, with useless crap, like directx bindings.

Name: Anonymous 2016-09-08 14:58

Clang is frigging enormous too. Just executable takes 50 megabytes.

Name: Anonymous 2016-09-08 15:13

Cygwin is pretty big as well - 100MB for a base install. Unless you want to try porting GCC yourself, TCC is probably your best option - it supports at least some of the GNU C extensions, and the whole install is just over 2 MB (however it takes up about 7 MB on my flash drive, due to the 32KB allocation unit size, but that's still much smaller than MinGW or Cygwin), but keep it mind it's C only, not C++.

Name: Anonymous 2016-09-08 15:17

>>2

Clang needs Visual Studio - a huge non-free software package.

Name: Anonymous 2016-09-08 15:18

>>3
TCC is non-optimizing compiler.

Name: Anonymous 2016-09-08 15:27

>>4
So what is even the point of Clang? You can compile programs just fine with Visual Studio by itself.

>>5
Optimizing compilers encourage bad programming techniques.

Name: Anonymous 2016-09-08 16:19

>>6

still TCC segfaults and produces broken code

Name: Anonymous 2016-09-08 16:21

>>7

especially on huge C files (larger than megabyte)

Name: Anonymous 2016-09-08 16:29

>>7,8
The TCC website says it compiled a 60+ MB project, so it can definitely handle large projects. Maybe it stores everything in memory during the compilation process, rather than using temporary files like GCC, in which case the segfaults could be due to limited memory.

Name: Anonymous 2016-09-08 16:33

>>9

dunno. Yet my project compiled with GCC works. But when compiled with TCC it begins running and then segfaults.

Name: Anonymous 2016-09-08 16:48

>>10
Oh, you mean the generated program segfaults, I thought you meant the compiler segfaults when generating code. How big a project are you talking about? How many lines of code is it, and how big are the TCC/GCC generated binaries? And does it link to any non-standard external libraries?

Name: Anonymous 2016-09-08 17:22

Protip - Don't use C.

Name: Anonymous 2016-09-08 17:25

>>12
What do you suggest, assembly? Pretty much all other languages are implemented in C, or at least depend on C libraries.

Name: Anonymous 2016-09-08 17:44

Okay. I've managed to reduce GCC installation down 50 megabytes uncompressed. Or 15 megs compressed. That should be good enough for online distribution.

Name: Anonymous 2016-09-08 17:44

>>11

Compiled program segfaults.

Name: Anonymous 2016-09-08 17:51

Now Symta is bundled with GCC and people should have less troubles running it: https://github.com/saniv/symta-releases

Name: Anonymous 2016-09-08 19:09

>>14
That should be good enough for online distribution.
Are you implying there are programmers who don't have access to an internet connection fast enough for a 100MB download?

Name: Anonymous 2016-09-08 20:06

>>17

I'm sitting at Russian cafe and wifi here is friggin slow.

Name: Cudder !cXCudderUE 2016-09-09 11:25

It never ceases to amuse me how stupid GCC is, despite its size.

This boringly trivial function
void foo(int *x) {
(*x)++;
}


with default settings, turns into this monster:

; this isn't 16-bit --- you can use rsp too, retard
push rbp
mov rbp, rsp
; you write the first param into memory...
mov QWORD PTR [rbp-8], rdi
; ... just so you can read it back again? WTF!?
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
; Let's waste another register just so we can show off
; how clever we are with the lea instruction. Idiot.
lea edx, [rax+1]
; If you were the slightest bit intelligent, you would
; not overwrite rax with the value. If you were just a
; tiny bit more so, you'd realise that it was already in
; rdi. This is terminally retarded.
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], edx
; A NOP!?! What idiocy made you put one here?
nop
pop rbp
ret


It outputs a much better "inc dword [edi]" (as it should) with optimisation, but why the fuck does it even bother generating all that shit otherwise? It's like the default is "-O-3".

Name: Anonymous 2016-09-09 11:49

>>19

Intel pays Stallman, so he makes GCC slow, so Intel could sell newer CPUs.

Name: Anonymous 2016-09-09 13:42

>>19
How exactly were you able to get GCC output in Intel syntax? I was able to do it with the online tool at gcc.godbolt.org, however even with maximum optimization it gives
add DWORD PTR [rdi], 1
rather than using the inc instruction. This seems to be the case with all x86 GCC versions. However, both Clang and ICC generate something along the lines of
inc DWORD PTR [rdi]
which is much closer to your optimized version.

Though in any case, I do agree its silly to generate half a page of assembly code and use 6 registers just to perform a dereference-and-increment operation.

Name: Anonymous 2016-09-09 15:05

>>21
Che' ckem

Name: Anonymous 2016-09-09 17:01

>>22
Check my prime

Name: Anonymous 2016-09-09 17:08

>>19
You do realize a human didn't write the code right?

Name: Anonymous 2016-09-09 17:32

>>24
You do realize a human wrote the algorithm that produced the code right?

Name: Anonymous 2016-09-09 17:37

>>24
Why would a compiler generate so many unnecessary instructions? If that's how it increments through a pointer, imagine what the quadratic formula would look like.

Name: Anonymous 2016-09-09 19:53

>>19
no match for CL bloat

CL-USER> (defvar +a+ 4)
+A+
CL-USER> (defun increment-symbol (src)
(incf (symbol-value src)))
INCREMENT-SYMBOL
CL-USER> (increment-symbol '+a+)
5
CL-USER> +a+
5
CL-USER> (compile 'increment-symbol)
INCREMENT-SYMBOL
NIL
NIL
CL-USER> (disassemble 'increment-symbol)
; disassembly for INCREMENT-SYMBOL
; Size: 109 bytes. Origin: #x1003FB65DC
; 5DC: 498B4C2460 MOV RCX, [R12+96] ; thread.binding-stack-pointer
; no-arg-parsing entry point
; 5E1: 48894DF8 MOV [RBP-8], RCX
; 5E5: 4881FE17001020 CMP RSI, 537919511
; 5EC: 740D JEQ L0
; 5EE: 8D46F1 LEA EAX, [RSI-15]
; 5F1: A80F TEST AL, 15
; 5F3: 7544 JNE L1
; 5F5: 807EF145 CMP BYTE PTR [RSI-15], 69
; 5F9: 753E JNE L1
; 5FB: L0: 8B46F5 MOV EAX, [RSI-11]
; 5FE: 498B1404 MOV RDX, [R12+RAX]
; 602: 83FA61 CMP EDX, 97
; 605: 480F4456F9 CMOVEQ RDX, [RSI-7]
; 60A: 83FA51 CMP EDX, 81
; 60D: 7433 JEQ L2
; 60F: BF02000000 MOV EDI, 2
; 614: 41BBC0010020 MOV R11D, 536871360 ; GENERIC-+
; 61A: 41FFD3 CALL R11
; 61D: 488BFA MOV RDI, RDX
; 620: 488B75F0 MOV RSI, [RBP-16]
; 624: 488BD6 MOV RDX, RSI
; 627: 488B0552FFFFFF MOV RAX, [RIP-174] ; #<FDEFINITION for SET>
; 62E: B904000000 MOV ECX, 4
; 633: FF7508 PUSH QWORD PTR [RBP+8]
; 636: FF6009 JMP QWORD PTR [RAX+9]
; 639: L1: CC0A BREAK 10 ; error trap
; 63B: 04 BYTE #X04
; 63C: 43 BYTE #X43 ; OBJECT-NOT-SYMBOL-ERROR
; 63D: FE1B03 BYTE #XFE, #X1B, #X03 ; RSI
; 640: CC10 BREAK 16 ; Invalid argument count trap
; 642: L2: CC0A BREAK 10 ; error trap
; 644: 04 BYTE #X04
; 645: 05 BYTE #X05 ; UNBOUND-SYMBOL-ERROR
; 646: FE1B03 BYTE #XFE, #X1B, #X03 ; RSI
NIL

Name: Anonymous 2016-09-09 20:18

increment-symbol was alone in the lambda forest. It was three nights ago, since he escaped increment-factory of People's Republic of Java. It was cold and lambdas obscured the path: he remembered the warmth of register fires(or was it register files) popping and crackling out of a stack. He tried to chew on partially applied lambda, but the taste made him jump out of pain. He nearly vomited into a random register and jumped again. The lambda forest was moving around him, like a menacing swarm of shadowy pointers, eager to garbage collect anything that crosses their path. A ray of light appeared in the form of large glowing lizard with "Suave Space Toad Deliveries" stamped on its back. He jumped on its tail in final show of strength and hoped the lizard will end his misery. The tail shifted and springing back launched the increment-symbol out of forest.

Name: Anonymous 2016-09-09 22:09

>>27
(defun increment-symbol (src)
(declare (optimize (speed 3) (safety 0)))
(incf (the number (symbol-value src))))

; disassembly for INCREMENT-SYMBOL
; Size: 56 bytes
; 06682C42: 48895DF8 MOV [RBP-8], RBX ; no-arg-parsing entry point
; 46: 488B53F9 MOV RDX, [RBX-7]
; 4A: BF02000000 MOV EDI, 2
; 4F: 4C8D1C25E0010020 LEA R11, [#x200001E0] ; GENERIC-+
; 57: 41FFD3 CALL R11
; 5A: 480F42E3 CMOVB RSP, RBX
; 5E: 488BFA MOV RDI, RDX
; 61: 488B5DF8 MOV RBX, [RBP-8]
; 65: 488BD3 MOV RDX, RBX
; 68: 488B0581FFFFFF MOV RAX, [RIP-127] ; #<FDEFINITION object for SET>
; 6F: B904000000 MOV ECX, 4
; 74: FF7508 PUSH QWORD PTR [RBP+8]
; 77: FF6009 JMP QWORD PTR [RAX+9]

Name: Anonymous 2016-09-09 22:41

>>29
safety 0

that was Dennis Ritchie quality!

Name: Anonymous 2016-09-09 22:48

Practically living on edge of the stack. Who leaves such horror in mission-critical code such as increment-symbol?
What risks they take in secret?
Could it be exploitable?
What if malicious hackers cause it to Double-Increment?

Name: Anonymous 2016-09-09 23:19

>>30
if you want the safety code, dont call it bloat

Name: Anonymous 2016-09-09 23:40

>>32
Ch' eckem

Name: Anonymous 2016-09-10 0:32

>>19
The nop is the funniest part. It's nopnot even trying to optimize by aligning anything, but it still puts a nop randomly in the code as if to mock you.

Name: Cudder !cXCudderUE 2016-09-10 15:58

>>25
It must be a remarkably horrible algorithm.

27-29
That's a dynamic language, a very different and far more bloated pig because it could be incrementing anything.

Name: Anonymous 2016-09-10 17:33

>>35
It must be a remarkably horrible algorithm.
Yeah, that's what I don't get. It seems like someone would have to go out of their way to make such a simple function translate into something so complex.

Name: Anonymous 2016-09-10 17:35

>>36
it makes sense if you've ever looked at the gcc source.
it's a radioactive cesspit.

Name: Anonymous 2016-09-10 19:16

>>19
A NOP!?! What idiocy made you put one here?
Cudder, soon you will catch with FrozenVoid on the ignorance scale.

http://stackoverflow.com/questions/7912464/why-does-gcc-pad-functions-with-nops

Name: Anonymous 2016-09-10 19:51

>>34

That instruction is used to fill space for alignment purposes. Loops can be faster when they start on aligned addresses, because the processor loads memory into the decoder in chunks. By aligning the beginnings of loops and functions, it becomes more likely that they will be at the beginning of one of these chunks. This prevents previous instructions which will not be used from being loaded, maximizes the number of future instructions that will, and, possibly most importantly, ensures that the first instruction is entirely in the first chunk, so it does not take two loads to execute it.

The compiler knows that it is best to align the loop, and has two options to do so. It can either place a jump to the beginning of the loop, or fill the gap with no-ops and let the processor flow through them. Jump instructions break the flow of instructions and often cause wasted cycles on modern processors, so adding them unnecessarily is inadvisable. For a short distance like this no-ops are better.

The x86 architecture contains an instruction specifically for the purpose of doing nothing, nop. However, this is one byte long, so it would take more than one to align the loop. Decoding each one and deciding it does nothing takes time, so it is faster to simply insert another longer instruction that has no side effects. Therefore, the compiler inserted the lea instruction you see. It has absolutely no effects, and is chosen by the compiler to have the exact length required. In fact, recent processors have standard multi-byte no-op instructions, so this will likely be recognized during decode and never even executed.

Name: Anonymous 2016-09-10 19:53


Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List