1

I've got a bit of a issue with pointers.

So to start off I have to use the C language, and I've created a struct called _Arguments that holds a set of data including a few pointers. Some of these pointers point to other structs that I've created.

I'll cut a few things out of the structs to help keep the post small but hopefully still containing the main information.

So we have:

struct _Arguments
{
    struct _AirPlanes *InAirPlanes;
    struct _GroundPlanes *GroundedPlanes;
    struct _Runway *Runways;
} Arguments;

Then

typedef struct _Runway
{
    struct _GroundPlanes *FirstGroundPlane;
    struct _AirPlanes *FirstAirPlane;
    struct _Runway *Next;
    struct _Runway *Previous;
};

And

typedef struct _AirPlanes
{
    struct _AirPlanes *Next;
    struct _AirPlanes *Previous;
    struct _AirPlanes *NextOnRunway;
    struct _AirPlanes *PrevOnRunway;
};

And Finally

typedef struct _GroundPlanes
{    
    struct _GroundPlanes *NextOnRunway;
    struct _GroundPlanes *PrevOnRunway;
    struct _GroundPlanes *Next;
    struct _GroundPlanes *Previous; 
};

The structs contain a few more vairables but that's the main parts.. So as you can see I'm kind of working with linked lists here and making a runway like thing.

Now I've got loads of the code up and running, however I'm having a issue when looking for the next best runway. I call a function in my main loop called

struct _Runway* NextAvailable = NextAvailableRunway(&Arguments.Runways);

This runs through all the runways to find the one with the least grounded planes. However, if there are two runways with the same number of grounded planes I then want to test them against one another to find out what one has the least planes waiting to land.

This means I have the following (Made shorthand so its easier to find the key issue)

struct _Runway* NextAvailableRunway(struct _Runway** MainStartingRunway)
{
    struct _Runway* CurrentRunway = *MainStartingRunway;
    struct _GroundPlanes* CurrentGroundedPlane;
    struct _Runway* BestRunway = NULL;

    // Main Loop used to check ALL Runways
    while (CurrentRunway != NULL)
    {
        // Look for the first plane on the current runway
        // Loop through all the planes to count the planes on current Runway
        // If the count of planes is the smallest found so far 
            BestRunway = CurrentRunway;

        // Else if it matches our current smallest
            BestRunway = RunwayWithLeastAir(BestRunway, CurrentRunway);

        // Then finally go to next runway to loop though them all
        CurrentRunway = CurrentRunway->Next;    
    }
    return BestRunway;
}

Obviously the code above is shortened but it works none the less other than the line

BestRunway = RunwayWithLeastAir(BestRunway, CurrentRunway);

So what I'm hoping to do here is pass over the BestRunway that we had along with the CurrentRunway so that we can test them both and return the best one of the two. As far as I can tell both things that are passed by that function are pointers to a struct and so with the following code it should be fine.

struct _Runway* RunwayWithLeastAir(struct _Runway* BestRunway, struct _Runway* CurrentRunway)
{
    struct _Runway* RunwayToCount = BestRunway;
    struct _AirPlanes* CurrentAirPlane = NULL; 
    struct _Runway* LeastAirRunway = NULL;
    int SmallestQueSize = -1;

    //  Loop through both runways
    // Count the planes in the air for runway 1
    // Count the planes in the air for runway 2
    // Return the runway with the least in air planes.

    while (RunwayToCount != NULL)
    {
        CurrentAirPlane = RunwayToCount->FirstAirPlane;
        int CurrentRunwaysQueSize = 0;

        // Loop to count the planes on current Runway
        while (CurrentAirPlane != NULL)
        {
            CurrentRunwaysQueSize++;    
            CurrentAirPlane = CurrentAirPlane->NextOnRunway;
        }

        if (CurrentRunwaysQueSize < SmallestQueSize || SmallestQueSize == -1)
        {
            SmallestQueSize = CurrentRunwaysQueSize;
            LeastAirRunway = RunwayToCount; 
        }

        if (RunwayToCount == BestRunway)
            RunwayToCount = CurrentRunway;
        else
            RunwayToCount = NULL;

    }
    return LeastAirRunway;
}

The error I get however is: Error C2373 'RunwayWithLeastAir': redefinition; different type modifiers

Now I'd assume that the issue here is that I'm passing something other than two pointers across to the RunwayWithLeastAir function. And when I comment out the line that runs the function (the one in the NextAvailableRunway function) it runs fine, however when i try and actually use the function the way I'd assume it should run it fails.

I believe this could be because I'm using a pointer pointer in the NextAvailableRunway function and so maybe when its passing CurrentRunway its actually passing something other than a standard pointer???

Any ideas guys?

James Best
  • 65
  • 1
  • 7
  • Why are you passing a pointer to a pointer to `NextAvailableRunway`? It doesn't make any sense. Also, the C specification reserves names beginning with an underscore followed by an upper-case letter in *all* scopes. – Some programmer dude Feb 24 '17 at 09:28
  • 1
    As for your problem, how does the *declaration* of `RunwayWithLeastAir` look like? You *do* have a declaration of it before you use it? And can you please edit your question to include a complete copy-paste of the full error, preferably the full build log? – Some programmer dude Feb 24 '17 at 09:28
  • I get these warnings (not related): 1>main.c(55): warning C4091: 'typedef ': ignored on left of '_Runway' when no variable is declared 1>main.c(64): warning C4091: 'typedef ': ignored on left of '_AirPlanes' when no variable is declared 1>main.c(73): warning C4091: 'typedef ': ignored on left of '_GroundPlanes' when no variable is declared – Jabberwocky Feb 24 '17 at 09:30
  • I pass a pointer to a pointer because I pass over through the function a pointer pointer, thus if I just passed it through as itself it wouldnt work properly. I mainly used this as a guide http://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c – James Best Feb 24 '17 at 09:31
  • Also using the code above will most likely show errors because it's not the full code.. I've had to shorten it by loads because the actual code is huge. – James Best Feb 24 '17 at 09:32
  • 2
    @JamesBest You don't really have those `typedef`s there, do you? Because that's not valid syntax, it can't be copy-pasted code that builds. The syntax can be described as `typedef DECLARATION ALIAS;` but you don't provide the ALIAS part. – unwind Feb 24 '17 at 09:32
  • As for the Declaration of RunwayWithLeastAir... it's defined just as shown, meaning that the function shown above is the only instance of its declaration and the function call is the only call – James Best Feb 24 '17 at 09:33
  • Could you provide a [MCVE]? – Jabberwocky Feb 24 '17 at 09:33
  • What you're doing with `NextAvailableRunway` is emulating *pass by reference*. It is useful if you want to modify the passed arguments inside the function, which you do not do (at least not in the simplified version you show us). – Some programmer dude Feb 24 '17 at 09:34
  • I can try and make a minimal example, however it would take some time as there's one main.cpp and 4 .h files that are all used :S – James Best Feb 24 '17 at 09:36
  • @JamesBest BTW: while making the [MCVE] you will most likely find out what's wrong by yourself – Jabberwocky Feb 24 '17 at 09:37
  • I can upload the full code as a pastebin if need be, but it can only be up for a short while as its part of a Uni project that shouldn't really be shared about, however i have no idea why its throwing that one issue.. – James Best Feb 24 '17 at 09:38
  • @JamesBest go for making a MCVE (all in one .c file). Anyway doing this is also a common debugging method. – Jabberwocky Feb 24 '17 at 09:40
  • Are you missing a prototype too? – Antti Haapala -- Слава Україні Feb 24 '17 at 09:41
  • I'll work on it now then... – James Best Feb 24 '17 at 09:42
  • 1
    Hint: don't look only on the errors but also on the warnings. – Jabberwocky Feb 24 '17 at 09:43

1 Answers1

1

Following lines gives you a warning:

BestRunway = RunwayWithLeastAir(BestRunway, CurrentRunway);

Warning C4013 'RunwayWithLeastAir' undefined; assuming extern returning int

These warnings should be considered as errors.

Now you declare your RunwayWithLeastAi like this:

struct _Runway* RunwayWithLeastAir(struct _Runway* BestRunway, struct _Runway*  CurrentRunway)

but as the compiler already assumed that RunwayWithLeastAir is a function returning int this declaration is in contraduction and hence error.

To get rid of the error you must declare the function before using it.

Just put this after your struct declarations, but at least before the NextAvailableRunway function.

struct _Runway* RunwayWithLeastAir(struct _Runway* BestRunway, struct _Runway*  CurrentRunway);

Following minimal example illustrates the problem:

int bar()
{
  foo(1);
}

void *foo(int a)
{
}

But this will compile:

void *foo(int a);

int bar()
{
  foo(1);
}

void *foo(int a)
{
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • OMG Thank you!! funny enough it was something simple that I had actually done so many times. I completely forgot that in the .h file for the two functions, the RunwayWithLeastAir function was created after the NextAvailableRunway function, thus it hadn't been declared a return type when compiling (Thus assumed int).... Honestly, I'm shocked that I didn't spot that earlier like I have with all the others. Adding in a declaration line at the top of the .h file soon fixed it, that or just swaping the functions around so that the NextAvailableRunway is written after the RunwayWithLeastAir. :D – James Best Feb 24 '17 at 09:55
  • Have done :) Going to take a break for now as lack of coffee might just be the issue haha Seriously, thank you though! – James Best Feb 24 '17 at 09:59