Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1614 Add policy to uninitialized array
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Eltzschig <me@elchris.org>
Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai>
  • Loading branch information
elfenpiff authored and FerdinandSpitzschnueffler committed Oct 17, 2022
1 parent 33a3eb7 commit 56f7ff0
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,30 @@ namespace iox
{
namespace containers
{
template <typename ElementType, uint64_t Capacity, typename index_t = uint64_t>
template <typename ElementType, uint64_t Capacity>
struct FirstElementZeroed
{
// NOLINTJUSTIFICATION required by low level UnitializedArray building block and encapsulated in abstraction
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays)
alignas(ElementType) cxx::byte_t value[Capacity * sizeof(ElementType)]{0};
};

template <typename ElementType, uint64_t Capacity>
struct UninitializedBuffer
{
// NOLINTJUSTIFICATION required by low level UnitializedArray building block and encapsulated in abstraction
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays)
alignas(ElementType) cxx::byte_t value[Capacity * sizeof(ElementType)];
};

template <typename ElementType,
uint64_t Capacity,
typename index_t = uint64_t,
template <typename, uint64_t> class Buffer = UninitializedBuffer>
class UnitializedArray
{
public:
constexpr UnitializedArray() noexcept;
constexpr UnitializedArray() noexcept = default;

constexpr ElementType& operator[](const index_t index) noexcept;

Expand All @@ -43,11 +62,9 @@ class UnitializedArray
static constexpr uint64_t capacity() noexcept;

private:
// NOLINTJUSTIFICATION required by low level UnitializedArray building block and encapsulated in abstraction
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays)
alignas(ElementType) cxx::byte_t m_buffer[Capacity * sizeof(ElementType)];

constexpr ElementType* toPtr(index_t index) const noexcept;

Buffer<ElementType, Capacity> m_buffer;
};

} // namespace containers
Expand Down
3 changes: 2 additions & 1 deletion iceoryx_hoofs/include/iceoryx_hoofs/cxx/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef IOX_HOOFS_CXX_STRING_HPP
#define IOX_HOOFS_CXX_STRING_HPP

#include "iceoryx_hoofs/containers/uninitialized_array.hpp"
#include "iceoryx_hoofs/cxx/optional.hpp"
#include "iceoryx_hoofs/cxx/type_traits.hpp"
#include "iceoryx_hoofs/internal/cxx/string_internal.hpp"
Expand Down Expand Up @@ -608,7 +609,7 @@ class string

// safe access is guaranteed since the char array is wrapped inside the string class
// NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
char m_rawstring[Capacity + 1U]{'\0'};
containers::UnitializedArray<char, Capacity + 1U, uint64_t, containers::FirstElementZeroed> m_rawstring;
uint64_t m_rawstringSize{0U};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,50 +24,45 @@ namespace iox
{
namespace containers
{
// UninitializedArray shall behave like a c-array; we explicitly do not want to initialize m_buffer. The constexpr
// default c'tor is needed to enable constexpr c'tors in classes that have an UnitializedArray member.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
template <typename ElementType, uint64_t Capacity, typename index_t>
inline constexpr UnitializedArray<ElementType, Capacity, index_t>::UnitializedArray() noexcept
{
}

template <typename ElementType, uint64_t Capacity, typename index_t>
inline constexpr ElementType& UnitializedArray<ElementType, Capacity, index_t>::operator[](const index_t index) noexcept
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr ElementType&
UnitializedArray<ElementType, Capacity, index_t, Buffer>::operator[](const index_t index) noexcept
{
return *toPtr(index);
}

template <typename ElementType, uint64_t Capacity, typename index_t>
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr const ElementType&
UnitializedArray<ElementType, Capacity, index_t>::operator[](const index_t index) const noexcept
UnitializedArray<ElementType, Capacity, index_t, Buffer>::operator[](const index_t index) const noexcept
{
return *toPtr(index);
}

template <typename ElementType, uint64_t Capacity, typename index_t>
inline constexpr ElementType* UnitializedArray<ElementType, Capacity, index_t>::ptr(const index_t index) noexcept
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr ElementType*
UnitializedArray<ElementType, Capacity, index_t, Buffer>::ptr(const index_t index) noexcept
{
return toPtr(index);
}

template <typename ElementType, uint64_t Capacity, typename index_t>
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr const ElementType*
UnitializedArray<ElementType, Capacity, index_t>::ptr(const index_t index) const noexcept
UnitializedArray<ElementType, Capacity, index_t, Buffer>::ptr(const index_t index) const noexcept
{
return toPtr(index);
}

template <typename ElementType, uint64_t Capacity, typename index_t>
inline constexpr uint64_t UnitializedArray<ElementType, Capacity, index_t>::capacity() noexcept
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr uint64_t UnitializedArray<ElementType, Capacity, index_t, Buffer>::capacity() noexcept
{
return Capacity;
}

template <typename ElementType, uint64_t Capacity, typename index_t>
inline constexpr ElementType* UnitializedArray<ElementType, Capacity, index_t>::toPtr(index_t index) const noexcept
template <typename ElementType, uint64_t Capacity, typename index_t, template <typename, uint64_t> class Buffer>
inline constexpr ElementType*
UnitializedArray<ElementType, Capacity, index_t, Buffer>::toPtr(index_t index) const noexcept
{
auto ptr = &(m_buffer[index * sizeof(ElementType)]);
auto ptr = &(m_buffer.value[index * sizeof(ElementType)]);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast, cppcoreguidelines-pro-type-const-cast) type erasure
return reinterpret_cast<ElementType*>(const_cast<cxx::byte_t*>(ptr));
}
Expand Down
3 changes: 2 additions & 1 deletion iceoryx_hoofs/include/iceoryx_hoofs/internal/cxx/string.inl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace iox
{
namespace cxx
{

template <uint64_t Capacity>
inline string<Capacity>::string(const string& other) noexcept
{
Expand Down Expand Up @@ -346,7 +347,7 @@ inline int64_t string<Capacity>::compare(char other) const noexcept
template <uint64_t Capacity>
inline const char* string<Capacity>::c_str() const noexcept
{
return m_rawstring;
return m_rawstring.ptr(0);
}

template <uint64_t Capacity>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ inline cxx::string<POSIX_CALL_ERROR_STRING_SIZE> errorLiteralToString(const char
template <typename T>
inline cxx::string<POSIX_CALL_ERROR_STRING_SIZE> PosixCallResult<T>::getHumanReadableErrnum() const noexcept
{
containers::UnitializedArray<char, POSIX_CALL_ERROR_STRING_SIZE> buffer;
buffer[0] = '\0';
containers::UnitializedArray<char, POSIX_CALL_ERROR_STRING_SIZE, uint64_t, containers::FirstElementZeroed> buffer;
return internal::errorLiteralToString(strerror_r(errnum, &buffer[0], POSIX_CALL_ERROR_STRING_SIZE), &buffer[0]);
}

Expand Down
2 changes: 1 addition & 1 deletion iceoryx_hoofs/source/posix_wrapper/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void setThreadName(iox_pthread_t thread, const ThreadName_t& name) noexcept

ThreadName_t getThreadName(iox_pthread_t thread) noexcept
{
containers::UnitializedArray<char, MAX_THREAD_NAME_LENGTH + 1> tempName;
containers::UnitializedArray<char, MAX_THREAD_NAME_LENGTH + 1, uint64_t, containers::FirstElementZeroed> tempName;

posixCall(iox_pthread_getname_np)(thread, &tempName[0], MAX_THREAD_NAME_LENGTH + 1U)
.successReturnValue(0)
Expand Down
2 changes: 1 addition & 1 deletion iceoryx_hoofs/source/posix_wrapper/unix_domain_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ UnixDomainSocket::timedReceive(const units::Duration& timeout) const noexcept
{
return cxx::error<IpcChannelError>(convertErrnoToIpcChannelError(setsockoptCall.get_error().errnum));
}
containers::UnitializedArray<char, MAX_MESSAGE_SIZE + 1> message;
containers::UnitializedArray<char, MAX_MESSAGE_SIZE + 1, uint64_t, containers::FirstElementZeroed> message;

auto recvCall = posixCall(iox_recvfrom)(m_sockfd, &message[0], MAX_MESSAGE_SIZE, 0, nullptr, nullptr)
.failureReturnValue(ERROR_CODE)
Expand Down

0 comments on commit 56f7ff0

Please sign in to comment.