Reserved names should not be used for preprocessor macros

# T002

# Reserved names should not be used for preprocessor macros

Description:

The C++ Standard reserves some forms of names for language implementations. One of the most frequent violations is a definition of preprocessor macro that begins with underscore followed by a capital letter or containing two consecutive underscores:

    #define _MY_MACRO something
    #define MY__MACRO something

Even though the majority of known compilers use more obscure names for internal purposes and the above code is not likely to cause any significant problems, all such names are formally reserved and therefore should not be used.

Apart from the use of underscore in macro names, preprocessor macros should not be used to redefine language keywords:

    #define private public
    #define const

Compliance: ISO

Show source code for this rule

Hide source code

    # Reserved names should not be used for preprocessor macros

    set keywords {
        asm
        auto
        bool
        break
        case
        catch
        char
        class
        const
        const_cast
        continue
        default
        delete
        goto
        do
        double
        dynamic_cast
        else
        enum
        explicit
        export
        extern
        false
        float
        for
        friend
        if
        inline
        int
        long
        mutable
        namespace
        new
        operator
        private
        protected
        public
        register
        reinterpret_cast
        return
        short
        signed
        sizeof
        static
        static_cast
        struct
        switch
        template
        this
        throw
        true
        try
        typedef
        typeid
        typename
        union
        unsigned
        using
        virtual
        void
        volatile
        wchar_t
        while

        and
        and_eq
        bitand
        bitor
        compl
        not
        not_eq
        or
        or_eq
        xor
        xor_eq
    }

    foreach f [getSourceFileNames] {
        foreach t [getTokens $f 1 0 -1 -1 {pp_define}] {
            set lineNumber [lindex $t 1]

            set line [getLine $f $lineNumber]
            set rest [string trimleft [string range $line \
                                           [expr [lindex $t 2] + [string length [lindex $t 0]]] end]]
            set macroName [string range $rest 0 [expr [string wordend $rest 0] - 1]]

            if {([regexp {^_} $macroName] && [string is upper -strict [string index $macroName 1]]) ||
                [string first "__" $macroName] != -1} {
                report $f $lineNumber "reserved name used for macro (incorrect use of underscore)"
            }
            if {[lsearch $keywords $macroName] != -1} {
                report $f $lineNumber "reserved name used for macro (keyword or alternative token redefined)"
            }
        }
    }

Rule index