2

The related procedure code is provided below.I often see such kind of code in open source projects which can run both on Linux and Windows. Somebody told me that it is to avoid compiling warning. Is it really the case?

class Base
{
public:
    virtual void on_publication_matched(Publisher* pub, PublicationMatchedStatus& info)
    {
        (void)pub;
        (void)info;
    }
};

I wonder why not define it like this:

class Base
{
public: 
       virtual void on_publication_matched(Publisher* pub, PublicationMatchedStatus& info){};
};

or

class Base
{
public: 
       virtual void on_publication_matched(Publisher* pub, PublicationMatchedStatus& info) = 0;
};
John
  • 2,963
  • 11
  • 33
  • Maybe relevant https://stackoverflow.com/questions/693652/what-is-the-meaning-of-having-void-in-the-constructor-definition – InUser Jun 08 '20 at 05:08
  • @Inga Thank you.But i can't see there is any relation with this question indeed. – John Jun 08 '20 at 05:10
  • Why would you put a `;` after the `{}` of the function body? And what is this `Class` thing, also a macro? – Ulrich Eckhardt Jun 08 '20 at 05:27
  • @UlrichEckhardt I have reedited it.Is it correct now? Look forward to hearing from you. – John Jun 08 '20 at 05:36
  • Only half of it, though you found the missing `;` after the class body yourself. BTW: How is it relevant to your question by how far the code is indented? Do you know the any difference between the three variants? – Ulrich Eckhardt Jun 08 '20 at 05:39
  • @Ulrich Echardt With the help of StefanKssmr & JaMiT & jvd, i fully comprehend the differences amont the three variants. You could see the answer of StefanKssmr . He make it easy to understand . As for the subject, it just show a simple example. The porpose of such code is to avoid the compiling warning. – John Jun 08 '20 at 05:43
  • That's cool! Still, fix your question! I believe some parts there are really irrelevant to what you've been pondering over. See also [ask]. – Ulrich Eckhardt Jun 08 '20 at 05:44
  • @UlrichEckhardt I would follow your advice. I am not a native speaker of English, posting a suitable title is not a very easy task for me. But i would have a try. – John Jun 08 '20 at 05:56

2 Answers2

3

Let have a look at the first two examples. They define a function that simply does nothing. The difference lies in the void cast

(void)pub;
(void)info;

which is typically used to avoid the unused-variable warnings by the compiler. It does a cast to void. The expression is discarded afterwards, so effectively e.g. (void)pub does nothing but the compiler won't complain about an unused variable. Since c++17 you can use the maybe unused attribute:

virtual void on_publication_matched([[maybe unused]]Publisher* pub, 
                                    [[maybe unused]]PublicationMatchedStatus& info){}

Alternatively, you can also write:

virtual void on_publication_matched(Publisher*,PublicationMatchedStatus&){}

This would also not give a warning. However, I prefer to have descriptive argument names. As remarked by @JaMiT you can use inline comments to get:

virtual void on_publication_matched(Publisher*/*pub*/,
                                    PublicationMatchedStatus& /*info*/){}

Your last example marks the function as purely virtual which is far different from the first to examples. That is you can't create an instance of the pure virtual class. You need to provide an implementation in the derived class to create an instance of it. See also this answer.

StefanKssmr
  • 1,196
  • 9
  • 16
  • Thank you for your clarification. I fully understand what you say. I have no doublt that you are right. But i still think it is a little strange to report unused variable warnings for the functions which is intend to do nothing. In other world, I don't think the compiler should report such warnings. – John Jun 08 '20 at 05:21
  • Unfortunately I am not an expert on how compilers work. So I can't tell you, why the compiler does no check what you have suggested. Maybe someone else can. – StefanKssmr Jun 08 '20 at 05:27
  • 1
    Another alternative in some use is `virtual void on_publication_matched(Publisher* /*pub*/, PublicationMatchedStatus& /*info*/){}`. Not everyone likes this alternative, though. – JaMiT Jun 08 '20 at 05:28
  • @JaMiT You are right, I totally forgot about that. I'll make an edit to include it in my answer. – StefanKssmr Jun 08 '20 at 05:31
  • @StefanKssmr Thank you for the clarification. I fully understand it with your help.One more question, what does `(void)pub` really mean? I never wrote such kind of code. – John Jun 08 '20 at 05:34
  • @John That does a cast to `void`. The expression is discarded afterwards, so effectively `(void)pub` does nothing. – StefanKssmr Jun 08 '20 at 05:38
  • @StefanKssmr Would this expression be compiled in the corresponding program? I mean whether this expresssion needs cpu resources or not. – John Jun 08 '20 at 05:40
  • @John I think compilers are smart enough to optimize it out. – StefanKssmr Jun 08 '20 at 05:42
1

This is to avoid unused variable warnings. The statement (void)pub; is a noop (does nothing), yet it still references the variable. Hence, the compiler does not complain that pub is not used.

Other examples do not avoid unused variable warnings and making the member function abstract might not be even desirable or the initial intention.

jvd
  • 764
  • 4
  • 14
  • I see. I think you are right. But i still think it is a little strange to report _unused variable warnings_ for the functions which is intend to do nothing. – John Jun 08 '20 at 05:18
  • 3
    @John The compiler does not know the *intent* of the function. The warning is there to let you know that the function does nothing. As far as the compiler knows, you might have intended to come back to this function but forgot to do so. The statements that use the parameters tell the compiler that the function is intended to do nothing, hence no more warning. – JaMiT Jun 08 '20 at 05:22
  • @JaMiT Glad to see you again.I had been confused for a long time; you make it clear to me now. I am very grateful to you.One more question, why `(void)pub`? What does `(void)pub` mean? I know you could use other expressions to avoid the warnings, but it's not key point. Could tell me what the expression mean? I have saw many such code, but i have not used it. – John Jun 08 '20 at 05:25