On 8/21/20 10:39 AM,
wyn...@gmail.com wrote:
> James Kuyper於 2020年8月21日星期五 UTC+8下午9時28分12秒寫道:
>> On 8/21/20 7:03 AM,
wyn...@gmail.com wrote:
>>> Juha Nieminen於 2020年8月21日星期五 UTC+8下午6時39分14秒寫道:
>>>>
wyn...@gmail.com wrote:
>>>>> class Arr {
>>>>> typedef uint16_t T;
>>>>>
>>>>> T arr[2];
>>>>>
>>>>> public:
>>>>> inline const T& lo() const { return arr[0]; };
>>>>> inline T& lo() { return arr[0]; };
>>>>> inline const T& hi() const { return arr[1]; };
>>>>> inline T& hi() { return arr[1]; };
>>>>> };
>>>>
>>>> Those are not returning a reference to a temporary, so they don't have
>>>> such an issue.
>>>
>>> Thanks Jorgen. Problem partially solved, compile time at least. I thought any
>>> user copy assignment operator would disable the default one as the constructor
"If the class definition does not explicitly declare a copy assignment
operator, one is declared implicitly." 15.8.2p2.
You declared an assignment operator, but you did not declare a copy
assignment operator.
>>> do! By now, running program compiled with -O2 showed something still not right
>>
>> What does that have to do with your problem? The code above doesn't
>> involve any copy assignment operators. Other code that was in your
>> original message, but was clipped above, makes use of assignment
>> operators. However, it does so only for uint16_t, for which you cannot
>> provide a user-defined overload.
>
> []$ g++ test2.cpp -std=c++11 -Wall -Wextra -pedantic
> test2.cpp: In copy constructor ‘DxInt<unsigned int>::DxInt(const DxInt<unsigned int>&)’:
> test2.cpp:16:35: warning: implicitly-declared ‘DxInt<unsigned int>& DxInt<unsigned int>::operator=(const DxInt<unsigned int>&)’ is deprecated [-Wdeprecated-copy]
> 16 | DxInt(const DxInt& s) { *this=s; };
> | ^
So the code you're talking about is not the code that you quoted from
the message you responded to. Instead, it's code from a different branch
of this discussion. You should have posted this comment on that branch,
not here.
This warning is occurring inside the copy constructor, because you don't
have a user-declared copy assignment operator. -Wextra turns on
-Wdeprecated-copy, which will warn you if you provide a copy constructor
and rely upon an implicitly declared copy assignment operator, or if you
provide a user-declared copy assignment operator and rely upon an
implicitly-declared copy constructor. Note that this is only a warning.
You don't have to turn it on (I personally recommend against using
-Wextra), and you don't have to pay attention to it if you don't want to.
The warning is correct - the standard does deprecate such code:
"If the class definition does not explicitly declare a copy constructor,
a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment
operator, the implicitly declared copy constructor is defined as
deleted; otherwise, it is defined as defaulted (11.4). The latter case
is deprecated if the class has a user-declared copy assignment operator
..." (15.8.1p6)
"If the class definition does not explicitly declare a copy assignment
operator, one is declared implicitly.
If the class definition declares a move constructor or move assignment
operator, the implicitly declared copy assignment operator is defined as
deleted; otherwise, it is defined as defaulted (11.4). The latter case
is deprecated if the class has a user-declared copy constructor ..."
(15.8.2p2).
The idea behind those deprecations is that it is generally not
reasonable to use the implicitly-defined version of one of those
functions, while explicitly defining the other. Either the
implicitly-defined version of both functions should be acceptable, or
explicit definitions for both are needed.
Your copy constructor is implemented by calling the copy-assignment
operator which you have not explicitly declared, so one is implicitly
declared and implicitly defined, which is what triggers the warning.
That's unnecessary - an implicitly declared copy constructor would do
exactly the right thing with your class.
Note: reinterpret_cast<> is dangerous, and should be avoided if
possible. It's quite easy to avoid it in this case by using a union, and
the code gets significantly simpler if you use that approach.