GDC(1)

πŸ“¦
version 10.5.0 Β· 2 versions
, in ubuntu noble

πŸŽ€ GDC(1): the GNU D compiler manual (part 1 of 2) πŸŽ€

✨ NAME ✨

gdc is 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...

okay so the synopsis only flashes the most useful options πŸ‘€ the rest are down below, bestie πŸ’–


✨ DESCRIPTION ✨

The gdc command is the GNU compiler for the D language, and it supports a lot of the same options as gcc πŸ”₯ This page only covers the options that are specific to gdc, so that's where the focus is πŸŽ€


✨ OPTIONS ✨

πŸ“‚ Input and Output files πŸ“‚

okay so the file name suffix decides what kind of compilation happens πŸ“‚ these are the input file name kinds that work:

  • 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 in the process πŸ”„ but if you use -o file, all the input files get compiled together into one single output file named file 🫢 that works even with -S or -c, periodt πŸ’…

a D interface file only holds what an import of the module actually needs, not the whole implementation of that module πŸ¦‹ you can make these from a D source file with the -H option. when the compiler resolves an import declaration, it looks for matching .di files first, and then for .d files πŸ‘€

a Ddoc source file holds code written in the D macro processor language 🧚 it's mainly made for turning embedded comments into user documentation, with a slight lean toward HTML generation 🌸 and if a .d source file starts with the string Ddoc, it gets treated as general purpose documentation instead of D source πŸ“–

🌈 Runtime Options 🌈

these options change how programs compiled with gdc behave at runtime ⚑

  • -fall-instantiations β€” generates code for all template instantiations 🧚 the default emission strategy is different though: it skips code for declarations that were either 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 give your performance a boost for code that uses arrays a lot 🏎️ it's safe to use this only if you're sure your code never throws a RangeError 🫢
πŸ’€ Heads up: if the code in question actually does violate array bounds constraints, this can result in unpredictable behavior.
  • -fbounds-check=value β€” an alternative to -fbounds-check that gives you more control over where bounds checking gets 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 ✨
  • -fdebug, -fdebug=value β€” turns on compilation of conditional debug code into your program πŸ› the -fdebug option by itself sets the debug level to 1, while -fdebug= enables debug code identified by any of these values:
    • level β€” sets the debug level to level, so any debug code <= level gets compiled in.
    • ident β€” turns on compilation of any debug code identified by ident.
  • -fno-druntime β€” implements the spec at https://dlang.org/spec/betterc.html πŸ“– it assumes you're compiling for an environment with no D runtime library πŸ•οΈ this is basically the same as compiling with these options πŸ‘‡
gdc -nophoboslib -fno-exceptions -fno-moduleinfo -fno-rtti
  • -fno-invariants β€” turns off code generation for class invariant contracts 🚫
  • -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 πŸ”— 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 🚫
  • -frelease β€” turns on release mode, which means no runtime checks for contracts and asserts πŸš€ array bounds checking isn't done for @system and @trusted functions, and assertion failures are undefined behavior. this is basically the same as compiling with these options πŸ‘‡
πŸ’€ Heads up: under -frelease, assertion failures are undefined behavior.
gdc -fno-assert -fbounds-check=safe -fno-invariants \
    -fno-postconditions -fno-preconditions -fno-switch-errors
  • -fno-rtti β€” turns off generation of run-time type information for all user defined types πŸ™… any code that uses language features requiring that info will result in an error πŸ’€
  • -fno-switch-errors β€” controls what code gets generated when no case is matched in a final switch statement πŸ”€ the default runtime behavior is to throw a SwitchError. turning off -fswitch-errors means the program's execution is immediately halted instead πŸ›‘
  • -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:
    • level β€” sets the version level to level, so any version code >= level gets compiled in.
    • ident β€” turns on compilation of version code identified by ident.
  • -fno-weak β€” turns off emission of instantiated declarations that can be defined in multiple objects as weak or one-only symbols πŸ•ΈοΈ the default is to emit all public symbols as weak, unless the target lacks support for weak symbols. disabling this option means common symbols are put in COMDAT instead, or become private πŸ”’

these options tell gdc where to look for files, libraries, and other parts of the compiler πŸ—‚οΈ

  • -Idir β€” specify a directory to search when looking for imported modules at compile time πŸ“¦ you can use multiple -I options, and the paths are searched in the same order.
  • -Jdir β€” specify a directory to search when looking for files in string imports at compile time πŸ“ this switch is required if you want to use import(file) expressions. you can use multiple -J options, and the paths are searched in the same order.
  • -Ldir β€” when linking, specify a library search directory, as with gcc πŸ”—
  • -Bdir β€” specifies where to find the executables, libraries, source files, and data files of the compiler itself, as with gcc πŸ› οΈ
  • -fmodule-file=module=spec β€” a little spicy 🌢️ but super useful. it manipulates file paths of imported modules, so that if an imported module matches all or the leftmost part of module, the file path in spec is used as the location to search for D sources. you'd use this when the source file paths and names don't match the 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, as annotated in the D code below:

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 contains target-specific D sources and interfaces 🎯
  • -iprefix prefix β€” specifies prefix as the prefix for the gcc directory that contains target-specific D sources and interfaces 🧭 if the prefix represents a directory, you should include the final /.
  • -nostdinc β€” doesn't search the standard system directories for D source and interface files 🚫 only the directories specified with -I options (and the directory of the current file, if appropriate) get searched πŸŽ€
  • -MD β€” okay so this one is basically -M -MF file in a cute little disguise πŸ§₯ The driver figures out file by chopping off any directory bits and the suffix from the input file, then slapping a .deps suffix on the end. πŸŽ€
  • -MMD β€” Same vibe as -MD, but it doesn't mention imported modules from the D standard library package directories πŸ™ˆ
  • -X β€” Dumps info about the contents of every source file being compiled, in JSON format, into a file. The driver names that file by removing any directory components and suffix from the input file, then adding a .json suffix. Literally so organized πŸ’œ
  • -Xf file β€” Same energy as -X, except all the JSON goes into the specific file you pick ✨
  • -fdoc β€” Generates "Ddoc" documentation and writes it to a file. The compiler names the file by removing directory components and suffix from the input file, then adding a .html suffix πŸ“„
  • -fdoc-dir=dir β€” Same as -fdoc, but the docs go into the directory dir. You can pair it with -fdoc-file=file to set the output file and directory path separately. Main character energy πŸ‘‘
  • -fdoc-file=file β€” Same as -fdoc, but the docs go into file. Use it with -fdoc-dir=dir if you want to set the file and directory independently πŸ¦‹
  • -fdoc-inc=file β€” Tells it to read file as a Ddoc macro file. You can use multiple -fdoc-inc options, and the files get read and processed in the same order you list them 🌈

✨ Warnings ✨

Okay bestie, warnings are diagnostic messages about constructions that aren't straight-up wrong but are risky, or that hint there's probably a bug hiding in the program. Unless you add -Werror, they won't stop your program from compiling 🫢

  • -Wall β€” Turns on all warning messages. Warnings aren't an official part of the D language, and every construct that might trigger one is still 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 whose bound can be larger than n bytes. -Wno-alloca-larger-than turns off the -Walloca-larger-than warning, and it's the same as -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 when casting between an imaginary and non-imaginary data type, or between a D and C++ class 🧚
  • -Wno-deprecated β€” Don't warn about deprecated features and symbols that have "deprecated" attributes πŸ™ˆ
  • -Werror β€” Turns every warning into an error. Serious, no cap πŸ”₯
  • -Wspeculative β€” Lists all error messages from speculative compiles, like __traits(compiles, ...). This option doesn't report the messages as warnings, so they never become errors, even when -Werror is also in use πŸ¦‹
  • -Wtemplates β€” Warns whenever a template instantiation is encountered. Some coding rules ban templates, and this can help you enforce that rule πŸ’œ
  • -Wunknown-pragmas β€” Warns when pragma() shows up and gdc doesn't understand it. This is different from -fignore-unknown-pragmas, because a pragma that's part of the D language but isn't implemented by the compiler won't get reported with this one πŸŽ€
  • -fignore-unknown-pragmas β€” Turns off errors for unsupported pragmas ✨
  • -fmax-errors=n β€” Caps the number of error messages at n. Once it hits that number, gdc bails out instead of trying to keep going through 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. You can combine it with -fdoc or -H to generate files for each module on the command line, but it doesn't produce any other output file 🌈
  • -ftransition=id β€” Reports extra info about D language changes identified by id. The supported values are:
    • all β€” Lists info on all language changes.
    • checkimports β€” Gives deprecation messages about -ftransition=import anomalies.
    • complex β€” Lists all usages of complex or imaginary types.
    • dip1000 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped pointers) πŸ”₯
    • dip25 β€” Implements https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md (Sealed references) πŸ’…
    • field β€” Lists all non-mutable fields that occupy an object instance.
    • import β€” Tells the compiler to go back to an old lookup behavior for resolving unqualified symbol names, where that lookup was done in a single pass and ignored any protection attributes. The default name lookup strategy uses two passes instead: the first ignores imported declarations, and the second only looks at imports. The protection ("private", "package", "protected") of symbols is also enforced, so conflicts between private and public symbols get resolved 🫣
    • nogc β€” Lists all hidden GC allocations πŸ™ˆ
    • tls β€” Lists all variables going into thread local storage 🧚

✨ Options for Linking ✨

These options only matter when the compiler links object files into an executable output file. If the compiler isn't doing a link step, they're meaningless, so don't stress πŸ¦‹

  • -defaultlib=libname β€” Specifies the library to use instead of libphobos when linking. Options that set 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 does nothing unless -g was also given on the command line. Options that set the linkage of libphobos, like -static-libphobos or -shared-libphobos, get ignored too 🌸
  • -nophoboslib β€” Don't use the Phobos or D runtime library when linking. Options that set 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 forces the shared version. If no shared version was built when the compiler was configured, this does nothing 🌈
  • -static-libphobos β€” On systems that provide libgphobos and libgdruntime as both a shared and a static library, this forces the static version. If no static version was built when the compiler was configured, this does nothing 🧚

✨ Developer Options ✨

This section is for the command-line options that mostly matter to developers or language tooling. Main developer hours πŸ€“πŸ’…

  • -fdump-d-original β€” Outputs the internal front-end AST after the "semantic3" stage. This is only useful for debugging the GNU D compiler itself πŸ™ˆ
  • -v β€” Dumps info about the compiler's 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 being compiled πŸ”₯

✨ SEE ALSO ✨

gpl(7), gfdl(7), fsf-funding(7), gcc(1) and the Info entries for gdc and gcc. Go read those when you want the full story, bestie πŸ“šπŸ’–

Copyright (c) 2006-2020 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 a wrap on GDC(1), bestie πŸŽ€ This one is from the gcc-10 source, dated 2023-07-07, and you absolutely slayed reading the whole thing πŸ’…βœ¨

πŸ“¦ where this page comes from