jp-embedded / scxmlcc

The SCXML state machine to C++ compiler
GNU General Public License v3.0
140 stars 34 forks source link

"example/hello_world.cpp" error pops up #104

Closed EduardShaid closed 5 years ago

EduardShaid commented 5 years ago

when compiling the project "example/hello_world.cpp" error pops up:

Error[Pe1449]: explicit specialization of function "sc_hello_world::state_actions::enter [with C=sc_hello_world::state_hello]" must precede its first use

jp-embedded commented 5 years ago

which system/version are you building on?

EduardShaid commented 5 years ago

IAR Embedded Workbench (IAR C/C++ Compiler) for ARM for Win64

jp-embedded commented 5 years ago

Have you taken the example as is? I can't see any specializations after first use/instantiation in the hello world example.

Is it possible for you to dig into this? Otherwise I would need an IAR license.

EduardShaid commented 5 years ago

Yes, I took an example of how it is, these are only two files from the example:

hello_world.cpp hello_world.h

I created a C ++ project in IAR and added these two files to it. When compiling, the following output occurs:

Building configuration: scxmlcc - Debug 
Updating build tree... 
main.cpp  
Error[Pe1449]: explicit specialization of function "sc_hello_world::state_actions<C>::enter [with C=sc_hello_world::state_hello]" must precede its first use (at line  D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 30 
48 of "D:\IAR Systems\8.32.1\projects\scxmlcc\hello_world.hpp") 
Error[Pe1449]: explicit specialization of function "sc_hello_world::state_actions<C>::enter [with C=sc_hello_world::state_world]" must precede its first use (at line  D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 35 
48 of "D:\IAR Systems\8.32.1\projects\scxmlcc\hello_world.hpp") 
Error while running C/C++ Compiler 

Total number of errors: 2 
Total number of warnings: 0 
EduardShaid commented 5 years ago

This is most likely a feature of the IAR Compiler itself. But how to get around this ?

EduardShaid commented 5 years ago

this error line is "explicit specialization of function sc_hello_world :: state_actions :: enter [with C = sc_hello_world :: state_hello]" must precede its first use" indicates the line of code:

template <> void sc :: state_actions <sc :: state_hello> :: enter (sc :: data_model & m)
{
cout << "hello" << endl;
}

and this error line "(at line D: \ IAR Systems \ 8.32.1 \ projects \ scxmlcc \ main.cpp 30" indicates a line of code:

template <class T> void enter (data_model & m, ...) {P :: template enter <T> (m, (T *) 0); state_actions <C> :: enter (m); }

inside sc_hello_world class

jp-embedded commented 5 years ago

Yes I think it is an issue with the IAR compiler. Specializations must be defined before first use. But the specialization is not used at hello_world.hpp:48 because it is inside a template which is not used before it is instantiated in main()

Could you try to remove line 48 in hello_wold.hpp and declare it in main.cpp after the two specializations to see what IAR then says?

EduardShaid commented 5 years ago

Is it possible to snatch this line 48 from the class context? There are dependencies in the class. I did so and this is what happened:

Building configuration: scxmlcc - Debug 
Updating build tree... 
main.cpp  
Error[Pe304]: no instance of function template "sc_hello_world::state_hello::enter" matches the argument list D:\IAR Systems\8.32.1\projects\scxmlcc\hello_world.hpp 67 
            argument types are: (sc_hello_world::data_model) 
            object type is: sc_hello_world::state_hello 
          detected during: 
            instantiation of "inline void sc_hello_world::transition<E, S, D, T>::state_enter(D *, sc_hello_world::data_model &, sc_hello_world::transition<E, S, D,  
T>::id<sc_hello_world::internal>, S *) [with E=&sc_hello_world::state::initial, S=sc_hello_world::scxml, D=sc_hello_world::state_hello, T=sc_hello_world::internal]" at  
line 78 
            instantiation of "inline sc_hello_world::state *sc_hello_world::transition<E, S, D, T>::operator()(S *, sc_hello_world &) [with  
E=&sc_hello_world::state::initial, S=sc_hello_world::scxml, D=sc_hello_world::state_hello, T=sc_hello_world::internal]" at line 125 
Error[Pe304]: no instance of function template "sc_hello_world::state_world::enter" matches the argument list D:\IAR Systems\8.32.1\projects\scxmlcc\hello_world.hpp 68 
            argument types are: (sc_hello_world::data_model) 
            object type is: sc_hello_world::state_world 
          detected during: 
            instantiation of "inline void sc_hello_world::transition<E, S, D, T>::state_enter(D *, sc_hello_world::data_model &, ...) [with  
E=&sc_hello_world::state::unconditional, S=sc_hello_world::state_hello, D=sc_hello_world::state_world, T=sc_hello_world::external]" at line 78 
            instantiation of "inline sc_hello_world::state *sc_hello_world::transition<E, S, D, T>::operator()(S *, sc_hello_world &) [with  
E=&sc_hello_world::state::unconditional, S=sc_hello_world::state_hello, D=sc_hello_world::state_world, T=sc_hello_world::external]" at line 130 
Error[Pe070]: incomplete type is not allowed D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe020]: identifier "data_model" is undefined D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe020]: identifier "m" is undefined D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe018]: expected a ")" D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe065]: expected a ";" D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error while running C/C++ Compiler 

Total number of errors: 7 
Total number of warnings: 0 
EduardShaid commented 5 years ago
Error[Pe070]: incomplete type is not allowed D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe020]: identifier "data_model" is undefined D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe020]: identifier "m" is undefined D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe018]: expected a ")" D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 
Error[Pe065]: expected a ";" D:\IAR Systems\8.32.1\projects\scxmlcc\main.cpp 43 

these errors point to the new line ("line 48 in hello_wold.hpp and declare it in main.cpp after the two specializations")

jp-embedded commented 5 years ago

How does this line 48 looks like now?

EduardShaid commented 5 years ago
#include "hello_world.hpp"
#include <iostream>

using namespace std;

typedef sc_hello_world sc;

template<> void sc::state_actions<sc::state_hello>::enter(sc::data_model &m)
{
    cout << "hello" << endl;    
}

template<> void sc::state_actions<sc::state_world>::enter(sc::data_model &m)
{
    cout << "world" << endl;    
}

template<class T> void enter(data_model &m, ...) { P::template enter<T>(m, (T*)0); state_actions<C>::enter(m); };
int main(int argc, char *argv[])
{
    sc sc;
    sc.init();

    return 0;
}
jp-embedded commented 5 years ago

you need to add the class names. Something like:

in hello_wold.h (declaration) - changed from definition to declaration: template<class T> void enter(data_model &m, ...);

in main.cpp (definition): template<class C, class P> template<class T> void sc::composite<C, P>::enter(sc::data_model &m, ...) { P::template enter<T>(m, (T*)0); state_actions<C>::enter(m); }

EduardShaid commented 5 years ago

Yes. it works ! Thank you for your project !

jp-embedded commented 5 years ago

Good to hear :-)