Reputation: 29022
The expression new int;
such as in int * x = new int;
is a new expression. The term "new operator" seems to be used interchangeably with "new expression", for example in this question : Difference between 'new operator' and 'operator new'?
Is it correct to say that the keyword new
as it is used in a new expression is an operator? Why or why not?
If not, is there another justification for calling a new expression "new operator"?
I am having trouble finding an authoritative definition for what constitutes an operator.
I already understand the distinction between operator new which allocates memory for an object and "new expression" which may eventually call an operator new
.
Upvotes: 86
Views: 8613
Reputation: 41484
new
in new int
is not considered to be an operator. It is also not considered to be not an operator.
The C++ standard is really vague, and even inconsistent, about what constitutes an 'operator'. When listing operators (as defined during lexing and preprocessing), it lists them along with "punctuators" (things like (
), but never really gives any rules for punctuators in general. It lists new
as both a keyword and an operator. It lists sizeof
in the set of keywords but NOT in the set of operators, but later refers to it as an operator.
The takeaway here is that the C++ standards committee is not overly concerned with separating the lexical world into "operators" and "non-operators". This is because there isn't really any need to. There's no grammatical rules which apply to all operators or all non-operators. Important sets, like the set of overloadable operators, are given separately; grammatical rules for things like binary arithmetic expressions are given one at a time.
Basically, "operator" is not a category which is formally meaningful to the C++ language, so any categorical answer is going to be based on how it "feels". You can call it an operator if you like, but you can also call it a keyword (or a punctuator!) and the language standard will not disagree with you.
Upvotes: 143
Reputation: 67743
Is it correct to say that the keyword
new
as it is used in a new-expression is an operator? Why or why not?
No. The new
in a new-expression is a keyword identifying a new-expression.
A new-expression calls an operator new
or operator new[]
to get storage. It also initializes that storage, and de-allocates it (with operator delete
or operator delete[]
) if the initialization throws.
There's a clear distinction, in that operator new
is only referred to as a overloadable user-replaceable function, and a new-expression does more than just call this function.
Reference: 7.6.2.8/10 [expr.new]
A new-expression may obtain storage for the object by calling an allocation function (
[basic.stc.dynamic.allocation]
). If the new-expression terminates by throwing an exception, it may release storage by calling a deallocation function. If the allocated type is a non-array type, the allocation function's name isoperator new
and the deallocation function's name isoperator delete
. If the allocated type is an array type, the allocation function's name isoperator new[]
and the deallocation function's name isoperator delete[]
.
Consider by way of counterexample, that we define both
T operator+(T, T);
void* T::operator new(std::size_t);
for some type T, then addition in either form:
T a, b;
T c = a + b;
T d = T::operator +(a, b);
is identical. The infix notation is just syntactic sugar for the operator call.
Allocation however, behaves very differently:
T *p = new T;
// does much more than
void *v = T::operator new(sizeof(T));
so it's not reasonable to call the new-expression syntactic sugar for a call to operator new
. Thus, the new
keyword isn't simply selecting the function to call. It can't be, or it would have to mention the operator delete
function that might also be called.
Upvotes: 16
Reputation: 17454
No.
Well, sort of yes, in the sense that there exist people who consider new
in new int
to be an operator. However, this opinion is (mostly) at odds with the standard.
Firstly, [lex.operators/1]
lists the operators in the language. Don't be fooled into thinking that these are just "preprocessing operators", either; no such distinction exists in the sense of lexical operators. It wouldn't make sense, either, since you cannot (for example) ++
a macro.
new
is, in fact, a keyword (per [lex.key/1]
).
Next, let's look at new-expression itself. This is where things get a little more wooly. There is, for example, the following wording in [expr.new/4]
:
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types
I consider this to be an editorial error, since it is at odds with the definitions provided above, and does not occur anywhere else in that section.
Then we come to operator overloading. In its grammatical production for an operator declaration, the terminal listing things (including new
) is named operator ([over.oper.general/1]
). I don't think we need to worry about this. The names of terminals in the grammar have never been intended to introduce definitions of terms. After all, you have and-expression that _doesn't need to be a bitwise AND operation; it can just be an equality-expression:
and-expression:
equality-expression
and-expression&
equality-expression
It's common to define grammars like this, and it certainly doesn't mean that every equality-expression is somehow to be considered an invocation of the bitwise AND operator.
Finally, some have claimed that the following wording (also in the operator overloading section) is proof that new
is somehow now, in isolation, magically an operator:
The operators
new[]
,delete[]
,()
, and[]
are formed from more than one token
To them I say, not only is new
not even listed, but this is clearly using the term "operator" in the more broad sense of "things that can be overloaded", even though new
in itself is still not an operator. It's also in a non-normative note, which should tell you all you need to know.
And, as you point out yourself, we already consider operator new
to be something else.
Upvotes: 8
Reputation: 11483
While I know you're looking for a semantical answer, as far as opinion I would say it's a "keyword" (as it's clearly reserved), and I assume we both know that it's simply C++'s construct for memory allocation. That said, when I think of C++'s "operator"s, I tend to think of functions with a set input/output that can be overriden for specific types. new is the same for all types (and more confusingly it can be overridden).
Not sure how official cppreference is, but:
The new-expression allocates storage by calling the appropriate allocation function. If type is a non-array type, the name of the function is operator new. If type is an array type, the name of the function is operator new[]
https://en.cppreference.com/w/cpp/language/new
It seems to follow then that new <type>
is an expression to allocate memory, while new
is the operator for that expression.
Using that same logic:
sizeof
is an "operator" for the expression sizeof(<type>)
(though sizeof
is a "compile-time" operator, a bit different than what we're used to)+
is an operator for an expression <type> <operator> <type>
throw
is an operator for the expression throw <throwaable>
Upvotes: 7
Reputation: 73186
This is governed by [expr.new], which clearly differentiates between a new-expression and how a new expression may obtain storage by means of calling an allocation function, which is named operator new
. Particularly, from [expr.new]/8 [emphasis mine]:
A new-expression may obtain storage for the object by calling an allocation function ([basic.stc.dynamic.allocation]). If the new-expression terminates by throwing an exception, it may release storage by calling a deallocation function. If the allocated type is a non-array type, the allocation function's name is
operator new
and the deallocation function's name is operator delete. If the allocated type is an array type, the allocation function's name is operatornew[]
and the deallocation function's name is operatordelete[]
.
Is it correct to say that the keyword
new
as it is used in a new expression is an operator?
Particularly, the example, albeit non-normative, of [expr.new]/4 describe this function as an operator function; "[...] the new
operator":
[...] Instead, the explicitly parenthesized version of the new operator can be used [...]
Upvotes: 9
Reputation: 40852
I would only call it new expression to avoid confusion with void* operator new ( std::size_t count )
which only allocates memory as part of the process the new expression invoices (allocation memory, starting lifetime, calling constructor).
The problem with new
is that it does more than just calling the operator new
. Which is a bit confusing because for x + y
the +
only calls operator +
.
Upvotes: 12