GDC(1)

πŸ“¦ version 15.3.0+git11272, in opensuse-leap 16.0

πŸ¦‹ GDC(1) β€” GNU's gdc, the GCC-based compiler for the D language πŸ¦‹

✨ NAME ✨

gdc β€” a GCC-based compiler for the D language. That's the whole main-character energy of this page, bestie. πŸ’…

🌈 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.

πŸ’… DESCRIPTION πŸ’…

The gdc command is the GNU compiler for the D language, and it supports many of the same options as gcc. This manual is specifically here to document the options that are specific to gdc β€” iykyk. ✨

πŸŽ€ OPTIONS πŸŽ€

πŸ“ Input and Output files πŸ“

For any given input file, the file name suffix determines what kind of compilation gets 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, and each one is 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. Slay. 🫢

A D interface file contains only what an import of the module needs, rather than the whole implementation of that module. gdc can create them 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. If a .d source file starts with the string "Ddoc", then it's treated as general purpose documentation, not as a D source file. πŸ“

⚑ Runtime Options ⚑

These options affect the runtime behavior of programs compiled with gdc. Let's get into it. πŸ”₯

  • -fall-instantiations β€” generates 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 β€” turns off code generation for assert contracts.
  • -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's safe to use this option if you're sure 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 recognizes when a function in the core.stdc package is a built-in function.
  • -fcheckaction=value β€” controls what code is generated on an assertion, bounds check, or final switch failure. The following values are supported:
    • context β€” throws an AssertError with extra context information.
    • halt β€” halts the program execution.
    • throw β€” throws an AssertError (the default).
  • -fdebug, -fdebug=value β€” turns on compilation of conditional debug code into the program. The -fdebug option itself sets the debug level to 1, while -fdebug= enables debug code 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>. It 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 β€” includes 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, because it lets you run 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 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 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.
  • -fno-switch-errors β€” 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.
  • -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:

  • -Idir β€” bestie, this is the "look here for imported modules at compile time" flag πŸ’… You can stack as many -I options as you want, and the paths get searched in the same order you gave them.
  • -Jdir β€” same vibe but for string imports: it tells the compiler where to look for files in import(file) expressions at compile time πŸŽ€ This switch is required if you want to use import(file) at all, no cap. Multiple -J options can be used, and the paths are searched in the same order.
  • -Ldir β€” when linking, specify a library search directory, exactly like you'd do with gcc ✨
  • -Bdir β€” this one tells the compiler where to find its own executables, libraries, source files, and data files, as with gcc 🫢
  • -fmodule-file=module=spec β€” okay so this is the module path remix 🎧 It messes with file paths of imported modules: if an imported module matches all (or the leftmost part) of module, then the file path in spec is used as the location to search for D sources. Use it when your source file paths and names don't line up with your package/module hierarchy. Lowkey essential. Consider these examples:
        gdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar

This tells the compiler to search in all import paths for the source file foo.d when importing A.B, and the directory bar/ when importing C, like this D code is annotated:

        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 contains target-specific D sources and interfaces 🌸
  • -iprefix prefix β€” specify prefix as the prefix for the gcc directory containing target-specific D sources and interfaces. Real talk: if the prefix represents a directory, you gotta include the final / 🎯
  • -nostdinc β€” do NOT search the standard system directories for D source and interface files. Only the directories you specified with -I options (and the directory of the current file, if appropriate) get searched. Independent icon behavior πŸ’€

✨ Code Generation ✨

On top of the many gcc options controlling code generation, gdc has several options that are specific to itself 🧚

  • -H β€” generates D interface files for all modules being compiled. The compiler figures out the output file from the name of the input file: strip any directory components and the suffix, then slap .di on it πŸ’…
  • -Hd dir β€” same as -H, but writes interface files to directory dir. You can pair this with -Hf file so the output file and directory path are set independently.
  • -Hf file β€” same as -H but writes interface files to file. Pair it with -Hd dir to independently set the output file and directory path 🫢
  • -M β€” outputs the module dependencies of all source files being compiled, in a format suitable for make. The compiler outputs 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 does not mention imported modules from the D standard library package directories πŸŽ€
  • -MF file β€” when used with -M or -MM, specifies a file to write the dependencies to. And when used with the driver options -MD or -MMD, -MF overrides the default dependency output file. Multitasking icon ✨
  • -MG β€” this option exists for compatibility with gcc, and the compiler just ignores it. It's giving "I'm here for moral support" πŸ’€
  • -MP β€” outputs a phony target for each dependency other than the modules being compiled, which makes each of them depend on nothing.
  • -MT target β€” changes the target of the rule emitted by dependency generation to be exactly the string you specify. Need multiple targets? Pass them as a single argument to -MT, or just use multiple -MT options 🀝
  • -MQ target β€” same as -MT, but it quotes any characters that are special to make. Considerate queen πŸ‘‘
  • -MD β€” equivalent to -M -MF file. The driver determines file by removing 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 information describing the contents of all source files being compiled, in JSON format, to a file. The driver determines file by stripping 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 removing 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. Pair with -fdoc-file=file to independently set the output file and directory path.
  • -fdoc-file=file β€” same as -fdoc, but writes documentation to file. Pair with -fdoc-dir=dir to independently set the output file and directory path πŸ’–
  • -fdoc-inc=file β€” specifies file as a Ddoc macro file to be read. Multiple -fdoc-inc options can be used, and files are read and processed in the same order.
  • -fdump-c++-spec=file β€” for D source files, generate the corresponding C++ declarations in file. C++ crossover episode 😭
  • -fdump-c++-spec-verbose β€” in conjunction with -fdump-c++-spec= above, add 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. Super useful for debugging compilation errors, and it gives debuggers source to show when asked πŸ”₯

πŸ’€ Warnings πŸ’€

Warnings are diagnostic messages reporting constructions that are not inherently erroneous but are risky, or that suggest there's likely a bug in the program. Unless -Werror is specified, they do not prevent compilation of the program 🫢

  • -Wall β€” turns on all warning messages. Warning: warnings are not a defined part of the D language, and all constructs for which this may generate a warning message 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. Meanwhile -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 is declared with an incompatible signature. Ngl that's a red flag behavior and it will be flagged πŸ™ˆ
  • -Wcast-result β€” warns about casts that will produce a null or zero result. Currently this is only done 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 with deprecated attributes. Let the past be the past, bestie πŸ’…
  • -Werror β€” turns all warnings into errors. Main character energy, zero tolerance βœ‹
  • -Wextra β€” enables some extra warning flags that are not enabled by -Wall. The lineup:
    • -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's representing πŸ“
  • -Wspeculative β€” lists all error messages from speculative compiles, like __traits(compiles, ...). Heads up: this option does not report messages as warnings, so these messages therefore never become errors even when -Werror is also used ⚠️
  • -Wunknown-pragmas β€” warns when a pragma() is encountered that is not understood by gdc. And this differs from -fignore-unknown-pragmas: there, 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.
  • -fno-ignore-unknown-pragmas β€” do not recognize unsupported pragmas. Any pragma() encountered that is not part of the D language will result in an error. > Heads up bestie: this option is now deprecated and will be removed in a future release πŸ’€
  • -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's no limit on how many error messages get produced 😭
  • -fsyntax-only β€” checks the code for syntax errors, but does not actually compile it. You can use it alongside -fdoc or -H to generate files for each module present on the command-line, but no other output file gets made πŸ¦‹
  • -ftransition=id β€” reports additional information about D language changes identified by id. The supported values:
    • 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. Real talk: 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 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. Heads up: 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 β€” 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 option 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 β€” bestie, when your system ships libgphobos and libgdruntime both as a shared and a static library, this lil flag forces the static one to be the one you use πŸ’…. Key caveat tho: if no static version was built when the compiler was configured, this option just... does nothing. No effect. Zero. Nada. πŸ™ˆ

✨ Developer Options ✨

Okay so this next cluster is for the devs and the language-tooling girlies β€” primarily of interest to developers or language tooling, as the ancients say 🧚. If you're just out here writing D code, you can vibe-check right past this. But if you're poking at the compiler's insides? Welcome, this is your era πŸ‘‘

  • -fdump-d-original β€” dumps out the internal front-end AST after the "semantic3" stage 🌸. Real talk though: this one is only useful for debugging the GNU D compiler itself. It's not a you-and-your-code tool, it's a looking-inside-the-machine tool πŸ”₯.
  • -v β€” the gossip flag πŸ’–. It dumps info about the compiler's language processing stages as your source program is being compiled. Specifically it gives you:
    • a listing of all modules processed through the "parse", "semantic", "semantic2", and "semantic3" stages πŸ‘€
    • all "import" modules and their file paths πŸ¦‹
    • all "function" bodies that are being compiled πŸ’€

It's giving "tell me everything, I want the whole group chat" and honestly? Iconic.


πŸ‘€ SEE ALSO

Go read these too, they're the supporting cast and they ate:

Copyright (c) 2006-2025 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) 🫢


And that's the whole page, bestie β€” no cap, we made it πŸ’œ. This masterpiece is stamped gcc-15, dated 2026-06-12, and lives its best life as GDC(1). Periodt. 🌈

πŸ“¦ where this page comes from