-1

I have a warning from GCC that a base class should be initialized in the copy constructor. The problem is, I believe the original intention is its a constructor, but not a copy constructor. Here's what the simplified version looks like (I added the initializer Base() in response to the warning):

class Base { ... };

class Derived : public Base
{
  public:
    Derived(Derived& d, int x = 0)
      : Base(), m_b(d) { ... };
  protected:
    Base& m_b;
};

class Derived provides the Base interface, and it has a Base member. The design is such that data can flow from a source to a sink, with arbitrary intermediate objects in between that can transform or process data (arbitrary but constrained by the interface).

The distinction between constructor and copy constructor is important. In the case of the constructor, Base is being default initialized; and in the case of a copy constructor, Base is being initialized with rhs.

Is it sufficient to use the default constructed base Base to give the compiler a hint that its a constructor, but not a copy constructor?

If not, how do I tell the compiler that the constructor is not a copy constructor? I'm happy to use a GCC extension, like an __attribute__, to direct the compiler in the right direction.

(The other option, change the signature, cannot happen at the moment because it breaks versioning requirements on most major platforms, like Apple).


Here are the files in question:

Here is the compiler warning (the namespace has been removed for brevity):

g++ -DDEBUG -g2 -O2 -Wall -Wextra -fPIC -march=native -pipe -c asn.cpp
asn.cpp: In copy constructor ‘DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder&, byte)’:
asn.cpp:497:1: warning: base class ‘class ByteQueue’ should be explicitly initialized in the copy constructor [-Wextra]
 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)

asn.cpp:497 is pointing to line 487 (the second constructor) in the unmodified online sources.

The system is Fedora 22, x86_64, fully patched, with GCC 5.1.1:

$ uname -a
Linux localhost.localdomain 4.1.6-201.fc22.x86_64 #1 SMP Fri Sep 4 17:49:24 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_module
bash: lsb_module: command not found...
$ g++ --version
g++ (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
...
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • I don't get that warning with or without `Base()` with GCC 5.2. – chris Sep 13 '15 at 16:26
  • 5
    The constructor you show is not a copy constructor. The warning is about something else. Show the complete program that reproduces the problem, together with the exact and complete error message. – Igor Tandetnik Sep 13 '15 at 16:29
  • 2
    I don't get any warnings with your code. What compiler/flags are you using? – Galik Sep 13 '15 at 16:30
  • Maybe your real use case has a default argument for `x`? If so, it *is* a copy ctor. – Angew is no longer proud of SO Sep 13 '15 at 16:33
  • 3
    All I can say that [this program](http://rextester.com/ENAL85856) doesn't produce any warnings. Therefore, the problem must needs lie in the code you haven't shown. – Igor Tandetnik Sep 13 '15 at 16:38
  • Igor, Galik - the code in question and the compiler output has been added to the question. – jww Sep 13 '15 at 16:55
  • 3
    Seriously, post an MCVE already. With 22.6K rep points you should know better. – juanchopanza Sep 13 '15 at 16:55
  • 1
  • 1
    The relevant line is the [declaration in the header file](http://www.cryptopp.com/docs/ref/asn_8h_source.html#l00163), where the default argument is declared. So it is definitely a copy constructor. – rici Sep 13 '15 at 17:06
  • @Lightness Races in Orbit - maybe it never meant what you thought... – jww Sep 13 '15 at 17:07
  • 1
    @jww: It used to be a pretty good indicator. Of course there was always the odd exception (like you!) – Lightness Races in Orbit Sep 13 '15 at 17:09
  • 1
    we all have off days – Ed Heal Sep 13 '15 at 17:10
  • @Lightness Races in Orbit - yep, that includes me. I got my points answering OpenSSL and Crypto++ questions. Its easy to accumulate them with subject matter expertise. – jww Sep 13 '15 at 17:14
  • @Rici - what is the best way to proceed to tell the compiler its a constructor, and not a copy constructor? – jww Sep 13 '15 at 17:15
  • 2
    @EdHeal: Doesn't change the fact there is _still_ no MCVE. OP is just repeating the same nonsensical question and not listening to anyone. Very disappointing. – Lightness Races in Orbit Sep 13 '15 at 17:19
  • 1
    @jww: It is a copy constructor because it accepts a single argument. The only way for it not to be a copy constructor would be to insist that the second argument be provided. – rici Sep 13 '15 at 17:20
  • 1
    @jww: To be honest, I don't understand your design at all. You have a Base object as part of Derived, which apparently you don't use, and you also have a reference to a Base object which you do use. I'm sure you have your reasons but it feels odd to me. – rici Sep 13 '15 at 17:21
  • @Rici - Its not my design. Its essentially a third party library and the filtered design (where data flows from sources to sinks) is part of the library. (And I've never fully understood this particular area very well myself. I don't quite understand why the `DERGeneralEncoder` is both a ***`is a`*** and a ***`has a`***). – jww Sep 13 '15 at 17:53
  • @Lightness Races in Orbit - forgive my ignorance... just how non nonsensical is it? It seems to me the original code has the intention the function in question is a constructor, and not a copy constructor. Is it as nonsensical as hacking the compiler? Or is at as nonsensical as joining a working group and changing ISO/IEC standards? Like you said, *Very disappointing..."* (And my apologies for mostly ignoring you. I know your *m.o.*, and I prefer to minimize engagements with you). – jww Sep 13 '15 at 18:11
  • That's one heck of an apology. Perhaps if you didn't minimize engagements with those who know what they are talking about, this situation wouldn't have taken place. – Lightness Races in Orbit Sep 13 '15 at 22:54
  • @jww: please clarify *why* you want to stop the constructor being a copy constructor - if it's just to silence the warning, adding the explicit base default constructor does that without changing behaviour. Separately, if you want to prevent accidental copy construction, the easiest way may be to remove the `= 0` for `x`: you may then need to provide it explicitly in some calling code, but I'd hazard such a change won't be visible as far as the framework API / ABI is concerned, as default parameters are normally injected in calling code - worth checking if it's really a problem. – Tony Delroy Sep 14 '15 at 01:31

2 Answers2

3

In your real code, the constructor in question is a copy constructor, because it's callable with one argument of the type of the class (because the second parameter has a default argument). Note that the compiler will not even generate the default copy constructor, since you are providing your own copy constructor.

So, to make the warning go away, simply initialise the base class explicitly; the compiler is in the right to treat it as a copy constructor, and you should as well.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thanks Agnew. The best I can tell (I did not write the code), the intention of the original code is a constructor, and not a copy constructor. What is the best way to proceed to move things back to the original intentions? If you can help with that, then I would be happy to accept the answer. – jww Sep 13 '15 at 17:49
  • @jww If the code works fine as-is, simply add the base initialisation to get rid of the warning. If you want to actively *prevent* that ctor from being a copy ctor, you'll have to remove the default argument. By definition, a ctor of class `X` which is callable with a single argument of type `X` is a copy ctor. – Angew is no longer proud of SO Sep 13 '15 at 18:06
  • Yeah, that puts the code in a bad spot because of versioning requirements. I don't believe the signature can change without performing a major version bump. Hence the reason I was trying to work around it by informing the compiler of what's supposed to be going on. Maybe using a GCC `__attribute__` or similar... – jww Sep 13 '15 at 18:15
  • @jww There is no way to make *this* ctor stop being a copy ctor. If the code relies on it, it is fundamentally flawed. If you cannot fix that, simply provide the base initialiser and forget about it. – Angew is no longer proud of SO Sep 13 '15 at 18:21
0

what is the best way to proceed to tell the compiler its a constructor, and not a copy constructor?

Since this is a copy constructor, you have two options:

  1. Hack the compiler's source code such that it misinterprets yours;
  2. Become a member of the Core Working Group, and somehow manage to make it so that this is not a copy constructor in some future version of the C++ standard.
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    I like this answer. :) – Cheers and hth. - Alf Sep 13 '15 at 17:23
  • 1
    Only on Stack Overflow can a 100% factual and direct answer be attacked by the downvote brigade! – Lightness Races in Orbit Sep 13 '15 at 17:26
  • I *adore* the irony in criticizing me at 22K, when this is what you offer at 171K and subject matter expertise. Its exactly like you said, *"Of course there was always the odd exception (like you!)"*. Oh, the irony.... – jww Sep 13 '15 at 17:26
  • 1
    @jww This addresses the "question" you are asking. You should be happy somebody is doing all the work for you. Of course, the better solution would have been for you to fix your question, as suggested by others. – juanchopanza Sep 13 '15 at 17:27
  • 1
    @jww: This is the answer to your question. I'm sorry that you don't like it, but attacking my character is not going to change that. Frankly you're lucky I even bothered, as your question is absurd. – Lightness Races in Orbit Sep 13 '15 at 17:31
  • @Lightness Races in Orbit - I seem to recall you have had problems with a number of folks on Stack Overflow. I don't feel lucky when you show up; rather, I kind of dread it. I'd really prefer you add me to a kill file so I never have to deal with you again (*q.v.*), but I know [Stack Overflow does not have them](http://meta.stackoverflow.com/q/290851/608639). So I'll have to continue the banter with you... – jww Sep 13 '15 at 17:42
  • @juanchopanza - please forgive my ignorance... what do you suggest I fix? The code is existing library code; and the best I can tell the original intention of the code is that particular function is a constructor (and not a copy constructor). I think the question accurately reflects the original intentions of the code. But I'd be happy to change it if you tell me how it should be done. – jww Sep 13 '15 at 18:00
  • @jww Posting an MCVE? Anyway, somebody else fixed it for you. It is still not an MCVE, but it is enough for people to figure out what is most likely going on. But it really is up to you to do that. – juanchopanza Sep 13 '15 at 21:20
  • @juanchopanza - OK, thanks. Its existing library code. Its nothing that I am creating, so I don't really have a MCVE. – jww Sep 13 '15 at 22:02
  • @jww You are supposed to _create one_. Nobody expects that you have an MCVE spoon-fed to you by the real-world library you're using. This is called _debugging_. – Lightness Races in Orbit Sep 13 '15 at 22:56
  • @LightnessRacesinOrbit - I'm not sure why someone with 172K needs an MCVE spoon fed to them. GCC diagnostics showed what the problem was, and that the intent of the original code was honored because the code itself was defective. We have additional constraints that won't allow us to change it in the most direct or obvious way, so we needed to look for other potential solutions. The two questions have remained the same across all revisions of the question. All you had to do was answer the question posed in the question. – jww Sep 16 '15 at 07:49
  • 1
    @jww: Er?! It's not about "spoon-feeding a 172k user", it's about writing a concise and reproducible question, per the rules of this site and also common sense. If you have not yet constructed an MCVE, then you haven't finished your own debugging, and it's insulting to expect us to do that for you. Come on man. – Lightness Races in Orbit Sep 16 '15 at 09:03