etl icon indicating copy to clipboard operation
etl copied to clipboard

Initializer List not working for vector and list

Open PiPointX opened this issue 3 years ago • 11 comments

When I try to initialize a vector with no standard-type I get the following error message:

error: could not convert '{{"Test", "Test2"}}' from '' to 'const etl::vector<element, 5>'

struct element { etl::string<16> key; etl::string<16> value; }; const etl::vector<element, 5> dumpData = { {"Test", nullptr} };

The same behaviour is for etl::list.

PiPointX avatar Jul 20 '22 07:07 PiPointX

What compiler and version of C++ and ETL are you using?

jwellbelove avatar Jul 20 '22 09:07 jwellbelove

What is the definition of ETL_HAS_INITIALIZER_LIST for your project. Is it set to 0 or 1? (This is not set by you; it is deduced in platform.h)

jwellbelove avatar Jul 20 '22 09:07 jwellbelove

Note: The ETL's version of std::initialiser_list can only be used when not using the STL anywhere in your project. initializer_list is special in that it must exist in the std namespace.

jwellbelove avatar Jul 20 '22 09:07 jwellbelove

I can get an example to work using this code.

CMakeLists.txt

cmake_minimum_required(VERSION 3.5.0)
project(etl_initializer_list_unit_tests)

add_definitions(-DETL_DEBUG)
add_definitions(-DETL_NO_STL)
add_definitions(-DETL_FORCE_ETL_INITIALIZER_LIST)


include_directories(${PROJECT_SOURCE_DIR}/../../include)

set(TEST_SOURCE_FILES
	test_initializer_list.cpp
  )

add_executable(etl_tests
  ${TEST_SOURCE_FILES}
  )

target_include_directories(etl_tests
  PUBLIC
  ${CMAKE_CURRENT_LIST_DIR}
  )

# Enable the 'make test' CMake target using the executable defined above
add_test(etl_initializer_list_unit_tests etl_tests)

# Since ctest will only show you the results of the single executable
# define a target that will output all of the failing or passing tests
# as they appear from UnitTest++
add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)

#RSG
set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17)

Test app

#include "etl/initializer_list.h"
#include "etl/list.h"
#include "etl/string.h"

int main()
{
  struct element { etl::string<16> key; etl::string<16> value; };

  const etl::list<element, 5> dumpData = { {"Test", nullptr} };

  return 0;
}

jwellbelove avatar Jul 20 '22 10:07 jwellbelove

I'm using the GCC10 with C++17.

ETL has the version 20.28.0

ETL_HAS_INITIALIZER_LIST is 0 in platform.h.

If I use the define ETL_FORCE_ETL_INITIALIZER_LIST from your example, the compile error persists. But if I change to ETL_FORCE_STD_INITIALIZER_LIST it compiles. So it just seems to be a configuration issue on my side.

PiPointX avatar Jul 21 '22 06:07 PiPointX

Do you have ETL_NO_STL defined?

jwellbelove avatar Jul 21 '22 09:07 jwellbelove

Yes ETL_NO_STL is defined

PiPointX avatar Jul 21 '22 09:07 PiPointX

For ETL_HAS_INITIALIZER_LIST to be defined as 0 there are only two conditions where that is true. Are you able to tell which #if/#else it is selecting?

//*************************************
// Determine if the ETL should use std::initializer_list.
#if (defined(ETL_FORCE_ETL_INITIALIZER_LIST) && defined(ETL_FORCE_STD_INITIALIZER_LIST))
  #error ETL_FORCE_ETL_INITIALIZER_LIST and ETL_FORCE_STD_INITIALIZER_LIST both been defined. Choose one or neither.
#endif

#if (ETL_USING_CPP11 && !defined(ETL_NO_INITIALIZER_LIST))
  // Use the compiler's std::initializer_list?
  #if (ETL_USING_STL && ETL_NOT_USING_STLPORT && !defined(ETL_FORCE_ETL_INITIALIZER_LIST)) || defined(ETL_IN_UNIT_TEST) || defined(ETL_FORCE_STD_INITIALIZER_LIST)
    #define ETL_HAS_INITIALIZER_LIST 1
  #else
    // Use the ETL's compatible version?
    #if defined(ETL_COMPILER_MICROSOFT) || defined(ETL_COMPILER_GCC)  || defined(ETL_COMPILER_CLANG) || \
        defined(ETL_COMPILER_ARM6) || defined(ETL_COMPILER_ARM7) || defined(ETL_COMPILER_IAR)   || \
        defined(ETL_COMPILER_TEXAS_INSTRUMENTS) || defined(ETL_COMPILER_INTEL)
      #define ETL_HAS_INITIALIZER_LIST 1
    #else
      #define ETL_HAS_INITIALIZER_LIST 0
    #endif
  #endif
#else
  #define ETL_HAS_INITIALIZER_LIST 0
#endif

jwellbelove avatar Jul 21 '22 09:07 jwellbelove

So this is my current configuration: ETL_TARGET_DEVICE_GENERIC ETL_TARGET_OS_NONE ETL_COMPILER_GENERIC ETL_CPP11_SUPPORTED ETL_CPP14_SUPPORTED ETL_CPP17_SUPPORTED ETL_NO_STL ETL_NO_NULLPTR_SUPPORT=0 ETL_NO_LARGE_CHAR_SUPPORT=0 ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED=0 ETL_CHECK_PUSH_POP ETL_FORCE_STD_INITIALIZER_LIST

With this, it jumps into the last #define ETL_HAS_INITIALIZER_LIST 0 because auf !defined(ETL_NO_INITIALIZER_LIST)

PiPointX avatar Jul 21 '22 09:07 PiPointX

Try changing ETL_COMPILER_GENERIC to ETL_COMPILER_GCC or let platform.h deduce it for itself. platform.h can deduce many of the configuration settings nowadays, specifically compiler type and C++ level support.

jwellbelove avatar Jul 21 '22 09:07 jwellbelove

I'm going to be out for the afternoon, but I'll be back about 7pm UK time (UTC+1) to answer any more questions.

jwellbelove avatar Jul 21 '22 10:07 jwellbelove

I'm closing this as there have been no updates.

jwellbelove avatar Nov 02 '22 19:11 jwellbelove