If I use C-Style in my C ++ project, is it worth refactoring to do C ++?

I use C-style cast in my LOC project C ++ 15K, 90% of the time for castings between child and base classes.

Even when I read that using them is bad and that they can lead to serious errors, because they are not safe types, like C ++ drives, I still feel great and comfortable using them.

I have not yet had one error in my project, which was caused, for example, by the randomly confusing C-Style.

There are two main reasons why I did not use them:

  • I did not know enough about them yet.
  • I did not like their syntax, they are more detailed and difficult to read for me.

My questions:

  • (Why) Should I reorganize my project to use C ++ style styles?
  • Why should I use C ++ style for my future projects?

I use as well as all the other advantages offered by C ++ from OOP, including virtual and abstract base classes, namespaces, STL, etc., and not the syntax of a new type. The argument "Why aren't you using C then?" not working for me.

+62
c ++ casting refactoring
Feb 18 2018-11-21 at
source share
7 answers

The main advantage of C ++ style styles, as you already mentioned, is type safety. Each action in C ++ processes one specific type of transformation (or a family of related transformations), and so the compiler can go and check that you are not doing the unnecessary transformations that you intended, or the sequence of transformations that are basically unsafe.

One thing to think about is that, although you are comfortable using C-style casts, and even though you haven't made any mistakes with them, other code-based people may not be as light with these scum as you. Using casting operators makes code more self-documenting. If you have something in C style, someone who reads the code may not immediately establish what exactly you are doing. If they see something like

T* ptr = (T*) var; 

They may not immediately determine if it is

  • Cast from base class to derived class or vice versa.
  • Dropping const discarded var
  • Converting from an integral type to a pointer.

While they can probably get this out of context, it’s much more obvious what happens if you use a listing like

 T* ptr = static_cast<T*>(var); 

or

 T* ptr = const_cast<T*>(var); 

Another reason to prefer C ++-style casting operators is that they make the code more resilient to change. For example, suppose I have this function:

 void DoSomething(Base* ptr) { Derived* derived = (Derived *) ptr; DoSomethingElse(derived); } 

Now suppose that I understand that this function should not make any changes to its argument, so I decided to note its const . For example:

 void DoSomething(const Base* ptr) { Derived* derived = (Derived *) ptr; DoSomethingElse(derived); } 

But now we have a problem - my C-style style, which was used only for down down, now also removes const ness. This can lead to a slight error when DoSomethingElse mutates the pointer that I pass, although the DoSomething promises method itself does not do this. If instead I wrote this code as

 void DoSomething(Base* ptr) { Derived* derived = static_cast<Derived *>(ptr); DoSomethingElse(derived); } 

And then change the code by adding const :

 void DoSomething(const Base* ptr) { Derived* derived = static_cast<Derived *>(ptr); DoSomethingElse(derived); } 

Now I will get a compiler error telling me that my old throw is broken, which may make me find that there is a logical error in the code (namely, that DoSomethingElse mutates its argument, so I cann’t naively make a ptr pointer to const .

In short, using C ++ casting operators makes the code more readable and more convenient. This makes the code logic more explicit. And this makes the code less error prone, as compiler errors catch either as they are created, or later when you return and change the old code. I would recommend trying to use C ++-style casting operators in the future for these main reasons.

As for whether you need to go back and try to replace your current C-style styles with C ++ - styles, it really is up to you. As an exercise, I would suggest doing this in order to learn how to study what types of techniques you use. In addition, you can find there a logical error that will make the search suitable for you!

+83
Feb 18 2018-11-18T00:
source share

In the company with which I worked, we somehow had to transfer several million lines of application code to the new platform. What started as “just another port for another Unix platform” (code already running on Windows, OSX and half a dozen Unix-like platforms) turned out to be a huge problem. IIRC, the reason was that there were strict alignment requirements on this platform, and some of our throws turned off hardware exceptions due to misalignment.

It would be easy enough to fix if it weren’t for the fact that a certain percentage of these stocks were C-style cast . It was impossible for them to effectively grep . The search revealed literally tens of thousands of lines of code that all had to be manually checked by human beings , 99.99% of which were completely irrelevant.
This did not help us people tend to skip a few of these hard-to-reach throws, which would then have to be found in another round of tens of thousands of lines of code, 99.99% of which are exactly the same as in the first round.

This task was almost impossible to complete at the indicated time, but almost broke the company because they faced a serious penalty under the contract if we missed the deadline.

Needless to say, it was subsequently decided to replace all C-styles for their copies with C ++. However, if this policy existed before we had to make this port ...

+28
Feb 18 '11 at 21:38
source share

(Why) Should I reorganize my project to use C ++ style styles?

Yes. For the same reason, you should use them in the future.

Why should I use C ++ style for my future projects?

The list is actually quite long, but I will consider the most important ones.

First, they clearly state the intention of the throw. By reading "static_cast", you know that the author intended to perform a static acting interpretation, not reinterpret or const.

Secondly, they do one and only one. For example, you cannot accidentally drop constness.

They are easy to find. Search for "const_cast" to find all casts to / from const. How do you do it using C-style? You could not.

They do not change the appearance of the cast when changing the semantics of local code. For example, (Widget*)(blah) will silently change to reinterpret if Widget ceases to inherit from any type that the blah pointer was on. It also changes to reinterpret if the Widget definition is not available locally. If you use new-style casts, instead you get compiler vomiting rather than a tacit interpretation of the statement.

You can make a dynamic roll. C-style casts cannot do this.

+10
Feb 18 2018-11-18T00:
source share

Well, two parts:

(Why) Should I reorganize my project to use C ++ style styles?

If your code works. Then do not correct it. Leave it as it is. In any case, finding C clips can be pretty tricky. If you are working on code and encountering line C, change it as needed.

Why should I use C ++ style for my future projects?

Because C throws are easily mistaken.

+9
Feb 18 '11 at 22:07
source share

If 90% of your casts are subclassed to the base class, then deleting them will be the beginning - they should not be needed. If you have a lot of castings from base to sub, then you are doing something else wrong.

For the rest, you tell the compiler that something strange is happening and you break the rules - either the rules of the type system with reinterpret_cast or const_cast, you run the risk of representing static_cast to a smaller integral type, or you violate the LSP and should be aware of the particular type of subclass when given base class.

Making these cases explicit is good.

+4
Feb 18 2018-11-18T00:
source share
 (Why) Should I refactor my project to use C++-style casts? Why should I use C++-style casts for my future projects? 

There are some good answers (including my own IMO) to the second question to this question.

For the first question, if I were in your place, I would replace the C ++ style casts for C-style castings whenever I already edited the file. You probably shouldn't leave aside a day or so to edit all of your code and recompile it, but it’s probably worth it to gradually improve your code base when you are already working on it.

If you have time to re-factorize, this will be a good candidate for this.

+3
Feb 18 '11 at 21:58
source share

If I were, I would continue to use the C-style cast. You have good reasons: you don’t experience the alleged flaws of C-style casts, C ++ casts are more detailed, C ++ translations are more difficult to read and less familiar to you.

More generally, as a C ++ programmer, you will often read or tell that some way to do things is old, wrong, capable of doing things and that you should use the New, Correct, C ++ method. Some examples:

  • you should use C ++ stylecasts instead of C style styles
  • you should use links instead of pointers.
  • you should use the keyword "const" a lot
  • you should use generics instead of void pointers or types
  • you should use initializer lists instead of initializing member variables in the body of the constructors
  • you should use constructors instead of the initialization function after building
  • you should never use macros

You will usually be told that the new method is safer, which allows the compiler to catch more errors and makes the code more understandable.

I suggest you look at such advice with suspicion. Instead, consider: is using the new C ++ function using the problem that you actually have? Does this create new problems (by the way, increasing the granularity of the code and decreasing the readability are problems)? If the answer to the first question is missing, or the answer to the first question is yes, you should consider sticking to the "Old, wrong", "C" method.

Component commentary on code clarity: verbosity reduces clarity if the added text does not help the reader understand the program. If I were you, I would consider the statement that C ++ style casting improves code clarity skeptically, because you, the reader of your program, do not feel the benefits.

I used to be the person who always tried to use the New, Right, C ++ method. I'm not so dogmatic anymore. The essay on the link above was a big factor in changing my mind.

http://yosefk.com/c++fqa/

+2
Feb 18 2018-11-18T00:
source share



All Articles