0

I'm having trouble with passing a pointer to a function that is called by another pointer. I'm trying to modify a pointer (i.e. p1) that calls the function min (i.e. p1->min()) which takes a pointer as a parameter (i.e. p1->min(*p2)). Note: *p2 isn't modified at all, just passed for its values, for which p1 will be modified based on the values of p2.

Note: I removed irrelevant code (only inside functions, everything else is as is) to make it easier to read.

Test.h

// Don't worry about the create method, just assume it works
// I'm having issues with the "min" function, more details below

class Test {
    protected:
        std::vector<std::vector<std::string> > vec;
    public:
        static Test *create(std::string file); // instantiates vec
        void *min(Test *); // modifies vec 
};

Test.cc

// Don't worry about create (factory method), just assume it works
// "min" is causing compiler errors (see below)

Test *Test::create(string file) { /* instantiates vec with file contents */ }
void *Test::min(const Test *&p) { /* modifies vec */ }

main.cc

// Main cannot change, this is how it must be implemented
// However, Test.cc and Test.h CAN be modified.

Test *p1 = Test::create("file1");
Test *p2 = Test::create("file2");
p1->min(*p2); // modify p1 based on values of p2, p2 is NOT modified

Compiler Errors:

fatal error: control reaches end of non-void function

What is weird is that its declared void but expecting a return value So, when I do return something it shows up another compiler error

fatal error: no viable conversion from return value of type 'Test' to function return type 'void *'

I'm so confused on the compile errors. I'm thinking it has something to do with my declarations. Note: There is no constructor since the base class must use a factory method while the derived classes use their own constructors, hence the *Test::create and *Test::min.

Please help.

16
  • 1
    Test::min's declaration doesn't match it's definition. The arguments are different. And are you sure you want min to return void*? What's the significance of the return value? Commented Nov 1, 2018 at 17:45
  • 2
    void* is not the same as void. Voting to close as typo Commented Nov 1, 2018 at 17:46
  • I don't need a return value. p1->min(*p2) just modifies p1, it doesn't need to return anything. Commented Nov 1, 2018 at 17:46
  • 1
    I see no base class or derived class. If you aren't going to change the return type then you have to return something. Commented Nov 1, 2018 at 17:50
  • 2
    tbh i think this question is a train wreck. I suggest you to create a new one which does include a minimal reproducible example (ie include your base) Commented Nov 1, 2018 at 17:54

3 Answers 3

1

What is weird is that its declared void

No, it isn't.

   Test *Test::create(string file) { /* instantiates vec with file contents */ }
// ^^^^^^ return type is Test*

   void *Test::min(const Test *&p) { /* modifies vec */ }
// ^^^^^^ return type is void*

It's unfortunate that you use right-aligned asterisks and ampersands, because it has directly led to your confusion. It looks like you forgot the * was there, or thought it was part of the syntax of the function declaration itself (like how, in your question, you've referred to the functions as "*Test::create and *Test::min").

If you start aligning them to the left (which won't affect the program's semantics, it's just style), your intent and the meaning of types will be clear:

Test* Test::create(string file) { /* instantiates vec with file contents */ }
void* Test::min(const Test*& p) { /* modifies vec */ }

Now you can easily see at a glance that your return type isn't what you thought it was, and can correct the declaration of Test::min (and, possibly, Test::create).

Some people will start going on about how the internal grammar binds the * to the name rather than to the type, or about how the left-aligned approach makes it marginally more awkward to get right that really important and frequently-used construct, the multi-variable declaration. Ignore them!

Speaking more broadly, you have a lot of pointers going on here, and I suggest trying to minimise that. It's only going to lead to unnecessary trouble. Love objects.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the clarification.
0
void *Test::min(const Test *&p) { /* modifies vec */ }

If this function doesn't have a return statement, remove the * from void *.

Comments

0

The resolution to my issue is that I needed to return a void pointer. This may cause issues down the road with other things unrelated to this current problem, but this format had specific parameters to follow, which is why I mentioned main cannot change, among other things (including format). Thanks again.

4 Comments

Just any void *? You'd better check what it's used for.
This doesn't sound right. If your function really did need to return something in a void pointer, you'd already have been doing that. So it sounds like you've just hacked around having used the wrong return type, by returning some bogus/dummy value to shut up the compiler. That is not the proper solution.
void* Test::min(const Test &p) { // bunch of code; return this; } works for me. I'm able to modify the pointer using the referenced values from the passed in pointer. It compiles and works as I wanted it to.
Like I said, I have certain parameters that I have to follow. Unfortunately, that means that it may not look efficient or pleasing to look at. I could make it look more efficient but that would require changing main and adding a constructor in the base class and changing a lot of other things and that would cause problems when were specified to follow certain parameters. All in all, the issue is resolved and it does what I wanted it to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.