Can reserved function names be overloaded?
Asked Answered
M

2

9

This question is a follow-up question of this one.

Consider the following program:

#include <cmath>

// meaningless, only for language-lawyer purpose
void abs(void*) {}

int main(){
    abs(nullptr);
}

Does this program result in undefined behavior?


The related part in the standard is [extern.names]/4:

Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.

I'm not sure whether overloading is permitted.

Muns answered 19/6, 2018 at 9:54 Comment(11)
I don't know whether the behaviour is undefined, but it is certainly unexpected.Dropsonde
That's a weird paragraph. It starts with signatures, which is quite clear, and then segues to names.Burnett
@Ron int abs(int); is a function signature from the C Standard library declared with external linkage. The non-bold text says this signature is reserved; but then the bold part goes on to say that the signature is reserved as a name, which makes no senseDespain
Some "functions" are sometimes implemented as marcos - htons for example. While not a "reserved" function that I know of, it highlights how poor some implementations can be.Halfbreed
@UKMonkey: C++ specifically says the C names which can be implemented as functions or macros have to be functions in C++. However, htons is not a Standard C function, which is why it's not covered by that rule.Kenakenaf
Why would you ever want to do something like this?Allbee
@Allbee there are a number of questions about overriding std::to_string() for custom objects I imagine this has similar motivationsHalfbreed
@Halfbreed Nope. This question is not about overloading any methods in std. So your example doesn't apply.Allbee
@Allbee Yup If you seriously can't think of a function that would be of use to overload in global namespace, and you can't understand the word "similar" Then I don't see how you can say doesn't apply. Maybe you mean "I can't think of any similar examples - could you give me one"?Halfbreed
@Halfbreed No, I cannot think about such a thing. A user should add nothing to the global namespace except int main(). All other stuff can happily live in an anonymous namespace.Allbee
@Allbee Well don't ask questions if you don't want to know the answer then.Halfbreed
K
1

There are two parts to this statement, as it talks about names (from the C standard) that are reserved (for C++ implementations). In particular,

Part 1: Each function signature from the C standard library declared with external linkage

This includes the C library function abs

Part 2: is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.

So the name ::abs is reserved for the C++ implementation. You can't use it. Overloading is irrelevant.

Kenakenaf answered 19/6, 2018 at 10:28 Comment(9)
If it means the name ::abs is reserved, then all the un-bold text in the original quote would be redundant. Not saying you're wrong but there still seems to be some mystery about this paragraph.Despain
@M.M: Names with "C" linkage don't live precisely in the global namespace, IIRC.Kenakenaf
abs is not a function signature, so cannot be referred to in Part 1.Allbee
@Despain The un-bold text brings the constraint into non-global namespace. This is a related discussion.Muns
For some reason everyone skips p3: "Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace."Bonn
@Bonn That seems very relevant. But I don't understand it really. Does this imply that using namespace foo; if foo contains, say, abs(funny) is illegal in the global namespace?Allbee
@Bonn Why is that relevant? I don't declare abs with C linkage.Muns
@Walter: Why would that be the case? using namespace Foo only makes Foo::abs visible, it doesn't move Foo::abs to the global namespace.Kenakenaf
The name is reserved for use by the implementation in (among other things) the global namespace. The use to which the implementation puts it is not relevant.Bonn
H
0

tl;dr - yes, you can

http://www.eel.is/c++draft/reserved.names#extern.names

Pulling in the rest of the context:

20.5.4.3.2: If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.

And then also

20.5.4.3.3.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.

20.5.4.3.3.4 Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage,182 or as a name of namespace scope in the global namespace.

These suggest you can, as it is only the signature that is reserved.

Bonus for namespace ::std

http://www.eel.is/c++draft/library#namespace.std

20.5.4.2.1.1 Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std.

http://en.cppreference.com/w/cpp/language/extending_std has summarised the exceptions

Halfbreed answered 19/6, 2018 at 10:53 Comment(9)
There was no question of adding to namespace std, but to adding to the global namespace.Allbee
@Allbee if the standard states explicitly that std can not be extended, but then doesn't say anything about the global namespace; and explicitly states that it is the function signatures that are reserved - then adding new ones in the global namespace isn't rejected by the standard...Halfbreed
Do we need the part with std in this argumentation?Allbee
@Allbee because the first parts suggest that you can overload any function in std too - which you can't, and I don't want this answer to suggest you can.Halfbreed
This is a red herring. The question clearly related to the global namespace (only).Allbee
But the specification says "or as a name". Note it says "as a function signature" in the first half part.Muns
@Muns "or" - used to link alternatives. That means one OR the other. If they're a function - they're reserved as a function. If they're a name, they're reserved as a name.Halfbreed
But the subject is "each function signature". Well, I agree with you that this paragraph is weird, as StorryTeller pointed out in the comment.Muns
@Muns To be honest, not doing so is by far the safest thing; the c++ standard has been changing so fast in recent years the whole of the global namespace could end up reserved soon, but that wasn't your question ;)Halfbreed

© 2022 - 2024 — McMap. All rights reserved.