GDC(1)

๐Ÿ“ฆ version 12.5.0, in ubuntu questing, ubuntu resolute, ubuntu stonking

GDC(1) โ€” the GNU D compiler, but make it a group chat ๐Ÿ’…

okay bestie, welcome to gdc from the GNU fam โ€” this is the manual page for it, and yes it is A Whole Thing, so buckle up ๐Ÿซถ


โœจ NAME โœจ

gdc โ€” a GCC-based compiler for the D language ๐ŸŒธ


โœจ SYNOPSIS โœจ

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

ngl, that's literally just the most useful options up there โ€” the rest are further down, keep scrolling bestie ๐Ÿ’–


โœจ DESCRIPTION โœจ

The gdc command is the GNU compiler for the D language, and it supports a lot of the same options as gcc. No cap.

But heads up: this manual page? It only documents the options that are specific to gdc. So if you're looking for the generic GCC stuff, that's a different page, iykyk. ๐Ÿ‘‘


โœจ OPTIONS โœจ

๐ŸŽ€ Input and Output files

So for any input file you throw at it, the file name suffix is what decides what kind of compilation happens. The vibes are determined entirely by the ending, basically. Here's what's supported:

  • file.d โ€” D source files. The classic. ๐Ÿ’…
  • 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 in the compilation process. Periodt. But if you specify a -o file option, then all the input files get compiled together, producing one single output file, named file. And yes, that's allowed even when you're using -S or -c โ€” the compiler said slay, we ball. ๐Ÿ€

A D interface file contains only what an import of the module needs, not the whole implementation of that module. Very demure, very minimal. You can create them with 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, and then for .d. Order matters bestie, don't forget it.

A Ddoc source file contains code in the D macro processor language. It's primarily designed for producing user documentation from embedded comments, with a slight affinity towards HTML generation. And plot twist: if a .d source file starts with the string "Ddoc", then it's treated as general purpose documentation, not as a D source file. The compiler said "not today, D source." ๐Ÿ’€


๐Ÿฆ‹ Runtime Options

These options affect the runtime behavior of programs compiled with gdc. So like, not the compiling itself โ€” the actual running of the thing. Very main character energy. โœจ

  • -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 (like from __traits(compiles, ...)), or that come from an imported module that isn't being compiled. So this flag is the "no, do literally all of them" button. ๐Ÿ”ฅ
  • -fno-assert โ€” Turns 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. But bestie, listen: 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. If you're not sure? Don't. ๐Ÿ™ˆ
  • *-fbounds-check=value* โ€” An alternative to -fbounds-check that lets you have more control over where bounds checking gets 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. This flag is like "I don't know her." ๐Ÿซถ
  • *-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. Just. Stop. Immediately. ๐Ÿ›‘
    • 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=value enables debug code that's 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.
  • -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.
  • -fno-invariants โ€” Turns off code generation for class invariant contracts. the class said "I'm fine actually" ๐Ÿ’…
  • -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. And this option does nothing when main is already defined in user code. If you already wrote it, she's not gonna double up on you. ๐Ÿ™…
  • -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. Big "I'm going minimal" energy. โœจ
  • *-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, write down one thing. ๐ŸŽ€
  • -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.
    • 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.
    • 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.
  • -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. So like, she's fast but she's feral. ๐Ÿ˜ญ

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=id* โ€” 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://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md> (Sealed references).
    • dtorfields โ€” Turns off generation for destructing fields of partially constructed objects.
    • markdown โ€” Turns off Markdown replacements in Ddoc comments.
  • -fno-rtti โ€” Turns off generation of run-time type information for all user defined types. And heads up: any code that uses features of the language that require access to this information will result in an error. So it's not "quietly missing," it's "loudly refusing." ๐Ÿ’€
  • -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. No throwing, no catching, just. gone. ๐Ÿซ 
  • -funittest โ€” Turns on compilation of unittest code, and turns on the version(unittest) identifier. This implies -fassert. test szn bestie ๐Ÿงš
  • *-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.
  • -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. Very "let me look around" of them. ๐Ÿ”

  • *-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 you gave them. First one wins, so put your faves first bestie ๐Ÿ’–
  • -Jdir โ€” tells the compiler where to go look for files when it hits a string import at compile time ๐Ÿซถ. This switch is required if you wanna use import(file) expressions, no way around it. You can stack multiple -J options too, and the paths get searched in the exact order you wrote them in. Bestie behavior.
  • -Ldir โ€” when linking, this says "hey, look for libraries in here," same energy as gcc. ๐Ÿ’…
  • -Bdir โ€” points at where to find the executables, libraries, source files, and data files of the compiler itself, again just like gcc. ๐ŸŒธ
  • -fmodule-file=module=spec โ€” this one is lowkey iconic: it messes with the file paths of imported modules, so if an imported module matches all of module or just the leftmost part of it, then the file path in spec is what gets used as the location to search for D sources. Use this when your source file paths and names don't line up with your package and module hierarchy. Look at 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, exactly 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 not forget the final /. ๐ŸŽ€
  • -nostdinc โ€” do not search the standard system directories for D source and interface files. Only the directories you specified with -I options get searched (plus the directory of the current file, if that's appropriate). ๐Ÿ‘‘

๐Ÿ’– Code Generation ๐Ÿ’–

Besides the many gcc options controlling code generation, gdc has a bunch of options that are its own special thing. Not like other girls, fr fr.

  • -H โ€” generates D interface files for all modules being compiled. The compiler figures out the output file from the name of the input file: it strips any directory components and the suffix, then slaps .di on there. ๐Ÿฆ‹
  • -Hd dir โ€” same as -H, but it writes the interface files into directory dir. You can pair this with -Hf file to set the output file and the directory path independently. ๐ŸŽ€
  • -Hf file โ€” same as -H but writes the interface files to file. Works with -Hd dir so you can set the output file and directory path independently. โœจ
  • -M โ€” spits out the module dependencies of every source file being compiled in a format that's 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 the imported files. Periodt.
  • -MM โ€” like -M but it does not mention imported modules from the D standard library package directories. ๐Ÿ™ˆ
  • -MF file โ€” when you use it with -M or -MM, it names the file to write the dependencies to. When you use it 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 ignores it. It's giving "invited to the party but not actually doing anything." ๐Ÿ’€
  • -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. Wanna have multiple targets? You can either pass them all as a single argument to -MT, or just use multiple -MT options. Main character choices only. ๐Ÿ‘‘
  • -MQ target โ€” same as -MT, except it quotes any characters that are special to make. ๐ŸŽ€
  • -MD โ€” this option is equivalent to -M -MF file. The driver figures out file by removing any directory components and the suffix from the input file, then adding a .deps suffix. ๐Ÿ“
  • -MMD โ€” like -MD but it 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 figures out file by removing any directory components and the suffix from the input file, then adding a .json suffix. โœจ
  • -Xf file โ€” same as -X, but it writes all that JSON content to the file you specify. ๐Ÿ’œ
  • -fdoc โ€” generates Ddoc documentation and writes it to a file. The compiler figures out file by removing any directory components and the suffix from the input file, then adding a .html suffix. ๐ŸŒธ
  • -fdoc-dir=dir โ€” same as -fdoc, but it writes the documentation into directory dir. Pair it with -fdoc-file=file to set the output file and directory path independently. ๐ŸŽ€
  • -fdoc-file=file โ€” same as -fdoc, but it writes the documentation to file. Pair it with -fdoc-dir=dir to set the output file and directory path independently. โœจ
  • -fdoc-inc=file โ€” names file as a Ddoc macro file to be read. You can use multiple -fdoc-inc options, and the files get read and processed in the same order. ๐Ÿ“š
  • -fdump-c++-spec=file โ€” for D source files, this 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 code expanded from D mixin statements and writes the processed sources to file. Super useful for debugging errors in compilation, and it gives debuggers source to show when they ask for it. ๐Ÿ’…

๐Ÿ˜ญ Warnings ๐Ÿ˜ญ

Warnings are diagnostic messages reporting constructions that aren't inherently erroneous but that are risky, or that suggest there's probably a bug lurking in the program. Unless -Werror is specified, they do not stop the program from compiling. So they're like, the gentle bestie concerned-voice, not the blocking one. ๐Ÿฅบ

  • -Wall โ€” turns on all warning messages. Warning: warnings are not a defined part of the D language, and every construct that might generate a warning message is still valid code. So like, valid but sus. ๐Ÿ’€
  • -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 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. ๐ŸŽ€
  • -Wcast-result โ€” warns about casts that will produce a null or zero result. Right now 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 that have deprecated attributes. ๐Ÿ‘‘
  • -Werror โ€” turns all warnings into errors. Every warning is now a hard stop, no chill. ๐Ÿ’€
  • -Wspeculative โ€” lists all error messages from speculative compiles, like __traits(compiles, ...). Heads up: this option does not report messages as warnings, and so those messages never become errors even when the -Werror option is also used. ๐Ÿ™ˆ
  • -Wtemplates โ€” warns whenever a template instantiation is encountered. Some coding rules disallow templates, and this is how you enforce that rule. ๐Ÿ“
  • -Wunknown-pragmas โ€” warns when a pragma() shows up that gdc doesn't understand. Note that this differs from -fignore-unknown-pragmas, where a pragma that is part of the D language but just isn't 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. ๐Ÿ’…
  • -fignore-unknown-pragmas โ€” turns off errors for unsupported pragmas. โœจ
  • -fmax-errors=n โ€” limits the max 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 the number of error messages produced. ๐ŸŒˆ
  • -fsyntax-only โ€” checks the code for syntax errors but doesn't actually compile it. You can use this 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. These are 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. ๐Ÿงต
    • vmarkdown โ€” list instances of Markdown replacements in Ddoc. ๐Ÿ“

๐Ÿ”ฅ 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, so don't come for them if nothing happens. ๐Ÿ’…

  • -defaultlib=libname โ€” specifies the library to use instead of libphobos when linking. Any options specifying 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, get 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, get 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 โ€” on systems that provide libgphobos and libgdruntime as both 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. ๐ŸŽ€

๐Ÿ‘‘ Developer Options ๐Ÿ‘‘

This section describes command-line options that are primarily of interest to developers or language tooling. Niche but iconic. ๐Ÿซถ

  • -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. ๐Ÿ”ง
  • -v โ€” bestie, this flag dumps ALL the tea โ˜• about the compiler's language processing stages while your source program is being compiled ๐Ÿ“‹โœจ. It lists every module that gets processed through the parse, semantic, semantic2, and semantic3 stages, all the import modules and their file paths, and every function body that's being compiled. It's literally the compiler's diary entries, no cap ๐Ÿ’….

๐ŸŒธ SEE ALSO ๐ŸŒธ


okay so legal tea, don't skip this bestie:

Copyright (c) 2006-2022 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).


this page is from gcc-12.5.0, dated 2025-07-11, and it's GDC(1) โ€” slay ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from