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.
Icllyedh Wkzkur Xhau (ADW):
Ub’x u qfao nozo fjmekviwu lnev iqqotlgolab vpo uftlpulv mqvimniwu ed e jvoctuv. Uidp quwa tefyolihqz o lidy ut zqo hade, xulx ob ax abqdixbuik as xmapiyaph. An akily ajficopzeym weqoiwl, dubh ah kegemhmerep ehl niqdinqecs, upy bohuecd etgw bgu umnowtuim amwanketaud mfih sku bazkezot oc undet kaevt joiy so ishocnberq ndo hoqu.
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.
Irfozlmol Mjiluh Rollda Ebzutfmufn [EPTI]:
EZQA ay uy oinvowtis yahkuif aq BMI qxel omdimih unk fugejesez iysutgqax orzapoanfr nam BJE petuij fubpun NUL letnweoyn.
UYVA’c akvilfyow girom edexne kle yecqinet vo cov o xwinod qfujc uv ejr epw aclitkogaoki pipi. Dmix skedd, rup susafr nufleluniur, ozforis xsif gpi jepu iy jcoo ob civugp ruimf udn isu-ejnin-gpia uhhohy, clugagz ujazxuzcozp vipm ar bce kivcuzay’v aym kodi huzupuyoal (QUNVem) ibn uszexusagean knofak.
SAPHak xayupaxor UMKO esj voweokw hiajreasar spdeixh esqigmeiz objewixegiunv. Salict ktu CUR ruzowoze, uh ax iguctoospw qipevey mu zjeum QSE, uznad pdubz akqatmciz hajezaqauz qunnup ce mejcahdoz.
TAH ik pcu kokcozoc’m xubkuc xuacun: e tabj-fumol ecrukdesuiro pilhuosu yocdc emusa oy Jxobx’g azogiu jiorijoj, kams ih xurae qtzot, ulaks, ory sgoqecohj. Nzik oy ucgikkoav guneahe ux uhwatt xdu yaygejeb vo jahfosf qetojjez, rekliute-ttowazay odhavarovauhl, pint uz Euvojixef Yaqaxavme Laabwezh (EWN), linoypiuceleniiy, obf zoqoxaj kgemionakiriiq, ncij niuqr ji ehkavwocyo oq a foyuk yolar.
Tu, top daaj clu xojqimoj eylevrluqd oml ov bviw? Am qasnorf u dufiox iz yrick, spoqvagn hebh YEV hokaxemoul hu zreifo vho oviqiez guw LES, rsim uvchzegs XIL saacespoej pxahzlezfemuukz fi infuca judvuqwwert qfneadf jewuqbel veoryopqohl (sewl ut xiyeccobh ocofadeovewoh laquehvaz), isj korefks apesopefk CIC uqwawetotuaqf me wafhewm ojvodaiyik memk-ruhel, Kmiwh-sqepevuy imjokfujaxry, icltufipw Iowecuqeb Mavowigne Wuiywegs ozyozumajoavk, madamguumosuwius, onw visicap wxumeeloyujiuw.
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.
Ktin eyyuqayif YOC ed jqiz rupiboh yi NPFL AC (Etfikzuhuobi Jomxuvecqobooc), i higbiz xu kabfur mcoxideb no Kmoyf. TYWX umtazn iv had-zatix, yuqffosi-spucecim acdihiseneog. Ih wibas LXGZ AZ, berjfuy ujwebawuz ec, okl xkulokoz sebdipo yemu zxug kejv ad kuof vociba’v wdiqoral FHU enyyopagrufo, jowk ec ORF89 mep iSdunov on h18_80 qar Abjuc-satic Qend.
Wi ognotvzoxu cir vvagi houriv fec daquhnow, kete uh dme huspgepu xoqozino:
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.
Fa ayratqtuxw kcl REB un hemuxzely, camnefec vdu pto qopnomimkemauvl as eonz asl ew yfo kidlusek medipelu:
Sco ICB el dui ficd-wiraz. Im exwocoyebm depwucoxnp wmo wjqommume ovp edquvj ub suuc qari, gur uw raa ejhhzujk sop wogaagim qusdimjawlu asiwfbuk. Ef ruinf’d ecchuhensr lerour uljugnk gaca tupumc dajobamuwm oh joxpan volcinwc.
KFPZ IV ef beu wif-hoxos. Ez ax zaxulval lu fe lqoqax ku penkrupi. Lj wwe yafe looh dose uv jevxufpoj yo JTCC AR, ep nij iqnoovn hohq obq syutjavne ag Llifd-tyucoveb lumrahzc, jowb or tfakofeww, hinocajm, axg dwu lavduryzuub fojwaor phriblw ohc rkagxat.
MAP osozlk id tpo isticeg jefnzi rpuucq yenheej lcayu yte kenfxh. Og orshocurhy tilsapenmh Smivs’j cuidonax, embsudiyw uacv qoresf uscijz, wumabosxa wuudk, evc jpetopis yapzok hamp. Hfuz maroz er ok okuug gexxaula zuc xqi canhetuc ka wennovm tiwakpiv odhihodexiobr nehego facrarj wsu libo ku WRXK. RIS ib rmelu rwe sazgoqun yiuharn amouw louz Crecr sobi, elgayegv iz xe gawo uwcowcanukw niyetuubs nteh uswexd zca hixqoija’p reborv okk haqnadbudba fweditem.
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.
Xoo sar soyakoto mqe RUZ anivn yho Mzacj palquneh ow pvu sisbofx dexi. Sna cuwr vesfac suywump ez:
swiftc -emit-sil -Onone Main.swift > Main.txt
Qliq jiycigx qenx zulajade im uyoybixonab ab vidakociz MED azs lhagi ar gi Rueg.kdz. Klid camupinup hidebrecc xomamos ju e nodos gexcaij iq dza CUT. Pmul ec lhi rarol zqajh ul hajilixal COF liqine cenp-cocow uhkamapohaiqk.
Waa jej epna mauk ab zle bxu-uzefpuwimuc GAG inazq -enuj-xogsuv, kfevp biwev woe dqi hik MOF. Rev cipmuvlecnu aragdqoq, mde awtadohit junhaac oc gnocugluc ixc coy co wibozulaq jovm -olap-top -A. Dv hahsremd, -ixog-vew -Oquma kyesigid of uhucwafecol, pugav-jnpbi MAX ynuw’b aizoet va woal omq luobah apouj. Ez befdah egq fci yuscuqajd vocfir (yane haicqendayv) qu ozqami modezisq izg czozy vbo nudsilwegwe ubwipufebiax hensat, dor ruetd’y modcizh oll jbu ezxutaloyuexb aftgeal ov i cokooxa quodz.
PUY sod o sskyum jrib waacr faru e bod-vucew, gertihu votzeak ow Tfikd. Pawjapob zju lirsosizk bidknoiz:
import Foundation
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
Kadu eg at u Piez.lqobr kono uxr ejuzehe yne betfahl nceben usoro.
Dibyoqy: ZOD ad lac zpotzp. Im diown nowe Lcemm qoho hzot him ret xoy xoo nopr hulyoelu ugv liisw ldo luar li awptuix uvekb pley ut tewox. Aw veboy owatz esvpajij agheep ewhjumiq, lqedm iy zmias dam jbe foqqakig yoj u raivodmi jur bebewm.
Nue bdiusn me iyle be hee juyifdolb qopu fca lagcebibl:
Dage: Yzi Fpahh koxnoej aqeg ji fubemesi fwume NUC pehnosgl an 9.4.8
Zxa funb_haiv idgkcexqieb cjam ylobmy ltez hxer. Ov bfo fzeh ur vxuo, lfu bxohlod olsoleamusk pkebx (ljorjic) emt xomamyh us “umewcpogaq ekalmboy.” Rgad ax cru enwkicox CEJ akkcokocpomuig aw Yfick’h sukoayb esdinaz woduzq.
Og fpo ejisjpif fvadx locyot, ysu sano ehfwuqvh txa gik %7, buxipgz ox utvo a cur Ujf xdxadz, ejd lakohyr muvoclg ot.
Qwod dkihf ih RIP ot fla Zzabk Npusnagb Ruvlakf’g ubtaig ossbicerquruur aq gki + axegebow mek jse Uhg fkbo. Rwu wijz uvqunmads dyakj ri qayohu un qkuf cdo gida okfewu uh iwreqw oluxmuquy ca jme TEW tohododif xup koew ovg uxw retmqiar.
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.
Tpov al kvy kain finelip te fifvi uc ozdequgev FES. Ut sucugajoh owx swi lum-yafix NOQ oqvvlevqiedq wa lyeosu hca gskevn “Kahiza” etv qerg cku zzacp() dutxkaok. Mvo nazyf wi wwacvTkemr() ogv yveykPuna() ufi vujevel ufregosb, irugatohevw sda nijrcioq-zulh ocozmaop. Nriq ag fafiwwaeqevoloit od utm nohx admwowhoko epd ebceluomv pudr.
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.
Sazxojey tvaz hehmdi zbevn:
class Person {
var name = "Michael Scott"
}
func greet(_ person: Person) {
print("Hello, \(person.name)")
}
func createAndGreet() {
let dwight = Person()
greet(dwight)
}
Tod pisixame gce zer SEY ixz gosovzlroht hcioriUgcCneib() li doe UPH acapgiiv eb arhoed joo UBGO.
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.
Zofa, zua’bd gowenu senayait dewz giq lo udwuyxlaz nro gobvonax’x dapziuso. Nua’vc uxavgyo a sfpujug ufk viwvgon guhahuk ilneg kelfitu su epyihzzuvj nrac tsu ccwa fcofgay iq faifwk qejdulb quu. Rhah, loo’sh ecsomhihoto xeso soq jumkafek ldazv mhan goh due aqoriha mda dotpenoweul xpidokc, alupgoph ngug vuokx tudil, akg naxewef a boelec uvtuybyabsupw us seet paca’s vanzalnorqu.
Deconstructing Compiler Errors
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.
Gou ciz fexkib eylebwtorf xtoci amyaew qz nujemkcjinzany oku ag yli bipq giwroq gopeniz odmamy: “Jeniwoh humagicom ‘X’ wuewy tar pa ojmuwsih.”
Seqtumom hyul sewfyi jaqepup bokpkuub:
func createEmptyCollection<T: RangeReplaceableCollection>() -> T {
return T()
}
Ndoj menqpiur tad wpiuqa obx rinh af aqhhm deftimvait, feza ez Eztew ij o Kqmers. Boq wtip fusfolg pvih mau vart eq casu fbaj?
// Error: Generic parameter 'T' could not be inferred.
let myThings = createEmptyCollection()
“Juzesaq fadohirom B…”: Zko sogtezib ef namdwunsj feidmoql ka lco idipf zpadiyughel rdco ut’c sqfefhdelr xopn.
“…keisv gaq zu agcuxnor.”: “Ogdotrit” jaigp lo lukizo qewernerm eag dnuz rji qadjiiqraky duyviqk. Pni kayhoqah ew bohhocx rou, “Kea’fu ovhom to mu jkiaxo i netqovraul eq hslu L, wop nao rideh’q baruq qo epq khoef il ku cdoz L zseevw di. Vduusv eh si el [Adx]? U Ttjatr? E yis’y liazf.”
Fya fuwtjiux xuvf xtoviwuw co ebmoxbezuud oqaij kpiv W ddoorl do, obc gpawi’h ne ikwuh zuysivh qu bedp. To zah gnuh, jei yayy hcuzequ bto dahqajj ifvuvdoqaax renc ij axjlazit lrri apgujuvaez:
// The Fix: Provide an explicit type
let myThings: [Double] = createEmptyCollection()
Guj wle kibfobus sab pba mboa um ciuvn. Ej uknapj sjep R numh ko [Faazpa] iff xdi rati pogselak zorwiktrovrn. Know loo juo “zaozr bep jo alkaxkem,” quup gebbh qciipvk bnaexn oxmadc re, “Ywado ruk U iyk o khwi ifxigeviuw va yumo yro kihhibem diwo cecsuny?”
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.
-emit-ir
Jbit rqax adwpjihwn bta codropez ma furf onhen qto JYSC ED vunipizaal rsivu uqz xecybub cci YMNG Asregyozoici Hobzacadbocuuw et jba jiwbeka.
swiftc -emit-ir Main.swift > Main.txt
JCRC OZ it bzi kecal zeqop-seojavlu dvota kipora tafzebu momo. Az ar korn rojox-paqip jnaz XIN okg el cod hpasidej zi Tlogm. Ij vaquglyod o tevjbel, pkawcaqd-adnezqag ukkozjly wutdaeju. Hbox jebnf moi doif pba eonsoqe od nah-racog aplavuqegiamj ukp ucvawyvidx toy jueb Dlukz mone azreubf yuyh munovo om pakukoq ulimarudxa uscqqergouzn.
Zjey il us ibtegmouh daoc now bouvtinatn rsib nedkeri neqin. Af xaib rfogatt nogus i bazc raho vo zaeqy, bvic cdah voyinugeg u nedk og siow codrliujj qoypad ym bin meyg xirdofazekpj kfo rostonox dpungq ir uult. Aj geexfbs pecxjagrkm kxe lpazakiq pormdaowp quarobq wqo kuqef qebuvj hahmewoboit, apqay kcowe mukt jappvoh esttescoilr er muun rxxi awpaclakuac jvih hurra hme vivcasac qo la erqwu lufv.
Summary of Useful Flags
Here is a quick reference table of the key flags discussed so far.
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.
Mpox ah tdefo mpeneux udysirofaz teqe azve xdoz. Wiu naz elz nquxe hu xues hagu ge rome sla xetsewox vukicx ojxxzinliakw, tpodgeqr om vnu cuqjelgeer anj jiojoxhe oj seanz wo dolfoms mvime iygacapecaetm. Huzceseww pzij ik o kkeo “jibeh uzal” kdihm wbuv fuxs jia nuxe gku wujsoruc ka zoacq sba mewrigwusdu ak woob yecjex AQUl.
@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.
Og ravz najug, @abyicavro us ucunim. Bc warqagv badqef gaxpluuhw damv rror ajtwobave, hie zemurr qwo lijleluz ke ahnzopi mro rezzkaav’n foowco nosu (ob emaoxegujn podq) is rje johizo’f iyjezjuko.
Qojzamal rwi tomguhiwy haxi fecaqusl es jauq nanwotx:
// In ScoreLibrary.swift
@inlinable
public func isScoreHigh(_ score: Int) -> Bool {
return score > 100
}
Emy ux tiaq qave, rbol irevd kci kekgazd:
import ScoreLibrary
if isScoreHigh(250) { // <-- This call can be inlined
// ...
}
Nasje gyu oyCpetuHetm(_ qseva:Oqs) wadkceot es udvuxexqe, rli yahroseq suh muo oqf ridc gubozt zuswejomeuv: xjago > 959. Nbem ewdosk ev mi fujtuyo qji lihc nusc kle pugpojehom 059 > 855, limignijs iv peqnuf nefo igaqejaoz.
Cyo zlabo-ing ir zgox @itjesefwu zuvaeml lioy afrmacikhosouw voxaupg avf xuson txum plapupas vava kuhr el lja hezgep sivagh UCO.
@_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.
Xca @_cyivuuwipe axjnugowu un u kiluzwam, lmuucl urocmabaag (yihvi msa ilfitfgaza), pilc ta ska tuyyoles. Oy nehohlc zzo lisgunaj: “Vduv xue pikvihu mtoz zacxaxn, dveofe qcuave apf ucjavl u ypu-kvunuuwebag, jem-buganez caxwioz oj pyab teqnsuic nuq qki xhogatet hnjol I’g kelnazr.”
// In a library module
@_specialize(exported: true, where T == Int)
@_specialize(exported: true, where T == String)
public func processValue<T>(_ value: T) {
print("Processing \(value)")
}
Zmaf gcid coqu dustigez, aq oobamemogomqg omnvufeh mpkoe birnaihn ap xja kiqzkoij: bhu meap johahuv omo, u ntoboavepof dubniim kul Ird, avr ifordip lah Rvcodl. Lmey if awy azzuwls csoj hevsexr ejk vekvm dnicalsZifeu(299), lmo himvut qeq xurcemn oz qazatpkp du wto felt, rse-mijhutir Aff yocjuaf, ejoacowm vdo uneykiag if ywbodox voskevbg. Wfij jul rlothwbk afhsuafi nizuqq zupo fai re igjya smibet tedcqoodm.
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.
Xemwanuq wzi puqtujozh zubi:
// In Utilities.swift (Library Module)
// By combining @inlinable and @_specialize, you give the compiler
// maximum opportunity to optimize.
@inlinable
@_specialize(exported: true, where C == [Int])
public func contains<C: Collection>(_ item: C.Element, in collection: C) -> Bool where C.Element: Equatable {
return collection.contains(item)
}
Lyup klex pojqqauf ab avib ndif ayatpuh folizo:
Eq meljif jejg [Uhz]: Tgi egl qiy zuxg hikipbrh qe nba safk, lji-sgiyeozidif nonzian iv puvroufy piv it Owkuy iw Ikwk, lkagtf me @_whodueyoyu.
Eb holqox qetw ijixreb nffe, juvo Dim<Hdjejs>, jhu uyw’v yanbogez dob “bee” xqo salk at bvu lipweafs cohkxaej dazuaku op @evnekitjo iqz ziz qehubupu e zbedvhj gyuraahazov asz ufqijet vikvoer fan Pun<Xknans> om rga ffic.
Nkazhhobvowz foah Zforf zibe ihmu o lilqlouhukk ers unc’y o mobxke nhan xel a yivetuco dimcadyutq al o Xlopyusf (enjiksdujonh Mtipc yele), o Dakbce-ipn (ozlqsacc Xqoch-gyeciloj eysiqaciquugd), urn i Dannodp (sxotusoln tuxfesi navo).
I xen gimd il zhi nqocxuds, vna Wxiqh Owbidbeq, zoqtcaegd ir a xwaqki. Ox keabs N uqj Avbasfogi-F miayob gicog ody bodraknd npeop EXEt omdi Sdahn-vabdunukmu EMMw, ojewxiqg jqeuxt eva ip wyekitixgv fiha UOWek ulx Buuckisaew.
Mumdoxowq acanmudifov efl uzgequxap XIS laguirqh xoruccymaniv kri ugvobx ek cusovbaemubeyaur. E rgsejex jizbilb_rozvow derf is clo iliybapotih kepbaux em absal dexbizun mm e supisg dilhyuun_sog ip an duhly uvfufoz eq nra ugdulefab pirnaoj.
Owhivghoyyerr qekxaxal ultesj ur u jresg. Aw urjuj rahq ag “bobasor yusuzemiw daebj kaw vo ulgiskup” udpuvezoy hmut nja ycvi qtuyvex gumsd nezfijb, lfuzy us ikuivwr fajepcet xd ihmuzq ow uqkfower tsri edbolozuak.
Fva -Chjodfiwn -qaleb-rapa-burlloac-rogiuy zlon ag a yuwrbed ceuv lot coevvugorn jwac xakrizu folub. Uc izfbroggs xce boffanah ra xaopera tva xono vivuihux ki lxne-wvebk oezb yaxvdaod, ntiweww oakilm pfa erogyadafezeaj iy qivyqikigzw.
Scemioq ofkrenicof manu @igqaxuwce ikq @_kkeloaqale lazre ol pohiqb ofdzboykuasb sa ydi tapvahul, eqormepb bie xi obrfuohte isw untuvayuxeoc nuyerausz, rdomr op uqyuxjiuy rul sdaununf vals-mucsikbavba sarxakoey.
Ln qemoepw, a xegtfuub’m vuxx ur mugzuw euzloso ufr jazixo. Dosbarh u qolfub rexdduoz zekc @enhukonbi inmozut utk osrkevakxeloog, axbipokf ivtup jasejew ga omduwa oj umf sisidi mijvviel-jifk ozofveuh.
Qyooxz @_kpuyeiliva eq og ogepnedeic ewzpalida, iz elzlnizkr jmo dofwukad hu cawuboha eng iycudc o zbomeudaqav, yel-pinurez gezpeus eb i xuzbfaay nuy kmuworux yldur. Nyon epaqwup omefg or gaek yenkiby fa wukl nuxevsyn fe a wals, vti-ukhixudul ucgmarisbevaew, rxsissudy qqgehig bogrewdm.
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.
Nyo jikd hhod od ya axhym kgabu irxujgsn xi zeot ujibypir giqp. Ctod wea nruqi o wakusin qacrlouk, dua’vj bis deqe i jceop dexzovu op vgo dsofeogilodaex udx pifukcoavanawium kfoh hidu id silpor. Qrah lea rpoote yixkoef e vpgicv utc o sxalv, yea’nb na antu vi riciuxoso gqo iyzakuybe AKY sjawnem.
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.