codeql-coding-standards icon indicating copy to clipboard operation
codeql-coding-standards copied to clipboard

`DCL51-CPP`: Only reserve function names when used within the global namespace

Open lcartey opened this issue 2 years ago • 5 comments

Affected rules

  • DCL51-CPP

Description

The rule currently enforces that function names defined in standard library headers are not reused in any namespace. However, a careful re-reading of the C++ standard suggests that's overly specific. [reserved.names] specifically states that the only kinds of name that are reserved are macros, "global names" and "names with external linkage". In [extern.names], the standard says:

Each global function signature declared with external linkage in a header is reserved to the implementation to designate that function signature with external linkage.

So only global function signatures are reserved, and only where they have external linkage. I think we need to do the following:

  • Apply only to the global namespace
  • Filter list of reserved function names by those that appear in the global namespace and have external linkage (this may already be the case).
  • Match function signatures (I believe it is valid to reuse the name as long as the signature is different).

We may also need to review the rules for objects and _ prefixes.

Example

namespace MyNamespace {
  void all_of(); // COMPLIANT
}

lcartey avatar Nov 28 '22 14:11 lcartey

Don't miss:

rcseacord avatar Nov 28 '22 17:11 rcseacord

in your description above I think you meant to say "C++ standard suggests that's overly general" and not overly specific.

rcseacord avatar Nov 28 '22 17:11 rcseacord

[extern.names] states:

1 # Each name declared as an object with external linkage in a header is reserved to the implementation to designate that library object with external linkage,164 both in namespace std and in the global namespace. 2 # Each global function signature declared with external linkage in a header is reserved to the implementation to designate that function signature with external linkage.165

so, for example, std::min and ::min are both reserved names

164) The list of such reserved names includes errno, declared or defined in cerrno. 165) The list of such reserved function signatures with external linkage includes setjmp(jmp_­buf), declared or defined in csetjmp, and va_­end(va_­list), declared or defined in cstdarg. 166) The function signatures declared in cuchar, cwchar, and cwctype are always reserved, notwithstanding the restrictions imposed in subclause 4.5.1 of Amendment 1 to the C Standard for these headers.

rcseacord avatar Nov 28 '22 17:11 rcseacord

struct ThisIsNotReserved {
  void errno();
};

that member function is not a global name, nor does it have external linkage (IIRC), but it needs to be reserved.

"Match function signatures (I believe it is valid to reuse the name as long as the signature is different)."

No, it is not. Reserved means reserved.

Names are reserved for the implementation to steal the name to give it meaning or it's for the standard to steal the name to give it meaning, and the name might become a keyword or a macro instead of a regular identifier. Once you attack it from that angle, the rule makes more sense. It's basically saying "don't try to take names that aren't yours and use them in ways that may cause problems in the future"

rcseacord avatar Nov 28 '22 18:11 rcseacord

Then, I think the rule boils down to:

Don't cause a name clash with a std:: function by using the same name, whatever signature that user-defined function bears, whatever scope that user-defined function lives in. Also, whether it's extern or not do not matter.

@lcartey Could you confirm my understanding is correct?

One thing I'm not sure is if this only applies to functions. Should macros be covered then as well?

jeongsoolee09 avatar Feb 08 '23 00:02 jeongsoolee09