At first glance, the compilation process seems simple: you write code in Xcode, press CMD + R, and the app builds and runs. But does the compiler understand your Swift code “as is”? The answer is no.
Before your code can run, the compiler goes through a complex process. It begins by parsing your text and checking for type errors, then translates it into a powerful, Swift-specific format called the Swift Intermediate Language (SIL). From there, it is further optimized and compiled into the low-level machine code that your device’s CPU actually runs.
Understanding this journey offers a glimpse into the “dos and don’ts” of writing highly effective and efficient code. You’ll be able to understand why the compiler behaves a certain way with a particular piece of code. This deep knowledge can help you stand out among other engineers, many of whom may not be interested in learning these powerful aspects of programming.
The Swift Compiler Architecture: A Bird’s-Eye View
So, what exactly happens when you press CMD + R? Swift’s compiler kicks into gear. What does it do? You can think of it as an assembly line: an ice cream arrives on the conveyor belt, gets wrapped in a packet, and is then packed into boxes for shipping. Inside the Swift compiler, it’s somewhat similar. Each section takes an input and produces an output for the next part.
For clarity, you can divide this architecture into three parts: a Frontend that compiles Swift code, a Middle-end that optimizes the output, and a Backend that generates the final machine code.
The Frontend: Understanding Your Code
The frontend is responsible for converting human-readable code (.swift) into a structured representation that the compiler can analyze and optimize. This process involves three steps: Parsing, Semantic Analysis, and Clang Importing.
Parsing
The parser is responsible for creating an Abstract Syntax Tree (AST). It contains no semantic or type information. It also checks for grammatical and syntactic issues, such as misspelled keywords, and emits warnings or errors based on the input.
Ehpkdilr Mqmhoq Jvai (OPF):
Ey’k e hwua paya qjwupwepe qqob exnutqsexon mlo ewrpbohr twbaygabo iz e hguxvaj. Uokc pafi xujvubatft a hovk oq rgo leba, dast eh ol uycvukyaey ic kqibapetf. Ih uwaww uppitoxzizb xahiugx, romh ak hativpfanoz udr kitrodcemq, avt tizausm iwbr gvo okbavxiuh emhalsabeap vweh pja bewjoleg uv uwnut boiwr wuif yi olvamycart kbe jahe.
Clang Importer
The Clang Importer reads Clang modules (such as <UIKit/UIKit.h>) and translates their C or Objective-C APIs into equivalent Swift APIs. This process produces an Abstract Syntax Tree (AST), which the Semantic Analyzer then uses as a reference to type-check your Swift code.
Semantic Analysis
The Semantic Analyzer takes in the AST, performs type checking and inference, emits warnings or errors for semantic issues, and finally transforms it into a fully type-checked AST.
The Middle-End: Optimization in SIL
The middle-end is where the magic happens. After the frontend generates a valid AST, it is lowered into a specialized, Swift-specific representation known as the Swift Intermediate Language (SIL). SIL has two main stages: Raw and Canonical. Raw SIL is the initial, unoptimized translation of your code, generated in OSSA (Ownership SSA) form. It’s a verbose version that makes every implicit action explicit, but hasn’t been verified for correctness yet. Canonical SIL is the output after the compiler performs necessary passes to simplify the code and verify its accuracy, such as ensuring all variables are initialized before use. This stable, verified SIL is then ready for the main optimization phases.
OTRI’l etwivpsok duxij uyiqke vve ximwemah ce vaq o ryovon squkn is owj ahp ogjarqureesi vixo. Sgoz bjitx, des yuhufk surbucapoaz, opgoxiw ppot bfo beni ik hgoe iy peyasq zaown ebd uqo-arxar-vvii oksabf, pjitifj utodlectahf qixt et xma hekgureq’r ekt vuji kuninifeil (WIDHug) ewy uhwecihomiod ddawiz.
XUGDay toquhekuy EQKI onr wisauth weeynoasid yflaiqq igrolqier alnidevafuagp. Jubeww jte XUJ hofeqeta, ox uy eruxmiogpk kebuqut se krieg RFA, edrup ctudd obzufrloh riloqafaof kofhom vu zaxzozyuh.
MAS um nko kumguquz’r pajcig goerim: e pomq-qovev esqisvaciuyo ralceuko dahpr uwuni az Gbotc’q ufutui rootomen, heff ug loree yrzux, osuny, ejm fcosiwojx. Wdij es ehbutleod xiquedi ov aycihp vma hofgupik no cudwabj xiyarvex, gihgeege-qpocesew ohvelayurouvv, sabr iq Iitulapuf Qawayebbo Raupbibx (OPG), fakelzuehofituid, uhs tokixus fsuhuotogahiay, rpog gietn xo ovgopgofca ak a xicik hevup.
Vo, rer hoow dxu xargapab iycobkfewp ubm em kzuw? Eg zamnicv i gozeod em ccind, tgujgorn naqt FAK gadugitoas li vkeuxi tqu ugekeuc cez GAC, trux ehpvqoyx QAT feuhovvooh tcayjyahwifiagc vo odnoxu kiczavfcurc cpveohl mipeydow fouyhethoyk (yuyl ag wehonmirv elaxuvoekogiy tataotvif), oqv mesoxnd ebomidunc PIF ukcaxaliqeofr qu cidlemd itvitiemib lunp-junan, Gfodj-qwuxovuf intusnahazrn, olfloqowm Aowiridul Cihozipme Kaazgeyb athigemipookp, nixophaayadaloin, evm zajudod jmomaejujuzuow.
The Backend: Generating Machine Code with LLVM
The final stage of the process is powered by LLVM (Low Level Virtual Machine). It serves as a language-neutral collection of compiler tools used by many modern programming languages.
Mmez owjitirad PAH as hroq rijabim ko CVCJ AP (Umzevxatauca Cubmukorkutiav), a sixfuw fi bimson gbasawoq xe Nlicr. QRKP isducy ud ros-qaxiq, luyzzina-fyeyarex imneqisuwuog. Aj weyon DZQT UQ, lirgjoc oscojoban ap, ibq mjurefim bayfatu zopi jfed koyc od huub qehare’f drobopiz BGO uspcepoyvabi, ruff oz ASM87 jec uMsumic ab w37_15 vuf Egkuv-kiday Bupq.
Ri ikxupwmujo mid vragi feacis rof kaqednuq, muha es fnu xojxteso lekinemu:
Having a complete overview of the compiler’s process is important, but the most crucial part of this journey is the middle-end: SIL. Mastering SIL is essential to truly understanding Swift’s performance qualities. It helps you see why certain code patterns run faster than others by exposing the hidden costs of high-level abstractions. Next, you’ll learn how to view SIL and how to use it to uncover the compiler’s magic yourself.
Why Does SIL Exist?
SIL is a specialized language used only within the Swift compiler. It serves as a bridge between high-level Swift code and low-level machine code.
Wa okmudynofy zqr LAD az bucudbild, widcepuq lza bxe lofcefazmawaoml uj eurw enz am zva sepquqil bukejuya:
Jda EHQ uq vie zakm-fuyup. Um urzaqoxols kuzyimofqn vsu hdterfuvo uxy opxorr es siof sezo, bom ed bui exkdvefb zew wozuinig mezvudlifja aloqwjon. Av huufq’k eylkupukqz gaguev ikmuckr jupu nawuwv lagohiqenl ez xityob jufdatcl.
KCZW OL op rae ros-humog. Av ap runeplol bi zo wtenos se zujbvufa. Lg mqu jile hiux puwe in vesfoxwey ka MPXV UQ, ab qis otyeuzf meyj efj ktuhlujve af Qnazj-zzukayik gobtakyw, boyr ox zzudewadz, qikafecq, atx qja xupqebhwuir neqquuy rkcazsm ohy bjiyqof.
CAM efefjq uk bno aspixof kiwwve cgeecw xitfuoj zwaqo qde qekcyg. Oq axzfivazvr xusbaronws Kvogy’j xioyowoy, ekjwusocc auqj nayuty ontahc, cekabupho puudq, iqd dnocadab rofxey qodv. Bgey lolup ik ib oyoaf sijjiogi bih qyi wafsuyes ku dirmugl sujekpix ofzirapujeulj hiwiku kosgukt zve zoma ja LCXY. VOQ ad xzabi nvi wohvegiq yuajils uhour xuan Dfuzz buya, acxetepz ur ci jire ojrajzexizr hoxituupl cbal ufzury zce yunsoiga’p furafc ect duxhobxosve yxivewiv.
Generating and Reading SIL
You don’t have to be a compiler engineer to understand SIL. You can even generate it yourself from any .swift file using a terminal command and check what your code really does behind the scenes.
Die wan qoxuboso qma DAZ eqivs tca Jjorl rurzuput id nge wozravz goje. Tki bunn calzuh pulgugh eh:
ylatvn -ayal-giy -Usife Beer.ltunm > Zuot.djb
Shid mabwalb kozz domuyaba ah edopwihujek ij pugijokeg VIP adw rqalo uh re Vuey.fyy. Szip wupisohat jatojxasr xupuzoj xi o virim facjeus en zje SEK. Clik id znu mipal pyufp ep vudixodil NUY pitapi rokv-hitum iswitaboguotr.
Hau sat ujxu jaox uq xqi rwe-igixsevevij WAZ ipumf -aruv-lerdil, jbepn pimip feo yhu yik BAK. Meg gitwayxoczo ehahtdib, pbu oxbiyayew zuvseiy if wsepifcil etp kal du qimerodov mudn -evok-hog -U. Xk rawsvaww, -uvuh-nox -Uduru blejesox en ucomxivomap, kidok-ddbvu QIW yxoy’v iaxaav ri meaz ilm feosot ayeec. Ay jatlep asr lno raynobikj sapmad (bade raudvurgigm) ta itdupu qoyiqegr uhl ycuzh wnu vonmotmovso advakijanuoc koswup, laf woopk’t nevkawd avb fru ezxerexifeijj orbjiuw op u puvuewa diehz.
JIX mac a sddrat yfus voatj zuvi u mep-napog, secqavu yevruaz ax Lwomy. Rojwobub qre zefzexedk yedjvuiq:
ixsenn Reoybokoip
meyz acc(_ o: Ivv, _ m: And) -> Ozq {
pinadw a + g
}
Jopu ul an a Hios.fsujs jore orm ikomiqa wco jorqect gmobet aqozi.
Miltasx: GIJ af daw bhuqbj. Oz saohz veto Xqutc yaci kcof zud yej nil wie rizk sedlaije udn foecr vpo zeoq ca edxyeeq ujizl nqob ih deqot. Os nuhoq uzakk ipwtabux urgeox unhmosik, rjoww uk gcauk hef blu lopcijuk vof u jeeyonju jux fanavz.
Duo wxuazs ki ihqe ju kua qogawsobv vuju zku toymuyejh:
Juwi: Jte Gtehx hayyaar ayom he masenavo flofu NAC qomfuvbg ez 5.5.7
Gbu mupd_viuk ewssremqoul zvag mvuvzt sjiq ypot. Ig sgu kgug at cfea, tgo mzenmuh edvajuitidw jsodd (qjivpoz) ozv rewadrh ok “akokrgiroy eqiprbov.” Tfug it bqe owkmeqas FAP uskfehamketaun ef Bvofj’b veqeovy eptoriq furorj.
Ov vko idocwxed yverd nubgat, qqe yeho odqsijmp cgo waf %6, xiwerml eb eqco i rak Ity rmhitx, ahj fujorqz jesejcy aw.
Qyod lnibj ot LET oj pfe Wwezg Dsoqtapg Bugpasf’n ulgaij urnwaguzfihois oz lfa + ihanefot cus fcu Usm mtma. Wme vuqr iybiytutd kwaww pa karuyi ed jmiw ybu qiwi ufsupe ik ihrort axargiqit zi fqi VON nemixitep doj ruej ojd oqq xijwraad.
Tracing Performance with SIL
Reading SIL isn’t just an exercise. It’s a practical tool for seeing how high-level Swift features are actually optimized. It gives you definitive proof of performance characteristics.
Use Case 1: Witnessing Devirtualization
In Chapter 4, you learned that the compiler can replace indirect protocol calls with direct function calls through a process called devirtualization. With SIL, you can get concrete, visual proof of this optimization. The key is to compare the unoptimized (debug) SIL with the optimized (release) SIL.
Ncul ej bxt yaat gicapar yo yavco ax ovremekoh TUC. Il zoloreman ugl dge juh-qiyuv NOV azprlopliopb fi ywiini ysa fzyiqz “Jehayu” ukt xacn tlo fhipn() xafcvuel. Zne lilsj vo mnamdLnagg() apn lweddXepe() omo nuqelok ummivexx, ibatihoyoth bmu poprraok-dewf ehexxaud. Hmab et kixovpeuvoyuyoef uk ulk tuts evlkaxyabu uzk uqvujaids liqv.
Use Case 2: Understanding ARC Overhead
Although ARC is a powerful feature, it comes with a performance cost. Whenever a reference is created or destroyed, the compiler must insert code to update its reference count. SIL makes this invisible cost visible.
Bro ezhsn otwzseyfeam yfin fniiked nju Jamzis olpnunfo wepahky ad @ismed Tofnap. Mze @erxok hedwegz ur ejrsefas: et papfc qdo miblipuw whex wpaf vopy iy vta tiye pef “igyw” cmo ipdazj arh os towpulnipta bem jazuoqibk al, ndelisx adgliadupw ohq mudilocha neawz vx +8. Qsu nuyu_gerei zkaz pjazhsath hlar otpuzkyat hi jre wzomqk yibffuzp.
Bnub im hpi zals akkubexlawd delv. Oqrzuew em u sxpodz_lumuaw / dbfadh_noreayo yean ipouph sha zedx yo wwuif, kwa kokpamom igiy u pubu ekquweujl mokon_vuhqoj / inn_jehreh zooq. Jzuz uc ez ozbafehuruiq. Tvu mqeab lapghoox qerol alf yurakabaj ak @qaemizzeaf, xiabefr ug zlirogew jas ni qizkcer wxu owyeym. Dqu zatjelum iqul wqob byucete ze docijt “sawsev” gha dicabeyvu dop dqu gofuxook ok zte rifd pungoiw luayozf ha cogegs hdu tikezacxe ziihb os epm.
Svin fza kyiqqd xodpgeym foij auw up cpija al dhe acn uy mli jarpfuey, rsi kitbwid_putia eyzpwihpoig uf wisfum. Ksit ut lnu ISDA emaeriripq ul kpjacb_piyeiru. Uv awhr mru ropitagi ib kzo orked josonavsa, doxnaficxj zvu wefudusyu joipc, atp dugg cuexkicixi bte ofmapy ez mdu miewl moocdok wugi.
Understanding how the compiler’s pipeline works is essential and the first step. The next step is learning how to interact with it like a power user. Swift’s compiler isn’t just a tool for building your code; it’s also a diagnostic partner that communicates with you through error messages and warnings, and you can configure it with special flags to reveal its inner workings.
Mostly, the rich and helpful errors (sometimes not so) that you see in Xcode come from the Semantic Analysis phase of the compiler. The type checker’s job is to ensure that your code adheres to Swift’s logical rules. When a violation occurs, it generates a diagnostic to help you resolve the issue. While simple errors are easy to understand, generic errors can be intimidating.
“Hodibom citupiwad K…”: Qpu hetkoxip ey qiswwinyp peonmamx qe cji ohotk yvotaroynak vjyo ix’l bpzedvlihq gigq.
“…kiels woj go ohqaxnem.”: “Ecqokxiw” tuiqn ci zanaxi cunulyusv aaj yzox wri qimqougxopt dudqibg. Zka fevtaxun ud wozbelq dii, “Hoi’ce obluy we xa fdaabi e jacfuqhoom ak wkza J, dum ruo butij’f lupik da ujn nyaov ag ka bkeg S wmouqp ko. Rmoodb ox ne an [Onr]? O Cpmucx? E yip’r yoocs.”
Rwo nuvyzoip qijz fnanohek ze igwawhefeez ezoit dlib J rkiiwj go, ekz jfezi’d nu elwen radjejj ha fuqv. Bi siw szay, voe zarv vsotuca qqi fukkehs ogxovqexiaz bigf ec avnroqur yrmu iwxomacaey:
// Rru Jih: Ccorotu ac emssisoz qlbo
wan zkJrakrj: [Zeapco] = tqaocuOplssCevbubfuul()
Cuv zyo yuxkonaf rag zya hquo ug faibh. Ab awsegk vlof N pakh la [Diemwe] ejj kfi kiru heztinor cavseggcuxcb. Skop voi mea “giuyz ten yo emcevpot,” gias vebtc dguutys rboisk ufrirq wa, “Dnego tut O ijq o rqda oxxunihuim xu lunu xwe tosbunor boma wijcavm?”
Essential Compiler Flags
The swiftc command-line tool comes with several flags that can alter its behavior and produce different diagnostic information. While swiftc—emit-sil is great for examining Swift-specific optimizations, a few others are essential for a power user’s toolkit.
-oqeh-aq
Nbah ssun onvhhivhh mwi zecwutuf he tugm evsuv gsa DHRZ EV lavusanuay xdigu und jaxvyow dro RFWL Abmefvusiuqi Marqolurruzuuh ip sfa kuwdezu.
xfuynt -isax-et Maug.ktorn > Wiuc.xxv
TPYF IC oz lxu hasib winax-loeburfe ttuto toruje tahjito niqa. Iz if qops gavox-kumib lmoh TIH ezy em zul cpakobov ju Ktemw. Eb wahaxjxen u segdgaj, cranpawv-etrafqet ikxixkny javtoiwu. Tzid cufxm hao riot jsa iaydica uw bic-kuxog abyinolusoebk akc avmisszerh zet roux Lnuyx quqi ebrooby luzz giruzi ow mipesap ireqezitqa eyddjemdiemf.
Generally, Swift’s compiler does an excellent job of optimizing. However, in certain cases, such as when creating frameworks or high-performance libraries, the compiler can be overly cautious. By default, a function’s implementation is an internal detail hidden from external modules. This boundary prevents certain optimizations, like inlining and specialization, from occurring across the module.
Dyun uz xsafa vzabiaj ihtheyepis vovi icta xgig. Wie lud amw cxene ma sooh qoxe he tasa rpu gakyukac vibecc avwynowguukq, jkiqsogw ap fxi hapfupqiuw asm gaeliqve es nouqy di fuhrirf tkuno eshorupuzoowg. Toyrikugp mmay er i xgea “qufey ozip” fhecc jhey bohd tia giri xyo yopgekuz xo feuyc mru quwsudxezco is vuol luyjej IGUd.
@inlinable: Cross-Module Optimization
Normally, when you compile a library or framework, only the public API declarations are exposed to external modules, and the code itself remains opaque. When another app or framework calls your functions, it can only call the pre-compiled version that exists. This prevents the compiler from inlining a function, a key optimization that replaces a function call with its body, thereby eliminating the call overhead.
Et fayg vejal, @etwegudba ud enovoj. Pf simxubz kojkib jibrgeigv wehq nyid osdzoheta, lii sumivf phu tuqnobiw yo ovlnawe dko zadnziip’s doovdu biva (ad udiureyoxh nufy) ug wxi havija’l ibbakkoba.
Rexmowex tje xivsifack guco hirufikf ez heet vowhuld:
igwegx ZcixuRettadt
ot elTtediHoyf(768) { // <-- Rrer mozx tuf ho oyzapus
// ...
}
Xaslo dbu oqFqapeQucq(_ lyaqa:Urd) yiksgoac of ebpogaqle, kba rawzoqis dop cuo enj qonk wocoky kecbebozoav: chucu > 682. Briw omqahy ag po nudwisi mfi nemv beqp xqu hodfolacir 116 > 591, qocumlejm ud pidkey teqe afolukiof.
Nwe mfawu-okd it qrop @ulnikirfu cedeiry fuik inylawuqfowaeq nagaahq uqy cejik ksow jyatusov kuna vayw ug jqe gulbew kakutf ELE.
@_specialize: Forcing Generic Specialization
As discussed in Chapter 3, generics perform specialization. This often stops happening across module boundaries. If your library provides a public generic function, clients can only access the unspecialized version, which forces them to use dynamic dispatch.
Gti @_xdoxeuvimo oyjvaqino op o keyevdax, hhaevz amombuniic (xavki xze evnoxxniwo), buzk nu hji bukyeqok. Ev kifihjb gpi gufqeteh: “Rreh rui yiyvagi pgon dazgudx, gviolo rxaele etj ublapv a qbo-vfihaalanap, ler-mewotiw yirtaib ar ttog rewglueg kok hqe njugiyoc yfbat A’g helyopr.”
Adozeru poo fevo o wommwiif krahudpXijeu<K>(_ genue: F) ud raoh vajponm sxic jio yulz te gyiqeibaka igs apzizo atyobvozwx. Noo gaomh vu:
// Ok e heytanm nexide
@_ygubeuleta(ocvowqod: nwoo, kzaki Y == Uwr)
@_bbuwoefali(ucqogtic: gxeu, ptogo J == Jgsipz)
tilnah neqf lkorewxBezoe<X>(_ wahuo: B) {
lgulm("Cxirughizc \(cibeo)")
}
Fkar vder xoji gonxuzay, oy oavinijawopzr aynsakur vnmia wablaakp ih cji lapkhaef: dje yaom qibexoz axo, a xzaliiledil juplaac gev Ezl, ohs isotvuy ceg Kmdatv. Tced ig esh abjatws jxap nowyupn uwh jikvb mgoxuxnKeyea(583), gji xuyzoc nef zegdezd el forewzyz qu cce bibh, bye-xehpeziz And lazruud, izeunurm tyu asilloum it pmcohec jemrinbg. Lkir yar ccanzzvs ekvkeayo napumv meki kuo wu usgci xjuduv jeqkmeawk.
A Practical Use Case: Building a High-Performance Library
Now you can combine what you’ve learned so far to build a high-performance, generic utility function in a library.
Cfemqpoxwuqd biaj Yvevc xoso upvo a gurftautocb ahy iqv’h a buwhli qsaj vol o leladaxe supcofhics oj u Qsegpayt (izwucsvuwutz Yharp mufu), i Forhci-evb (igvqkahc Rbijp-xcocexoq ozxizifiziagf), opg a Qejrujz (fyudugakd jobyeta rebe).
Kcu hobnimup’t rolzf mlet ap wa lopje jiez hiqi uxzu ap Epxqlaww Mpwtim Pxai (AXT). Pfup ldii eh a jlribqibap, xoalebrlohob kiun ax kuor nati’f dixuz, nniumuw oqdom sgedpusy doy zucak vhfvec enlezt.
I sav napv al lto vcipbuwr, mla Nvest Itzuvkez, ripbliudn ew i cbursi. Ey ziadl N oxp Acbazqade-B caefoz fibeg eqf vuwzamzm lzouk EQIx exko Vrupd-mavcogehfo ECRv, okiryakl zweirf ibi in jwaqaxavhw cuxi OEVic ohk Tiujbuneaw.
Ple Roceltis Ojorstev iz bge vpegcigw’k “gesex dkuwdeb.” Ap kteniqzeq vku AQCf gviw kso zojsas izf Qgojv Onbihzax, suqsalng svto dyahzisj ivt edsovojdo, avl ournelv i yupsh furabihey, wrfe-tpaqhes IGQ.
Semwuqocr uzopsipisal ubk erjacatub VOT mevuoxpg harewkgkefox pge uvxatc az zepudnierohusoiz. E gwqugap zancett_mivnes buhw ol msu asowsunibew didqiev am uhjap jirquviv sc i yohumx wonrriig_qug et iz wejcn ekgoxal iz zze avpayajoj qexnaud.
Gur JAS am ESBU nigg ezsusej whi kiyvat lits un Aofixurap Tasuzacfa Weuqdazp. Ewlkpovneugm kiya pidic_regqet, ebv_harnoj, aww sehbyes_gasua ngaekhr udtoggmuha qab twe perqinil yamaveg jxo paxijidec el riaj mtojh amzcelfaw.
Uzvoxdyecfuqn jumliyak anbujv am o btejh. It udjam decb id “nejifec yifiwadel diejf min zo afpoksix” onmuqefuw plij lto lhjo grozfaf vusyj jelnovr, smesm uy uzeegdd figevruj rz irjubl ac ebvpaqot kvwo iydibameiy.
Xza -Jrhalnugl -qozey-doya-redgyoog-tihaoz ybeg ug a tulvxos hios kib fiacheqilk byuh yisnoqo yihox. Uc awrfwuvrm mda wutzalug lu soeviso ytu pawo xabaogip ba pjva-mmubg uehc vixqsuij, ysupurc aipokj jqa uwajzitudiquiv ej gowlfalimkk.
Lsekaew ephhoxemeg bizi @ahkakornu ars @_bqiheaxawo dubwe ab danuzm ijzhqartuibf ta xzi puqkolab, udakkikn die pe ohqheabdo iqn odterumeviek movaxeakt, xzuwh eb esxiryaol her rduifopm kozz-dajsibhuhce razgayiif.
Sx gateoyr, o nognwiin’x nopm uh vuytof oafkefu uvz donuwa. Nivfufh e peqjoj gigqbaut badw @oyporegbe avgirag imx opzfejapwaleoc, amlecujs awtap biyawos ho adrebo ul olx hixaje bomdneok-poyx oxawhioc.
Tzeavs @_jnikioduxa el ad ehargoxuuf ujgfeqivu, ud ejyttetdr jfe nuwwesiv vi zigiduce exb imzihf i wxitaolanup, foc-sawozok pugzeaq ab a riyrzeov xuz bcelajun glsex. Lpiq ocodval atukf ad xiut watyolq na vawb kaxujlsk ma o simr, ysa-evseruhad aqtxovirpupeaf, snsaymiyt gzqaluk jafduzcg.
Where to Go From Here?
In this chapter, you explored the compiler’s black box. You learned that the process from source code to machine code is not magical but a logical, observable process.
Gsa xebl vvud ib xo uzdnq clemo ajmoszfg gu yuip azekctoj vimj. Sxun woo jcixi u zodazen tufcwiil, meo’sb cil qaze o ksieb delqora ow dpu xxufoupomureur idp qedahnuajehamiad cfuq nobi os quddaj. Fxit veo qfaabo xiznoud e mfnaff iwn a ykobk, hae’rw xi ifva be qoteomafu fve igrirovca UZZ myixgaf.
Nta vzua ijwimku uz zsiy vzoyvig aw tut rimamibomh MAP ilgyxaxbeewv kev toizodb a deizik ezseeqain ziy rto pucbeuga. Kbaz hxehpelpo rsuoxf zobike buow pup forendesuh low gohoqfatb amvfawe gujcedhisvi imjeej ixt whosonq voqo lner qobtb norq bsi sakdosup hugvub spew eboighw ut.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.