6

There is a rule that states that one shouldn't define or use identifiers in C or C++ that start with an underscore followed by a capital, e.g. _Foo. This is because these identifiers are reserved by the compiler and thus might collide with some compiler code and result in undefined behavior.

Although this rule is well-known and adopted by many coding standards, I have never seen a real life situation in which this rule could have prevented a lot of damage.

Does somebody know a real-life example of a violation of this rule? EDIT: I am talking about code that compiles and links fine but shows unexpected behavior because of this.

Paul Jansen
  • 1,216
  • 1
  • 13
  • 35
  • 3
    If there is a name-collision then it should have been detected at compile-time not as a crash or other UB at run-time. – Some programmer dude Jun 13 '17 at 14:31
  • Additionally, identifier names containing two consecutive underscores "__" anywhere are also reserved. – Jesper Juhl Jun 13 '17 at 14:34
  • 3
    I've seen several questions here that boiled down to a system header file being skipped because the programmer used a reserved name for an include guard macro and ended up with the same name a system header was already using. It's not a problem that is easily searchable, though. – Ben Voigt Jun 13 '17 at 14:36
  • 2
    Here's one: https://stackoverflow.com/q/1744144/103167 – Ben Voigt Jun 13 '17 at 14:38
  • Fairly easy to reproduce, I would think. Just use any identifier that's used in some compiler lib and you'll get linker errors. – Lundin Jun 13 '17 at 14:39
  • 5
    I'm voting to close this question as off-topic because it asks for a list and can never be answered comprehensively. List questions are not a good fit for Stack Overflow. Please see https://meta.stackoverflow.com/a/293890/103167 – Ben Voigt Jun 13 '17 at 14:40
  • 2
    Does it truly matter whether there is an example of it? when something is reserved for future use, do not use it. That is a rule that should be respected in all situations. :) – Tommy Andersen Jun 13 '17 at 14:43
  • 2
    "that one shouldn't define or use identifiers" - The standard say **shall not**. It is not a recommendation. – too honest for this site Jun 13 '17 at 14:50
  • Here's an example of the opposite (a standard library implementation NOT using _X) causing errors and confusion: https://stackoverflow.com/questions/44217701/does-algorithm-define-a-macro-x#comment75446195_44217701 – Richard Critten Jun 13 '17 at 15:12
  • This is not off-topic because I am asking for just one example that meets the following: the code compiles and links fine but it behaves unexpectedly because it interferes with some built-in compiler identifier. – Paul Jansen Jun 13 '17 at 17:17
  • @SomeProgrammerDude the name collisions *might* get hidden because most of the symbols exported by the library are exported as weak symbols. So compiling or even linking won't complain. But the behaviour would be unexpected during runtime. – Ajay Brahmakshatriya Jun 13 '17 at 17:36
  • @PaulJansen if you just want an example consider this - the windows x64 compiler has a library function called __chkstk which checks during stack frame creation (or some other cases) if the stack overflow has occurred. If you define a function with exact same name, the compiler or the linker won't complain since the library implementation of __chkstk is exported as a weak symbol. What it means is that it will be ignored and the call will be linked with your __chkstk. This might cause your function to be called instead of the check and can easily lead into a stack overflow. – Ajay Brahmakshatriya Jun 13 '17 at 17:40

1 Answers1

3

I worked on a system where our application code had a function _bind() (for binding host variables in SQL statements) that was not made static so it was publicly available.

On one revision (at least) of one O/S (I forget which; it was all in the last millennium), the system provided a function _bind() which — surprise, surprise — had a different interface and did a different job (binding sockets to IP addresses, or thereabouts). When the application code was linked with the system library, the system library code ended up calling our _bind() function when trying to establish network connections. Things did not progress well.

We either renamed the function or made it static (or both) and the problem went away. Modern shared libraries minimize the chances of this sort of thing happening. Our code used static libraries, and I think the O/S was using a static C library too (it was a long time ago!). Using shared libraries alters the dynamics.

Apocryphal information with lots of blurry details omitted — this is the sort of thing that tends to be a transient problem as people fix them fairly quickly.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • `_bind` (unlike e.g. `_Bind` or `__bind`) is not reserved for the implementation though, and that was an OS function, not a standard function. All kinds of bad things can happen when including OS headers (WinDef.h anyone?) that are not covered by the language standard. – Arne Vogel Jun 13 '17 at 17:03
  • @ArneVogel identifiers beginning with an underscore (not necessarily followed by a capital) are reserved in the global scope if memory serves. – Quentin Jun 13 '17 at 17:24
  • Application identifiers starting with an underscore and a lower case letter are valid at file scope. "This is most often done by using a prefix, often one or more underscores. C and C++ are notable in this respect: C99 reserves identifiers that start with two underscores or an underscore followed by an uppercase letter, and further reserves identifiers that start with a single underscore (in the ordinary and tag spaces) for use in file scope;[1] with C++03 further reserves identifiers that contain a double underscore anywhere" Source: https://en.wikipedia.org/wiki/Reserved_word#Reserved_ranges – Arne Vogel Jun 14 '17 at 13:23