How to avoid implicit conversion in C++

Exact types of Fasteners
Exact types of Fasteners

nothing_but<T>

Value Handle to Avoid Implicit Conversions in standard C++

Introduction

“… C++ is not a bad language per se. It’s just, well kinda suffers from bloat. In the words of Richard E. Gooch, “It seduces the programmer, making it much easier to write bloatware“…”
The source

Probably you indulge into recreational C++ and the following is just a light curiosity for you ( https://godbolt.org/z/u0fkZo ) :

That is also C code. In any case modern compilers give little or no warnings. Unless you use -Wall. Even then only unsigned to signed assignment produces a warning.

Or. Perhaps you are not fan of “recreational programming” and you do take the above so seriously you actually do not use C++ on mission critical projects? Perhaps your code is a firmware that has to be installed, inside some medical equipment your company delivers?

You might take the C++ implicit conversions so seriously that “even” the following is a very serious matter for you.

Not because you happen to be “unreasonable”, but because you need to deliver code where implicit conversion are simply not allowed. Just like for example exceptions, in many real-time projects are not allowed. They simply do not exist over there.  Them exceptions are simply switched off.

Here is yet another (not that) funny example:

The output?

Not laughing any more. And very likely, you have already turned to the “official sources” just to come back disappointed. Those advice are, to put it mildly, not feasible, in real life, non-trivial projects.

Interestingly, some other coding platforms,  do have exact types , should  we say “for ages”. Alas, never part of C++ or C.

One options is to plan for usual extended test/debug/test/debug, cycles ad-infinitum, of course. Spending a **lot** of time chasing this kind of bugs.

Before you dump C++, can we offer to you

The suggestion

So, before you start learning Ada and discard (with the heavy heart) C++ for your mission critical projects, we might perhaps suggest you look into this ridiculously tiny single standard  C++ header? Here is some code to tickle your fancy.

Just declarations first. As ever, make default initialized content, but with a twist: of exactly the types required.

Now comes the interesting part.

To actually assign anything to these types you must very consciously make those types first.

You, or your team simply can not introduce a bug there. The following will simply not compile.

Just a perfect API to avoid those nasty little pests growing into bugs very difficult to find.

Now, this might seem like “not a lot of code” to you, but we are just showing an API new to you. Above code looks almost too simple. It is easy to forget the safety service this API provides.

Now the really worn out phrase: Your imagination is the limit. Very true here.

Type’s handled

This API does handle all the arithmetic types.

  • integral types
    • bool
    • char
    • char16_t
    • char32_t
    • wchar_t
    • signed char
    • short int
      int
    • long int
    • long long int
    • unsigned char
    • unsigned short int
    • unsigned int
    • unsigned long int
    • unsigned long long int
  • floating point types
    • float
    • double
    • long double

These are the types where implicit conversions do happen, by design.

But what about compound types? For example what about:

  • References
  • Pointers
  • Arrays

Why not handling them too? Simply because, in case you need them you will naturally use them as ever before, but combined with this API.

Please do note, how above, all the standard C++ default value initialization rules are respected.

In case of some serious bugs, or singularities discovered, or edge case, we will reconsider the currently handled types.

Going beyond arithmetics it is very unlikely the implicit conversion might be the problem in your code.

Dependencies

This API depends on C++ std lib only. We are developing using the Visual Studio 2017 15.9.X, But we are always checking it is equally usable with both CLANG and GCC.

Installation

This API is header-only: it consists entirely of one header file:

dbj_nothing_but.h

No compilation necessary. No installation required.

Just drop it in and include. Make it part of your project.

Every attempt has been made to make this into a cross-platform, header only, standard C++ library.

At time of this writing (2019-Q1) standard C++ is C++17.

  • Builds and tests are passing with C++14 (/std:c++14)
  • Builds and tests are passing with C++17 (/std:c++17)

Contact

Please report issues or questions here.

You can contact me via twitter at @dbjdbj

Contributing

Any feedback from users and stakeholders will be used to improve the library.

Copyright(C) 2019 Dušan B. Jovanović (dbj@dbj.org)

CC BY SA 4.0

So little C++ so much good!
So little C++ so much good!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.