Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. One more error using function pointers - void value not ignored as it ought to be

One more error using function pointers - void value not ignored as it ought to be

Scheduled Pinned Locked Moved C / C++ / MFC
helpoop
16 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Vaclav_

    Here is the error from compiler I need assistance with deciphering. I did try different type in the pointer declaration and it did just generated different errors. I tried without specifying parameters - no char * - and obviously got different errors . After removing the parameters from Process_INHERITANCE_A( Text); I got same error. Help would be appreciated. Thanks Inheritance_A.h:27: error: void value not ignored as it ought to be FunctionPointer_B = Process_INHERITANCE_A( Text); Here is the stripped down code void (*FunctionPointer_B)(char *); class INHERITANCE_A : public INHERITANCE_B , public INHERITANCE_C { public: void Process_INHERITANCE_A(char *Text); }; bool INHERITANCE_A::TestFunctionPointer(char*Text) { FunctionPointer_B = Process_INHERITANCE_A( Text); This is the only offending code line return true; } void INHERITANCE_A::Process_INHERITANCE_A(char *Text) { } ^

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #2

    You need to add the class declaration to the definition of the pointer, or make the function static. See https://isocpp.org/wiki/faq/pointers-to-members[^]. [edit]

    // Function pointer assignment should just provide the function (and class) name
    FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A;

    // call the function through the pointer by
    FunctionPointer_B(Text);

    V 1 Reply Last reply
    0
    • L Lost User

      You need to add the class declaration to the definition of the pointer, or make the function static. See https://isocpp.org/wiki/faq/pointers-to-members[^]. [edit]

      // Function pointer assignment should just provide the function (and class) name
      FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A;

      // call the function through the pointer by
      FunctionPointer_B(Text);

      V Offline
      V Offline
      Vaclav_
      wrote on last edited by
      #3

      Richard, setting the class function to static breaks calls from class A to class D , no biggie. I need to fix this pointer first. Adding class name to the funtion I wnat to point too got me this error: cannot convert 'INHERITANCE_A::Process_INHERITANCE_A' from type 'void (INHERITANCE_A::)()' to type 'void (*)()' Removing the function parameter - char* - created this error . I interpter iot as missing char. // bool (*FunctionPointer_A)(void); FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A; // (Text); ketch/Inheritance_A.h: In static member function 'static bool INHERITANCE_A::TestFunctionPointer(char*)': Inheritance_A.h:27: error: invalid conversion from 'void (*)(char*)' to 'void (*)()' [-fpermissive] FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A; // (Text); ^ This is getting frustrating , but still this is only a test. I am hoping to be able to have access from one class in inheritance chain to another member of the inheritance chain. I do not like this dependencies / calls between the classes in the inheritance chain , but I kinda of inherited that. No pun intended. I got it working going down the chain, now I need to go up the chain and hoping class pointers will work. Sorry for this mess.

      L 1 Reply Last reply
      0
      • V Vaclav_

        Here is the error from compiler I need assistance with deciphering. I did try different type in the pointer declaration and it did just generated different errors. I tried without specifying parameters - no char * - and obviously got different errors . After removing the parameters from Process_INHERITANCE_A( Text); I got same error. Help would be appreciated. Thanks Inheritance_A.h:27: error: void value not ignored as it ought to be FunctionPointer_B = Process_INHERITANCE_A( Text); Here is the stripped down code void (*FunctionPointer_B)(char *); class INHERITANCE_A : public INHERITANCE_B , public INHERITANCE_C { public: void Process_INHERITANCE_A(char *Text); }; bool INHERITANCE_A::TestFunctionPointer(char*Text) { FunctionPointer_B = Process_INHERITANCE_A( Text); This is the only offending code line return true; } void INHERITANCE_A::Process_INHERITANCE_A(char *Text) { } ^

        L Offline
        L Offline
        leon de boer
        wrote on last edited by
        #4

        Sorry to butt in but your problem has nothing to do with classes or inheriting it's just code syntax that would not work anywhere. Lets review function pointers .. 1.) you can set then to a function using the "&" symbol 2.) you can transfer the value to another function pointer that matches. Can I suggest you first try and write just two function pointers in normal C++ and try to set them ... here let me write the code for you

        void someFunc (char* text){
        // .... some code in here
        }

        // Here are our two function pointers
        void(*FunctionPointer_A)(char *);
        void(*FunctionPointer_B)(char *);

        // You can set either of them to the function using the & symbol .. item 1 use of function pointers
        FunctionPointer_A = &someFunc;
        FunctionPointer_B = &someFunc;

        // Or you can set one and copy the other which is item 1 then item 2 use of function pointers
        FunctionPointer_A = &someFunc;
        FunctionPointer_B = FunctionPointer_A ;

        I think this later is what you are attempting to do and if you copy the code in you should find it happily compiles. Forgetting the class prefix this what you typed is nonsense .. it doesn't meet either of the item 1 or 2 formats

        FunctionPointer_B = Process_INHERITANCE_A( Text);

        After Richards suggestion you at least seem to get the function pointer setting

        FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A;

        That I can at least I can understand and is ever so close but now we come details of a class. Any class function has a hidden self pointer pushed down on the function call. You don't see it the C++ compiler hides the syntax from you. So basically your function pointer doesnt equal the actual function of a class function .. that is what the compiler is complaining about. Your function pointer B needs to reflect its a class member function pointer .. not a function pointer to a static code redefine it to

        void(INHERITANCE_A::*FunctionPointer_B)(char *);

        You may also need to typedef this if you want to carry the function as a forward declaration All that is really happening is the function pointer knows to push the class self pointer down before it calls but from your perspective it makes the compiler see the two as the same type. There are better ways to do the function pointer assignment for classes, the magic term to do a search for is memberfunctionpointer. Because you are trying to make a function pointer to a member function in a class. Try:

        L 1 Reply Last reply
        0
        • L leon de boer

          Sorry to butt in but your problem has nothing to do with classes or inheriting it's just code syntax that would not work anywhere. Lets review function pointers .. 1.) you can set then to a function using the "&" symbol 2.) you can transfer the value to another function pointer that matches. Can I suggest you first try and write just two function pointers in normal C++ and try to set them ... here let me write the code for you

          void someFunc (char* text){
          // .... some code in here
          }

          // Here are our two function pointers
          void(*FunctionPointer_A)(char *);
          void(*FunctionPointer_B)(char *);

          // You can set either of them to the function using the & symbol .. item 1 use of function pointers
          FunctionPointer_A = &someFunc;
          FunctionPointer_B = &someFunc;

          // Or you can set one and copy the other which is item 1 then item 2 use of function pointers
          FunctionPointer_A = &someFunc;
          FunctionPointer_B = FunctionPointer_A ;

          I think this later is what you are attempting to do and if you copy the code in you should find it happily compiles. Forgetting the class prefix this what you typed is nonsense .. it doesn't meet either of the item 1 or 2 formats

          FunctionPointer_B = Process_INHERITANCE_A( Text);

          After Richards suggestion you at least seem to get the function pointer setting

          FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A;

          That I can at least I can understand and is ever so close but now we come details of a class. Any class function has a hidden self pointer pushed down on the function call. You don't see it the C++ compiler hides the syntax from you. So basically your function pointer doesnt equal the actual function of a class function .. that is what the compiler is complaining about. Your function pointer B needs to reflect its a class member function pointer .. not a function pointer to a static code redefine it to

          void(INHERITANCE_A::*FunctionPointer_B)(char *);

          You may also need to typedef this if you want to carry the function as a forward declaration All that is really happening is the function pointer knows to push the class self pointer down before it calls but from your perspective it makes the compiler see the two as the same type. There are better ways to do the function pointer assignment for classes, the magic term to do a search for is memberfunctionpointer. Because you are trying to make a function pointer to a member function in a class. Try:

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #5

          A nice clear explanation. :thumbsup:

          L 1 Reply Last reply
          0
          • V Vaclav_

            Richard, setting the class function to static breaks calls from class A to class D , no biggie. I need to fix this pointer first. Adding class name to the funtion I wnat to point too got me this error: cannot convert 'INHERITANCE_A::Process_INHERITANCE_A' from type 'void (INHERITANCE_A::)()' to type 'void (*)()' Removing the function parameter - char* - created this error . I interpter iot as missing char. // bool (*FunctionPointer_A)(void); FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A; // (Text); ketch/Inheritance_A.h: In static member function 'static bool INHERITANCE_A::TestFunctionPointer(char*)': Inheritance_A.h:27: error: invalid conversion from 'void (*)(char*)' to 'void (*)()' [-fpermissive] FunctionPointer_B = &INHERITANCE_A::Process_INHERITANCE_A; // (Text); ^ This is getting frustrating , but still this is only a test. I am hoping to be able to have access from one class in inheritance chain to another member of the inheritance chain. I do not like this dependencies / calls between the classes in the inheritance chain , but I kinda of inherited that. No pun intended. I got it working going down the chain, now I need to go up the chain and hoping class pointers will work. Sorry for this mess.

            L Offline
            L Offline
            leon de boer
            wrote on last edited by
            #6

            I can't for the love of me work out what you are trying to do but is this what you are trying to write

            class INHERITANCE_B {

            };

            class INHERITANCE_C {

            };

            class INHERITANCE_A : public INHERITANCE_B, public INHERITANCE_C
            {
            public:

            void Process\_INHERITANCE\_A(char \*Text);
            bool TestFunctionPointer(char\*Text);
            

            };

            typedef void(INHERITANCE_A::*FunctionPointer_B)(char *);

            bool INHERITANCE_A::TestFunctionPointer(char*Text)
            {
            FunctionPointer_B somePtr = &INHERITANCE_A::Process_INHERITANCE_A;
            return true;
            }

            void INHERITANCE_A::Process_INHERITANCE_A(char *Text)
            {

            }

            In vino veritas

            1 Reply Last reply
            0
            • L Lost User

              A nice clear explanation. :thumbsup:

              L Offline
              L Offline
              leon de boer
              wrote on last edited by
              #7

              I am still confused what he is trying to do. Why does he need the function pointer internal to the class he can call any function from the inherited interfaces directly. You usually only do member function calls from a block of code outside the class.

              In vino veritas

              L 1 Reply Last reply
              0
              • L leon de boer

                I am still confused what he is trying to do. Why does he need the function pointer internal to the class he can call any function from the inherited interfaces directly. You usually only do member function calls from a block of code outside the class.

                In vino veritas

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #8

                Yes, I can't quite figure out what is (supposed to be) going on, and none of the code snippets make it any clearer.

                V 1 Reply Last reply
                0
                • L Lost User

                  Yes, I can't quite figure out what is (supposed to be) going on, and none of the code snippets make it any clearer.

                  V Offline
                  V Offline
                  Vaclav_
                  wrote on last edited by
                  #9

                  Thanks, really helpful to make me understand how function pointer works. The whole exercise is to be able to call from one class to another in the hierarchy. What I am doing is recoding an app which was written without classes, I call it "flat" for lack of other words. It is basically relations between embedded processor hardware devices - USB , USB host, UART ( print) , LCD and video camera ( USB device). I am trying to use compound inheritance with top class managing the process of getting video data to the LCD. It is interrupt driven and I think that is where I went wrong - I need to rebuild the inheritance relations to have the interrupt driven class as "mother ship". I am pretty much done , the last piece is to actually process the video buffer. That is where the function pointers are used. Thanks again, you guys are very helpful and I appreciate that,

                  L 1 Reply Last reply
                  0
                  • V Vaclav_

                    Thanks, really helpful to make me understand how function pointer works. The whole exercise is to be able to call from one class to another in the hierarchy. What I am doing is recoding an app which was written without classes, I call it "flat" for lack of other words. It is basically relations between embedded processor hardware devices - USB , USB host, UART ( print) , LCD and video camera ( USB device). I am trying to use compound inheritance with top class managing the process of getting video data to the LCD. It is interrupt driven and I think that is where I went wrong - I need to rebuild the inheritance relations to have the interrupt driven class as "mother ship". I am pretty much done , the last piece is to actually process the video buffer. That is where the function pointers are used. Thanks again, you guys are very helpful and I appreciate that,

                    L Offline
                    L Offline
                    leon de boer
                    wrote on last edited by
                    #10

                    So the function call is from outside the class in the interrupt? That will be fun trying to make sure the class in a stable running state not starting or closing, before you start passing interrupts into it. You will get a nice big crash if you pass an interrupt into the class and it isn't stable :-)

                    In vino veritas

                    V 1 Reply Last reply
                    0
                    • L leon de boer

                      So the function call is from outside the class in the interrupt? That will be fun trying to make sure the class in a stable running state not starting or closing, before you start passing interrupts into it. You will get a nice big crash if you pass an interrupt into the class and it isn't stable :-)

                      In vino veritas

                      V Offline
                      V Offline
                      Vaclav_
                      wrote on last edited by
                      #11

                      The original code has ISR collecting the (video ) data and when it detects end of frame another function does the actual video output to the LCD. I put the ISR code in one class and the output to LCD in another class. Now both classes inherited from Print class so I can do code debugging etc. There are other hardware inheritances - USB , SPI but that is all working. That is how the compound inheritance came to be, and that is basically working. The issue is the link between the ISR and LCD class. I was hoping for another upper layer of class to be the controlling class, but that seems to be convoluted way to do it. I think I have a better grasp on using function pointers and will try to just call from one class to another using pointers. BTW the hardware interrupt is continuous and there are some checks in the actual interrupt handler and ISR functions making sure it is running and getting correct data / USB packages. Thanks to the group I think I got the basics, now it is just a matter of organizing the puzzle.

                      L 1 Reply Last reply
                      0
                      • V Vaclav_

                        The original code has ISR collecting the (video ) data and when it detects end of frame another function does the actual video output to the LCD. I put the ISR code in one class and the output to LCD in another class. Now both classes inherited from Print class so I can do code debugging etc. There are other hardware inheritances - USB , SPI but that is all working. That is how the compound inheritance came to be, and that is basically working. The issue is the link between the ISR and LCD class. I was hoping for another upper layer of class to be the controlling class, but that seems to be convoluted way to do it. I think I have a better grasp on using function pointers and will try to just call from one class to another using pointers. BTW the hardware interrupt is continuous and there are some checks in the actual interrupt handler and ISR functions making sure it is running and getting correct data / USB packages. Thanks to the group I think I got the basics, now it is just a matter of organizing the puzzle.

                        L Offline
                        L Offline
                        leon de boer
                        wrote on last edited by
                        #12

                        What you have just said above is what makes what you are doing weird to us. There is no need to inherit a print class just to print, you just hold a print class instance in your class data and initialize it and you can print to it at any time you need. You don't inherit things just so you can use them. You only inherit things you need to change the behaviour. Your class interface is just bloating up and you gain exactly zero as you could already print what you need using the original class. So let me ask the specific question does your class change the print interface it inherits in any way? If you answer no then you don't need to inherit it just create an instance of the class in your class.

                        In vino veritas

                        V 1 Reply Last reply
                        0
                        • L leon de boer

                          What you have just said above is what makes what you are doing weird to us. There is no need to inherit a print class just to print, you just hold a print class instance in your class data and initialize it and you can print to it at any time you need. You don't inherit things just so you can use them. You only inherit things you need to change the behaviour. Your class interface is just bloating up and you gain exactly zero as you could already print what you need using the original class. So let me ask the specific question does your class change the print interface it inherits in any way? If you answer no then you don't need to inherit it just create an instance of the class in your class.

                          In vino veritas

                          V Offline
                          V Offline
                          Vaclav_
                          wrote on last edited by
                          #13

                          The idea was - lazy man way . As written originally - the LCD class was derived / inherited from class Print. All usage of class Print was just calling the Print methods via inheritance, directly. To do what you suggest , which make perfect sense, I would have to change my other classes using Print methods to use the Print object. That is why I though multiple inheritance would work. It does , but things get tangled. And yes, I know how to do "find and replace ". I also have these "chain" dependencies and not sure how to tackle that using your method. I guess going from "flat" implantation to OOP is not that easy, but I hope I have Lerner few things in process. Would using "friend" class be of any advantage? Not that I need another headache. And no, my usage of inheritance does not change anything in class itself , they all basically just change / modify the data for their usage.

                          L 1 Reply Last reply
                          0
                          • V Vaclav_

                            The idea was - lazy man way . As written originally - the LCD class was derived / inherited from class Print. All usage of class Print was just calling the Print methods via inheritance, directly. To do what you suggest , which make perfect sense, I would have to change my other classes using Print methods to use the Print object. That is why I though multiple inheritance would work. It does , but things get tangled. And yes, I know how to do "find and replace ". I also have these "chain" dependencies and not sure how to tackle that using your method. I guess going from "flat" implantation to OOP is not that easy, but I hope I have Lerner few things in process. Would using "friend" class be of any advantage? Not that I need another headache. And no, my usage of inheritance does not change anything in class itself , they all basically just change / modify the data for their usage.

                            L Offline
                            L Offline
                            leon de boer
                            wrote on last edited by
                            #14

                            You said ... "To do what you suggest , which make perfect sense, I would have to change my other classes using Print methods to use the Print object." No you don't all you need to do is create a printer class at initialization, lets say you have a private variable printer class called "ThePrinter". All it means is at the moment you are calling the inherited methods of the printer class directly so xyz_func(); so instead of that it would become ThePrinter.xyz_Func(); Really from a code point it's that simple a small change in the constructor and the name of the held printer infront of the printer class methods you are directly calling. Besides making your interface a hell of a lot smaller and removing bloating code and data in your class it also allows you to do things you can't do like change the printer device on the fly or pass the printer class to another object or a block of code. If you want to share the printer, so two different classes can write to the exact same printer (which may be likely in your case), you get one class to make the printer and then simply make a function on that class so the other classes can get a pointer to the printer. So the class that has the printer does this via a function GetMyPrinter

                            class IHavePrinter{
                            public:
                            PrinterClass* GetMyPrinter(void); // Return the created printer is a public function
                            private:
                            PrinterClass ThePrinter; // The actual created printer in this classes constructor
                            }

                            IHavePrinter:: PrinterClass* GetMyPrinter(void){
                            return(&ThePrinter); // Return pointer to the created printer
                            }

                            That is the point of keeping classes detached so you can do things you can't possibly do if you bind them into your object inheritance and you stop the vicious cross connection you are getting. I think most of your dependency issues is actually cause by your inheritance scheme and wouldn't exist if you did it properly. You could just have exposed the printer object as a public but the few lines to pass it on a function means that later on if you want to track who is using the printer or know if it's in use you can modify that function to track that etc. So a bit of forward planning built into the concept and trying to keep the classes as detached as possible not accessing each others fields.

                            In vino veritas

                            V 1 Reply Last reply
                            0
                            • L leon de boer

                              You said ... "To do what you suggest , which make perfect sense, I would have to change my other classes using Print methods to use the Print object." No you don't all you need to do is create a printer class at initialization, lets say you have a private variable printer class called "ThePrinter". All it means is at the moment you are calling the inherited methods of the printer class directly so xyz_func(); so instead of that it would become ThePrinter.xyz_Func(); Really from a code point it's that simple a small change in the constructor and the name of the held printer infront of the printer class methods you are directly calling. Besides making your interface a hell of a lot smaller and removing bloating code and data in your class it also allows you to do things you can't do like change the printer device on the fly or pass the printer class to another object or a block of code. If you want to share the printer, so two different classes can write to the exact same printer (which may be likely in your case), you get one class to make the printer and then simply make a function on that class so the other classes can get a pointer to the printer. So the class that has the printer does this via a function GetMyPrinter

                              class IHavePrinter{
                              public:
                              PrinterClass* GetMyPrinter(void); // Return the created printer is a public function
                              private:
                              PrinterClass ThePrinter; // The actual created printer in this classes constructor
                              }

                              IHavePrinter:: PrinterClass* GetMyPrinter(void){
                              return(&ThePrinter); // Return pointer to the created printer
                              }

                              That is the point of keeping classes detached so you can do things you can't possibly do if you bind them into your object inheritance and you stop the vicious cross connection you are getting. I think most of your dependency issues is actually cause by your inheritance scheme and wouldn't exist if you did it properly. You could just have exposed the printer object as a public but the few lines to pass it on a function means that later on if you want to track who is using the printer or know if it's in use you can modify that function to track that etc. So a bit of forward planning built into the concept and trying to keep the classes as detached as possible not accessing each others fields.

                              In vino veritas

                              V Offline
                              V Offline
                              Vaclav_
                              wrote on last edited by
                              #15

                              Thanks, so in my simple words - instead of using multiple inheritance in downstream fashion doing it this way is sort of in reverse - the printer class goes first. Your are very helpful and much appreciated. Thanks. Cheers Vaclav

                              L 1 Reply Last reply
                              0
                              • V Vaclav_

                                Thanks, so in my simple words - instead of using multiple inheritance in downstream fashion doing it this way is sort of in reverse - the printer class goes first. Your are very helpful and much appreciated. Thanks. Cheers Vaclav

                                L Offline
                                L Offline
                                leon de boer
                                wrote on last edited by
                                #16

                                Yes we are putting composition over inheritance, so our classes are trying to achieve multiple and flexible behaviour (reusing as much code as possible) rather than inheritance from a base or parent class. I would also add there is one final thing you will be able to do if you go that path which you can't possibly do with your current scheme, which is to thread the classes or at least the one that had the old ISR code to help its response and speed.

                                In vino veritas

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups