Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it okay and/or normal to use #include to put large chunks of repetitive code into a separate file?

I have been dissecting some code and I saw something I haven't seen before, and I was wondering if it is a good/bad practice and if it is normal.

Basically there is a header file with a class definition for a class with a bunch (around 90) of pure virtual functions. There are a lot of these virtual functions, so they are all put into a separate file and then included in the class definition like so:

Foo.h

class Foo
{
public:
    virtual ~Foo() {};
    #define FOO_VIRTUAL_IMPL = 0
    #include "Foo_prototypes.h"
};

Foo_prototypes.h

#if ! defined(FOO_VIRTUAL_IMPL)
# define FOO_VIRTUAL_IMPL
#endif

virtual void doSomething() FOO_VIRTUAL_IMPL;

virtual void doSomethingElse() FOO_VIRTUAL_IMPL;

Also

Is using the define macro like that also common (i.e. allowing the same include file to be used for pure virtual and normal virtual functions)? Is this sort of stuff used often, or just for little hacks to save a little bit of time/effort?

I suppose these things made the code seem less readable to me, but it may just be because I am not used to these tricks and once I get used to them I will be better equipped to read this sort of code.

The code in question is Interactive Brokers' C++ API, if anyone cares to see it in context. Relevant files are: EWrapper.h and TestCppClient.h and EWrapper_prototypes.h.

like image 474
Stephen Luke Czaus Avatar asked Sep 18 '18 11:09

Stephen Luke Czaus


People also ask

Is it still okay to use and or?

Please do not use "and/or" in either formal or informal writing. In common English, the "or" is a "non-exclusive or" which means "either A or B, or A and B". When I say "I can have a banana OR I can have coffee" then I am also OK with having both. Having a banana does not prevent me from having coffee.

Is okay formal or informal?

We use okay (also spelt OK) in informal language. We use it in different ways, as a discourse marker, adjective or adverb.


2 Answers

Wellll, this isn't exactly what I'd call well-styled code. Yes, technically you can include headers in that kind of place, but it's not exactly standard, so I wouldn't recommend it. Just in general, "stay away from the dusty corners of a language". However, if you really want to do that kind of thing, you can. However, not following standard practices can have two effects.

  1. Non-standard code is generally harder to read, so less people will be able or willing to contribute.

  2. Non-standard code can have more bugs that aren't as noticed, just because it's not standard.

An example of the bugs I mentioned beforehand is the way FOO_VIRTUAL_IMPL works. #define's aren't limited to scope, so this would be visible to all your code. It would be really really easy to #define it in one header, and not define it at all in another header. This would cause all the virtual functions in the second header to be purely virtual, probably not what you intended.

EDIT: Also, as Caleth said, if your class requires that much repetitive code, it would be good to redesign your class entirely.

like image 174
OrdoFlammae Avatar answered Sep 20 '22 08:09

OrdoFlammae


There are several issues here.

If you have a class with the same pure virtual functions over and over again, it's an interface by defintion. There is absolutely no reason not to wrap things up in a well-defined, named interface. Modern IDE's will support you when implementing those interfaces (so there is no need for macro-magic).

Generally, using macros is bad. We wouldn't accept macro-programming in any code-review. Check out the C++ ISO guideline for more info:

Macros are a major source of bugs. Macros don't obey the usual scope and type rules. Macros ensure that the human reader sees something different from what the compiler sees. Macros complicate tool building.

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-macros

like image 21
dan Avatar answered Sep 19 '22 08:09

dan