ETLCPP / etl

Embedded Template Library
https://www.etlcpp.com
MIT License
2.05k stars 372 forks source link

Compiler error with etl::variant #835

Closed mike919192 closed 5 months ago

mike919192 commented 5 months ago

Hi

I am getting compiler errors when I try to add etl variant to my project. I am using gcc-arm-none-eabi version 12.2 and standard c++20.

My usage is simple etl::variant<int, float>

Sorry for the long list but here are all the errors:

All errors in variant_legacy.h
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'<declaration error>' is not a template [-fpermissive]
'R4' was not declared in this scope; did you mean 'T4'?
'R4' was not declared in this scope; did you mean 'T4'?
'R4' was not declared in this scope; did you mean 'T4'?
'R4' was not declared in this scope; did you mean 'T4'?
'R4' was not declared in this scope; did you mean 'T4'?
'R5' was not declared in this scope; did you mean 'T5'?
'R5' was not declared in this scope; did you mean 'T5'?
'R5' was not declared in this scope; did you mean 'T5'?
'R5' was not declared in this scope; did you mean 'T5'?
'R6' was not declared in this scope; did you mean 'T6'?
'R6' was not declared in this scope; did you mean 'T6'?
'R6' was not declared in this scope; did you mean 'T6'?
'R7' was not declared in this scope; did you mean 'T7'?
'R7' was not declared in this scope; did you mean 'T7'?
'R8' was not declared in this scope; did you mean 'T8'?
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)' cannot be overloaded with 'virtual void etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader_type<<anonymous> >::read(int)'
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
request for member 'read' in 'r', which is of non-class type 'etl::legacy::variant<T1, T2, T3, T4, T5, T6, T7, T8>::reader' {aka 'int'}
template argument 1 is invalid
template argument 1 is invalid
template argument 1 is invalid
template argument 1 is invalid
template argument 1 is invalid
type/value mismatch at argument 1 in template parameter list for 'template<class T> struct etl::parameter_type'
type/value mismatch at argument 1 in template parameter list for 'template<class T> struct etl::parameter_type'
type/value mismatch at argument 1 in template parameter list for 'template<class T> struct etl::parameter_type'
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)
wrong number of template arguments (8, should be 1)

Some small troubleshooting steps I have done one at a time:

include "platform.h"

if !ETL_USING_CPP11 || defined(ETL_USE_LEGACY_VARIANT)

include "private/variant_legacy.h" // etl::variant

else

//#include "private/variant_legacy.h" // etl::legacy::variant

include "private/variant_variadic.h" // etl::variant

endif

endif



If there is any other information I can provide, let me know.  Thanks
jwellbelove commented 5 months ago

I'll take a look at the errors, but etl::variant_new is to be preferred over etl:: variant_legacy as it has better conformance with the API of std::variant.

jwellbelove commented 5 months ago

The one selected is decided in variant.h.

mike919192 commented 5 months ago

Hi John, thanks for the reply. I am using the variant_variadic (new), but just the inclusion of the variant_legacy.h from variant.h is causing the errors. Thats what I was trying to show in the last code snippet that I remove the legacy include and there are no errors.

jwellbelove commented 5 months ago

That's odd, the inclusion of the two headers should be mutually exclusive.

mike919192 commented 5 months ago

This is the unmodified variant.h. If the variant_variadic is selected, the legacy is also included but placed in a separate namespace.

#ifndef ETL_VARIANT_INCLUDED
#define ETL_VARIANT_INCLUDED

#include "platform.h"

#if !ETL_USING_CPP11 || defined(ETL_USE_LEGACY_VARIANT)
  #include "private/variant_legacy.h"   // etl::variant
#else
  #include "private/variant_legacy.h"   // etl::legacy::variant
  #include "private/variant_variadic.h" // etl::variant
#endif

#endif
jwellbelove commented 5 months ago

Ah OK, I remember now. I'm out at the moment but I'll take a look when I get back tonight, or tomorrow morning.

mike919192 commented 5 months ago

I also checked and the errors are triggered with only #include "etl/variant.h" in the main.cpp. No instance of an actual etl::variant is needed to trigger the errors.

Edit: Definitely has something to do with include order. I'm trying to get to the bottom of it.

mike919192 commented 5 months ago

Oof, it was a macro conflict. Some ancient code had defined R1, R2 and R3 and those names are used in the variant_legacy. I guess the PC build didn't trigger it due to different include order. Sorry to raise a non issue.

jwellbelove commented 5 months ago

Ah macros, isn't it fun when they apply themselves to all scopes!

I had a strange error many years ago with Win32 where my class had a GetMessage member function and the compiler was complaining that it couldn't find GetMessageA. Turned out that the windows header had a macro that defined GetMessage as either GetMessageA or GetMessageW depending of the use of ascii or wide char types.