Code Monkey home page Code Monkey logo

9cc's Introduction

9cc C compiler

Note: 9cc is no longer an active project, and the successor is chibicc.

9cc is a successor of my 8cc C compiler. In this new project, I'm trying to write code that can be understood extremely easily while creating a compiler that generates reasonably efficient assembly.

9cc has more stages than 8cc. Here is an overview of the internals:

  1. Compiles an input string to abstract syntax trees.
  2. Runs a semantic analyzer on the trees to add a type to each tree node.
  3. Converts the trees to intermediate code (IR), which in some degree resembles x86-64 instructions but has an infinite number of registers.
  4. Maps an infinite number of registers to a finite number of registers.
  5. Generates x86-64 instructions from the IR.

There are a few important design choices that I made to keep the code as simple as I can get:

  • Like 8cc, no memory management is the memory management policy in 9cc. We allocate memory using malloc() but never call free(). I know that people find the policy odd, but this is actually a reasonable design choice for short-lived programs such as compilers. This policy greatly simplifies code and also eliminates use-after-free bugs entirely.

  • 9cc's parser is a hand-written recursive descendent parser, so that the compiler doesn't have any blackbox such as lex/yacc.

  • I stick with plain old tools such as Make or shell script so that you don't need to learn about new stuff other than the compiler source code itself.

  • We use brute force if it makes code simpler. We don't try too hard to implement sophisticated data structures to make the compiler run faster. If the performance becomes a problem, we can fix it at that moment.

  • Entire contents are loaded into memory at once if it makes code simpler. We don't use character IO to read from an input file; instead, we read an entire file to a char array in a batch. Likewise, we tokenize a whole file in a batch rather than doing it concurrently with the parser.

Overall, 9cc is still in its very early stage. I hope to continue improving it to the point where 9cc can compile real-world C programs such as Linux kernel. That is an ambitious goal, but I believe it's achievable, so stay tuned!

9cc's People

Contributors

nico avatar rui314 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

9cc's Issues

error: invalid escape sequence (unrecognized character) in '.ascii' directive .ascii

Simply run make test

➜  9cc git:(master) ✗ make test
cc -Wall -std=c11 -g   -c -o gen_ir.o gen_ir.c
cc -Wall -std=c11 -g   -c -o gen_x86.o gen_x86.c
cc -Wall -std=c11 -g   -c -o irdump.o irdump.c
cc -Wall -std=c11 -g   -c -o liveness.o liveness.c
cc -Wall -std=c11 -g   -c -o main.o main.c
cc -Wall -std=c11 -g   -c -o opt.o opt.c
cc -Wall -std=c11 -g   -c -o parse.o parse.c
cc -Wall -std=c11 -g   -c -o preprocess.o preprocess.c
cc -Wall -std=c11 -g   -c -o regalloc.o regalloc.c
cc -Wall -std=c11 -g   -c -o sema.o sema.c
cc -Wall -std=c11 -g   -c -o token.o token.c
token.c:96:19: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  fprintf(stderr, msg);
                  ^~~
token.c:96:19: note: treat the string as an argument to avoid this
  fprintf(stderr, msg);
                  ^
                  "%s", 
token.c:107:9: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  error(msg);
        ^~~
token.c:107:9: note: treat the string as an argument to avoid this
  error(msg);
        ^
        "%s", 
2 warnings generated.
cc -Wall -std=c11 -g   -c -o util.o util.c
cc -Wall -std=c11 -g   -c -o util_test.o util_test.c
cc -o 9cc gen_ir.o gen_x86.o irdump.o liveness.o main.o opt.o parse.o preprocess.o regalloc.o sema.o token.o util.o util_test.o 
./9cc -test
tmp-test1.s:1318:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\0\'\000"
        ^
tmp-test1.s:1324:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\0\'\000"
        ^
tmp-test1.s:1330:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\00\'\000"
        ^
tmp-test1.s:1336:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\00\'\000"
        ^
tmp-test1.s:1342:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\000\'\000"
        ^
tmp-test1.s:1348:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\000\'\000"
        ^
tmp-test1.s:1354:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\1\'\000"
        ^
tmp-test1.s:1360:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\1\'\000"
        ^
tmp-test1.s:1366:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\7\'\000"
        ^
tmp-test1.s:1372:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\7\'\000"
        ^
tmp-test1.s:1378:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\100\'\000"
        ^
tmp-test1.s:1384:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
 .ascii "\'\\100\'\000"
        ^
make: *** [test] Error 1

error: invalid instruction mnemonic 'movzb'

Simply run make test

./9cc -test
tmp-test1.s:1318:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\0\'\000"
               ^
tmp-test1.s:1324:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\0\'\000"
               ^
tmp-test1.s:1330:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\00\'\000"
               ^
tmp-test1.s:1336:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\00\'\000"
               ^
tmp-test1.s:1342:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\000\'\000"
               ^
tmp-test1.s:1348:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\000\'\000"
               ^
tmp-test1.s:1354:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\1\'\000"
               ^
tmp-test1.s:1360:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\1\'\000"
               ^
tmp-test1.s:1366:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\7\'\000"
               ^
tmp-test1.s:1372:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\7\'\000"
               ^
tmp-test1.s:1378:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\100\'\000"
               ^
tmp-test1.s:1384:9: error: invalid escape sequence (unrecognized character) in '.ascii' directive
        .ascii "\'\\100\'\000"
               ^
tmp-test1.s:2506:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2579:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2652:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2725:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2798:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2874:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:2955:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3041:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3120:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3204:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3288:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3409:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3484:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3569:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3657:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3743:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3831:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:3919:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4000:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4079:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4167:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4250:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4343:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:4436:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4526:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4616:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4706:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4796:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4886:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:4976:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5066:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5135:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5142:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5213:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5220:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5291:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5298:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5369:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5376:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5447:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5454:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5525:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5532:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5603:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5610:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5681:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5688:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5759:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5766:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5837:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5844:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5915:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:5922:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:5993:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6000:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6071:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6078:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6149:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6156:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6227:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6234:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6305:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6312:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6389:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6466:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6545:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6624:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6703:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6774:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6781:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6852:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:6859:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:6938:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7017:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7109:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7196:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7288:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7375:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7462:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7547:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7620:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7696:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7772:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7848:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:7924:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8000:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8076:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8152:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8231:2: error: invalid instruction mnemonic 'movzb'
        movzb r12, r12b
        ^~~~~
tmp-test1.s:8255:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8358:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8463:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8542:2: error: invalid instruction mnemonic 'movzb'
        movzb r12, r12b
        ^~~~~
tmp-test1.s:8568:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8647:2: error: invalid instruction mnemonic 'movzb'
        movzb r13, r13b
        ^~~~~
tmp-test1.s:8677:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8756:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8789:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:8866:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:8896:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:8909:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9015:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:9028:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9116:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:9146:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:9159:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9261:2: error: invalid instruction mnemonic 'movzb'
        movzb r12, r12b
        ^~~~~
tmp-test1.s:9287:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9358:2: error: invalid instruction mnemonic 'movzb'
        movzb r13, r13b
        ^~~~~
tmp-test1.s:9372:2: error: invalid instruction mnemonic 'movzb'
        movzb r13, r13b
        ^~~~~
tmp-test1.s:9386:2: error: invalid instruction mnemonic 'movzb'
        movzb r14, r14b
        ^~~~~
tmp-test1.s:9399:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9483:2: error: invalid instruction mnemonic 'movzb'
        movzb r13, r13b
        ^~~~~
tmp-test1.s:9497:2: error: invalid instruction mnemonic 'movzb'
        movzb r13, r13b
        ^~~~~
tmp-test1.s:9511:2: error: invalid instruction mnemonic 'movzb'
        movzb r14, r14b
        ^~~~~
tmp-test1.s:9524:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9602:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9616:2: error: invalid instruction mnemonic 'movzb'
        movzb r12, r12b
        ^~~~~
tmp-test1.s:9722:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9803:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9903:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:9976:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10095:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10214:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10333:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10452:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10541:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10663:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10778:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10851:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10924:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:10997:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11070:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11143:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11216:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11289:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11362:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11435:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11508:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11581:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11654:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11725:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:11732:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11824:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11897:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:11970:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12043:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12116:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12189:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12262:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12338:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12345:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12421:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12428:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12504:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12511:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12587:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12594:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12670:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12677:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12753:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12760:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12840:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12847:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:12927:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:12934:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13014:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:13021:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13101:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:13108:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13185:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13259:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13336:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13409:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13525:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13607:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13680:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13753:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13826:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13909:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:13992:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:14006:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14093:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:14108:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14195:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:14210:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14283:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14439:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14514:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14589:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14662:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14753:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14845:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:14937:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15026:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15115:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15205:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15295:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15400:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15487:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15576:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15651:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15722:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:15729:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15827:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:15838:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15847:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:15918:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:15923:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:15930:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16001:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16006:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16013:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16084:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16089:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16096:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16167:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16172:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16179:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16252:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16257:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16264:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16340:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16345:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16352:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16423:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16428:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16433:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16438:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16445:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16516:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16521:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16526:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16531:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16538:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16609:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16614:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16619:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16626:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16697:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16702:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16707:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16714:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16788:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16793:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16803:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:16877:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16882:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
tmp-test1.s:16892:2: error: invalid instruction mnemonic 'movzb'
        movzb rbx, bl
        ^~~~~
tmp-test1.s:17352:2: error: invalid instruction mnemonic 'movzb'
        movzb r11, r11b
        ^~~~~
make: *** [test] Error 1

macos 10.14, gcc 8.2.0

how to run?

HI dear author,
It's truly a honor to write a letter to you, I'm building your project nowadays and found the error when building as following, I wonder if there is a chance that you know the reason? :)

image

thank you
best regards to you
William

On free()

Compilers may be short-lived programs, but they often capitalize on a large amount of memory even when they are using free(). For example, installing dependencies in C, C++, Java, Node.js, and Haskell tends to require upwards of 4GB of memory on build machines. Some operating systems / dev tool pairs are more efficient, using <1GB of memory. But in general, compilation tends to be one of the most memory-intensive things you can do! And I'm not talking about building complex projects like the Linux kernel or video games, I'm talking about absolute minimum requirements to build small-to-medium size middleware projects you'd find on GitHub.

I think 8cc/9cc is a cool project, but for building projects of realistic size, it is probably worth freeing memory whenever we can. Otherwise, many projects may require more buildtime memory hardware than a typical laptop offers. Does that make sense?

I do think it is cool to think about different memory styles, like skipping free() closer to the end of main() functions... But valgrind isn't smart enough to handle that, so I tend to put them there anyway :P

segment fault when compiling nqueen.c

macOS High Sierra 10.13.6

➜  9cc git:(master) ✗ cc --version
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
➜  9cc git:(master) ✗ ./9cc examples/nqueen.c
[1]    60186 segmentation fault  ./9cc examples/nqueen.c
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xc)
    frame #0: 0x000000010000c4b4 9cc`vec_push(v=0x0000000000000000, elem=0x0000000100207150) at util.c:29
  * frame #1: 0x00000001000052bc 9cc`add_lvar(ty=0x0000000100207110, name="board") at parse.c:81
    frame #2: 0x0000000100007f29 9cc`param_declaration at parse.c:717
    frame #3: 0x0000000100004eff 9cc`toplevel at parse.c:895
    frame #4: 0x0000000100004d79 9cc`parse(tokens_=0x0000000100206880) at parse.c:961
    frame #5: 0x00000001000049ba 9cc`main(argc=2, argv=0x00007ffeefbff858) at main.c:34
    frame #6: 0x00007fff6badf015 libdyld.dylib`start + 1
    frame #7: 0x00007fff6badf015 libdyld.dylib`start + 1

Seems because lvars is initialized at parse.c#L901, but used in param_declaration at parse.c#L895.

invariant check pass

Some node types and c types have a few invariants assumed, perhaps there could be an optional check pass in between stages that basically just documents + checks. I remember 8cc had one about the left and right side of a '+' if there was a pointer type for example.

I can see an argument against it in terms of keeping the codebase small. Its just more annoying to remember every assumption and add it later.

As always, I don't mind what approach you take, just a point for discussion.

segfault on: "void f(int n) {}"

// yo.c
void f(int n) {}

Compilation:

$ ./9cc yo.c
[1]    27537 segmentation fault  ./9cc yo.c

Backtrace:

$ gdb --args ./9cc yo.c
Reading symbols from ./9cc...done.
(gdb) run
Starting program: /tmp/9cc/9cc yo.c

Program received signal SIGSEGV, Segmentation fault.
0x000055555555e5ab in vec_push (v=0x0, elem=0x55555556a990) at util.c:29
29        if (v->len == v->capacity) {
(gdb) bt
#0  0x000055555555e5ab in vec_push (v=0x0, elem=0x55555556a990) at util.c:29
#1  0x000055555555b728 in add_lvar (ty=0x55555556a7d0, name=0x555555569a80 "n") at parse.c:81
#2  0x000055555555d827 in param_declaration () at parse.c:717
#3  0x000055555555e0df in toplevel () at parse.c:895
#4  0x000055555555e3b5 in parse (tokens_=0x555555569fa0) at parse.c:961
#5  0x000055555555b4c4 in main (argc=2, argv=0x7fffffffe688) at main.c:34
(gdb) 

error: 32-bit absolute addressing is not supported in 64-bit mode

Simply run make test after fix #14 and #24

➜  9cc git:(fix-the-issue-14) make test
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tmp-test1.s:16830:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r12, .L.str680
 ^
tmp-test1.s:16831:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r13, .L.str681
 ^
tmp-test1.s:16846:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea rbx, stderr
 ^
tmp-test1.s:16849:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r12, .L.str682
 ^
tmp-test1.s:16851:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r14, .L.str683
 ^
tmp-test1.s:16917:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea rbx, stderr
 ^
tmp-test1.s:16919:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r12, .L.str684
 ^
tmp-test1.s:16920:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r13, .L.str685
 ^
tmp-test1.s:16935:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea rbx, stderr
 ^
tmp-test1.s:16938:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r12, .L.str686
 ^
tmp-test1.s:16940:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r14, .L.str687
 ^
tmp-test1.s:17375:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r11, .L.str692
 ^
tmp-test1.s:17388:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r11, stderr
 ^
tmp-test1.s:17390:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea rbx, .L.str688
 ^
tmp-test1.s:17391:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r12, .L.str689
 ^
tmp-test1.s:17406:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r11, stderr
 ^
tmp-test1.s:17409:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea rbx, .L.str690
 ^
tmp-test1.s:17411:2: error: 32-bit absolute addressing is not supported in 64-bit mode
 lea r13, .L.str691
 ^
make: *** [test] Error 1

#include <stdio.h>

Hello. I can't include the C standard library yet. what is the plan for this?

wrong var->offset calculation on emit_code()

void emit_code(Function *fn) {
  // Assign an offset from RBP to each local variable.
  int off = 0;
  for (int i = 0; i < fn->lvars->len; i++) {
    Var *var = fn->lvars->data[i];
    off += var->ty->size;
    off = roundup(off, var->ty->align);  // (*)
    var->offset = -off;
  }
...

At the point (*), var->ty->ailgn may be 0. In such case, roundup() returns 0 regardless of off value and it causes the accumulation of the offset to break.

An example of the fix:

diff --git a/gen_x86.c b/gen_x86.c
index 5453e01..5aa2989 100644
--- a/gen_x86.c
+++ b/gen_x86.c
@@ -184,7 +184,8 @@ void emit_code(Function *fn) {
   for (int i = 0; i < fn->lvars->len; i++) {
     Var *var = fn->lvars->data[i];
     off += var->ty->size;
-    off = roundup(off, var->ty->align);
+    if (var->ty->ty != FUNC)
+      off = roundup(off, var->ty->align);
     var->offset = -off;
   }
 
diff --git a/util.c b/util.c
index a4d30d0..7bf0c5b 100644
--- a/util.c
+++ b/util.c
@@ -129,6 +129,7 @@ char *sb_get(StringBuilder *sb) {
 }
 
 int roundup(int x, int align) {
+  assert(align != 0);
   return (x + align - 1) & ~(align - 1);
 }
 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.