From 870aeeef3939a20a7f85e5656ef0cbeeed71cae7 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Mon, 15 Oct 2018 22:46:24 +0200
Subject: [PATCH] Add no_init value

This value is used to define explicitly constructors with no initialization. In
particular, it allows to define default (no init) constructor helper when
writing trivial types: default constructor being defined as (=default). This
helps to avoid compiler to complain about false uninitialized variables.
---
 src/algebra/TinyMatrix.hpp | 23 ++++++++++++++---------
 src/algebra/TinyVector.hpp | 11 ++++++++---
 src/utils/Types.hpp        |  3 +++
 3 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/src/algebra/TinyMatrix.hpp b/src/algebra/TinyMatrix.hpp
index 23273a0ea..cdf7353c0 100644
--- a/src/algebra/TinyMatrix.hpp
+++ b/src/algebra/TinyMatrix.hpp
@@ -36,7 +36,7 @@ public:
   PASTIS_INLINE
   constexpr TinyMatrix operator-() const
   {
-    TinyMatrix opposed;
+    TinyMatrix opposed{no_init};
     for (size_t i=0; i<N*N; ++i) {
       opposed.m_values[i] = -m_values[i];
     }
@@ -63,7 +63,7 @@ public:
   constexpr TinyMatrix operator*(const TinyMatrix& B) const
   {
     const TinyMatrix& A = *this;
-    TinyMatrix AB;
+    TinyMatrix AB{no_init};
     for (size_t i=0; i<N; ++i) {
       for (size_t j=0; j<N; ++j) {
         T sum = A(i,0)*B(0,j);
@@ -80,7 +80,7 @@ public:
   constexpr TinyVector<N,T> operator*(const TinyVector<N,T>& x) const
   {
     const TinyMatrix& A = *this;
-    TinyVector<N,T> Ax;
+    TinyVector<N,T> Ax{no_init};
     for (size_t i=0; i<N; ++i) {
       T sum = A(i,0)*x[0];
       for (size_t j=1; j<N; ++j) {
@@ -129,7 +129,7 @@ public:
   PASTIS_INLINE
   constexpr TinyMatrix operator+(const TinyMatrix& A) const
   {
-    TinyMatrix sum;
+    TinyMatrix sum{no_init};
     for (size_t i=0; i<N*N; ++i) {
       sum.m_values[i] = m_values[i]+A.m_values[i];
     }
@@ -148,7 +148,7 @@ public:
   PASTIS_INLINE
   constexpr TinyMatrix operator-(const TinyMatrix& A) const
   {
-    TinyMatrix difference;
+    TinyMatrix difference{no_init};
     for (size_t i=0; i<N*N; ++i) {
       difference.m_values[i] = m_values[i]-A.m_values[i];
     }
@@ -255,6 +255,11 @@ public:
     }
   }
 
+  // Default constructor helper. Used to define uninitialized TinyMatrix
+  // avoiding compiler's false uninitialized warning.
+  PASTIS_INLINE
+  constexpr TinyMatrix(const NoInitType&) noexcept {}
+
   PASTIS_INLINE
   constexpr TinyMatrix(const TinyMatrix&) noexcept = default;
 
@@ -262,7 +267,7 @@ public:
   TinyMatrix(TinyMatrix&& A) noexcept = default;
 
   PASTIS_INLINE
-  ~TinyMatrix()=default;
+  ~TinyMatrix() = default;
 };
 
 template <size_t N, typename T>
@@ -270,7 +275,7 @@ PASTIS_INLINE
 constexpr TinyMatrix<N,T> tensorProduct(const TinyVector<N,T>& x,
                                         const TinyVector<N,T>& y)
 {
-  TinyMatrix<N,T> A;
+  TinyMatrix<N,T> A{no_init};
   for (size_t i=0; i<N; ++i) {
     for (size_t j=0; j<N; ++j) {
       A(i,j) = x[i]*y[j];
@@ -287,7 +292,7 @@ constexpr T det(const TinyMatrix<N,T>& A)
   static_assert(std::is_floating_point<T>::value, "determinent for arbitrary dimension N is defined for floating point types only");
   TinyMatrix<N,T> M = A;
 
-  TinyVector<N, size_t> index;
+  TinyVector<N, size_t> index{no_init};
   for (size_t i=0; i<N; ++i) index[i]=i;
 
   T determinent = 1;
@@ -358,7 +363,7 @@ constexpr TinyMatrix<N-1,T> getMinor(const TinyMatrix<N,T>& A,
 {
   static_assert(N>=2, "minor calculation requires at least 2x2 matrices");
   Assert((I<N) and (J<N));
-  TinyMatrix<N-1, T> M;
+  TinyMatrix<N-1,T> M{no_init};
   for (size_t i=0; i<I; ++i) {
     for (size_t j=0; j<J; ++j) {
       M(i,j)=A(i,j);
diff --git a/src/algebra/TinyVector.hpp b/src/algebra/TinyVector.hpp
index 7dc42a158..483a0dbb7 100644
--- a/src/algebra/TinyVector.hpp
+++ b/src/algebra/TinyVector.hpp
@@ -31,7 +31,7 @@ class TinyVector
   PASTIS_INLINE
   constexpr TinyVector operator-() const
   {
-    TinyVector opposed;
+    TinyVector opposed{no_init};
     for (size_t i=0; i<N; ++i) {
       opposed.m_values[i] =-m_values[i];
     }
@@ -106,7 +106,7 @@ class TinyVector
   PASTIS_INLINE
   constexpr TinyVector operator+(const TinyVector& v) const
   {
-    TinyVector sum;
+    TinyVector sum{no_init};
     for (size_t i=0; i<N; ++i) {
       sum.m_values[i] = m_values[i]+v.m_values[i];
     }
@@ -125,7 +125,7 @@ class TinyVector
   PASTIS_INLINE
   constexpr TinyVector operator-(const TinyVector& v) const
   {
-    TinyVector difference;
+    TinyVector difference{no_init};
     for (size_t i=0; i<N; ++i) {
       difference.m_values[i] = m_values[i]-v.m_values[i];
     }
@@ -197,6 +197,11 @@ class TinyVector
     this->_unpackVariadicInput(t, args...);
   }
 
+  // Default constructor helper. Used to define uninitialized TinyVector
+  // avoiding compiler's false uninitialized warning.
+  PASTIS_INLINE
+  constexpr TinyVector(const NoInitType&) noexcept {}
+
   PASTIS_INLINE
   constexpr TinyVector() noexcept = default;
 
diff --git a/src/utils/Types.hpp b/src/utils/Types.hpp
index 90d0e8407..6151a3734 100644
--- a/src/utils/Types.hpp
+++ b/src/utils/Types.hpp
@@ -1,6 +1,9 @@
 #ifndef TYPES_HPP
 #define TYPES_HPP
 
+enum class NoInitType { no_init };
+constexpr NoInitType no_init=NoInitType::no_init;
+
 enum class ZeroType { zero };
 constexpr ZeroType zero=ZeroType::zero;
 
-- 
GitLab