cdecl - Man Page
compose and decipher C & C++ declarations and casts
Examples (TL;DR)
Synopsis
cdecl [options] [command ...]
c++decl [options] [command ...]
explain [options] gibberish
Description
“I'm still uncertain about the language declaration syntax, where in declarations, syntax is used that mimics the use of the variables being declared. It is one of the things that draws strong criticism, but it has a certain logic to it.”
— Dennis M. Ritchie, Creator of C
“I consider the C declarator syntax an experiment that failed.”
— Bjarne Stroustrup, Creator of C++
cdecl is a program for composing and deciphering C (or C++) declarations or casts, aka “gibberish.” Additionally, cdecl is also for developing and debugging C preprocessor macros by performing expansion step-by-step.
cdecl can be used interactively on a terminal or accept input from either the command-line or standard input.
Invocation
Executable Name
cdecl may be invoked under a number of different names (by either renaming the executable or creating either a symbolic or hard link to it). If it is invoked as:
- cdecl
Runs with the latest supported version of C as the default language.
- c++decl | cppdecl | cxxdecl
Runs with the latest supported version of C++ as the default language.
- explain
Runs with the latest supported version of C as the default language interpreting the rest of the command-line (if given) as gibberish, performs the conversion to pseudo-English, and exits.
For example (where $
is the shell prompt):
$ explain 'int *const (*p)[4]' declare p as pointer to array 4 of constant pointer to integer
For declarations given on the command line, care must be taken either to escape or quote shell metacharacters. The default language can be specified via the cdeclrc file (see Configuration Files).
First Argument
cdecl will also behave as above if the first non-option argument on the command-line or the first whitespace separated word thereof is a cdecl command (see Commands):
$ cdecl declare p as pointer to array 4 of int int (*p)[4]; $ c++decl 'reinterpret cast n into pointer to unsigned' reinterpret_cast<unsigned*>(n)
Standard Input
If no arguments are given, standard input will be read until end-of-file is encountered or one of the exit, q, or quit commands is read.
You can use cdecl as you create a C (or C++) program from within an editor. For example, in vi(1), type the declaration in pseudo-English, then filter the line through cdecl:
!!cdecl<CR>
where <CR>
is the return key.
Interactive Input
If standard input is coming from a terminal, a prompt of either cdecl>
or c++decl>
will be written to the terminal before each line of input. The prompt can be turned off by either the --no-prompt or -P option or the set noprompt command.
cdecl uses the GNU readline(3) library (if available and compiled in) to provide keyword completion, command-line history, and editing.
Options
An option argument f means file, n means unsigned integer, and s means string.
- --alt-tokens | -a
Turns on alternative token output. The alternative tokens are:
and
(&&
),and_eq
(&=
),bitand
(&
),bitor
(|
),compl
(~
),not
(!
),not_eq
(!=
),or
(||
),or_eq
(|=
),xor
(^
), andxor_eq
(^=
). (Supported only in C95 and later.)- --bison-debug | -B
Turns on bison(1) debugging output (if compiled in). The additional output is of grammar productions as they are being reduced by the parser. (This is a debugging aid for developers of cdecl itself.)
- --color=s | -k s
Sets when to colorize output to s (which is case-insensitive). (See the CDECL_COLORS environment variable about colorization.) The choices for s are:
- always
Always colorize.
- auto | isatty | tty
Colorize only when standard output is connected to a TTY (terminal).
- never
Never colorize.
- not_file | not_isreg
Colorize only when not writing to a regular file (hence writing to a TTY or pipe). (Specifically, fstat(3) is called on standard output: colorize only if
S_IFREG
is false.)This is more useful than isatty since it accommodates the common case of allowing color output to be piped to less(1) and still display in color since less understands SGR (“Select Graphic Rendition”) ASCII terminal escape sequences that produce color.
The default is not_file.
- --commands | -K
Prints a sorted list of all cdecl commands for the current language that may be used as the first argument on a command-line. (See First Argument.) This is intended for consumption by a shell completion function. (See also --options or -O.)
- --config=f | -c f
Specifies the configuration file f to read (see Configuration Files).
- --debug[=s] | -d[s]
Turns on cdecl debugging output:
- While parsing a command, prints additional JSON5 output of an abstract syntax tree (AST) as it is being constructed from user input while the parser is reducing grammar productions.
- While expanding a macro, prints additional JSON5 output of the tokens.
- If an error or warning message is printed, includes the
[
file:
line]
of the code that generated said message. - For syntax errors, includes the numeric
[
id]
of the token that caused the error.
(This is a debugging aid for developers of cdecl itself.)
Valid formats for s are:
- u
Include AST node
unique_id
values in JSON5 output as an additional debugging aid.
Alternatively,
*
may be given to mean “all” or-
may be given to mean “none.”- --digraphs | -2
Turns on digraph token output. The digraph tokens are:
<:
([
) and:>
(]
). (Supported only in C95 and later.)- --east-const | -e
Turns on “east const” output where
const
(andvolatile
) are printed to the right (“east”) of the type, e.g.:const int i; // west int const j; // east
(Not supported in K&R C.)
- --echo-commands | -E
Echoes commands before their corresponding output, but only when not interactive. (This is primarily useful for associating command output with input in test scripts.)
- --explicit-ecsu=s | -S s
For C++ only, sets the type keywords to s (which is case-insensitive) that should be explicitly included in declarations. Valid formats for s are:
- e
enum
- c
class
- s
struct
- u
union
Multiple format may be given, one immediately after the other. Alternatively,
*
may be given to mean “all” or-
may be given to mean “none.” The default is su. For example, using the default:c++decl> declare ps as pointer to struct S struct S *ps; c++decl> declare pt as pointer to class T T *pt;
(See Other Caveats.) For C,
enum
,struct
, andunion
are always included in declarations.- --explicit-int=s | -i s
Sets the integer types to s (which is case-insensitive) that should have
int
explicitly included in declarations. (Normally,int
is omitted forshort
,long
,long long
, orunsigned
declarations whereint
is implied.) Valid formats for s are:- i
All signed integer types.
- u
All unsigned integer types.
- [u]{i|s|l[l]}
Possibly
unsigned
:int
,short
,long
, orlong long
.
Multiple formats may be given, one immediately after the other, e.g.,
usl
meansunsigned short
and (signed)long
. Parsing is greedy so commas may be used to separate formats. For example,ulll
is parsed asunsigned long long
andlong
whereasul,ll
is parsed asunsigned long
andlong long
. Note that sinceu
is both a shorthand and a modifier,iu
means all signed and unsigned integer types whereasui
means justunsigned int
. Alternatively,*
may be given to mean “all” or-
may be given to mean “none.”- --file=f | -f f
Reads commands from file f.
- --flex-debug | -F
Turns on flex(1) debugging output (if compiled in). The additional output is of lexer rules as they are being tokenized by the lexer. (This is a debugging aid for developers of cdecl itself.)
- --help | -h
Prints a help message for command-line options and exits.
- --infer-command | -I
Tries to infer a command when an input line doesn't start with any. If an input line starts with a:
- Macro name, infers expand;
- C (or C++) declaration, infers explain.
- --language=s | -x s
Specifies which version of what language s (which is case-insensitive) to use. (See C and C++ Language Versions for valid languages.) The default is C23 (for cdecl) and C++23 (for c++decl).
- --lineno=n | -L n
Specifies an integer n to add to all line numbers in error and warning messages. (This is a debugging aid for developers of cdecl itself.)
This is useful when cdecl is called from a shell script with a here document for input. Consider a
test-script
(showing line numbers) like:1 #! /usr/bin/env bash 2 cdecl --echo-commands --lineno=$LINENO <<END 3 explain int 4 END
where
$LINENO
(the shell environment variable containing the current the line number of the script, in this case, the one cdecl is called on — in this example: 2) is given. When executed, the script will print:$ test-script cdecl> explain int ^ 3,12: error: declaration expected
where the line number printed is 3 (the starting line number 1 plus 2 from
$LINENO
) which is the absolute line number within the script as opposed to the here document that makes locating offending lines easier. (See Other Caveats.)- --no-buffer-stdout | -b
Sets standard output to unbuffered. (This is a debugging aid for developers of cdecl itself.)
- --no-config | -C
Suppresses reading of any configuration file, even one explicitly specified via either --config or -c.
- --no-english-types | -T
Prints types in C/C++ (e.g.,
int
), not pseudo-English (e.g.,integer
) when explaining gibberish.- --no-prompt | -P
Suppresses printing of the prompt.
- --no-semicolon | -s
Suppresses printing of a final semicolon for C (and C++) declarations.
- --no-typedefs | -t
Suppresses predefining standard types, e.g.,
size_t
,uint8_t
, etc. (See Predefined Types.)- --no-using | -u
Always declares types with
typedef
rather thanusing
in C++11 and later.- --options | -O
Prints a sorted list of all cdecl options that may be used on a command-line in an easily parsable form. This is intended for consumption by a shell completion function. (See also --commands or -K.)
- --output=f | -o f
Sends all non-error output to file f.
- --permissive-types | -p
Permits keywords in language versions other than the current language as types in pseudo-English. By default, a declaration in C like:
declare p as pointer to class
would result in an “unsupported type in C” error even though
class
could be a valid user-defined type in C. This option permits such declarations. (See Permissive Types.)- --trigraphs | -3
Turns on trigraph token output. The trigraph tokens are:
??(
([
),??)
(]
),??'
(^
),??'=
(^=
),??!
(|
),??!=
(|=
),??!??!
(||
), and??-
(~
). (Supported only between C89 and C17 and between C++03 and C++14.)- --trailing-return | -r
Declares functions and operators using the trailing return type syntax in C++11 and later.
- --version | -v
Prints the version number and exits. If given twice, additionally prints the set of configure feature & package options and whether GNU readline(3) (if compiled in) is genuine.
- --west-decl=s | -w s
Sets when to print the
*
for pointer and&
and&&
for references adjacent to the type (“west”) versus adjacent to the name (“east”) to s (which is case-insensitive), e.g.:int *p; // east int* q; // west
Valid formats for s are:
- b
Block return type.
- f
Function (and pointer to function) return type.
- l
User-defined literal return type.
- o
Operator return type.
- r
All return types (same as bflo).
- s
Structured binding.
- t
Non-return type.
Multiple formats may be given, one immediately after the other. Alternatively,
*
may be given to mean “all” or-
may be given to mean “none.” The default is r.However, when more than one name is given in the same declare command for anything other than a structured binding, the
*
,&
, and&&
are always printed adjacent to the name (“east”):cdecl> declare f, g as function returning pointer to char char *f(), *g();
C and C++ Language Versions
The argument to the --language or -x option or the set command is one of the following versions (which are case-insensitive):
- C
Use the latest supported version of the C language.
- CK&R | CKNR | CKR | K&R | K&RC | KNR | KNRC | KR | KRC | C78
Use the pre-ANSI Kernighan & Ritchie version of the C language as given in the first edition of The C Programming Language.
- C89 | C90
Use the C89 (first ANSI C) version of the C language. Adds support for
const
,enum
,long double
,signed
,unsigned char
,unsigned long
,unsigned short
,void
,volatile
, and function prototypes. Adds support for C preprocessor token concatenation via##
and stringification via#
.- C95
Use the C95 version of the C language. Adds support for
wchar_t
.- C99
Use the C99 version of the C language. Adds support for
_Bool
,_Complex
,_Imaginary
,inline
functions,long long
,restrict
, andstatic
, type-qualified, and variable length array function parameters. Adds support for C preprocessor variadic macros.- C11
Use the C11 version of the C language. Adds support for
_Alignas
,_Atomic
,char16_t
,char32_t
,_Noreturn
, and_Thread_local
.- C17 | C18
Use the C17 version of the C language. (Minor revision: no new features. Equivalent to C11.)
- C23
Use the C23 version of the C language. Adds support for
alignas
,auto
(as a deduced type),_BitInt
,bool
,char8_t
,constexpr
,[[deprecated]]
,false
, fixed-type enumerations,[[maybe_unused]]
,[[nodiscard]]
,nullptr
,[[reproducible]]
,thread_local
,true
,typeof
,[[unsequenced]]
, and the__VA_OPT__
preprocessor macro.- C++
Use the latest supported version of the C++ language.
- C++98
Use the C++98 version of the C++ language. Adds support for
class
, constructors, destructors, exception specifications (throw
),mutable
data members,namespace
, new-style casts, overloaded operators, references, pointers to class members, user-defined conversion, andvirtual
functions.- C++03
Use the C++03 version of the C++ language. (Minor revision; no new features. Equivalent to C++98.)
- C++11
Use the C++11 version of the C++ language. Adds support for
alignas
,auto
(as a deduced type),[[carries_dependency]]
,char16_t
,char32_t
,constexpr
,default
anddelete
for member functions,enum class
,final
, fixed-type enumerations, function trailing return-types,inline
namespaces, lambdas,long long
, member function ref-qualfiers,noexcept
,[[noreturn]]
,override
, rvalue references,thread_local
,using
(as atypedef
synonym), and user-defined literals.- C++14
Use the C++14 version of the C++ language. Adds support for
auto
andconstexpr
return types and[[deprecated]]
.- C++17
Use the C++17 version of the C++ language. Adds support for
inline
variables,[[maybe_unused]]
, nested namespace declarations,[[nodiscard]]
, and structured bindings.- C++20
Use the C++20 version of the C++ language. Adds support for
auto
parameters and parameter packs,char8_t
,consteval
,constinit
,default
relational operators,export
, nestedinline
namespaces,[[no_unique_address]]
,operator<=>
, and the__VA_OPT__
preprocessor macro.- C++23
Use the C++23 version of the C++ language. Adds support for
_Atomic
, explicit object parameters,static operator()
, and zero or more parameters foroperator[]
.- C++26
Use the C++26 version of the C++ language. Adds support for
= delete("
reason")
.
Cdecl Language
Commands
In what follows, [] means zero or one, * means zero or more, {} means one of, and | means alternate.
cdecl has the following commands:
- cast [s-name] {as|[in]to} english
Composes a C (or C++) cast from pseudo-English.
- {const|dynamic|reinterpret|static} cast s-name {as|[in]to} english
Composes a C++ new-style cast from pseudo-English.
- declare s-name [, s-name]* as english [width number [bits]]
Composes C (or C++) declarations from pseudo-English with an optional bit-field width (for integral types only).
- declare s-name [, s-name]* as english aligned [as|to] { number [bytes] | english }
Composes C (or C++) declarations from pseudo-English aligned to either a specific number of bytes or the same alignment as english.
- declare operator as english
For C++ only, composes an overloaded operator declaration from pseudo-English.
- declare store* lambda [[captures] [captures]] [([args])] [returning english]
For C++ only, composes a lambda declaration from pseudo-English.
- declare store* user-defined conversion [operator] [of scope-e s-name]* returning english
For C++ only, composes a user-defined conversion operator from pseudo-English.
- define s-name as english
Defines a type (
typedef
) from pseudo-English.- #define name [pp-tokens]
Defines an object-like macro that expands into pp-tokens.
- #define name([pp-params]) [pp-tokens]
Defines a function-like macro that expands into pp-tokens. Note that the
(
must be adjacent to name.- enum [class] s-name [: type]
Defines s-name as an
enum
(or anenum class
in C++) type optionally of a fixed underlying type. In C, this is equivalent to:typedef enum s-name s-name
- expand name [([pp-args])] [pp-tokens]
Expands a previously defined macro step by step using the supplied arguments (if given). The additional pp-tokens (if given) are appended and expanded.
- explain gibberish [, gibberish]*
Deciphers C (or C++) declarations or a new-style cast (C++ only) into pseudo-English.
- explain (gibberish)[s-name]
Deciphers a C (or C++) cast into pseudo-English.
- include "path"
Includes the file denoted by path and performs the contained commands. (This is typically used in a configuration file to include another configuration file.) Shell meta characters in path, e.g.,
~
, are expanded.Note that include is recognized as a cdecl command only when immediately followed by a string literal.
- #include "path"
Same as include, except #include may not end with
;
and must be on a line by itself.- { struct | union | class } s-name
Defines s-name as a
struct
,union
, orclass
(C++ only) type. In C, this is equivalent to:typedef { struct | union } s-name s-name
- scope-c s-name { [{ scope-c | typedef | using } ;]* }
For C++ only, defines s-name as a scope-c (
struct
,union
, orclass
) type; or begins anamespace
. Also executes zero or more class, struct, typedef, union, or using commands within the scope of s-name thus declaring type(s) within that scope.- set [option [= value] | options | lang]*
In the first form, sets a particular option (see Set Options for valid options); in the second form, prints the current value of all options; in the third form, sets the current language to lang. If no argument is given, it's equivalent to the second form.
- show [ s-name | [all] [predefined | user] [glob]] [[as] {english | typedef | using}]
- For s-name, shows the definition for a previously defined type (via define, typedef, or using) having that name.
- For all only, shows all predefined and user-defined types.
- For predefined, shows only predefined types that are valid in the current language or later.
- For user, shows only user-defined types that were defined in the current language or later.
- For either all predefined or all user, shows their respective set of types regardless of the current language.
- For none of s-name, all, predefined, user, or glob, equivalent to show user.
By default, types are shown as they were defined. If typedef is given, types are shown as
typedef
declarations. For C++11 or later only, if using is given, types are shown asusing
declarations.- show { name | [predefined | user] macros }
- For name, shows the definition for a previously defined macro (via #define) having that name.
- For predefined, shows only predefined macros that are valid in the current language or later.
- For user, shows only user-defined macros.
- For neither predefined nor user, equivalent to show user.
- type[def] gibberish [, gibberish]*
Defines types via a C (or C++)
typedef
declaration.- #undef name
Undefines a previously defined macro.
- using name = gibberish
For C++11 or later only, defines a type via a
using
declaration.- { help | ? } [ command[s] | command | english | options ]
Prints help that's sensitive to the current programming language (C or C++). By default or when command or commands is given, prints help on cdecl's commands (this section); if command is given, prints help only for that command; if english is given, prints help on pseudo-English (see English below); if options is given, prints help on cdecl's options (see Set Options below).
- exit | q[uit]
Quits cdecl. Note that q is recognized as a synonym for quit only when it's the only thing on a line other than whitespace.
where:
- args
A comma-separated list of s-name, english, s-name as english; or one of varargs, variadic, or ... (ellipsis).
- captures
Optionally either copy by default (or =) or reference by default (or &) followed by a comma-separated list of name or reference to name.
- name
A valid C (or C++) identifier.
- operator
A valid C++ operator.
- s-name
For C, is the same as name; for C++, is either the same as name or is a scoped name that may always be specified using
::
, e.g.,S::T::x
, or in an english context, may alternatively be specified as s-name [of scope-e s-name]*.- glob
For C, a name; or for C++, a scoped name that may contain
::
. Either may contain*
as a wildcard, e.g.,T*
(any type name starting withT
),*::T*
(any type name starting withT
in any top-level scope). As a special case for C++, glob may start with**::
to match a type name in any scope.- pp-args
A comma-separated list of valid C (or C++) tokens for macro arguments.
- pp-params
A comma-separated list of valid C (or C++) identifiers for macro parameters. In C99 and later, the last parameter may be ....
- pp-tokens
A set of valid C (or C++) tokens.
- scope-c
A C or C++ scope-creating keyword, one of: class, namespace, struct, or union.
- scope-e
An extended scope-creating keyword, either one of scope-c or the cdecl-specific scope when the particular scope-c is either unknown when
T
wasn't previously declared or when it doesn't matter. For example:c++decl> explain int T::x declare x of scope T as integer
cdecl knows
T
is one of scope-c, but it has no way to know which one so it uses the generic scope. Similarly, you may use scope when you don't care which:c++decl> declare x of scope T as int int T::x;
Commands are terminated by either a semicolon or newline. However, commands may be given that span multiple lines when newlines are escaped via \
. When a newline is escaped, the next prompt (if enabled) changes to either cdecl+ or c++decl+ to indicate that the current line will be a continuation of the previons line.
English
In what follows, [] means zero or one, * means zero or more, {} means one of, and | means alternate. The only punctuation characters used in pseudo-English are hyphens in hyphenated words and parentheses around and commas between constructor, function, operator, user-defined literal, or block parameters, and brackets around lambda captures.
English is one of:
store* ar-qual* array [number|name|*] of english
store* ar-qual* variable [length] array of english
block [([args])] [returning english]
cv-qual* concept s-name [parameter pack]
store* constructor [([args])]
[virtual] destructor [()]
store* fn-qual* [[non-]member] function [([args])] [returning english]
store* fn-qual* [[non-]member] operator [([args])] [returning english]
cv-qual* pointer to [member of class s-name] english
[rvalue] reference to english
structured binding
store* user-defined literal [([args])] [returning english]
store* modifier* [C-type]
{ enum [class|struct] [of [type] english] | class | namespace | struct | union } s-name
where:
- ar-qual
One of:
non-empty
,const
,restrict
, orvolatile
.- C-type
One of:
auto
(C23 or C++11 or later),bool
,char
,char8_t
,char16_t
,char32_t
,wchar_t
,int
,float
,double
,parameter pack
, orvoid
; or for C99 only:_Accum
or_Fract
.- cv-qual
One of:
_Atomic
,const
,restrict
, orvolatile
.- fn-qual
One of:
const
,final
,override
,reference
,restrict
,rvalue reference
, orvolatile
.- modifier
One of:
short
,long
,signed
,unsigned
,_Complex
,_Imaginary
, or_Sat
(C99 only).- number
One of a decimal, octal (if starting with
0
), hexadecimal (if starting with either0x
or0X
), or binary (if starting with either0b
or0B
) number.- store
One of:
auto
(C17 or earlier, or C++03 or earlier),block
,carries-dependency
,consteval
,constexpr
,deprecated
,explicit
,export
,extern
,extern "C"
,final
,friend
,inline
,maybe-unused
,mutable
,nodiscard
,non-throwing
,noreturn
,override
,register
,reproducible
,static
,thread-local
,typedef
,unsequenced
,virtual
, orpure virtual
.
If returning english is omitted, it's equivalent to returning int in C95 and earlier or returning void in C99 and later or C++.
Synonyms
Some synonyms are permitted within pseudo-English. The terms on the left are synonyms for what's on the right:
accum _Accum atomic _Atomic automatic auto bit precise integer _BitInt bit-precise integer _BitInt bool _Bool boolean _Bool Boolean _Bool capture capturing captures capturing carries dependency carries_dependency carries-dependency carries_dependency char 8 char8_t char 16 char16_t char 32 char32_t character char command commands complex _Complex constant const constant evaluation consteval constant-evaluation consteval const-eval consteval constant expression constexpr constant-expression constexpr const-expr constexpr constant initialization constinit constant-initialization constinit const-init constinit conv conversion ctor constructor double precision double double-precision double dtor destructor enumeration enum eval evaluation exported export expr expression external extern floating point float floating-point float fract _Fract func function imaginary _Imaginary init initialization integer int len length maybe unused maybe_unused maybe-unused maybe_unused mbr member no discard nodiscard no-discard nodiscard non-discardable nodiscard no except noexcept no-except noexcept no-exception noexcept no unique address no_unique_address no-unique-address no_unique_address non-unique-address no_unique_address non-mbr non-member noreturn _Noreturn no return _Noreturn no-return _Noreturn non-returning _Noreturn non-throwing throw() oper operator overridden override predef predefined ptr pointer ref reference restricted restrict ret returning sat _Sat saturated _Sat structure struct type typedef thread local thread_local thread-local thread_local thread_local _Thread_local user defined user-defined user-def user-defined var variable varargs ... variadic ... vector array wide character wchar_t
Gibberish
Gibberish is any supported C (for cdecl) or C++ (for c++decl) declaration of a variable, constant, array, macro, pointer, reference, rvalue reference, function, constructor, destructor, or overloaded operator; or user-defined type, conversion, or literal; or type cast. (See Examples for examples and Caveats for unsupported declarations.)
Gibberish also includes support for the following:
- Apple's “blocks” syntax and the
__block
storage class. - For C99 only, Embedded C's
_Accum
and_Fract
types, and the_Sat
modifier. - For C99 only, Unified Parallel C's
relaxed
,shared
, andstrict
qualifiers. - GNU C's
__auto_type
,__complex
,__complex__
,__const
,__inline
,__inline__
,__restrict
,__restrict__
,__signed
,__signed__
,__thread
,__typeof__
,__volatile
, and__volatile__
. - GNU C's
__attribute__
syntax, but all attributes are ignored. - Microsoft C's
__declspec
syntax, but all attributes are ignored. - Microsoft C's calling conventions
__cdecl
,__clrcall
,__fastcall
,__stdcall
(alsoWINAPI
),__thiscall
, and__vectorcall
. Pseudo-English also allows the same convention names but without the leading__
. - Microsoft C's
__forceinline
, but it's treated as a synonym forinline
. - Microsoft C's
_asm
,_cdecl
,_declspec
,_fastcall
,_forceinline
,_inline
,_restrict
,_stdcall
, and_vectorcall
that are synonyms for their respective__
counterparts.
Set Options
The set command takes several options (which ignore hyphens). Unambiguous option abbreviations may be used.
- [no]alt-tokens
Turns [off] on alternative token output — default is off. (Supported only in C95 and later.)
- [no]bison-debug
Turns [off] on bison(1) debugging output (if compiled in) — default is off.
- debug[=s]
Turns on cdecl debugging output — default is off. (See the --debug or -d option for details.)
- nodebug
Turns off cdecl debugging output.
- nographs
Turns off either digraph or trigraph output, i.e., reverts to emitting all characters as-is.
- digraphs
Turns on digraph output for
[
and]
— default is off. (Supported only in C95 and later.)- [no]east-const
Turns [off] on “east const” output where
const
(andvolatile
) are printed to the right (“east”) of the type — default is off. (Not supported in K&R C.)- [no]echo-commands
Turns [off] on echoing commands before corresponding output, but only when not interactive — default is off.
- [no]english-types
Turns [off] on printing types in pseudo-English (e.g.,
integer
), not C/C++ (e.g.,int
) when explaining gibberish — default is on.- explicit-ecsu=s
For C++ only, turns on explicit
enum
,class
,struct
, orunion
in declarations — default issu
(forstruct
andunion
). (See the --explicit-ecsu or -S option for details.)- explicit-int=s
Turns on explicit
int
for the integer types s — default is none. (See the --explicit-int or -i option for details.)- noexplicit-ecsu
For C++ only, turns off explicit
enum
,class
,struct
, andunion
in declarations.- noexplicit-int
Turns off explicit
int
for all integer types.- [no]flex-debug
Turns [off] on flex(1) debugging output (if compiled in) — default is off.
- [no]infer-command
Turns [off] on trying to infer a command when an input line doesn't start with any — default is off. (See the --infer-command or -I option for details.)
- language=s
Use s (which is case-insensitive) as the current language. (See C and C++ Language Versions for valid languages.)
- lang
Shorthand for language=lang.
- options
Prints the current value of all options.
- [no]permissive-types
Turns [off] on permitting keywords in language versions other than the current language as types — default is off. (See the --permissive-types or -p option for details.)
- [no]prompt
Turns [off] on the prompt — default is on.
- [no]semicolon
Turns [off] on printing a semicolon at the end of a C (or C++) declaration — default is on.
- trigraphs
Turns on trigraph output for
[
,]
,^
,|
, and~
— default is off. (Supported only between C89 and C17 and between C++03 and C++14.)- [no]trailing-return
Turns [off] on declaring functions and operators using the trailing return type syntax in C++11 and later — default is off.
- [no]using
Turns [off] on declaring types with
using
rather thantypedef
in C++11 and later — default is on.- west-decl=s
Turns on printing the
*
for pointer and&
and&&
for reference types adjacent to the type (“west”) to s — default is r (only all return types). (See the --west-decl or -w option for details.)- nowest-decl
Turns off printing the
*
for pointer and&
and&&
for reference types adjacent to the type (“west”) for all types.
Predefined Types
The following types are predefined (unless either the --no-typedefs or -t option is given) in the specified language and later. However, the types std::partial_ordering
, std::strong_ordering
, and std::weak_ordering
, are always defined in C++20 and later since they are required by operator<=>()
.
K&R C
caddr_t
, daddr_t
, dev_t
, FILE
, ino_t
, jmp_buf
, off_t
, time_t
, tm
C89
blkcnt_t
, blksize_t
, cc_t
, clockid_t
, clock_t
, DIR
, div_t
, double_t
, errno_t
, fd_set
, femode_t
, fenv_t
, fexcept_t
, float_t
, fpos_t
, fsblkcnt_t
, fsfilcnt_t
, gid_t
, iconv_t
, id_t
, imaxdiv_t
, in_addr_t
, in_port_t
, key_t
, lconv
, ldiv_t
, lldiv_t
, locale_t
, long_double_t
, mbstate_t
, mode_t
, nfds_t
, nlink_t
, pid_t
, posix_spawnattr_t
, posix_spawn_file_actions_t
, ptrdiff_t
, regex_t
, regmatch_t
, regoff_t
, rlim_t
, sa_family_t
, sig_atomic_t
, sighandler_t
, sigset_t
, sig_t
, size_t
, socklen_t
, ssize_t
, suseconds_t
, timer_r
, uid_t
, useconds_t
, va_list
,
_Decimal32
, _Decimal32_t
, _Decimal64
, _Decimal64_t
, _Decimal64x
, _Decimal128
, _Decimal128_t
, _Decimal128x
,
_Float16
, _Float16_t
, _Float32
, _Float32_t
, _Float32x
, _Float64
, _Float64_t
, _Float64x
, _Float128
, _Float128_t
, _Float128x
C95
pthread_t
, pthread_barrier_t
, pthread_barrierattr_t
, pthread_cond_t
, pthread_condattr_t
, pthread_key_t
, pthread_mutex_t
, pthread_mutexattr_t
, pthread_once_t
, pthread_rwlock_t
, pthread_rwlockattr_t
, pthread_spinlock_t
, wctrans_t
, wctype_t
, wint_t
,
__float80
, __float128
, __fp16
, __ibm128
, __int128
, __m128
, __m128d
, __m128i
, __m64
,
ATOM
, BOOL
, BOOLEAN
, BYTE
, CCHAR
, CHAR
, COLORREF
, DWORD
, DWORD32
, DWORD64
, DWORDLONG
, DWORD_PTR
, FLOAT
, HALF_PTR
, HANDLE
, HBITMAP
, HBRUSH
, HCOLORSPACE
, HCONV
, HCONVLIST
, HCURSOR
, HDC
, HDDEDATA
, HDESK
, HDROP
, HDWP
, HENHMETAFILE
, HFILE
, HFONT
, HGDIOBJ
, HGLOBAL
, HHOOK
, HICON
, HINSTANCE
, HKEY
, HKL
, HLOCAL
, HMENU
, HMETAFILE
, HMODULE
, HMONITOR
, HPALETTE
, HPEN
, HRESULT
, HRGN
, HRSRC
, HSZ
, HWINSTA
, HWND
, INT
, _int8
, _int16
, _int32
, _int64
, __int8
, __int16
, __int32
, __int64
, INT_PTR
, LANGID
, LARGE_INTEGER
, LCID
, LCTYPE
, LGRPID
, LONG
, LONG32
, LONG64
, LONGLONG
, LONG_PTR
, LPBOOL
, LPBYTE
, LPCHAR
, LPCOLORREF
, LPCSTR
, LPCTSTR
, LPCVOID
, LPCWSTR
, LPDWORD
, LPHANDLE
, LPINT
, LPLONG
, LPSTR
, LPTSTR
, LPVOID
, LPWORD
, LPWSTR
, LRESULT
, PBOOL
, PBOOLEAN
, PBYTE
, PCHAR
, PCSTR
, PCTSTR
, PCWSTR
, PDWORD
, PDWORD32
, PDWORD64
, PDWORDLONG
, PDWORD_PTR
, PFLOAT
, PHALF_PTR
, PHANDLE
, PHKEY
, PINT
, PINT16
, PINT32
, PINT64
, PINT8
, PINT_PTR
, PLCID
, PLONG
, PLONG32
, PLONG64
, PLONGLONG
, PLONG_PTR
, PSHORT
, PSIZE_T
, PSSIZE_T
, PSTR
, PTBYTE
, PTCHAR
, PTSTR
, PUCHAR
, PUHALF_PTR
, PUINT
, PUINT16
, PUINT32
, PUINT64
, PUINT8
, PUINT_PTR
, PULONG
, PULONG32
, PULONG64
, PULONGLONG
, PULONG_PTR
, PUSHORT
, PVOID
, PWCHAR
, PWORD
, PWSTR
, QWORD
, SC_HANDLE
, SC_LOCK
, SERVICE_STATUS_HANDLE
, SHORT
, SIZE_T
, SSIZE_T
, TBYTE
, TCHAR
, UCHAR
, UHALF_PTR
, UINT
, UINT16
, UINT32
, UINT64
, UINT8
, UINT_PTR
, ULARGE_INTEGER
, ULONG
, ULONG32
, ULONG64
, ULONGLONG
, ULONG_PTR
, UNICODE_STRING
, USHORT
, USN
, WCHAR
, __wchar_t
, WORD
, WPARAM
C99
int8_t
, int16_t
, int32_t
, int64_t
, intmax_t
, intptr_t
, uint8_t
, uint16_t
, uint32_t
, uint64_t
, uintmax_t
, uintptr_t
,
int_fast8_t
, int_fast16_t
, int_fast32_t
, int_fast64_t
, int_least8_t
, int_least16_t
, int_least32_t
, int_least64_t
, uint_fast8_t
, uint_fast16_t
, uint_fast32_t
, uint_fast64_t
, uint_least8_t
, uint_least16_t
, uint_least32_t
, uint_least64_t
,
int_hk_t
, int_hr_t
, int_k_t
, int_lk_t
, int_lr_t
, int_r_t
, uint_uhk_t
, uint_uhr_t
, uint_uk_t
, uint_ulk_t
, uint_ulr_t
, uint_ur_t
C11
atomic_bool
, atomic_char16_t
, atomic_char32_t
, atomic_char
, atomic_flag
, atomic_int
, atomic_intmax_t
, atomic_intptr_t
, atomic_llong
, atomic_long
, atomic_ptrdiff_t
, atomic_schar
, atomic_short
, atomic_size_t
, atomic_uchar
, atomic_uint
, atomic_uintmax_t
, atomic_uintptr_t
, atomic_ullong
, atomic_ulong
, atomic_ushort
, atomic_wchar_t
,
atomic_int_fast8_t
, atomic_int_fast16_t
, atomic_int_fast32_t
, atomic_int_fast64_t
, atomic_int_least8_t
, atomic_int_least16_t
, atomic_int_least32_t
, atomic_int_least64_t
, atomic_uint_fast8_t
, atomic_uint_fast16_t
, atomic_uint_fast32_t
, atomic_uint_fast64_t
, atomic_uint_least8_t
, atomic_uint_least16_t
, atomic_uint_least32_t
, atomic_uint_least64_t
,
cnd_t
, constraint_handler_t
, max_align_t
, memory_order
, mtx_t
, once_flag
, rsize_t
, thrd_start_t
, thrd_t
, tss_dtor_t
, tss_t
C++98
std::bad_alloc
, std::bad_cast
, std::bad_exception
, std::bad_type_id
, std::codecvt_base
, std::ctype_base
, std::ctype_base::mask
, std::div_t
, std::domain_error
, std::exception
, std::filebuf
, std::fstream
, std::ifstream
, std::invalid_argument
, std::ios
, std::ios_base::Init
, std::ios_base::event
, std::ios_base::event_callback
, std::ios_base::fmtflags
, std::ios_base::iostate
, std::ios_base::openmode
, std::ios_base::seekdir
, std::ios_base
, std::iostream
, std::istream
, std::istringstream
, std::lconv
, std::ldiv_t
, std::length_error
, std::locale
, std::logic_error
, std::messages_base
, std::money_base
, std::new_handler
, std::nothrow_t
, std::ofstream
, std::ostream
, std::ostringstream
, std::osyncstream
, std::out_of_range
, std::overflow_error
, std::ptrdiff_t
, std::range_error
, std::runtime_error
, std::sig_atomic_t
, std::size_t
, std::streambuf
, std::streamoff
, std::streamsize
, std::string
, std::stringbuf
, std::stringstream
, std::syncbuf
, std::time_base
, std::tm
, std::underflow_error
, std::wfilebuf
, std::wfstream
, std::wifstream
, std::wios
, std::wiostream
, std::wistream
, std::wistringstream
, std::wofstream
, std::wostream
, std::wostringstream
, std::wosyncstream
, std::wstreambuf
, std::wstring
, std::wstringbuf
, std::wstringstream
, std::wsyncbuf
C++11
std::atomic_bool
, std::atomic_char16_t
, std::atomic_char32_t
, std::atomic_char8_t
, std::atomic_char
, std::atomic_flag
, std::atomic_int16_t
, std::atomic_int32_t
, std::atomic_int64_t
, std::atomic_int8_t
, std::atomic_int_fast16_t
, std::atomic_int_fast32_t
, std::atomic_int_fast64_t
, std::atomic_int_fast8_t
, std::atomic_int
, std::atomic_int_least16_t
, std::atomic_int_least32_t
, std::atomic_int_least64_t
, std::atomic_int_least8_t
, std::atomic_intmax_t
, std::atomic_intptr_t
, std::atomic_llong
, std::atomic_long
, std::atomic_ptrdiff_t
, std::atomic_schar
, std::atomic_short
, std::atomic_signed_lock_free
, std::atomic_size_t
, std::atomic_uchar
, std::atomic_uint16_t
, std::atomic_uint32_t
, std::atomic_uint64_t
, std::atomic_uint8_t
, std::atomic_uint_fast16_t
, std::atomic_uint_fast32_t
, std::atomic_uint_fast64_t
, std::atomic_uint_fast8_t
, std::atomic_uint
, std::atomic_uint_least16_t
, std::atomic_uint_least32_t
, std::atomic_uint_least64_t
, std::atomic_uint_least8_t
, std::atomic_uintmax_t
, std::atomic_uintptr_t
, std::atomic_ullong
, std::atomic_ulong
, std::atomic_unsigned_lock_free
, std::atomic_ushort
, std::atomic_wchar_t
,
std::adopt_lock_t
, std::allocator_arg_t
, std::bad_array_new_length
, std::bad_function_call
, std::bad_weak_ptr
, std::bernoulli_distribution
, std::chrono::high_resolution_clock
, std::chrono::steady_clock
, std::condition_variable
, std::condition_variable_any
, std::cv_status
, std::defer_lock_t
, std::error_category
, std::error_code
, std::error_condition
, std::future_errc
, std::future_error
, std::future_status
, std::imaxdiv_t
, std::ios_base::failure
, std::launch
, std::lldiv_t
, std::max_align_t
, std::mutex
, std::nullptr_t
, std::random_device
, std::recursive_mutex
, std::recursive_timed_mutex
, std::regex
, std::regex_constants::error_type
, std::regex_constants::match_flag_type
, std::regex_constants::syntax_option_type
, std::regex_error
, std::shared_mutex
, std::shared_timed_mutex
, std::system_error
, std::thread
, std::timed_mutex
, std::try_to_lock_t
, std::u32string
, std::u32string_view
, std::wregex
C++17
std::align_val_t
, std::any
, std::bad_any_cast
, std::bad_optional_access
, std::bad_variant_access
, std::byte
, std::chars_format
, std::from_chars_result
, std::memory_resource
, std::mono_state
, std::string_view
, std::to_chars_result
, std::u16string
, std::u16string_view
, std::wstring_view
,
std::filesystem::copy_options
, std::filesystem::directory_entry
, std::filesystem::directory_iterator
, std::filesystem::directory_options
, std::filesystem::file_status
, std::filesystem::file_type
, std::filesystem::filesystem_error
, std::filesystem::path
, std::filesystem::perm_options
, std::filesystem::perms
, std::filesystem::recursive_directory_iterator
, std::filesystem::space_info
,
std::pmr::memory_resource std::pmr::monotonic_buffer_resource std::pmr::pool_options std::pmr::synchronized_pool_resource std::pmr::unsynchronized_pool_resource
C++20
std::ambiguous_local_time
, std::compare_three_way
, std::endian
, std::latch
, std::noop_coroutine_promise
, std::strong_equality
, std::strong_ordering
, std::suspend_always
, std::suspend_never
, std::nonstopstate_t
, std::weak_equality
, std::stop_source
, std::stop_token
, std::destroying_delete_t
, std::format_error
, std::jthread
, std::partial_ordering
, std::u8string_view
, std::weak_ordering
,
std::chrono::choose
, std::chrono::day
, std::chrono::file_clock
, std::chrono::gps_clock
, std::chrono::is_clock
, std::chrono::last_spec
, std::chrono::leap_second
, std::chrono::local_info
, std::chrono::local_t
, std::chrono::month
, std::chrono::month_day
, std::chrono::month_day_last
, std::chrono::month_weekday
, std::chrono::month_weekday_last
, std::chrono::nonexistent_local_time
, std::chrono::sys_info
, std::chrono::system_clock
, std::chrono::tai_clock
, std::chrono::time_zone
, std::chrono::time_zone_link
, std::chrono::tzdb
, std::chrono::tzdb_list
, std::chrono::utc_clock
, std::chrono::weekday
, std::chrono::weekday_indexed
, std::chrono::weekday_last
, std::chrono::year
, std::chrono::year_month
, std::chrono::year_month_day
, std::chrono::year_month_day_last
, std::chrono::year_month_weekday
, std::chrono::year_month_weekday_last
C++23
std::bfloat16_t
, std::float128_t
, std::float16_t
, std::float32_t
, std::float64_t
, std::ispanstream
, std::ospanstream
, std::range_format
, std::spanbuf
, std::spanstream
, std::stacktrace
, std::stacktrace_entry
, std::unexpect_t
, std::wispanstream std::wospanstream
, std::wspanbuf
, std::wspanstream
Predefined Macros
The following macros are predefined in the specified language and later.
C89
- __DATE__
The local date in the form
"Mmm dd yyyy"
.- __FILE__
The current file name, if any, or
"stdin"
.- __LINE__
The current line number within
__FILE__
, if any, or an arbitrary line number.- __STDC__
1
. (Not defined in C++.)- __STDC_VERSION__
The current C version, e.g.,
202311L
for C23. (Not defined in C++.)- __TIME__
The local time in the form
"hh:mm:ss"
.
C99
- __VA_ARGS__
The variable arguments of a macro, if any.
C++
- __cplusplus
The current C++ version e.g.,
202302L
for C++23. (Not defined in C.)
C23 | C++20
- __VA_OPT__
Optional preprocessor tokens enclosed between parentheses.
Notes
main()
In C, a function named main
has its parameters and return type checked for those required by main
; in C++, this occurs only if it is not declared const
, consteval
, constexpr
, default
, delete
, final
, inline
, override
, __restrict
, static
, virtual
, nor volatile
. If it is so declared, it's assumed to be a member function.
Permissive Types
Permissive types via the --permissive-types or -p option is not the default because always permitting keywords in language versions other than the current language as types can result in confusing errors. For example, if permissive types were the default, then you would get the following in C:
cdecl> declare D as virtual destructor ^ 14: warning: "virtual" is a keyword in C++ virtual D; ^ 22: syntax error: "destructor": unexpected token ...
Here, virtual
, not being a keyword in C and therefore a valid name for a user-defined type, would be taken to be a type name, so cdecl would interpret that to mean you want to declare D
as a variable of type virtual
— and cdecl would do so by printing virtual D
(but still warning that virtual
is a keyword in C++). But then destructor
would be unexpectedly encountered and generate an error. (It could easily be the case that you simply forgot to set the current language to C++ instead of C.)
With the default non-permissive behavior, you instead get:
cdecl> declare D as virtual destructor ^ 14: error: "virtual": unsupported keyword in C
which is clearer, but at the cost of not permitting valid declarations that use or keywords in language versions other than the current language as types.
Configuration Files
cdeclrc
The cdeclrc file is used to configure cdecl by executing the contained commands on start-up (unless either the --no-config or -C option is given). The full path of this file can be specified by either the --config or -c option; or, if not, the path is taken from the value of the CDECLRC environment variable unless it is either unset or empty in which case the path defaults to ~/.cdeclrc.
The commands useful within a configuration file are:
- class, define, enum, namespace, struct, typedef, union, or using to pre-define user-specific types so that they may be subsequently used when either composing or deciphering declarations.
- #define to pre-define macros so that they may be subsequently expanded.
- include to include other configuration files.
- set to set the language or other options initially.
Configuration files may include blank lines, C-style /* */
comments, and C++-style //
comments, all of which are ignored.
Examples
C Declarations
To declare an array of pointers to functions that are like malloc(3):
cdecl> declare fptab as array of pointer to function \ cdecl+ returning pointer to void void *(*fptab[])();
When you see this declaration in someone else's code, you can make sense out of it by doing:
cdecl> explain void *(*fptab[])()
The function prototype for a function such as _exit(2) would be declared with:
cdecl> declare _exit as function (retval as int) returning void void _exit(int retval);
As a more complex example, signal(2) would be fully defined as:
cdecl> declare signal as function \ cdecl+ (sig as int, \ cdecl+ f as pointer to function (int) returning void) \ cdecl+ returning pointer to function (int) returning void void (*signal(int sig, void (*f)(int)))(int);
This is made more comprehensible with one of define, typedef, or using:
cdecl> define pfi_v as pointer to function (int) returning void cdecl> declare signal as function \ cdecl+ (sig as int, f as pfi_v) returning pfi_v pfi_v signal(int sig, pfi_v f);
cdecl can help figure out where to put const
and volatile
qualifiers:
cdecl> declare pci as pointer to const int const int *pci; cdecl> declare cpi as const pointer to int int *const cpi;
C++ Declarations
c++decl can help with declaring references:
c++decl> declare rpc as reference to pointer to char char *&rpc;
c++decl can help with pointers to member of classes:
c++decl> declare p as pointer to member of class C int int C::*p;
and:
c++decl> declare p as pointer to member of class C \ c++decl+ function (i as int, j as int) \ c++decl+ returning pointer to class D D *(C::*p)(int i, int j)
To define types within scopes:
c++decl> define A::B::T1 as int c++decl> define T2 of scope A as int c++decl> define T3 of scope B of scope A as int c++decl> define T4 of scope A::B as int c++decl> define T5 of class C::D as int c++decl> class C { typedef int T; } c++decl> class C1 { class C2 { typedef int T; }; } c++decl> struct S { typedef int T; } c++decl> namespace N { typedef int T; } c++decl> namespace N::M { typedef int T; } c++decl> union U { typedef int T; }
Preprocessor Macros
cdecl can help with understanding how macros expand:
cdecl> #define NAME2_HELPER(A,B) A ## B cdecl> #define NAME2(A,B) NAME2_HELPER(A,B) cdecl> expand NAME2(var_, __LINE__) NAME2(var_, __LINE__) => NAME2_HELPER(A,B) | A => var_ | B => __LINE__ | | __LINE__ => 42 | B => 42 NAME2(var_, 42) => NAME2_HELPER(var_,42) | NAME2_HELPER(var_, 42) => A ## B | NAME2_HELPER(var_, 42) => var_ ## 42 | NAME2_HELPER(var_, 42) => var_42 NAME2(var_, 42) => var_42
Exit Status
- 0
Success.
- 64
Command-line usage error.
- 65
Syntax or semantic error.
- 66
Open file error.
- 69
System resource unavailable.
- 70
Internal software error. (Please report the bug.)
- 71
System error.
- 73
Create file error.
- 74
I/O error.
Environment
- CDECL_COLORS
This variable specifies the colors and other attributes used to highlight various parts of the output in a manner similar to the GCC_COLORS variable used by gcc.
As with gcc, the value is composed of a colon-separated sequence of capabilities. Each capability is of the form name[=SGR] where name is a capability name and SGR, if present, is a “Select Graphic Rendition” value that is a semicolon-separated list of integers in the range 0-255. An example SGR value is
31;1
that specifies a bright red foreground on the terminal's default background.Capability names containing upper-case letters are unique to cdecl; those in all lower-case are upwards compatibile with gcc.
- caret=SGR
SGR for the caret pointing to the error on the line above (as with gcc). The default is
32;1
(bright green foreground over current terminal background).- error=SGR
SGR for the word “error.” The default is
31;1
(bright red foreground over current terminal background).- HELP-keyword=SGR
SGR for keywords in help output. The default is
1
(bold terminal foreground over current terminal background).- HELP-nonterm=SGR
SGR for nonterminals in help output. The default is
36
(cyan foreground over current terminal background).- HELP-punct=SGR
SGR for punctuation in help output. The default is
30;1
(dark dray forgreound over current terminal background).- HELP-title=SGR
SGR for titles in help output. The default is
34;1
(bright blue foreground over current terminal background).- locus=SGR
SGR for location information in error and warning messages. The default is
1
(bold current foreground over current terminal background).- MACRO-no-expand=SGR
SGR for a macro that can not expand. The default is
35
(magenta foreground over current terminal background).- MACRO-punct=SGR
SGR for macro expansion punctuation. The default is
32;1
(bright green foreground over current terminal background).- MACRO-subst=SGR
SGR for macro substituted tokens. The default is
36
(cyan foreground over current terminal background).- PROMPT=SGR
SGR for the prompt. The default is
32
(green foreground over current terminal background).- warning=SGR
SGR for the word “warning.” The default is
33;1
(bright yellow foreground over current terminal background).
The term “color” is used loosely. In addition to colors, other character attributes such as bold, underlined, reverse video, etc., may be possible depending on the capabilities of the terminal.
- CDECL_DEBUG
If set to an “affirmative” value (one of 1, t, true, y, or yes, case-insensitive), then cdecl will print its process ID and a “waiting for debugger to attach” message to standard error and wait indefinitely for a debugger to attach. (This is a debugging aid for developers of cdecl itself.) It is enabled only when cdecl was compiled with NDEBUG not defined.
- CDECL_TEST
If set to an “affirmative” value (one of 1, t, true, y, or yes, case-insensitive), then cdecl will (not) do the following to facilitate testing:
- CDECLRC
The full path to the user-specific configuration file (see Configuration Files). Used only if not empty and none of the --config, -c, --no-config, or -C options are given.
- COLUMNS
The number of columns of the terminal on which cdecl is being run. Used to get the terminal's width for limiting error and warning messages' length. Takes precedence over the number of columns specified by the TERM variable.
- HOME
The user's home directory: used to locate the default configuration file. If unset, the home directory is obtained from the password database entry for the effective user. If that fails, no default configuration file is read.
- TERM
The type of the terminal on which cdecl is being run.
Files
- ~/.cdeclrc
The default cdecl configuration file (see Configuration Files).
- ~/.editrc
Individual editline(3) initialization file. On systems where the readline(3) API is provided but is just a wrapper around libedit (e.g., macOS), the ~/.editrc file, if present, is read instead of ~/.inputrc. If present, add the following (undocumented) command:
bind ^I rl_complete
to make tab-completion work in cdecl.
- ~/.inputrc
Individual readline(3) initialization file.
Bugs
Readline Wrapper Around Editline
On systems where the readline(3) API is provided but is just a wrapper around the Editline Library, (e.g., macOS), there are a few issues:
- The wrapper has a bug that prevents color prompts from working correctly. Therefore, the PROMPT color cabapility is ignored on systems that do not provide genuine GNU readline(3).
- Hitting tab when there are no completion matches ordinarily rings the terminal's bell. However, older versions of the wrapper don't provide the
rl_ding()
function needed to ring the bell so cdecl provides a substitute. However, the substitute doesn't respect the user's preferred bell style (none, audible, or visual) and always does an audible bell. - In some cases, hitting tab causes the wrapper to suggest only a single completion rather than simply inserting it.
To avoid these issues, compile cdecl against the genuine GNU Readline Library.
See Also
https://github.com/paul-j-lucas/cdecl/issues
Caveats
Unsupported Declarations
The following types of declarations are not currently supported:
Only
enum
,class
,struct
, andunion
names and scoped type declarations are supported; complete declarations are not:struct S s; // supported struct S { typedef int Int; }; // supported (C++ only) struct S { int i; char c; } s; // not supported
- For array sizes, only integer literals, names, and
*
are supported; arbitrary expressions are not. - In C23 and later,
auto
as a storage-class specifier is no longer supported. For C23
typeof
andtypeof_unqual
declarations, only types are supported; arbitrary expressions are not:typeof(int*) x // supported typeof(x) y // not supported
Only C++ lambda signature declarations are supported; complete lambda declarations are not:
[n](int x) // supported [n](int x) { return n * x; } // not supported
- C++
decltype
, abbreviated function template, default argument, and template declarations are not supported. - For C++ function exception specifications, only
noexcept
,noexcept(true)
,noexcept(false)
, andthrow()
, are supported; arbitrary expressions fornoexcept
or types forthrow
are not. C++ namespace alias declarations are not supported:
namespace ALN = A_Long_Name; // not supported
- Multiple
_Alignas
oralignas
specifiers in the same declaration are not supported. - For the argument to either the
_Alignas
oralignas
specifier, only integer literals or types are supported; arbitrary expressions are not. - Only simple C++ attribute specifiers like
[[this]]
are supported; attribute specifiers with namespaces are not. Additionally, optional arguments fordeprecated
andnodiscard
are ignored. - C++20 contracts (
[[assert]]
,[[ensures]]
, and[[expects]]
) are not supported. - The C++20
explicit
specifier with an expression is not supported.
Other Caveats
Macros are expanded only via the expand command and can't be used elsewhere:
cdecl> #define exp explain cdecl> exp int *p // error: can't alias commands cdecl> #define FILE_PTR FILE* cdecl> explain FILE_PTR f // error: can't use as type
When converting from pseudo-English to a C++ declaration, any
enum
,class
,struct
, orunion
type keyword omitted from a declaration (via omission from either the --explicit-ecsu or -S option, or the set explicit-ecsu command) makes the declaration not “round-trippable”:c++decl> declare pt as pointer to class T T *pt; c++decl> explain T *pt ^ 18: error: "T": unknown name
This is because, when going from a C++ declaration to pseudo-English, cdecl doesn't know that an arbitrary name, in this example,
T
, is aclass
name.To include the type keywords explicitly and thus make the declarations “round-trippable,” include them via either the --explicit-ecsu or -S option, or the set explicit-ecsu command.
Alternatively, declare the type via one of class, define, enum, struct, typedef, union, or using:
c++decl> class T c++decl> explain T *pt declare pt as pointer to T
While class, enum, explain, namespace, struct, typedef, union, and using can accept names that are cdecl keywords, cast, declare, and define can not; hence, not all explanations are “round-trippable”:
cdecl> explain int explain declare explain as integer cdecl> declare explain as integer ^ 9: syntax error: "explain": name expected
When converting from one of the C++ overloaded operators
&
,*
,+
,++
,-
, or--
, to pseudo-English when declared as:T operator OP(U);
i.e., taking one parameter, it's ambiguous (to cdecl) between being a member or non-member operator since cdecl doesn't have the context in which the operator is declared. If it were declared in-class, e.g.:
class T { public: // ... T operator OP(U); };
then clearly it's a member operator; if it were declared at file scope, then clearly it's a non-member operator; but cdecl doesn't have this context. In such cases, cdecl omits either member or non-member from its output.
When converting from pseudo-English to a C23 or C++11 declaration for
auto
(or__auto_type
in GNU C), or aconst
,constinit
, reference, or an rvalue reference variable that is not a function parameter, the output doesn't include an initializer:c++decl> declare x as auto auto x; c++decl> declare x, y as structured binding auto [x, y]; c++decl> declare r as reference to int int &r;
These are illegal C++ declarations since such declarations must be initialized.
- Only casting a name is supported; casting an expression is not.
- When converting from or to a C++ new-style cast, only some semantic validation is performed to determine whether the type of cast is legal.
- When a predefined type, e.g.,
size_t
,uint16_t
, etc., is shown (via the show command), the underlying type is merely typical and does not necessarily match the underlying type on any particular platform or even the platform on which cdecl is running. - An integer literal given as the argument for an alignment specifier is only checked to ensure it's either zero or a power of two; it is not checked to see whether it meets the minimum alignment for the type.
In GNU C, the type
__int128
is a distinct type; in Microsoft C, the types__int8
,__int16
,__int32
,__int64
, and__wchar_t
are keyword synonyms. These types can take modifiers:unsigned __int128 x128; // legal in GNU C unsigned __int32 x32; // legal in Microsoft C
In cdecl, these types are
typedef
s and can't take modifiers since that's illegal in C.When using the --lineno or -L option with a here document containing escaped newlines (lines ending in
\
), the\
s also need to be escaped to get the line numbers correct because the shell ordinarily strips escaped newlines; for example:#define IDENT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" \\ "abcdefghijklmnopqrstuvwxyz" \\ "0123456789"
Authors
cdecl has been around since the mid-1980s and there have been many versions of cdecl, some with different subsets of authors. This list is a best-effort at a union of all authors. In reverse chronological order:
Paul J. Lucas <paul@lucasmail.org>
Peter Ammon <cdecl@ridiculousfish.com>
David R. Conrad <conrad@detroit.freenet.org>
Alexander Dupuy <dupuy@cs.columbia.edu>
Merlyn LeRoy <merlyn@rose3.rosemount.com>
Tony Hansen <tony@attmail.com>
David Wolverton <david_wolverton@att.com>
Graham Ross
See Also
bison(1), clang(1), flex(1), gcc(1), less(1), vi(1), yacc(1), isatty(3), readline(3), sysexits(3), editrc(5)
Referenced By
The man page c++decl(1) is an alias of cdecl(1).