Skip to content

paul-j-lucas/cdecl

Repository files navigation

cdecl

Introduction

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 (see-deh-kull) is a program primarily for composing and deciphering C (or C++) declarations or casts, aka ‘‘gibberish.’’ It can be used interactively on a terminal or accept input from either the command line or standard input. For example:

cdecl> explain int *const (*p)[4]
declare p as pointer to array 4 of constant pointer to integer

cdecl> declare p as pointer to const pointer to const char
const char *const *p;

Additionally, cdecl is also for developing and debugging C preprocessor macros by performing expansion step-by-step. For example:

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

This codebase fixes virtually all the deficiencies in earlier versions as well as adds many new features, most notably:

  • Using GNU Autotools for building.
  • Command-line long-options.
  • Distinguishes among K&R C, C89, C95, C99, C11, C17, C23, C++98, C++03, C++11, C++14, C++17, C++20, and C++23.
  • Support for C89 const, restrict, and volatile qualifiers.
  • Support for C99 static, type-qualified, and variable length array function parameters.
  • Support for C99 extensions Embedded C and Unified Parallel C.
  • Support for inline function and variable declarations.
  • Support for typedef declarations.
  • Pre-defined typedef declarations for many POSIX and standard library types (FILE, in_addr_t, int8_t, pid_t, pthread_t, ptrdiff_t, size_t, std::ostream, std::string, etc.), and all Microsoft Windows types.
  • Support for Microsoft Windows calling conventions.
  • Support for variadic function parameters.
  • Support for C and C++ alternative tokens (and, and_eq, etc.).
  • Support for C++ constructors, destructors, mutable data members, namespaces and scoped names, new-style casts, pointers to members, throw, overloaded operators, and friend, virtual and pure virtual member function declarations, and user-defined conversion operators.
  • Support for C++11 auto (as a deduced type), constexpr, enum class, fixed-type enumerations, final, lambdas, noexcept, override, rvalue references, user-defined literals, using (as a typedef synonym), the function trailing return-type syntax, and ref-qualified member function declarations.
  • Support for C++20 consteval, constinit, and export declarations.
  • Support for C++23 explicit object parameters.
  • Support for C++ [[carries_dependency]], [[deprecated]], [[maybe_unused]], [[nodiscard]], and [[noreturn]] attribute specifiers.
  • Better warning and error messages complete with location information, color, and "Did you mean ...?" suggestions.

Installation

The git repository contains only the necessary source code. Things like configure are derived sources and should not be included in repositories. If you have autoconf, automake, and m4 installed, you can generate configure yourself by doing:

./bootstrap

You will also need flex and bison (lex and yacc won't do); or you can download a released version that contains configure and the generated lexer and parser. In either case, then follow the generic installation instructions given in INSTALL.

If you would like to generate code coverage reports, you will also need gcov (part of gcc) and lcov; then instead do:

./configure --enable-coverage
make check-coverage

If you would like to generate the developer documentation, you will also need Doxygen; then do:

make doc                            # or: make docs

Licensing

cdecl was originally written by Graham Ross sometime in the mid-1980s. Tony Hansen, a major contributor, posted the source code with his changes (parts 1 & 2) to comp.sources.unix in 1988.

The source files have never had either a copyright notice or license. Attempts have been made independently by several people to contact Graham over the years to clear-up the licensing issue, all without success.

In 1996, David Conrad made contributions for version 2.5 and wrote:

I have no reason to believe there are any limitations on [cdecl's] use, and strongly believe it to be in the Public Domain.

(See the included README-2.5.txt for David's full comments.)

Something in the Public Domain allows anyone to do whatever they want with it. Assuming that David is correct and that cdecl is in the Public Domain, I therefore am licensing cdecl 3.0 (and later) under the GNU General Public License, v3.

However, even if you do not assume that the original version of cdecl is in the public domain, copyright law allows for "fair use" for which there are four factors to consider:

  1. Purpose and character of the use, including whether the use is of a commercial nature or is for nonprofit educational purposes.

    My version of cdecl is not of a commercial nature and is for nonprofit educational purposes.

  2. Nature of the copyrighted work.

    The purpose of cdecl is to provide a tool for C and C++ developers. Unlike, say, a literary work, the output of cdecl based on user input is what is of primary importance, not the source code itself.

  3. Amount and substantiality of the portion used in relation to the copyrighted work as a whole.

    The table below shows a comparison between Hansen's version of cdecl and a recent version of my cdecl. Hansen's files on the left map to my files on the right, both with total numbers of lines of code and the perecentage of my lines that Hansen's version is:

    Hansen's Lines Lucas's Lines %
    cdgram.y 855 parser.y 9199 9.3%
    cdlex.l 75 lexer.l 1719 4.4%
    cdecl.c 1014 *.[ch] 40507 2.5%
    Total 1944 51425 3.8%

    Hansen's version of cdecl accounts for only 3.8% of a recent total of the number of lines of code of my version of cdecl. Additionally, of that small percentage, there are very likely no lines that haven't been modified substantially.

  4. Effect of the use upon the potential market for or value of the copyrighted work.

    Given that there are millions of C and C++ developers, the potential market is huge; however, all versions of cdecl were released as open-source and distributed widely for free. Additionally, cdecl prior to 3.0 has limited value since it has not kept pace with the evolution of C and C++. Hence, it has no market value.

Note, however, that I am not a lawyer; but my layman's anaysis seems reasonable.

Notice of Non-Affiliation

The site https://github.com/paul-j-lucas/cdecl is the only offical site for cdecl versions 3.0 and later. I am not affiliated with any other site you might find some version of cdecl on.

Paul J. Lucas
San Francisco Bay Area, California, USA
5 January 2023