GDC(1)

πŸ’… GDC(1) β€” welcome to the group chat

okay so first things first: this is GDC(1), the GNU manual page for gdc, and bestie, we're gonna get through the WHOLE thing together. grab a snack πŸ“


✨ NAME

gdc β€” a GCC-based compiler for the D language. that's it, that's the whole vibe check. πŸ’–


πŸ¦‹ SYNOPSIS

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

okay so only the most useful options are listed here β€” the rest are down below, so keep scrolling, we're not done. πŸ‘‘


🌸 DESCRIPTION

gdc is the GNU compiler for the D language, and the way it slays is that it supports many of the same options as gcc. iconic family resemblance honestly. 🫢

but heads up: this manual only documents the options that are specific to gdc β€” like, the special ones. the gcc-isms live in their own house. πŸ’…


πŸŽ€ OPTIONS

πŸ’œ Input and Output files

okay so for any given input file, the file name suffix is what tells the compiler what kind of compilation to do. it's giving "your extension is your personality." 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, and each one gets compiled separately in the compilation process. cute, right? πŸŽ€

now: if you specify a -o file option, then all the input files are compiled together, producing a single output file named file. and yes, this is allowed even when you're using -S or -c. slay.

A D interface file contains only what an import of the module needs, rather than the whole entire implementation of that module. very minimal, very main-character-restraint. ✨ 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.

A Ddoc source file contains code in the D macro processor language. It's primarily designed for use in producing user documentation from embedded comments, with a slight affinity towards HTML generation. and here's the fun bit πŸ¦‹ β€” if a .d source file starts with the string "Ddoc" then it is treated as general purpose documentation, not as a D source file. plot twist.


🧚 Runtime Options

these options affect the runtime behavior of programs compiled with gdc. like, what your binary does after it leaves the house. πŸ’–

  • -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.
  • -fno-assert β€” Turn off code generation for "assert" contracts. no thoughts, no 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". πŸ™ˆ
  • -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.
  • -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.
  • -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).
  • -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:
    • ident β€” Turns on compilation of any "debug" code identified by ident.
  • -fno-druntime β€” Implements https://dlang.org/spec/betterc.html. Assumes that compilation targets an environment without a D runtime library. 🫢

This is equivalent to compiling with the following options:

gdc -nophoboslib -fno-exceptions -fno-moduleinfo -fno-rtti
  • -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.
    • c++23 β€” Sets "__traits(getTargetInfo, "cppStd")" to 202302.
  • -finclude-imports β€” Include imported modules in the compilation, as if they were given on the command line. When this option is enabled, all imported modules are compiled except those that are part of libphobos.
  • -fno-invariants β€” Turns off code generation for class "invariant" contracts.
  • -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. 🧚
  • -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.
  • -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. (so it reads everything, but only writes one thing. picky. love that. πŸ’…)
  • -fno-postconditions β€” Turns off code generation for postcondition "out" contracts.
  • -fno-preconditions β€” Turns off code generation for precondition "in" contracts.
  • -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.
    • bitfields β€” Implements bit-fields in D.
    • dip1000 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped pointers).
    • dip1008 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1008.md (Allow exceptions in @nogc code).
    • dip1021 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md (Mutable function arguments).
    • dip25 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md (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.
    • fiximmutableconv β€” Disallows unsound immutable conversions that were formerly incorrectly permitted.
    • 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.
    • nosharedaccess β€” Turns off and disallows all access to shared memory objects.
    • rvaluerefparam β€” Implements rvalue arguments to "ref" parameters.
    • systemvariables β€” Disables access to variables marked @system from @safe code.
  • -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
  • -frevert= β€” Turns off a D language feature identified by id. The following values are supported:
  • -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. so like, don't, unless you know. πŸ’€
  • -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. (dramatic much? yes. correct? also yes. πŸ”₯)
  • -funittest β€” Turns on compilation of "unittest" code, and turns on the version(unittest) identifier. This implies -fassert.
  • -fversion=value β€” Turns on compilation of conditional "version" code into the program identified by any of the following values:
    • ident β€” Turns on compilation of "version" code identified by ident.
  • -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. πŸ¦‹

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


and that's exactly where part one leaves us, bestie β€” mid-sentence, right on the directory-search cliffhanger. πŸ’… no cap, the next part picks it right up, so don't go anywhere. πŸŽ€

  • -Idir β€” tells the compiler "bestie, go look in dir when you're hunting down imported modules at compile time." You can stack multiple -I options and the paths get searched in the exact same order you gave them, no queue-jumping πŸ’…
  • -Jdir β€” same idea but for files pulled in by string imports at compile time. This switch is literally required if you wanna use import(file) expressions. Multiple -J options? Totally fine, and again the paths are searched in the order you listed them ✨
  • -Ldir β€” when linking, this says "here's a library search directory," exactly like gcc does it.
  • -Bdir β€” points the compiler at where its own executables, libraries, source files, and data files live, just like the gcc version of this flag.
  • -fmodule-file=module=spec β€” this one's a lil path-remix tool πŸ”€ If an imported module matches all of module, or at least its leftmost chunk, then the file path in spec becomes the place to search for D sources. Basically it's for when your source file paths/names don't line up with the package and module hierarchy. Peep this:
gdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar

So that tells the compiler: search all the import paths for the source file foo.d when importing A.B, and look in the directory bar/ when importing C. Like so, as annotated in this D code:

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 containing target-specific D sources and interfaces. If that prefix is a directory, do yourself a favor and include the final / 🫢
  • -nostdinc β€” do not go searching the standard system directories for D source and interface files. Only the directories you specified with -I options (plus the directory of the current file, if that's appropriate) get searched. Periodt.

✨ Code Generation ✨

On top of the many gcc options that control code generation, gdc has a bunch of options that are all its own. Main character energy πŸ‘‘

  • -H β€” generates D interface files for every module being compiled. The compiler figures out the output file from the name of the input file: strips any directory components and the suffix, then slaps a .di suffix on there.
  • -Hd dir β€” same as -H, but writes the interface files into directory dir. You can pair this with -Hf file so you can set the output file and the directory path independently πŸ’–
  • -Hf file β€” same as -H but writes interface files to file. Works alongside -Hd dir to set the output file and directory path independently.
  • -M β€” outputs the module dependencies of all source files being compiled, in a format that make can actually eat. The compiler spits out one make rule containing the object file name for that source file, a colon, and the names of all imported files.
  • -MM β€” like -M but it does not mention imported modules from the D standard library package directories. Keeping it lowkey 🀫
  • -MF file β€” when used with -M or -MM, this specifies a file to write the dependencies to. When used with the driver options -MD or -MMD, -MF overrides the default dependency output file.
  • -MG β€” this one exists purely for compatibility with gcc, and the compiler just ignores it. It's giving "invited but not actually participating" πŸ’€
  • -MP β€” outputs a phony target for each dependency other than the modules being compiled, which makes each one depend on nothing.
  • -MT target β€” changes the target of the rule emitted by dependency generation to be exactly the string you specify. Want multiple targets? Pass them as a single argument to -MT, or just use multiple -MT options. Your call, bestie.
  • -MQ target β€” same as -MT, but it quotes any characters that are special to make. Safety first ✨
  • -MD β€” equivalent to -M -MF file. The driver works out file by stripping any directory components and suffix from the input file, then adding a .deps suffix.
  • -MMD β€” like -MD but 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 out. 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 into directory dir. You can use this with -fdoc-file=file to set the output file and directory path independently πŸŽ€
  • -fdoc-file=file β€” same as -fdoc, but writes documentation to file. Can be combined with -fdoc-dir=dir to set the output file and directory path independently.
  • -fdoc-inc=file β€” specifies file as a Ddoc macro file to be read. Multiple -fdoc-inc options are allowed, and the files are read and processed in the order you gave them.
  • -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, this 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 some source to show when they ask for it πŸ›

🌸 Warnings 🌸

Warnings are diagnostic messages reporting constructions that aren't inherently erroneous but are risky, or that suggest there's probably a bug lurking in your program. Unless -Werror is specified, they do not stop the program from compiling. So they're like, a vibe check, not a blocker πŸ’…

  • -Wall β€” turns on all warning messages. Warnings are not a defined part of the D language, and every construct that might trigger one is still valid code. So don't panic.
  • -Walloca β€” warns on all uses of "alloca" in the source.
  • -Walloca-larger-than=n β€” warns on unbounded uses of alloca, and on bounded uses of alloca whose bound can 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.
  • -Wno-builtin-declaration-mismatch β€” warns if a built-in function gets declared with an incompatible signature. Rude, honestly.
  • -Wcast-result β€” warns about casts that will produce a null or zero result. Currently it only does this 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 every single warning into an error. No warnings survive, they all get promoted 😀
  • -Wextra β€” enables some extra warning flags that -Wall doesn't turn on:
    • -Waddress
    • -Wcast-result
    • -Wmismatched-special-enum
    • -Wunknown-pragmas
  • -Wmismatched-special-enum β€” warns when an enum the compiler recognizes as special gets declared with a different size than the built-in type it's representing.
  • -Wspeculative β€” lists all error messages from speculative compiles, like "__traits(compiles, ...)". Heads up though: this option does not report messages as warnings, and those messages therefore never become errors, even when -Werror is also used 🫢
  • -Wunknown-pragmas β€” warns when a pragma() comes 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 on questionable usage of the macros used to handle variable arguments, like "va_start".
  • -fno-ignore-unknown-pragmas β€” do not recognize unsupported pragmas. Any pragma() encountered that isn't part of the D language results in an error. > Fair warning bestie: this option is now deprecated and will be removed in a future release πŸ’€
  • -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 doesn't actually compile it. Can be used with -fdoc or -H to generate files for each module on the command-line, but no other output file. It's giving "just here to observe" πŸ‘€
  • -ftransition=id β€” reports extra info about D language changes identified by id. These values are supported:
    • 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.

πŸ¦‹ Options for Linking πŸ¦‹

These options show up when the compiler links object files into an executable output file. If the compiler isn't doing a link step, they're literally meaningless. Situational icons only ✨

  • -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 option has no effect unless the -g option was also given on the command line. Options specifying the linkage of libphobos, like -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. Going fully independent, love that for you 🫢
  • -shared-libphobos β€” on systems that provide libgphobos and libgdruntime as both a shared and a static library, this option forces the use of the shared version. If no shared version was built when the compiler was configured, this option has no effect. Can't force what doesn't exist πŸ’…
  • -static-libphobos β€” bestie, on systems that provide libgphobos and libgdruntime as a shared and a static library, this option forces the use of the static version. If no static version was built when the compiler was configured, this option has no effect. That’s it, that’s the rule πŸ’…

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

Okay so this section is for the devs and language-tooling girlies β€” these command-line options are primarily of interest to developers or language tooling. Slay for the toolchain, honestly.

  • -fdump-d-original β€” outputs the internal front-end AST after the semantic3 stage. This option is only useful for debugging the GNU D compiler itself, so it’s giving very much β€œcompiler dev main character energy” πŸ”βœ¨
  • -v β€” dumps information about the compiler language processing stages as the source program is being compiled. This includes listing all modules that are processed through the parse, semantic, semantic2, and semantic3 stages; all import modules and their file paths; and all function bodies that are being compiled. Literally the whole backstage tour, no cap πŸŽ¬πŸ‘€

πŸ”— SEE ALSO πŸ”—

Go check out gpl(7), gfdl(7), fsf-funding(7), gcc(1), and the Info entries for gdc and gcc. Link-up complete, bestie 🫢

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

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). Legally iconic, fr fr πŸ’–


πŸ’– That’s the tea: this page is source/version gcc-16, dated 2026-10-29. Stay iconic, bestie β€” mwah! πŸ’…βœ¨πŸŒΈ

πŸ“¦ where this page comes from
  • fedora 44: gcc-gdc 16.2.1-3.fc44 Β· GPL-3.0-or-later AND LGPL-3.0-or-later AND (GPL-3.0-or-later WITH GCC-exception-3.1) AND (GPL-3.0-or-later WITH Texinfo-exception) AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GNU-compiler-exception) AND BSL-1.0 AND GFDL-1.3-or-later AND Linux-man-pages-copyleft-2-para AND SunPro AND BSD-1-Clause AND BSD-2-Clause AND BSD-2-Clause-Views AND BSD-3-Clause AND BSD-4-Clause AND BSD-Source-Code AND Zlib AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-Exception) AND ZPL-2.1 AND ISC AND LicenseRef-Fedora-Public-Domain AND HP-1986 AND curl AND Martin-Birgmeier AND HPND-Markus-Kuhn AND dtoa AND SMLNJ AND AMD-newlib AND OAR AND HPND-merchantability-variant AND HPND-Intel
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms