GDC(1)

πŸ’… GDC(1) β€” or, the manual page, but make it a group chat

GNU Β· GDC(1)

okay bestie, sit down, hydrate, because we are learning gdc today and honestly? it's giving iconic compiler energy. this is the manual page for gdc, from the GNU fam. let's get into it. 🫢


✨ NAME ✨

gdc β€” a GCC-based compiler for the D language

yes queen, it's a compiler, and yes, it's built on GCC. two legends, one binary. πŸ’…

🌸 SYNOPSIS 🌸

gdc [-c|-S] [-g] [-pg]
    [-Olevel] [-Wwarn...]
    [-Idir...] [-Ldir...]
    [-foption...] [-mmachine-option...]
    [-o outfile] [@file] infile...

Only the most useful options are listed here; see below for the remainder. πŸ‘‘

not me putting the greatest hits up front and hiding the deep cuts down there. scroll, babe. there's like forty of them. 😭

πŸ¦‹ DESCRIPTION πŸ¦‹

The gdc command is the GNU compiler for the D language and supports many of the same options as gcc. This manual only documents the options specific to gdc.

so like, if you already know gcc, you already know 80% of this. the rest of this page is the D-flavored sprinkle on top. 🧚

πŸ‘‘ OPTIONS πŸ‘‘

πŸŽ€ Input and Output files πŸŽ€

For any given input file, the file name suffix determines what kind of compilation is done. The following kinds of input file names are supported:

  • file.d β€” D source files.
  • file.dd β€” Ddoc source files.
  • file.di β€” D interface files.

You can specify more than one input file on the gdc command line, each being compiled separately in the compilation process. If you specify a -o file option, all the input files are compiled together, producing a single output file, named file. This is allowed even when using -S or -c.

bestie, that's the plot twist: multiple inputs, ONE output file. it's giving polycule but make it a linker. πŸ’–

A D interface file contains only what an import of the module needs, rather than the whole implementation of that module. They can be created by gdc from a D source file by using the -H option. When the compiler resolves an import declaration, it searches for matching .di files first, then for .d.

so .di files are like the trailer, not the whole movie. and when gdc goes looking for an import, it checks .di before .d. priority. periodt. ✨

A Ddoc source file contains code in the D macro processor language. It is primarily designed for use in producing user documentation from embedded comments, with a slight affinity towards HTML generation. If a .d source file starts with the string Ddoc then it is treated as general purpose documentation, not as a D source file.

yes, the literal string Ddoc at the top of your file changes its whole identity. main character energy, honestly. 🎭

🌈 Runtime Options 🌈

These options affect the runtime behavior of programs compiled with gdc.

  • -fall-instantiations β€” Generate code for all template instantiations. The default template emission strategy is to not generate code for declarations that were either instantiated speculatively, such as from __traits(compiles, ...), or that come from an imported module not being compiled.
"generate code for EVERYTHING" β€” the maximalist option. obsessed. πŸ’…
  • -fno-assert β€” Turn off code generation for assert contracts.
bye bye asserts. 🫑
  • -fno-bounds-check β€” Turns off array bounds checking for all functions, which can improve performance for code that uses arrays extensively. Note that this can result in unpredictable behavior if the code in question actually does violate array bounds constraints. It is safe to use this option if you are sure that your code never throws a RangeError.
⚠️ okay so this one is fast but feral. if your code is actually out of bounds, behavior gets unpredictable. only safe if you're 100% sure you never throw a RangeError. no cap.
  • -fbounds-check=value β€” An alternative to -fbounds-check that allows more control as to where bounds checking is turned on or off. The following values are supported:
    • on β€” Turns on array bounds checking for all functions.
    • safeonly β€” Turns on array bounds checking only for @safe functions.
    • off β€” Turns off array bounds checking completely.
it's the "choose your own adventure" of bounds checking. 🌸
  • -fno-builtin β€” Don't recognize built-in functions unless they begin with the prefix __builtin_. By default, the compiler will recognize when a function in the core.stdc package is a built-in function.
builtins? not today. unless you name it __builtin_ explicitly. πŸ’€
  • -fcheckaction=value β€” This option controls what code is generated on an assertion, bounds check, or final switch failure. The following values are supported:
    • context β€” Throw an AssertError with extra context information.
    • halt β€” Halt the program execution.
    • throw β€” Throw an AssertError (the default).
so when things go wrong: extra tea, or full stop? you decide. throw is the default, so if you didn't pick, you're a throw girlie. πŸ“
  • -fdebug
  • -fdebug=value β€” Turn on compilation of conditional debug code into the program. The -fdebug option itself sets the debug level to 1, while -fdebug= enables debug code that are identified by any of the following values:
    • level β€” Sets the debug level to level, any debug code <= level is compiled into the program.
    • ident β€” Turns on compilation of any debug code identified by ident.
two flavors, one vibe: a number, or a name. πŸŽ€

This is equivalent to compiling with the following options:

gdc -nophoboslib -fno-exceptions -fno-moduleinfo -fno-rtti
betterC mode!! the "no runtime, no problems" arc. 🧚
  • -fextern-std=standard β€” Sets the C++ name mangling compatibility to the version identified by standard. The following values are supported:
    • c++98
    • c++03 β€” Sets __traits(getTargetInfo, "cppStd") to 199711.
    • c++11 β€” Sets __traits(getTargetInfo, "cppStd") to 201103.
    • c++14 β€” Sets __traits(getTargetInfo, "cppStd") to 201402.
    • c++17 β€” Sets __traits(getTargetInfo, "cppStd") to 201703. This is the default.
    • c++20 β€” Sets __traits(getTargetInfo, "cppStd") to 202002.
pick your C++ era. c++17 is the default, so that's the canon timeline. ⭐
  • -fno-invariants β€” Turns off code generation for class invariant contracts.
invariants? not invited. πŸ™ˆ
  • -fmain β€” Generates a default main() function when compiling. This is useful when unittesting a library, as it enables running the unittests in a library without having to manually define an entry-point function. This option does nothing when main is already defined in user code.
gdc writes your main() for you so you can test a library without hand-rolling an entry point. if you already wrote one, it respectfully does nothing. polite king. πŸ‘‘
  • -fno-moduleinfo β€” Turns off generation of the ModuleInfo and related functions that would become unreferenced without it, which may allow linking to programs not written in D. Functions that are not be generated include module constructors and destructors (static this and static ~this), unittest code, and DSO registry functions for dynamically linked code.
great for linking with non-D programs. the casualty list: static this, static ~this, unittest code, and DSO registry functions. πŸ’€
  • -fonly=filename β€” Tells the compiler to parse and run semantic analysis on all modules on the command line, but only generate code for the module specified by filename.
look at everything, commit to one. that's called being selective, bestie. πŸ’…
  • -fno-postconditions β€” Turns off code generation for postcondition out contracts.
no out contracts, no notes. ✨
  • -fno-preconditions β€” Turns off code generation for precondition in contracts.
and no in contracts either. we're going contract-free, it's giving minimalism. πŸ¦‹
  • -fpreview=id β€” Turns on an upcoming D language change identified by id. The following values are supported:
    • all β€” Turns on all upcoming D language features.
    • dip1000 β€” Implements <https://wiki.dlang.org/DIP1000> (Scoped pointers).
    • dip1008 β€” Implements <https://wiki.dlang.org/DIP1008> (Allow exceptions in @nogc code).
    • dip1021 β€” Implements <https://wiki.dlang.org/DIP1021> (Mutable function arguments).
    • dip25 β€” Implements <https://wiki.dlang.org/DIP25> (Sealed references).
    • dtorfields β€” Turns on generation for destructing fields of partially constructed objects.
    • fieldwise β€” Turns on generation of struct equality to use field-wise comparisons.
    • fixaliasthis β€” Implements new lookup rules that check the current scope for alias this before searching in upper scopes.
    • in β€” Implements in parameters to mean scope const [ref] and accepts rvalues.
    • inclusiveincontracts β€” Implements in contracts of overridden methods to be a superset of parent contract.
    • intpromote β€” Implements C-style integral promotion for unary +, - and ~ expressions.
    • nosharedaccess β€” Turns off and disallows all access to shared memory objects.
    • rvaluerefparam β€” Implements rvalue arguments to ref parameters.
    • shortenedmethods β€” Implements use of => for methods and top-level functions in addition to lambdas.
this is the ✨future feature✨ menu. all is the "give me the whole buffet" button. 🌈
  • -frelease β€” Turns on compiling in release mode, which means not emitting runtime checks for contracts and asserts. Array bounds checking is not done for @system and @trusted functions, and assertion failures are undefined behavior.

This is equivalent to compiling with the following options:

gdc -fno-assert -fbounds-check=safe -fno-invariants \
    -fno-postconditions -fno-preconditions -fno-switch-errors
⚠️ release mode = speed, but at what cost. assertion failures are undefined behavior. yes, THAT undefined behavior. πŸ”₯
  • -frevert= β€” Turns off a D language feature identified by id. The following values are supported:
    • all β€” Turns off all revertable D language features.
    • dip25 β€” Reverts <https://wiki.dlang.org/DIP25> (Sealed references).
    • dtorfields β€” Turns off generation for destructing fields of partially constructed objects.
    • markdown β€” Turns off Markdown replacements in Ddoc comments.
the undo button for language features. the anti-preview, if you will. 😭
  • -fno-rtti β€” Turns off generation of run-time type information for all user defined types. Any code that uses features of the language that require access to this information will result in an error.
no RTTI. if your code needs it, it's a whole error, not a warning. she's strict. πŸ’…
  • -fno-switch-errors β€” This option controls what code is generated when no case is matched in a final switch statement. The default run time behavior is to throw a SwitchError. Turning off -fswitch-errors means that instead the execution of the program is immediately halted.
unmatched final switch? default throws a SwitchError. flip -fswitch-errors off and the program just halts. no ceremony. πŸ’€
  • -funittest β€” Turns on compilation of unittest code, and turns on the version(unittest) identifier. This implies -fassert.
unittests ON, version(unittest) ON, and it drags -fassert in with it. ride or die. 🫢
  • -fversion=value β€” Turns on compilation of conditional version code into the program identified by any of the following values:
    • level β€” Sets the version level to level, any version code >= level is compiled into the program.
    • ident β€” Turns on compilation of version code identified by ident.
same two-flavor situation as -fdebug, but the comparison goes >=. not me noticing the little details. πŸ‘€
  • -fno-weak-templates β€” Turns off emission of declarations that can be defined in multiple objects as weak symbols. The default is to emit all public symbols as weak, unless the target lacks support for weak symbols. Disabling this option means that common symbols are instead put in COMDAT or become private.
weak symbols? cancelled. they go to COMDAT or go private. either way they're not weak anymore. glow up. ⭐

These options specify directories to search for files, libraries, and other parts of the compiler:

  • -Idir β€” Specify a directory to use when searching for imported modules at compile time. Multiple -I options can be used, and the paths are searched in the same order.
stack as many -I as you want β€” order matters, she searches top to bottom. 🌸
  • -Jdir β€” Specify a directory to use when searching for files in string imports at compile time. This switch is required in order to use import(file) expressions. Multiple -J options can be used, and the paths are searched in the same order.
🚨 this one is required for import(file) expressions. no -J, no string imports. and yeah, multiple -J allowed, same-order rules apply.
  • -Ldir β€” When linking, specify a library search directory, as with gcc.
the linker's -I. just gcc behaviour, copy-paste energy, and that's fine. πŸ’…
  • -Bdir β€” This option specifies where to find the executables, libraries, source files, and data files of the compiler itself, as with gcc.
where does the compiler find its own stuff? right here. as with gcc, bestie. πŸŽ€

✨ that's part one, and we're not even done yet β€” the rest is coming, so don't go anywhere. πŸ’–

  • -fmodule-file=module=spec β€” ok so this one is lowkey a ✨path remixer✨. If an imported module matches all of module, or just the leftmost part of it, then spec becomes the file path the compiler uses to hunt down D sources. You need this when your source file paths/names don't line up with the package + module hierarchy (iykyk, it happens). Peep the examples:
gdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar

That tells the compiler: when importing A.B, search all import paths for the source file foo.d; when importing C, look in the directory bar/. Which, in D code, looks like:

module test;
import A.B;     // Matches A.B, searches for foo.d
import C.D.E;   // Matches C, searches for bar/D/E.d
import A.B.C;   // No match, searches for A/B/C.d
  • -imultilib dir β€” use dir as a subdirectory of the gcc directory that holds target-specific D sources and interfaces. πŸ’…
  • -iprefix prefix β€” sets prefix as the prefix for the gcc directory with target-specific D sources and interfaces. Bestie, if your prefix is itself a directory, you gotta include the final /. no cap.
  • -nostdinc β€” do NOT go looking through the standard system directories for D source and interface files πŸ™…β€β™€οΈ. Only the directories you gave with -I options get searched β€” plus the directory of the current file, if that's appropriate.

🌈 Code Generation 🌈

On top of the many gcc options that control code generation, gdc has a few that are just its own thing. it's giving main character energy ✨

  • -H β€” generates D interface files for every module being compiled. The compiler figures out the output file from the input file's name, strips any directory components and suffix, then slaps on the .di suffix. πŸŽ€
  • -Hd dir β€” same as -H, but the interface files land in directory dir. You can pair this with -Hf file so you set the output file and directory path independently. πŸ’–
  • -Hf file β€” same as -H, but interface files go to file. Pairs with -Hd dir to independently set the output file and directory path. πŸ¦‹
  • -M β€” spits out the module dependencies of all source files being compiled, in a format make can vibe with. The compiler outputs one make rule: the object file name for that source file, a colon, then the names of all imported files. ⭐
  • -MM β€” like -M, but it does not mention imported modules that come from the D standard library package directories.
  • -MF file β€” when used with -M or -MM, names the file to write the dependencies to. And when used with the driver options -MD or -MMD, -MF overrides the default dependency output file. 🫢
  • -MG β€” this exists for compatibility with gcc, and the compiler literally ignores it. πŸ’€
  • -MP β€” outputs a phony target for each dependency that isn't one of the modules being compiled, making each of them depend on nothing.
  • -MT target β€” changes the target of the rule emitted by dependency generation to be exactly the string you give. Want multiple targets? Pass them as a single argument to -MT, or just use multiple -MT options. 🌸
  • -MQ target β€” same as -MT, except it quotes any characters that are special to make. iconic behavior honestly.
  • -MD β€” equivalent to -M -MF file. The driver figures out file by stripping any directory components and suffix from the input file, then adding a .deps suffix. ✨
  • -MMD β€” like -MD, but (again) does not mention imported modules from the D standard library package directories.
  • -X β€” outputs info describing the contents of all source files being compiled, in JSON format, to a file. The driver determines file by removing any directory components and suffix from the input file, then adding a .json suffix. πŸ”₯
  • -Xf file β€” same as -X, but writes all the JSON contents to the specified file.
  • -fdoc β€” generates "Ddoc" documentation and writes it to a file. The compiler determines file by stripping any directory components and suffix from the input file, then adding an .html suffix. πŸ“„
  • -fdoc-dir=dir β€” same as -fdoc, but writes documentation to directory dir. Pairs with -fdoc-file=file to independently set the output file and directory path. πŸ’œ
  • -fdoc-file=file β€” same as -fdoc, but writes documentation to file. Pairs with -fdoc-dir=dir to independently set the output file and directory path.
  • -fdoc-inc=file β€” names file as a Ddoc macro file to be read. You can stack multiple -fdoc-inc options, and the files are read and processed in the same order. 🧚
  • -fdump-c++-spec=file β€” for D source files, generates the corresponding C++ declarations into file.
  • -fdump-c++-spec-verbose β€” used together with -fdump-c++-spec= above, it adds comments for ignored declarations in the generated C++ header. πŸ™ˆ
  • -fsave-mixins=file β€” generates the code expanded from D "mixin" statements and writes the processed sources to file. Super useful for debugging compilation errors, and it gives debuggers a source to show when requested. πŸ’…

😭 Warnings 😭

Warnings are diagnostic messages that report constructions which aren't inherently erroneous but are risky, or which suggest there's probably a bug lurking in the program. Unless -Werror is specified, they do not stop the program from compiling. fr fr.

  • -Wall β€” turns on all warning messages. Warnings are not a defined part of the D language, so every construct that might trigger one here is still valid code. πŸ’–
  • -Walloca β€” warns on every single use of "alloca" in the source.
  • -Walloca-larger-than=n β€” warns on unbounded uses of alloca, and on bounded uses whose bound could be larger than n bytes. -Wno-alloca-larger-than disables the -Walloca-larger-than warning and is equivalent to -Walloca-larger-than=SIZE_MAX or larger. ⚠️
  • -Wcast-result β€” warns about casts that will produce a null or zero result. Right now this only happens for casting between an imaginary and non-imaginary data type, or casting between a D and C++ class. 😬
  • -Wno-deprecated β€” do not warn about usage of deprecated features and symbols that carry "deprecated" attributes.
  • -Werror β€” turns all warnings into errors. no survivors. πŸ’€
  • -Wspeculative β€” lists all error messages from speculative compiles, like "__traits(compiles, ...)". Heads up: this option does not report messages as warnings, so those messages never become errors even when -Werror is also on. 🌈
  • -Wtemplates β€” warns whenever a template instantiation is encountered. Some coding rules ban templates, so this can enforce that rule. πŸ‘‘
  • -Wunknown-pragmas β€” warns when a "pragma()" shows up that gdc doesn't understand. This differs from -fignore-unknown-pragmas, where a pragma that's part of the D language but not implemented by the compiler won't get reported. 🫢
  • -Wno-varargs β€” do not warn upon questionable usage of the macros used to handle variable arguments like "va_start".
  • -fignore-unknown-pragmas β€” turns off errors for unsupported pragmas. ✨
  • -fmax-errors=n β€” caps the maximum number of error messages at n, at which point gdc bails out instead of trying to keep processing the source code. If n is 0 (the default), there's no limit on how many error messages get produced. πŸŽ€
  • -fsyntax-only β€” checks the code for syntax errors, but does not actually compile it. Can be used alongside -fdoc or -H to generate files for each module present on the command-line, but no other output file. 🌸
  • -ftransition=id β€” reports extra info about D language changes identified by id. The supported values are:
    • all β€” list information on all D language transitions. ⭐
    • complex β€” list all usages of complex or imaginary types.
    • field β€” list all non-mutable fields which occupy an object instance.
    • in β€” list all usages of "in" on parameter.
    • nogc β€” list all hidden GC allocations. πŸ’€
    • templates β€” list statistics on template instantiations.
    • tls β€” list all variables going into thread local storage.
    • vmarkdown β€” list instances of Markdown replacements in Ddoc. ✨

πŸ”— Options for Linking πŸ”—

These come into play when the compiler links object files into an executable output file. If the compiler isn't doing a link step, they're meaningless. πŸ™ˆ

  • -defaultlib=libname β€” specifies the library to use instead of libphobos when linking. Options that specify the linkage of libphobos, like -static-libphobos or -shared-libphobos, get ignored. πŸ’…
  • -debuglib=libname β€” specifies the debug library to use instead of libphobos when linking. This one has no effect unless -g was also given on the command line. Options specifying the linkage of libphobos, such as -static-libphobos or -shared-libphobos, are ignored. πŸŽ€
  • -nophoboslib β€” do not use the Phobos or D runtime library when linking. Options specifying the linkage of libphobos, like -static-libphobos or -shared-libphobos, are ignored. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used. 🌈
  • -shared-libphobos β€” on systems that provide libgphobos and libgdruntime as both a shared and a static library, this forces the use of the shared version. If no shared version was built when the compiler was configured, this option has no effect. ✨
  • -static-libphobos β€” on systems that provide libgphobos and libgdruntime as both a shared and a static library, this forces the use of the static version. If no static version was built when the compiler was configured, this option has no effect. πŸ’–

πŸ› οΈ Developer Options πŸ› οΈ

This section is for the command-line options that are primarily of interest to developers or language tooling. iykyk. πŸ‘‘

  • -fdump-d-original β€” outputs the internal front-end AST after the "semantic3" stage. Only useful for debugging the GNU D compiler itself. 🧚
  • -v β€” dumps info about the compiler language processing stages while the source program is being compiled. That includes listing all modules processed through the "parse", "semantic", "semantic2", and "semantic3" stages; all "import" modules and their file paths; and all "function" bodies that are being compiled. 🌸

πŸ‘€ SEE ALSO πŸ‘€

gpl(7), gfdl(7), fsf-funding(7), gcc(1), and the Info entries for gdc and gcc. πŸ’œ

Copyright (c) 2006-2022 Free Software Foundation, Inc.

Okay bestie, here's the legal tea β˜• and it's actually kind of wholesome:

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation β€” with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

A copy of the license is included in the man page gfdl(7). So if you ever need to read the whole thing yourself (iconic behaviour, honestly), that's where it lives 🫢

TL;DR: you can share it, remix it, redistribute it β€” just follow the GFDL rules above, no cap. The Free Software Foundation said so and they ate πŸ’…

And that's the whole page, bestie!! πŸŽ€ You just read GDC(1) from the gcc-12 era, dated 2022-03-02 β€” a genuine little time capsule from the GCC 12 days πŸ¦‹βœ¨ Go compile something gorgeous with it. Mwah πŸ’–πŸŒˆπŸ‘‘

πŸ“¦ where this page comes from