2

According to Should we avoid language features that C++ has but Java doesn't?, I know it is horrible to write C++ as if Java, mostly because it drops the beneficial features of C++ languages.

But responding to the point 2 in this question:

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

I found it seems the following questions supports the statement above:

Is it effective to review code in language I don't know?

Should Junior Programmers be involved as code reviewers in the projects of Senior Programmers?

I think they seems support this point:

1.It allows more people (Java programmers) to review my C++ code

2.It allows Java programmers to learn C++ easier during reviewing my c++ code

I mean I'm not in extreme cases that dropping all C++ features, but I would prefer not using C++ features if the substitutes is not complex, for example, I would not write all C++ classes in .h like a single .java file:

class A{
private:
  int b;
  void methodC(){
    //some other code
  }
}

because separating .h and .cpp is easy for C++ newbies. But I would avoid C++ features if the C++ feature can easily be replaced by a pseudo code both for C++ and Java, for example: multiple inheritance, which can be replace by composition + multiple interface.

So My question is, is "letting more people(e.g.:Java programmers) to review my code" a reason to "write C++ like Java" at some degree?

  • 7
    Why is it important to have more people reviewing your code? Will the review be more helpful if you have 20 reviewers rather than 2? As the top ranked answers to your linked question explain, it can be very useful to have team members new to a language participate in a code review as a teaching tool. – Charles E. Grant Jun 7 '18 at 2:56
  • 3
    In Java Foo foo = new Foo(); is how you make an instance of Foo. In C++, it is a type error – Caleth Jun 7 '18 at 8:10
  • 14
    Why write C++ code in the first place if available programmers only know Java? – mouviciel Jun 7 '18 at 9:55
  • 2
    And again, downvotes from people who obviously didn't understand that downvotes are for bad questions, not for bad ideas. – Doc Brown Jun 7 '18 at 21:12
  • 1
    Difference between a programmer and developer is ceasing the opportunity to learn and grow. How do you becoe a better programmer and get better results if you stick to doing the same things the same way despite using a different language. If its supposed to be a C++ program, write a C++ program and the reviewers will become better programmers. Writing "A C++ syntax Java Program" does no one any favors. – mattnz Jun 8 '18 at 9:00
22

The whole statement "write C++ as Java" is total nonsense. You cannot write C++ as Java. If you tried, your program would leak, or crash, or both. C++ does not have garbage collection. C++ does not have proper exceptions. C++ has very different approach on parametric polymorphism.

And after all, it implies that all developers know Java.

Also, you seem to be focusing too much at review. Will the other developer be able to find and fix the bug in code? Basically, the reviews are just there to ensure that the reviewer, and supposedly, others in team, will further be able to operate the code without its author.

If you rephrase your question as "may some C++ features be avoided so that developers (at hands) can understand and edit it easier", then answer is definite "yes, of course". Most project have in their code style guides notes "we don't use ...". Actually, there are many experienced C++ developers which think that some feature does not work correctly, and should be avoided.

  • 5
    How are exceptions in C++ not proper? – Deduplicator Jun 7 '18 at 12:10
  • 2
    The most annoying thing for me is they do not collect the stack. So the Java/C#/Python pattern "catch all at bottom event loop/request handler, write to log, keep running" is not feasible because after catch the exception it is very often not really descriptive data, which may let you guess what and where happened. Instead, you have to let the program crash and then OS will collect memory dump and then you find the problematic place. And if you cannot afford crashing, your only choice is to stop throwing exceptions, or catch them as early as possible. Which defeats the whole point of them. – max630 Jun 7 '18 at 12:29
  • 10
    @max630: That kind of assumes that the way to handle exceptions is to write a call stack to a log and move on. If you're doing basically anything else besides that, exceptions work just fine. – Nicol Bolas Jun 7 '18 at 13:35
  • 2
    @Deduplicator: the point is that one probably needs to make it through the fourty pages of those chapters of that offline book to get a complete understanding of what hidden issues C++ has when trying to implement exception-safe code in templates. – Doc Brown Jun 7 '18 at 21:08
  • 5
    @max630: You specifically said "catch all at bottom event loop/request handler". There's no mention of recovering from the error, or figuring out how to complete the user's request based on it, or any number of alternatives that have to happen closer to the site of the exception being thrown. Most exception handling is not about logging where an exception was thrown; it's about figuring out how to move on based on what kind of exception it was. If you can't open a file, you don't log that a file couldn't be opened; you ask for a new file. There's no need to log that. – Nicol Bolas Jun 8 '18 at 2:40
11

The idea that Java programmers can review (i.e. find mistakes in) or maintain (i.e. modify) C++ code if it only uses the features that kinda look like Java is badly misguided.

The underlying execution model of C++ is different enough from Java that any such attempt will lead to bugs, pain, and in some cases expensive lawsuits from customers.

The main difficulty in switching from Java to C++ is not learning a few additional features of the language, it's understanding the execution model and idioms. Why is new in Java ubiquitous, but frowned upon in modern C++? How do you prevent memory leaks? How do you prevent use-after-free or invalidated iterators? What happens if you use an invalid index in an array, and how do you guard against that? These are the questions a C++ programmer must be able to answer, and a Java programmer just can't.

  • You actually do have to worry somewhat about those things in Java. Iterators CAN indeed go bad in Java, and multithreading is a common cause of that sort of insanity. Multithreading can lead to all sorts of Fun™ errors happening. – Haakon Løtveit Jun 8 '18 at 9:58
5

It isn't feasible at all to write C++ as if it was Java: memory leaks or ownership semantics, no explicit use of pointers/references etc. Besides, whoever is reviewing your code, should be able to understand what the code is doing.

Does that mean a learning C++ developer cannot review your code? Well, they sure can, because code reviews are a great learning tool. If you use a feature of C++ that the reviewer does not know about, they can ask. These additional questions can also help you catch mistakes.

Features such as multiple inheritance should be used sparingly, but not with the goal of making it more understandable for those that are not aware of the features/syntax of the language.

0

A very effective way to write c++ so that it is both readable and powerful is to hide expert complexity behind semantically simple interfaces.

A great example of this is std::shared_ptr<T>. Getting the implementation of a std::shared_ptr right without sacrificing performance or correctness in multi-threaded programs is not trivial.

But if your reviewer sees this code:

auto px = std::make_shared<X>();

It's pretty obvious to him that px is a pointer with shared ownership, regardless of the complexities of lock-free reference counting or type-erasure of the deleter (to name but 2).

Further, if ownership of X is always shared, then it makes sense to create a higher-level wrapper which can be treated as a value:

struct SharedX
{
    int some_x_method() { return px_->some_x_method(); }
private:
    std::shared_ptr<X> px_ = std::make_shared<X>();
}; 

Now we can write code like this:

auto x = SharedX();
do_something_with(x);

and we can't accidentally create an invalid SharedX.

If we want to be able to provide null handles, we can do that safely by demanding that the programmer specifically requests one:

struct SharedX
{
    SharedX()
    : px_(std::make_shared<X>())
    {}

    static SharedX invalidHandle() { return SharedX(nullptr); }

    int some_x_method() { 
        assert(px_);
        return px_->some_x_method(); 
    }

private:
    explicit SharedX(std::nullptr_t)
    : px_(nullptr)
    {}

private:
    std::shared_ptr<X> px_;
}; 

// create a new shared x
auto sx = SharedX();

// create an uninitialised shared x to act as a placeholder for
// some later value (eg if deserialised)
auto nsx = SharedX::invalidHandle();

Novices, Java programmers, experts and value-semantic-purists such as myself will now all be happy.

  • Actually, wrapping a smart-pointer is not such a great idea, as it doesn't gain you anything but noise. You can invoke Methods of the pointee using -> easily enough. Though if you insist, consider Just specializing std::shared_ptr to achieve your aims. – Deduplicator Jul 2 '18 at 16:13
  • @Deduplicator If value semantics are desired and the implementation of an object is best shared, then I would argue that wrapping the shared pointer is inevitable. I would agree that it is not always the correct design. However the motivation here is to reduce reader complexity without sacrificing the efficiency and preciseness of c++. – Richard Hodges Jul 3 '18 at 7:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.