GDC(1)

๐Ÿ“ฆ
version 16-20260322 ยท 2 versions
, in ubuntu resolute

๐ŸŒธ GDC(1) ยท GNU ๐ŸŒธ

๐ŸŽ€ NAME ๐ŸŽ€

okay so gdc is a GCC-based compiler for the D language ๐Ÿ’… that's literally it, bestie.

๐Ÿงพ SYNOPSIS ๐Ÿงพ

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

only the most useful options are shown up top โœจ scroll down for the rest, there's a lot more ๐Ÿ‘€

๐Ÿ’– DESCRIPTION ๐Ÿ’–

the gdc command is the GNU compiler for the D language ๐Ÿฆ‹ and it supports a lot of the same options as gcc, so if you already know gcc you're gonna feel right at home. this manual only covers the options that are specific to gdc ๐Ÿซถ

๐Ÿ‘‘ OPTIONS ๐Ÿ‘‘

๐Ÿ—‚๏ธ Input and Output files

for any input file, the file name suffix decides what kind of compilation happens ๐Ÿงš these are the input file name kinds that are supported:

  • file.d โ€” D source files ๐Ÿ’œ
  • file.dd โ€” Ddoc source files ๐Ÿ“
  • file.di โ€” D interface files ๐ŸŒˆ

you can pass more than one input file on the gdc command line, and each one gets compiled separately ๐Ÿ”ฅ but if you use -o file, all the inputs get compiled together into one single output file named file. this works even with -S or -c ๐Ÿ˜ญ

a D interface file only holds what an import of the module actually needs, not the whole implementation of that module, which is so smart โœจ you can make one from a D source file with the -H option. when the compiler resolves an import declaration, it looks for matching .di files first, and only then goes looking for .d files ๐Ÿฆ‹

a Ddoc source file has code written in the D macro processor language ๐Ÿ’… it's mostly for making user docs out of embedded comments, with a slight lean toward HTML output. if a .d source file starts with the string Ddoc, it gets treated as general purpose documentation instead of as D source ๐ŸŒธ

๐Ÿƒโ€โ™€๏ธ Runtime Options

these options change how programs compiled with gdc behave at runtime ๐Ÿ’–

  • -fall-instantiations โ€” generates code for every template instantiation ๐ŸŒˆ the default strategy is to skip generating code for declarations that were instantiated speculatively (like from __traits(compiles, ...)) or that come from an imported module that isn't being compiled.
  • -fno-assert โ€” turns off code generation for assert contracts ๐Ÿ™ˆ
  • -fno-bounds-check โ€” turns off array bounds checking for all functions, which can boost performance for code that uses arrays a lot โšก
โš ๏ธ this can cause unpredictable behavior if your code actually does break array bounds. it's only safe if you're totally sure your code never throws a RangeError ๐Ÿ˜ญ
  • -fbounds-check=value โ€” a more flexible alternative to -fbounds-check that lets you control where bounds checking is turned on or off ๐ŸŽ€ the supported values are:
    • 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 โ€” doesn't recognize built-in functions unless they start with the prefix __builtin_. by default, the compiler does recognize when a function in the core.stdc package is a built-in function ๐Ÿงš
  • -fcheckaction=value โ€” controls what code gets generated when an assertion, bounds check, or final switch fails ๐Ÿ’… the supported values are:
    • context โ€” throws an AssertError with extra context information ๐Ÿ”
    • halt โ€” halts the program execution ๐Ÿ›‘
    • throw โ€” throws an AssertError (this is the default) ๐Ÿ‘‘
  • -fdebug, -fdebug=value โ€” turns on compilation of conditional debug code into the program ๐Ÿž the -fdebug option by itself sets the debug level to 1, while -fdebug= enables debug code identified by any of these values:
    • ident โ€” turns on compilation of any debug code identified by ident โœจ
  • -fno-druntime โ€” implements <https://dlang.org/spec/betterc.html> ๐ŸŒธ this assumes the compilation targets an environment with no D runtime library.

this is the same as 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 named by standard ๐Ÿฆ‹ the supported values are:
    • 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 โ€” includes imported modules in the compilation, as if they were given on the command line ๐Ÿซถ when this is on, every imported module gets compiled except the ones 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 super handy when you're unittesting a library, since you can run its unittests without writing your own entry point. it does nothing if main is already defined in your user code ๐Ÿ’…
  • -fno-moduleinfo โ€” turns off generation of the ModuleInfo and related functions that would become unreferenced without it, which may let you link to programs that aren't written in D ๐Ÿฆ‹ the functions that don't get 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 ๐Ÿงš
  • -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 supported values are:
    • 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 so it uses 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 used to be 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 the 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 no runtime checks for contracts and asserts get emitted ๐Ÿš€ array bounds checking isn't done for @system and @trusted functions, and assertion failures are undefined behavior.
โš ๏ธ assertion failures are undefined behavior in release mode, so be careful, bestie ๐Ÿ˜ญ

this is the same as 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 supported values are:
  • -fno-rtti โ€” turns off generation of run-time type information for all user defined types ๐Ÿ™…โ€โ™€๏ธ any code that uses language features which need this info will throw an error.
  • -fno-switch-errors โ€” controls what code gets generated when no case matches in a final switch statement ๐Ÿ”€ the default run time behavior is to throw a SwitchError. turning off -fswitch-errors means the program instead halts immediately ๐Ÿ’€
  • -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 these 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 doesn't support weak symbols. disabling this means common symbols get put in COMDAT or become private instead.

these options tell the compiler which directories to search for files, libraries, and other parts of the compiler ๐Ÿ—บ๏ธ

  • -Idir: ๐Ÿ’– Tell the compiler where to look for imported modules at compile time! You can use as many -I options as you want, and they get searched in the order you wrote them.
  • -Jdir: ๐Ÿซถ This one points at where to search for files in string imports at compile time. You need this switch to use import(file) expressions. Multiple -J options work too, and they're searched in order.
  • -Ldir: ๐Ÿ”— When linking, add a library search directory, just like with gcc.
  • -Bdir: ๐Ÿงš This tells gdc where to find the compiler's own executables, libraries, source files, and data files. Same deal as gcc.
  • -fmodule-file=module=spec: โœจ This one is kind of iconic. It messes with the file paths of imported modules. If an imported module matches all or the leftmost part of module, the file path in spec becomes the place to search for D sources. You'd use it when your source file paths and names don't match your package and module hierarchy. Check out these examples:
gdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar

This tells the compiler to search all import paths for the source file foo.d when importing A.B, and the directory bar/ when importing C. The comments in this D code show exactly what happens:

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: ๐ŸŒธ Uses dir as a subdirectory of the gcc directory that holds target-specific D sources and interfaces.
  • -iprefix prefix: ๐Ÿ“ Sets prefix as the prefix for that same gcc directory with target-specific D sources and interfaces. If the prefix is a directory, make sure you include the final /.
  • -nostdinc: ๐Ÿ™… Don't search the standard system directories for D source and interface files. Only the directories given with -I options get searched, plus the directory of the current file if that's relevant.

โœจ Code Generation โœจ

In addition to the many gcc options controlling code generation, gdc has several options that are all its own ๐Ÿ’….

  • -H: Generates D interface files for all modules being compiled. The compiler figures out the output file from the input file's name, strips any directory components and suffix, then adds the .di suffix.
  • -Hd dir: Same as -H, but writes interface files to directory dir. You can pair it with -Hf file to set the output file and directory path separately.
  • -Hf file: Same as -H, but writes interface files to file. You can pair it with -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 works with make. It writes one make rule with the object file name for that source file, a colon, and the names of all imported files.
  • -MM: Like -M, but doesn't mention imported modules from the D standard library package directories.
  • -MF file: When used with -M or -MM, this says which 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's just for compatibility with gcc. The compiler ignores it.
  • -MP: Outputs a phony target for each dependency other than the modules being compiled, so each one depends on nothing.
  • -MT target: Changes the target of the rule made by dependency generation to be exactly the string you specify. For multiple targets, you can specify them as a single argument to -MT, or use multiple -MT options.
  • -MQ target: Same as -MT, but it quotes any characters that are special to make.
  • -MD: This is equivalent to -M -MF file. The driver figures out file by removing directory components and suffix from the input file, then adding a .deps suffix.
  • -MMD: Like -MD, but doesn't 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 figures out the file by removing 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 file you specify.
  • -fdoc: Generates "Ddoc" documentation and writes it to a file. The compiler figures out the file by removing directory components and suffix from the input file, then adding a .html suffix.
  • -fdoc-dir=dir: Same as -fdoc, but writes documentation to directory dir. You can use it with -fdoc-file=file to set the output file and directory path independently.
  • -fdoc-file=file: Same as -fdoc, but writes documentation to file. You can use it 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 work, and the files get read and processed in the order given.
  • -fdump-c++-spec=file: For D source files, generates the matching C++ declarations in 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 code expanded from D mixin statements and writes the processed sources to file. This is super useful for debugging compile errors, and it gives debuggers source to show when requested.

๐Ÿšจ Warnings ๐Ÿšจ

Warnings are diagnostic messages about constructions that aren't inherently wrong, but are risky or suggest there's probably a bug in the program. Unless -Werror is specified, they don't stop the program from compiling.

  • -Wall: Turns on all warning messages. Warnings aren't a defined part of the D language, and all constructs that might generate a warning are valid code.
  • -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 -Walloca-larger-than and is equivalent to -Walloca-larger-than=SIZE_MAX or larger.
  • -Wno-builtin-declaration-mismatch: Warns if a built-in function is declared with an incompatible signature.
  • -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: Doesn't warn about usage of deprecated features and symbols with deprecated attributes.
  • -Werror: ๐Ÿ’€ Turns all warnings into errors.
  • -Wextra: Enables some extra warning flags that are not enabled by -Wall:
-Waddress -Wcast-result -Wmismatched-special-enum -Wunknown-pragmas
  • -Wmismatched-special-enum: Warns when an enum the compiler recognizes as special is declared with a different size than the built-in type it represents.
  • -Wspeculative: Lists all error messages from speculative compiles, such as __traits(compiles, ...). This option doesn't report messages as warnings, so these messages never become errors, even when -Werror is also used.
  • -Wunknown-pragmas: Warns when a pragma() is encountered that gdc doesn't understand. This is different from -fignore-unknown-pragmas, where a pragma that is part of the D language but not implemented by the compiler won't get reported.
  • -Wno-varargs: Doesn't warn about questionable usage of the macros used to handle variable arguments, like va_start.
  • -fno-ignore-unknown-pragmas: Doesn't recognize unsupported pragmas. Any pragma() encountered that is not part of the D language will result in an error. This option is deprecated and will be removed in a future release.
โš ๏ธ Heads up bestie: -fno-ignore-unknown-pragmas is deprecated and will be removed in a future release, so don't build your whole life around it ๐Ÿฅบ.
  • -fmax-errors=n: Limits the maximum number of error messages to n, at which point gdc bails out instead of trying to keep processing the source code. If n is 0 (the default), there is no limit on the number of error messages produced.
  • -fsyntax-only: Checks the code for syntax errors, but doesn't actually compile it. This can be combined with -fdoc or -H to generate files for each module on the command line, but no other output file.
  • -ftransition=id: Reports additional information 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 come into play when the compiler links object files into an executable output file. They're meaningless if the compiler isn't doing a link step.

  • -defaultlib=libname: Specifies the library to use instead of libphobos when linking. Options specifying the linkage of libphobos, such as -static-libphobos or -shared-libphobos, are 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, such as -static-libphobos or -shared-libphobos, are ignored.
  • -nophoboslib: Doesn't use the Phobos or D runtime library when linking. Options specifying the linkage of libphobos, such as -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 use of the shared version. If no shared version was built when the compiler was configured, this option has no effect.
  • -static-libphobos โ€” okay so if your system ships both a shared and a static copy of libgphobos and libgdruntime, this flag forces the static version ๐Ÿ’œ If the static one wasn't built when the compiler was configured, this flag does literally nothing ๐Ÿ’€

โœจ Developer Options โœจ

This part is for the devs and language-tooling people ๐Ÿค“ Lowkey not for everyday bestie-level usage, but iconic if you're in the weeds ๐Ÿ”ฅ

  • -fdump-d-original โ€” dumps the internal front-end AST right after the "semantic3" stage ๐Ÿ™ˆ This is only useful for debugging the GNU D compiler itself, so unless you're fixing gdc, skip it ๐Ÿ’…
  • -v โ€” the main character of debugging flags โœจ It dumps info about the compiler's language processing stages while your source program is being compiled. That includes:
    • every module processed through the "parse", "semantic", "semantic2", and "semantic3" stages
    • all "import" modules and their file paths
    • all "function" bodies being compiled

โœจ SEE ALSO โœจ

Check out gpl(7), gfdl(7), fsf-funding(7), and gcc(1), plus the Info entries for gdc and gcc ๐Ÿงš

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. There are 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).


That's the whole page, bestie! ๐Ÿฆ‹ Pulled from gcc-16, dated 2026-03-22, GDC(1) energy all the way ๐Ÿ’– Stay iconic ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from