Other Parts Discussed in Thread: AWR1843
hi.
To reduce developer mistakes, I am actively using C++'s constexpr and template functions for code management and compile-time constant calculation.
We have confirmed mass production of more than 1 million units for 4 automotive vehicle models, so it is important to prevent coding mistakes.
I also tried MSVC and ARM GCC with the C++14 option turned on, but the compilation was successful.
Please refer to this compiler explorer link : Compiler Explorer (godbolt.org)
The CCS development environment used TI v20.2.7.LTS as the AWR1843 MSS core(ARM coretex R4F) target.
The code that causes a bug when compiling is as follows:
Please refer to the ENABLE_TI_COMPILER_ERROR and ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR macros to turn them on/off.
#include <stdio.h>
#include <type_traits>
#include <array>
#include <cmath>
#include <stddef.h>
#define ENABLE_TI_COMPILER_ERROR 1
#define ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR 0 // Warning: Please save all files you were working on before trying.
template <typename T>
struct is_std_array : std::false_type {};
template <typename V, size_t N>
struct is_std_array<std::array<V, N>> : std::true_type {};
template <typename V, size_t N>
struct is_std_array<const std::array<V, N>> : std::true_type {};
template<typename T>
constexpr bool is_std_array_v = is_std_array<T>::value;
#if ENABLE_TI_COMPILER_ERROR
/**
* @brief TI v20.2.7.LTS Compiler error
* : error #28: expression must have a constant value
* template constexpr bool does not appear to work
*/
#define STD_ARR_CHK(_TYPE_) is_std_array_v<_TYPE_>
#else
#define STD_ARR_CHK(_TYPE_) is_std_array<_TYPE_>::value
#endif
template<typename Ty>
inline constexpr Ty get_gt(Ty a, Ty b) {
return a > b ? a : b;
}
template<typename Ty, size_t N>
constexpr std::enable_if_t<!STD_ARR_CHK(Ty) && std::is_arithmetic<Ty>::value,
std::decay_t<Ty>> getArrMax(const std::array<Ty, N>& arr) {
auto max = arr[0];
for (size_t i = 1; i < N; i++)
max = get_gt(arr[i], max);
return max;
}
template<typename Ty, size_t N, typename std::enable_if_t<STD_ARR_CHK(Ty)>* = nullptr>
constexpr auto getArrMax(const std::array<Ty, N>& arr) {
auto max = getArrMax(arr[0]);
for (size_t i = 1; i < N; i++)
max = get_gt(getArrMax(arr[i]), max);
return max;
}
static constexpr std::array<const std::array<float, 3>, 2> testStdArr = {
std::array<float, 3>{0.f, 1.f, 2.f},
std::array<float, 3>{3.f, 4.f, -5.f}
};
static constexpr float testCstyleArr[2][3] = {
{0.f, 1.f, 2.f},
{3.f, 4.f, -5.f}
};
template<typename Ty>
struct Arr {
public:
typedef Arr __self;
typedef Ty value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
explicit constexpr Arr()
: p_(nullptr), sz_(0U) {};
template<size_t N>
explicit constexpr Arr(const value_type (&addr)[N])
: p_(const_cast<pointer>(addr)), sz_(N) {}
template<size_t N>
explicit constexpr Arr(std::array<value_type, N>&& arr)
: p_(N ? const_cast<pointer>(&(arr[0])) : nullptr)
, sz_(N) {}
template<size_t N>
explicit constexpr Arr(const std::array<value_type, N>& arr)
: p_(N ? const_cast<pointer>(&(arr[0])) : nullptr)
, sz_(N) {}
inline constexpr const_reference operator[](size_type n) const { return p_[n]; }
inline constexpr reference operator[](size_type n) { return p_[n]; }
inline constexpr iterator begin() noexcept { return p_; }
inline constexpr iterator end() noexcept { return p_ + sz_; }
inline constexpr const_iterator begin() const noexcept { return p_; }
inline constexpr const_iterator end() const noexcept { return p_ + sz_; }
inline constexpr const_iterator cbegin() const noexcept { return p_; }
inline constexpr const_iterator cend() const noexcept { return p_ + sz_; }
inline constexpr size_type size() const noexcept { return sz_; }
inline constexpr pointer data() noexcept { return p_; }
inline constexpr const_pointer data() const noexcept { return p_; }
inline constexpr operator pointer() noexcept { return p_; }
inline constexpr operator const_pointer() const noexcept { return p_; }
private:
pointer const p_;
const size_type sz_;
};
int main() {
static_assert(__cplusplus >= 201402L, "__cplusplus version require c++14");
#ifdef _LIBCPP_STD_VER
static_assert(_LIBCPP_STD_VER >= 14, "_LIBCPP_STD_VER error");
#endif
static constexpr auto arrMax = getArrMax(testStdArr);
static_assert(arrMax == 4.f, "getArrMax error");
static constexpr const Arr<float> cArrOk(testCstyleArr[0]);
static_assert(cArrOk.size() == 3, "Arr size error");
#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
/**
* @brief TI v20.2.7.LTS Compiler error
* : fatal error #4: out of memory
* array subscript compile error(?)
* Warning: Please save all files you were working on before trying.
*/
static_assert((cArrOk[0] < cArrOk[1]) && (cArrOk[1] < cArrOk[2]), "Arr elem compare fail(1)");
#endif
#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
/**
* @brief TI v20.2.7.LTS Compiler error
* : fatal error #4: out of memory
* constructor compile bug(?)
* Warning: Please save all files you were working on before trying.
*/
static constexpr const Arr<float> stdArrFail(testStdArr[0]);
static_assert(cArrOk[1] == stdArrFail[1], "Arr elem compare fail(2)");
#endif
#if ENABLE_TI_COMPILER_ERROR && ENABLE_TI_COMPILER_STACK_OVERFLOW_ERROR
/**
* @brief TI v20.2.7.LTS Compiler error
* : fatal error #4: out of memory
* double array subscript compile error(?)
* Warning: Please save all files you were working on before trying.
*/
static_assert(testStdArr[0][1] == 1.f, "");
#endif
return 0;
}
|
In the case of the std::array subscript problem, the array is copied and used, but it seems that memory may be wasted in some cases.
As for other issues, I hope they are fixed as soon as possible because code compatibility is not good.
I wish C++17 or later would be supported quickly, but I am satisfied because most of what I want is possible with C++14.
Thank you for your support.